summaryrefslogtreecommitdiffstats
path: root/Python/pyfpe.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/pyfpe.c')
0 files changed, 0 insertions, 0 deletions
/td>
-rw-r--r--.gitlab-ci.yml125
-rwxr-xr-x.gitlab/ci/cmake.sh16
-rw-r--r--.gitlab/ci/configure_common.cmake3
-rw-r--r--.gitlab/ci/configure_debian10_iwyu.cmake4
-rw-r--r--.gitlab/ci/configure_fedora31_sphinx.cmake8
-rw-r--r--.gitlab/ci/configure_fedora31_tidy.cmake3
-rw-r--r--.gitlab/ci/configure_sccache.cmake2
-rw-r--r--.gitlab/ci/ctest_build.cmake30
-rw-r--r--.gitlab/ci/ctest_configure.cmake32
-rw-r--r--.gitlab/ci/ctest_exclusions.cmake6
-rw-r--r--.gitlab/ci/ctest_test.cmake24
-rw-r--r--.gitlab/ci/docker/debian10/Dockerfile15
-rwxr-xr-x.gitlab/ci/docker/debian10/install_deps.sh22
-rwxr-xr-x.gitlab/ci/docker/debian10/install_iwyu.sh32
-rw-r--r--.gitlab/ci/docker/fedora31/Dockerfile5
-rwxr-xr-x.gitlab/ci/docker/fedora31/install_deps.sh19
-rw-r--r--.gitlab/ci/gitlab_ci.cmake49
-rwxr-xr-x.gitlab/ci/ninja.sh15
-rwxr-xr-x.gitlab/ci/sccache.sh16
-rw-r--r--Auxiliary/CMakeLists.txt4
-rw-r--r--Auxiliary/bash-completion/CMakeLists.txt24
-rw-r--r--Auxiliary/vim/syntax/cmake.vim11
-rw-r--r--CMakeLists.txt78
-rw-r--r--CTestConfig.cmake2
-rw-r--r--CTestCustom.cmake.in7
-rw-r--r--Copyright.txt3
-rw-r--r--Help/command/DEVICE_LINK_OPTIONS.txt10
-rw-r--r--Help/command/FIND_XXX.txt9
-rw-r--r--Help/command/add_custom_command.rst47
-rw-r--r--Help/command/add_custom_target.rst3
-rw-r--r--Help/command/add_link_options.rst2
-rw-r--r--Help/command/cmake_command.rst90
-rw-r--r--Help/command/ctest_test.rst24
-rw-r--r--Help/command/execute_process.rst13
-rw-r--r--Help/command/file.rst138
-rw-r--r--Help/command/find_package.rst18
-rw-r--r--Help/command/foreach.rst45
-rw-r--r--Help/command/function.rst4
-rw-r--r--Help/command/get_property.rst10
-rw-r--r--Help/command/get_source_file_property.rst11
-rw-r--r--Help/command/install.rst76
-rw-r--r--Help/command/list.rst7
-rw-r--r--Help/command/macro.rst10
-rw-r--r--Help/command/mark_as_advanced.rst6
-rw-r--r--Help/command/message.rst120
-rw-r--r--Help/command/option.rst2
-rw-r--r--Help/command/project.rst7
-rw-r--r--Help/command/separate_arguments.rst2
-rw-r--r--Help/command/set_property.rst16
-rw-r--r--Help/command/set_source_files_properties.rst13
-rw-r--r--Help/command/source_group.rst6
-rw-r--r--Help/command/string.rst21
-rw-r--r--Help/command/target_compile_features.rst6
-rw-r--r--Help/command/target_link_options.rst2
-rw-r--r--Help/cpack_gen/archive.rst65
-rw-r--r--Help/cpack_gen/cygwin.rst5
-rw-r--r--Help/cpack_gen/dmg.rst15
-rw-r--r--Help/cpack_gen/freebsd.rst5
-rw-r--r--Help/cpack_gen/ifw.rst198
-rw-r--r--Help/cpack_gen/nsis.rst33
-rw-r--r--Help/cpack_gen/packagemaker.rst58
-rw-r--r--Help/cpack_gen/productbuild.rst52
-rw-r--r--Help/cpack_gen/rpm.rst24
-rw-r--r--Help/dev/maint.rst18
-rw-r--r--Help/dev/review.rst21
-rw-r--r--Help/dev/source.rst162
-rw-r--r--Help/envvar/CCMAKE_COLORS.rst34
-rw-r--r--Help/envvar/CMAKE_EXPORT_COMPILE_COMMANDS.rst9
-rw-r--r--Help/envvar/CMAKE_LANG_COMPILER_LAUNCHER.rst10
-rw-r--r--Help/envvar/CMAKE_PREFIX_PATH.rst17
-rw-r--r--Help/generator/Ninja Multi-Config.rst87
-rw-r--r--Help/generator/Ninja.rst12
-rw-r--r--Help/guide/tutorial/Complete/CMakeLists.txt4
-rw-r--r--Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt2
-rw-r--r--Help/guide/tutorial/Complete/MultiCPackConfig.cmake (renamed from Help/guide/tutorial/MultiPackage/MultiCPackConfig.cmake)1
-rw-r--r--Help/guide/tutorial/Complete/tutorial.cxx4
-rw-r--r--Help/guide/tutorial/Consumer/CMakeLists.txt51
-rw-r--r--Help/guide/tutorial/Consumer/Config.cmake.in14
-rw-r--r--Help/guide/tutorial/Consumer/consumer.cxx11
-rw-r--r--Help/guide/tutorial/MultiPackage/MathFunctions/MakeTable.cxx25
-rw-r--r--Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt2
-rw-r--r--Help/guide/tutorial/Step12/CMakeLists.txt (renamed from Help/guide/tutorial/MultiPackage/CMakeLists.txt)14
-rw-r--r--Help/guide/tutorial/Step12/CTestConfig.cmake7
-rw-r--r--Help/guide/tutorial/Step12/Config.cmake.in (renamed from Help/guide/tutorial/MultiPackage/Config.cmake.in)0
-rw-r--r--Help/guide/tutorial/Step12/License.txt (renamed from Help/guide/tutorial/MultiPackage/License.txt)0
-rw-r--r--Help/guide/tutorial/Step12/MathFunctions/CMakeLists.txt (renamed from Help/guide/tutorial/MultiPackage/MathFunctions/CMakeLists.txt)10
-rw-r--r--Help/guide/tutorial/Step12/MathFunctions/MakeTable.cxx (renamed from Help/guide/tutorial/Step5/MathFunctions/MakeTable.cxx)0
-rw-r--r--Help/guide/tutorial/Step12/MathFunctions/MathFunctions.cxx (renamed from Help/guide/tutorial/MultiPackage/MathFunctions/MathFunctions.cxx)0
-rw-r--r--Help/guide/tutorial/Step12/MathFunctions/MathFunctions.h (renamed from Help/guide/tutorial/MultiPackage/MathFunctions/MathFunctions.h)0
-rw-r--r--Help/guide/tutorial/Step12/MathFunctions/mysqrt.cxx (renamed from Help/guide/tutorial/MultiPackage/MathFunctions/mysqrt.cxx)3
-rw-r--r--Help/guide/tutorial/Step12/MathFunctions/mysqrt.h (renamed from Help/guide/tutorial/MultiPackage/MathFunctions/mysqrt.h)0
-rw-r--r--Help/guide/tutorial/Step12/TutorialConfig.h.in (renamed from Help/guide/tutorial/MultiPackage/TutorialConfig.h.in)2
-rw-r--r--Help/guide/tutorial/Step12/tutorial.cxx (renamed from Help/guide/tutorial/MultiPackage/tutorial.cxx)3
-rw-r--r--Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt12
-rw-r--r--Help/guide/tutorial/index.rst389
-rw-r--r--Help/guide/user-interaction/GUI-Add-Entry.pngbin0 -> 33430 bytes-rw-r--r--Help/guide/user-interaction/GUI-Choose-Generator.pngbin0 -> 42066 bytes-rw-r--r--Help/guide/user-interaction/GUI-Configure-Dialog.pngbin0 -> 35250 bytes-rw-r--r--Help/guide/user-interaction/GUI-Source-Binary.pngbin0 -> 61975 bytes-rw-r--r--Help/guide/user-interaction/index.rst691
-rw-r--r--Help/guide/using-dependencies/index.rst200
-rw-r--r--Help/index.rst31
-rw-r--r--Help/manual/ID_RESERVE.txt7
-rw-r--r--Help/manual/VS-Choose-Arch.pngbin0 -> 11130 bytes-rw-r--r--Help/manual/cmake-commands.7.rst1
-rw-r--r--Help/manual/cmake-compile-features.7.rst13
-rw-r--r--Help/manual/cmake-env-variables.7.rst17
-rw-r--r--Help/manual/cmake-file-api.7.rst4
-rw-r--r--Help/manual/cmake-generator-expressions.7.rst197
-rw-r--r--Help/manual/cmake-generators.7.rst5
-rw-r--r--Help/manual/cmake-language.7.rst2
-rw-r--r--Help/manual/cmake-modules.7.rst1
-rw-r--r--Help/manual/cmake-policies.7.rst23
-rw-r--r--Help/manual/cmake-properties.7.rst35
-rw-r--r--Help/manual/cmake-toolchains.7.rst3
-rw-r--r--Help/manual/cmake-variables.7.rst29
-rw-r--r--Help/manual/cmake.1.rst138
-rw-r--r--Help/manual/ctest.1.rst65
-rw-r--r--Help/module/FindCUDAToolkit.rst1
-rw-r--r--Help/policy/CMP0098.rst30
-rw-r--r--Help/policy/CMP0099.rst24
-rw-r--r--Help/policy/CMP0100.rst40
-rw-r--r--Help/policy/CMP0101.rst20
-rw-r--r--Help/policy/CMP0102.rst25
-rw-r--r--Help/policy/CMP0103.rst22
-rw-r--r--Help/policy/CMP0104.rst31
-rw-r--r--Help/policy/CMP0105.rst19
-rw-r--r--Help/policy/CMP0106.rst19
-rw-r--r--Help/prop_dir/LINK_OPTIONS.rst2
-rw-r--r--Help/prop_gbl/CMAKE_CUDA_KNOWN_FEATURES.rst30
-rw-r--r--Help/prop_sf/GENERATED.rst33
-rw-r--r--Help/prop_sf/SKIP_PRECOMPILE_HEADERS.rst4
-rw-r--r--Help/prop_sf/UNITY_GROUP.rst5
-rw-r--r--Help/prop_sf/VS_SETTINGS.rst18
-rw-r--r--Help/prop_tgt/AIX_EXPORT_ALL_SYMBOLS.rst12
-rw-r--r--Help/prop_tgt/AUTOGEN_PARALLEL.rst6
-rw-r--r--Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst2
-rw-r--r--Help/prop_tgt/AUTOMOC.rst2
-rw-r--r--Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst3
-rw-r--r--Help/prop_tgt/AUTOMOC_MOC_OPTIONS.rst6
-rw-r--r--Help/prop_tgt/AUTOMOC_PATH_PREFIX.rst4
-rw-r--r--Help/prop_tgt/AUTORCC.rst7
-rw-r--r--Help/prop_tgt/AUTORCC_OPTIONS.rst4
-rw-r--r--Help/prop_tgt/AUTOUIC.rst7
-rw-r--r--Help/prop_tgt/AUTOUIC_OPTIONS.rst4
-rw-r--r--Help/prop_tgt/COMPILE_FEATURES.rst3
-rw-r--r--Help/prop_tgt/CONFIG_POSTFIX.rst3
-rw-r--r--Help/prop_tgt/CUDA_ARCHITECTURES.rst30
-rw-r--r--Help/prop_tgt/CUDA_RUNTIME_LIBRARY-VALUES.txt9
-rw-r--r--Help/prop_tgt/CUDA_RUNTIME_LIBRARY.rst21
-rw-r--r--Help/prop_tgt/DEPRECATION.rst7
-rw-r--r--Help/prop_tgt/DOTNET_TARGET_FRAMEWORK.rst13
-rw-r--r--Help/prop_tgt/DOTNET_TARGET_FRAMEWORK_VERSION.rst10
-rw-r--r--Help/prop_tgt/FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG.rst25
-rw-r--r--Help/prop_tgt/INSTALL_NAME_DIR.rst4
-rw-r--r--Help/prop_tgt/INSTALL_RPATH.rst4
-rw-r--r--Help/prop_tgt/INSTALL_RPATH_USE_LINK_PATH.rst14
-rw-r--r--Help/prop_tgt/JOB_POOL_PRECOMPILE_HEADER.rst21
-rw-r--r--Help/prop_tgt/LINK_LIBRARIES_INDIRECTION.txt6
-rw-r--r--Help/prop_tgt/LINK_OPTIONS.rst12
-rw-r--r--Help/prop_tgt/MACHO_COMPATIBILITY_VERSION.rst25
-rw-r--r--Help/prop_tgt/MACHO_CURRENT_VERSION.rst25
-rw-r--r--Help/prop_tgt/PCH_WARN_INVALID.rst8
-rw-r--r--Help/prop_tgt/SOVERSION.rst18
-rw-r--r--Help/prop_tgt/UNITY_BUILD.rst24
-rw-r--r--Help/prop_tgt/UNITY_BUILD_MODE.rst58
-rw-r--r--Help/prop_tgt/VERSION.rst18
-rw-r--r--Help/prop_tgt/VS_DOTNET_DOCUMENTATION_FILE.rst6
-rw-r--r--Help/prop_tgt/VS_DOTNET_TARGET_FRAMEWORK_VERSION.rst3
-rw-r--r--Help/prop_tgt/VS_PLATFORM_TOOLSET.rst10
-rw-r--r--Help/prop_tgt/VS_SOLUTION_DEPLOY.rst29
-rw-r--r--Help/prop_tgt/VS_SOURCE_SETTINGS_tool.rst19
-rw-r--r--Help/prop_tgt/XCODE_GENERATE_SCHEME.rst1
-rw-r--r--Help/prop_tgt/XCODE_SCHEME_WORKING_DIRECTORY.rst13
-rw-r--r--Help/release/3.17.rst348
-rw-r--r--Help/release/dev/0-sample-topic.rst7
-rw-r--r--Help/release/dev/CPackRPM-trans-scripts.rst7
-rw-r--r--Help/release/dev/CTestCoverageCollectGCOV-compress-opts.rst7
-rw-r--r--Help/release/dev/FPHSA-handle_components.rst5
-rw-r--r--Help/release/dev/FindBLAS-import-target.rst4
-rw-r--r--Help/release/dev/FindLAPACK-import-target.rst4
-rw-r--r--Help/release/dev/FindPython-IronPython-support.rst5
-rw-r--r--Help/release/dev/FindPython-artifacts-interactive.rst6
-rw-r--r--Help/release/dev/FindPython-dev-subcomponents.rst6
-rw-r--r--Help/release/dev/FindPython-find-implementations.rst5
-rw-r--r--Help/release/dev/FindPython-pypy.rst5
-rw-r--r--Help/release/dev/FindRuby-variable-case.rst7
-rw-r--r--Help/release/dev/GoogleTest-DISCOVERY_MODE.rst7
-rw-r--r--Help/release/dev/GoogleTest-XML_OUTPUT_DIR.rst6
-rw-r--r--Help/release/dev/ccmake-custom-colors.rst5
-rw-r--r--Help/release/dev/cmake-gui-env-platform-defaults.rst8
-rw-r--r--Help/release/dev/cmake_command-command.rst6
-rw-r--r--Help/release/dev/command-line-cat.rst5
-rw-r--r--Help/release/dev/ctest_resource_spec_file-variable.rst6
-rw-r--r--Help/release/dev/ctest_stop_on_failure.rst8
-rw-r--r--Help/release/dev/cuda-architectures-empty.rst7
-rw-r--r--Help/release/dev/cuda-architectures.rst6
-rw-r--r--Help/release/dev/curl-http2.rst8
-rw-r--r--Help/release/dev/deprecate-documentation-module.rst6
-rw-r--r--Help/release/dev/deprecate-policy-old.rst8
-rw-r--r--Help/release/dev/device-link-options.rst5
-rw-r--r--Help/release/dev/execute_process.rst5
-rw-r--r--Help/release/dev/export-multiple-calls.rst5
-rw-r--r--Help/release/dev/file-upload-tls.rst5
-rw-r--r--Help/release/dev/file_archive.rst7
-rw-r--r--Help/release/dev/file_configure.rst6
-rw-r--r--Help/release/dev/findswig-components.rst5
-rw-r--r--Help/release/dev/framework-multi-config-postfix.rst7
-rw-r--r--Help/release/dev/genex-DEVICE_LINK-HOST_LINK.rst6
-rw-r--r--Help/release/dev/genex-LINK_LANGUAGE.rst5
-rw-r--r--Help/release/dev/grouped-unity-build-mode.rst6
-rw-r--r--Help/release/dev/libxslt.rst4
-rw-r--r--Help/release/dev/list_natural_sort.rst5
-rw-r--r--Help/release/dev/ninja-compiler-PATH-windows.rst7
-rw-r--r--Help/release/dev/nsis-dpi-aware.rst6
-rw-r--r--Help/release/dev/parallel-lzma-compression.rst6
-rw-r--r--Help/release/dev/pch-warn-invalid.rst6
-rw-r--r--Help/release/dev/profiling.rst9
-rw-r--r--Help/release/dev/required_find_commands.rst6
-rw-r--r--Help/release/dev/sf-property-scopes.rst15
-rw-r--r--Help/release/dev/source_group_forward_slashes.rst5
-rw-r--r--Help/release/dev/string-hex.rst5
-rw-r--r--Help/release/dev/useswig-fortran.rst7
-rw-r--r--Help/release/dev/vs-non-built-file-item-metadata.rst10
-rw-r--r--Help/release/dev/vs-platform-toolset.rst6
-rw-r--r--Help/release/dev/vs-sln-deploy.rst6
-rw-r--r--Help/release/index.rst3
-rw-r--r--Help/variable/CMAKE_AIX_EXPORT_ALL_SYMBOLS.rst6
-rw-r--r--Help/variable/CMAKE_CFG_INTDIR.rst7
-rw-r--r--Help/variable/CMAKE_CROSS_CONFIGS.rst15
-rw-r--r--Help/variable/CMAKE_CTEST_ARGUMENTS.rst6
-rw-r--r--Help/variable/CMAKE_CUDA_ARCHITECTURES.rst17
-rw-r--r--Help/variable/CMAKE_CUDA_COMPILE_FEATURES.rst11
-rw-r--r--Help/variable/CMAKE_CUDA_RUNTIME_LIBRARY.rst24
-rw-r--r--Help/variable/CMAKE_CURRENT_FUNCTION.rst10
-rw-r--r--Help/variable/CMAKE_CURRENT_FUNCTION_LIST_DIR.rst41
-rw-r--r--Help/variable/CMAKE_CURRENT_FUNCTION_LIST_FILE.rst9
-rw-r--r--Help/variable/CMAKE_CURRENT_FUNCTION_LIST_LINE.rst10
-rw-r--r--Help/variable/CMAKE_DEFAULT_BUILD_TYPE.rst12
-rw-r--r--Help/variable/CMAKE_DEFAULT_CONFIGS.rst19
-rw-r--r--Help/variable/CMAKE_DOTNET_TARGET_FRAMEWORK.rst16
-rw-r--r--Help/variable/CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION.rst6
-rw-r--r--Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst3
-rw-r--r--Help/variable/CMAKE_FIND_DEBUG_MODE.rst23
-rw-r--r--Help/variable/CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG.rst8
-rw-r--r--Help/variable/CMAKE_GENERATOR_TOOLSET.rst5
-rw-r--r--Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst2
-rw-r--r--Help/variable/CMAKE_HOST_SYSTEM_PROCESSOR.rst13
-rw-r--r--Help/variable/CMAKE_INSTALL_RPATH_USE_LINK_PATH.rst12
-rw-r--r--Help/variable/CMAKE_JOB_POOL_PRECOMPILE_HEADER.rst6
-rw-r--r--Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst3
-rw-r--r--Help/variable/CMAKE_MESSAGE_CONTEXT.rst62
-rw-r--r--Help/variable/CMAKE_MESSAGE_CONTEXT_SHOW.rst15
-rw-r--r--Help/variable/CMAKE_MESSAGE_LOG_LEVEL.rst15
-rw-r--r--Help/variable/CMAKE_PCH_WARN_INVALID.rst5
-rw-r--r--Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst2
-rw-r--r--Help/variable/CMAKE_PROJECT_INCLUDE.rst3
-rw-r--r--Help/variable/CMAKE_PROJECT_INCLUDE_BEFORE.rst3
-rw-r--r--Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE.rst3
-rw-r--r--Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE_BEFORE.rst11
-rw-r--r--Help/variable/CMAKE_VS_WINRT_BY_DEFAULT.rst14
-rw-r--r--Help/variable/CMAKE_XCODE_SCHEME_ENVIRONMENT.rst15
-rw-r--r--Help/variable/CMAKE_XCODE_SCHEME_WORKING_DIRECTORY.rst12
-rw-r--r--Help/variable/CTEST_CONFIGURATION_TYPE.rst3
-rw-r--r--Help/variable/CTEST_MEMORYCHECK_TYPE.rst2
-rw-r--r--Help/variable/CTEST_NIGHTLY_START_TIME.rst8
-rw-r--r--Help/variable/CTEST_RESOURCE_SPEC_FILE.rst5
-rw-r--r--Help/variable/PROJECT_SOURCE_DIR.rst8
-rw-r--r--Modules/AndroidTestUtilities.cmake4
-rw-r--r--Modules/CMakeASMCompiler.cmake.in2
-rw-r--r--Modules/CMakeASMInformation.cmake4
-rw-r--r--Modules/CMakeASM_MASMInformation.cmake2
-rw-r--r--Modules/CMakeASM_NASMInformation.cmake12
-rw-r--r--Modules/CMakeAddFortranSubdirectory.cmake15
-rw-r--r--Modules/CMakeCCompiler.cmake.in1
-rw-r--r--Modules/CMakeCInformation.cmake11
-rw-r--r--Modules/CMakeCSharpInformation.cmake2
-rw-r--r--Modules/CMakeCUDACompiler.cmake.in27
-rw-r--r--Modules/CMakeCUDACompilerId.cu.in2
-rw-r--r--Modules/CMakeCUDAInformation.cmake36
-rw-r--r--Modules/CMakeCXXCompiler.cmake.in1
-rw-r--r--Modules/CMakeCXXInformation.cmake11
-rw-r--r--Modules/CMakeCheckCompilerFlagCommonPatterns.cmake1
-rw-r--r--Modules/CMakeDetermineASMCompiler.cmake18
-rw-r--r--Modules/CMakeDetermineCCompiler.cmake12
-rw-r--r--Modules/CMakeDetermineCUDACompiler.cmake30
-rw-r--r--Modules/CMakeDetermineCXXCompiler.cmake12
-rw-r--r--Modules/CMakeDetermineCompileFeatures.cmake63
-rw-r--r--Modules/CMakeDetermineCompiler.cmake30
-rw-r--r--Modules/CMakeDetermineCompilerABI.cmake27
-rw-r--r--Modules/CMakeDetermineCompilerId.cmake40
-rw-r--r--Modules/CMakeDetermineFortranCompiler.cmake17
-rw-r--r--Modules/CMakeDetermineOBJCXXCompiler.cmake2
-rw-r--r--Modules/CMakeDetermineSwiftCompiler.cmake2
-rw-r--r--Modules/CMakeDetermineSystem.cmake2
-rw-r--r--Modules/CMakeFindBinUtils.cmake1
-rw-r--r--Modules/CMakeFindFrameworks.cmake26
-rw-r--r--Modules/CMakeFortranCompiler.cmake.in2
-rw-r--r--Modules/CMakeFortranInformation.cmake9
-rw-r--r--Modules/CMakeGenericSystem.cmake14
-rw-r--r--Modules/CMakeGraphVizOptions.cmake146
-rw-r--r--Modules/CMakeMinGWFindMake.cmake7
-rw-r--r--Modules/CMakeNinjaFindMake.cmake1
-rw-r--r--Modules/CMakeOBJCInformation.cmake11
-rw-r--r--Modules/CMakeOBJCXXInformation.cmake11
-rw-r--r--Modules/CMakePrintSystemInformation.cmake6
-rw-r--r--Modules/CMakeRCInformation.cmake2
-rw-r--r--Modules/CMakeSwiftCompiler.cmake.in2
-rw-r--r--Modules/CMakeSwiftInformation.cmake17
-rw-r--r--Modules/CMakeTestCCompiler.cmake6
-rw-r--r--Modules/CMakeTestCSharpCompiler.cmake8
-rw-r--r--Modules/CMakeTestCUDACompiler.cmake32
-rw-r--r--Modules/CMakeTestCXXCompiler.cmake6
-rw-r--r--Modules/CMakeTestCompilerCommon.cmake11
-rw-r--r--Modules/CMakeTestFortranCompiler.cmake12
-rw-r--r--Modules/CMakeTestOBJCCompiler.cmake6
-rw-r--r--Modules/CMakeTestOBJCXXCompiler.cmake6
-rw-r--r--Modules/CMakeTestSwiftCompiler.cmake11
-rw-r--r--Modules/CPack.cmake134
-rw-r--r--Modules/CPackComponent.cmake87
-rw-r--r--Modules/CPackIFW.cmake23
-rw-r--r--Modules/CTest.cmake6
-rw-r--r--Modules/CTestCoverageCollectGCOV.cmake72
-rw-r--r--Modules/CheckCCompilerFlag.cmake33
-rw-r--r--Modules/CheckCSourceCompiles.cmake6
-rw-r--r--Modules/CheckCSourceRuns.cmake6
-rw-r--r--Modules/CheckCXXCompilerFlag.cmake29
-rw-r--r--Modules/CheckCXXSourceCompiles.cmake6
-rw-r--r--Modules/CheckCXXSourceRuns.cmake6
-rw-r--r--Modules/CheckFortranFunctionExists.cmake17
-rw-r--r--Modules/CheckFortranSourceCompiles.cmake12
-rw-r--r--Modules/CheckFortranSourceRuns.cmake12
-rw-r--r--Modules/CheckFunctionExists.cmake6
-rw-r--r--Modules/CheckIPOSupported.cmake6
-rw-r--r--Modules/CheckIncludeFile.cmake6
-rw-r--r--Modules/CheckIncludeFileCXX.cmake6
-rw-r--r--Modules/CheckIncludeFiles.cmake6
-rw-r--r--Modules/CheckLanguage.cmake28
-rw-r--r--Modules/CheckLibraryExists.cmake6
-rw-r--r--Modules/CheckOBJCSourceCompiles.cmake6
-rw-r--r--Modules/CheckOBJCSourceRuns.cmake6
-rw-r--r--Modules/CheckOBJCXXSourceCompiles.cmake6
-rw-r--r--Modules/CheckOBJCXXSourceRuns.cmake6
-rw-r--r--Modules/CheckPrototypeDefinition.cmake7
-rw-r--r--Modules/CheckSymbolExists.cmake6
-rw-r--r--Modules/CheckTypeSize.c.in8
-rw-r--r--Modules/CheckTypeSize.cmake6
-rw-r--r--Modules/CheckVariableExists.cmake6
-rw-r--r--Modules/Compiler/AppleClang-CXX.cmake5
-rw-r--r--Modules/Compiler/AppleClang-OBJCXX.cmake5
-rw-r--r--Modules/Compiler/CMakeCommonCompilerMacros.cmake44
-rw-r--r--Modules/Compiler/Clang-C.cmake4
-rw-r--r--Modules/Compiler/Clang-CXX.cmake120
-rw-r--r--Modules/Compiler/Clang-OBJCXX.cmake69
-rw-r--r--Modules/Compiler/Clang.cmake122
-rw-r--r--Modules/Compiler/GNU-ASM.cmake6
-rw-r--r--Modules/Compiler/GNU.cmake8
-rw-r--r--Modules/Compiler/Intel-C.cmake2
-rw-r--r--Modules/Compiler/Intel-CXX.cmake2
-rw-r--r--Modules/Compiler/Intel.cmake5
-rw-r--r--Modules/Compiler/MSVC-C.cmake2
-rw-r--r--Modules/Compiler/MSVC-CXX.cmake2
-rw-r--r--Modules/Compiler/NAG-Fortran.cmake6
-rw-r--r--Modules/Compiler/NVIDIA-CUDA.cmake69
-rw-r--r--Modules/Compiler/NVIDIA-DetermineCompiler.cmake10
-rw-r--r--Modules/Compiler/OpenWatcom-C.cmake1
-rw-r--r--Modules/Compiler/OpenWatcom-CXX.cmake1
-rw-r--r--Modules/Compiler/OpenWatcom.cmake118
-rw-r--r--Modules/Compiler/QCC-CXX.cmake2
-rw-r--r--Modules/Compiler/QCC.cmake3
-rw-r--r--Modules/Compiler/TI-C.cmake8
-rw-r--r--Modules/Compiler/TI-CXX.cmake7
-rw-r--r--Modules/Compiler/XL-CXX.cmake8
-rw-r--r--Modules/Compiler/XL-Fortran.cmake5
-rwxr-xr-xModules/Compiler/XL-Fortran/cpp29
-rw-r--r--Modules/CompilerId/VS-10.vcxproj.in2
-rw-r--r--Modules/DartConfiguration.tcl.in2
-rw-r--r--Modules/DeployQt4.cmake3
-rw-r--r--Modules/Documentation.cmake28
-rw-r--r--Modules/ExternalProject.cmake111
-rw-r--r--Modules/FetchContent.cmake34
-rw-r--r--Modules/FetchContent/CMakeLists.cmake.in2
-rw-r--r--Modules/FindArmadillo.cmake83
-rw-r--r--Modules/FindBLAS.cmake749
-rw-r--r--Modules/FindBoost.cmake747
-rw-r--r--Modules/FindCUDA.cmake28
-rw-r--r--Modules/FindCUDA/run_nvcc.cmake6
-rw-r--r--Modules/FindCUDAToolkit.cmake888
-rw-r--r--Modules/FindCURL.cmake28
-rw-r--r--Modules/FindCurses.cmake5
-rw-r--r--Modules/FindDCMTK.cmake6
-rw-r--r--Modules/FindDoxygen.cmake8
-rw-r--r--Modules/FindFLEX.cmake73
-rw-r--r--Modules/FindGLEW.cmake2
-rw-r--r--Modules/FindGTK2.cmake119
-rw-r--r--Modules/FindGTest.cmake11
-rw-r--r--Modules/FindHDF5.cmake104
-rw-r--r--Modules/FindLAPACK.cmake641
-rw-r--r--Modules/FindLibArchive.cmake15
-rw-r--r--Modules/FindLibXml2.cmake32
-rw-r--r--Modules/FindLibXslt.cmake60
-rw-r--r--Modules/FindLua.cmake3
-rw-r--r--Modules/FindMFC.cmake6
-rw-r--r--Modules/FindMPI.cmake98
-rw-r--r--Modules/FindMatlab.cmake1
-rw-r--r--Modules/FindOpenACC.cmake1
-rw-r--r--Modules/FindOpenAL.cmake99
-rw-r--r--Modules/FindOpenCL.cmake6
-rw-r--r--Modules/FindOpenGL.cmake43
-rw-r--r--Modules/FindOpenMP.cmake33
-rw-r--r--Modules/FindOpenSSL.cmake5
-rw-r--r--Modules/FindPNG.cmake10
-rw-r--r--Modules/FindPackageHandleStandardArgs.cmake83
-rw-r--r--Modules/FindPkgConfig.cmake60
-rw-r--r--Modules/FindProtobuf.cmake26
-rw-r--r--Modules/FindPython.cmake147
-rw-r--r--Modules/FindPython/Support.cmake2215
-rw-r--r--Modules/FindPython2.cmake135
-rw-r--r--Modules/FindPython3.cmake149
-rw-r--r--Modules/FindRuby.cmake585
-rw-r--r--Modules/FindSWIG.cmake71
-rw-r--r--Modules/FindSquish.cmake68
-rw-r--r--Modules/FindTCL.cmake2
-rw-r--r--Modules/FindThreads.cmake52
-rw-r--r--Modules/FindVulkan.cmake34
-rw-r--r--Modules/FindX11.cmake94
-rw-r--r--Modules/FortranCInterface.cmake6
-rw-r--r--Modules/FortranCInterface/CMakeLists.txt4
-rw-r--r--Modules/FortranCInterface/Detect.cmake16
-rw-r--r--Modules/GNUInstallDirs.cmake19
-rw-r--r--Modules/GoogleTest.cmake140
-rw-r--r--Modules/GoogleTestAddTests.cmake254
-rw-r--r--Modules/Internal/CPack/CPackDeb.cmake4
-rw-r--r--Modules/Internal/CPack/CPackFreeBSD.cmake2
-rw-r--r--Modules/Internal/CPack/CPackNuGet.cmake35
-rw-r--r--Modules/Internal/CPack/CPackRPM.cmake22
-rw-r--r--Modules/Internal/CPack/NSIS.template.in33
-rw-r--r--Modules/Internal/FeatureTesting.cmake14
-rw-r--r--Modules/Platform/AIX-GNU.cmake6
-rw-r--r--Modules/Platform/AIX-XL.cmake6
-rwxr-xr-xModules/Platform/AIX/ExportImportList37
-rw-r--r--Modules/Platform/Android-Clang.cmake8
-rw-r--r--Modules/Platform/Android-Common.cmake2
-rw-r--r--Modules/Platform/Android-Determine.cmake6
-rw-r--r--Modules/Platform/Android-Initialize.cmake6
-rw-r--r--Modules/Platform/Android.cmake5
-rw-r--r--Modules/Platform/Android/Determine-Compiler.cmake10
-rw-r--r--Modules/Platform/Apple-GNU.cmake12
-rw-r--r--Modules/Platform/BlueGeneL.cmake8
-rw-r--r--Modules/Platform/BlueGeneP-base.cmake4
-rw-r--r--Modules/Platform/BlueGeneQ-base.cmake6
-rw-r--r--Modules/Platform/CYGWIN-GNU.cmake2
-rw-r--r--Modules/Platform/DOS-OpenWatcom-C.cmake1
-rw-r--r--Modules/Platform/DOS-OpenWatcom-CXX.cmake1
-rw-r--r--Modules/Platform/DOS-OpenWatcom.cmake28
-rw-r--r--Modules/Platform/DOS.cmake14
-rw-r--r--Modules/Platform/Darwin-Initialize.cmake170
-rw-r--r--Modules/Platform/Darwin.cmake2
-rw-r--r--Modules/Platform/Generic-SDCC-C.cmake35
-rw-r--r--Modules/Platform/HP-UX-HP-C.cmake2
-rw-r--r--Modules/Platform/Linux-OpenWatcom-C.cmake1
-rw-r--r--Modules/Platform/Linux-OpenWatcom-CXX.cmake1
-rw-r--r--Modules/Platform/Linux-OpenWatcom.cmake25
-rw-r--r--Modules/Platform/Linux-como.cmake2
-rw-r--r--Modules/Platform/OS2-OpenWatcom-C.cmake1
-rw-r--r--Modules/Platform/OS2-OpenWatcom-CXX.cmake1
-rw-r--r--Modules/Platform/OS2-OpenWatcom.cmake35
-rw-r--r--Modules/Platform/OS2.cmake14
-rw-r--r--Modules/Platform/UnixPaths.cmake4
-rw-r--r--Modules/Platform/Windows-Apple-Swift.cmake1
-rw-r--r--Modules/Platform/Windows-Clang-ASM.cmake2
-rw-r--r--Modules/Platform/Windows-Clang.cmake62
-rw-r--r--Modules/Platform/Windows-Embarcadero.cmake2
-rw-r--r--Modules/Platform/Windows-GNU-ASM.cmake2
-rw-r--r--Modules/Platform/Windows-GNU.cmake14
-rw-r--r--Modules/Platform/Windows-Intel.cmake2
-rw-r--r--Modules/Platform/Windows-MSVC.cmake4
-rw-r--r--Modules/Platform/Windows-NVIDIA-CUDA.cmake24
-rw-r--r--Modules/Platform/Windows-OpenWatcom.cmake115
-rw-r--r--Modules/Platform/Windows-PGI.cmake3
-rw-r--r--Modules/Platform/Windows-df.cmake4
-rw-r--r--Modules/Platform/WindowsPhone-Clang-ASM.cmake1
-rw-r--r--Modules/Platform/WindowsPhone-GNU-ASM.cmake1
-rw-r--r--Modules/Platform/WindowsStore-Clang-ASM.cmake1
-rw-r--r--Modules/Platform/WindowsStore-GNU-ASM.cmake1
-rw-r--r--Modules/Platform/eCos.cmake4
-rw-r--r--Modules/Platform/gas.cmake2
-rw-r--r--Modules/Qt4Macros.cmake12
-rwxr-xr-xModules/Squish4RunTestCase.bat2
-rw-r--r--Modules/TestBigEndian.cmake17
-rw-r--r--Modules/TestCXXAcceptsFlag.cmake6
-rw-r--r--Modules/TestForANSIForScope.cmake6
-rw-r--r--Modules/TestForSSTREAM.cmake6
-rw-r--r--Modules/TestForSTDNamespace.cmake6
-rw-r--r--Modules/UseEcos.cmake6
-rw-r--r--Modules/UseJava.cmake90
-rw-r--r--Modules/UseJava/ClearClassFiles.cmake17
-rw-r--r--Modules/UseSWIG.cmake20
-rw-r--r--Source/CMakeLists.txt26
-rw-r--r--Source/CMakeVersion.cmake4
-rw-r--r--Source/CPack/IFW/cmCPackIFWCommon.cxx2
-rw-r--r--Source/CPack/IFW/cmCPackIFWGenerator.cxx10
-rw-r--r--Source/CPack/IFW/cmCPackIFWPackage.cxx3
-rw-r--r--Source/CPack/IFW/cmCPackIFWRepository.cxx4
-rw-r--r--Source/CPack/OSXScriptLauncher.cxx16
-rw-r--r--Source/CPack/WiX/cmCPackWIXGenerator.cxx32
-rw-r--r--Source/CPack/WiX/cmCPackWIXGenerator.h5
-rw-r--r--Source/CPack/WiX/cmWIXAccessControlList.cxx15
-rw-r--r--Source/CPack/WiX/cmWIXFilesSourceWriter.cxx5
-rw-r--r--Source/CPack/WiX/cmWIXPatch.cxx2
-rw-r--r--Source/CPack/WiX/cmWIXPatchParser.cxx24
-rw-r--r--Source/CPack/WiX/cmWIXPatchParser.h8
-rw-r--r--Source/CPack/cmCPackArchiveGenerator.cxx36
-rw-r--r--Source/CPack/cmCPackArchiveGenerator.h2
-rw-r--r--Source/CPack/cmCPackDebGenerator.cxx32
-rw-r--r--Source/CPack/cmCPackDragNDropGenerator.cxx51
-rw-r--r--Source/CPack/cmCPackExternalGenerator.cxx6
-rw-r--r--Source/CPack/cmCPackFreeBSDGenerator.cxx5
-rw-r--r--Source/CPack/cmCPackGenerator.cxx10
-rw-r--r--Source/CPack/cmCPackLog.cxx40
-rw-r--r--Source/CPack/cmCPackLog.h21
-rw-r--r--Source/CPack/cmCPackNSISGenerator.cxx79
-rw-r--r--Source/CPack/cmCPackNSISGenerator.h5
-rw-r--r--Source/CPack/cmCPackOSXX11Generator.cxx3
-rw-r--r--Source/CPack/cmCPackPKGGenerator.cxx66
-rw-r--r--Source/CPack/cmCPackPKGGenerator.h8
-rw-r--r--Source/CPack/cmCPackPackageMakerGenerator.cxx5
-rw-r--r--Source/CPack/cmCPackProductBuildGenerator.cxx2
-rw-r--r--Source/CPack/cpack.cxx11
-rw-r--r--Source/CTest/cmCTestBZR.cxx9
-rw-r--r--Source/CTest/cmCTestBuildAndTestHandler.cxx40
-rw-r--r--Source/CTest/cmCTestBuildCommand.cxx13
-rw-r--r--Source/CTest/cmCTestBuildCommand.h2
-rw-r--r--Source/CTest/cmCTestBuildHandler.cxx29
-rw-r--r--Source/CTest/cmCTestCVS.cxx6
-rw-r--r--Source/CTest/cmCTestConfigureCommand.cxx9
-rw-r--r--Source/CTest/cmCTestCoverageCommand.cxx6
-rw-r--r--Source/CTest/cmCTestCoverageHandler.cxx57
-rw-r--r--Source/CTest/cmCTestCurl.cxx9
-rw-r--r--Source/CTest/cmCTestCurl.h2
-rw-r--r--Source/CTest/cmCTestGIT.cxx4
-rw-r--r--Source/CTest/cmCTestHG.cxx5
-rw-r--r--Source/CTest/cmCTestHandlerCommand.cxx2
-rw-r--r--Source/CTest/cmCTestMemCheckCommand.cxx2
-rw-r--r--Source/CTest/cmCTestMemCheckHandler.cxx224
-rw-r--r--Source/CTest/cmCTestMemCheckHandler.h4
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.cxx162
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.h30
-rw-r--r--Source/CTest/cmCTestP4.cxx5
-rw-r--r--Source/CTest/cmCTestResourceSpec.cxx6
-rw-r--r--Source/CTest/cmCTestRunTest.cxx91
-rw-r--r--Source/CTest/cmCTestRunTest.h36
-rw-r--r--Source/CTest/cmCTestSVN.cxx7
-rw-r--r--Source/CTest/cmCTestScriptHandler.cxx60
-rw-r--r--Source/CTest/cmCTestScriptHandler.h26
-rw-r--r--Source/CTest/cmCTestSubmitCommand.cxx16
-rw-r--r--Source/CTest/cmCTestSubmitHandler.cxx46
-rw-r--r--Source/CTest/cmCTestTestCommand.cxx17
-rw-r--r--Source/CTest/cmCTestTestCommand.h2
-rw-r--r--Source/CTest/cmCTestTestHandler.cxx234
-rw-r--r--Source/CTest/cmCTestTestHandler.h9
-rw-r--r--Source/CTest/cmCTestUploadCommand.cxx7
-rw-r--r--Source/CTest/cmCTestVC.cxx2
-rw-r--r--Source/CTest/cmCTestVC.h2
-rw-r--r--Source/CTest/cmParseCacheCoverage.cxx34
-rw-r--r--Source/CTest/cmParseCacheCoverage.h5
-rw-r--r--Source/CTest/cmParseCoberturaCoverage.cxx2
-rw-r--r--Source/CTest/cmParseGTMCoverage.cxx2
-rw-r--r--Source/CTest/cmParseGTMCoverage.h2
-rw-r--r--Source/CTest/cmParseMumpsCoverage.cxx9
-rw-r--r--Source/CTest/cmParseMumpsCoverage.h4
-rw-r--r--Source/CTest/cmParsePHPCoverage.cxx10
-rw-r--r--Source/CTest/cmProcess.cxx53
-rw-r--r--Source/CTest/cmProcess.h15
-rw-r--r--Source/Checks/Curses.cmake9
-rw-r--r--Source/Checks/cm_c11_thread_local.cmake10
-rw-r--r--Source/Checks/cm_cxx14_check.cmake12
-rw-r--r--Source/Checks/cm_cxx17_check.cmake12
-rw-r--r--Source/Checks/cm_cxx17_check.cpp10
-rw-r--r--Source/Checks/cm_cxx_features.cmake16
-rw-r--r--Source/Checks/cm_message_checks_compat.cmake13
-rw-r--r--Source/CursesDialog/CMakeLists.txt25
-rw-r--r--Source/CursesDialog/ccmake.cxx29
-rw-r--r--Source/CursesDialog/cmCursesBoolWidget.cxx15
-rw-r--r--Source/CursesDialog/cmCursesCacheEntryComposite.cxx16
-rw-r--r--Source/CursesDialog/cmCursesColor.cxx78
-rw-r--r--Source/CursesDialog/cmCursesColor.h27
-rw-r--r--Source/CursesDialog/cmCursesLongMessageForm.cxx62
-rw-r--r--Source/CursesDialog/cmCursesLongMessageForm.h15
-rw-r--r--Source/CursesDialog/cmCursesMainForm.cxx294
-rw-r--r--Source/CursesDialog/cmCursesMainForm.h25
-rw-r--r--Source/CursesDialog/cmCursesOptionsWidget.cxx10
-rw-r--r--Source/CursesDialog/cmCursesPathWidget.cxx8
-rw-r--r--Source/CursesDialog/cmCursesStringWidget.cxx10
-rw-r--r--Source/LexerParser/.gitattributes2
-rw-r--r--Source/LexerParser/cmCommandArgumentParser.cxx121
-rw-r--r--Source/LexerParser/cmCommandArgumentParserTokens.h2
-rw-r--r--Source/LexerParser/cmDependsJavaParser.cxx1381
-rw-r--r--Source/LexerParser/cmDependsJavaParserTokens.h2
-rw-r--r--Source/LexerParser/cmExprParser.cxx121
-rw-r--r--Source/LexerParser/cmExprParserTokens.h2
-rw-r--r--Source/LexerParser/cmFortranParser.cxx372
-rw-r--r--Source/LexerParser/cmFortranParser.y1
-rw-r--r--Source/LexerParser/cmFortranParserTokens.h9
-rw-r--r--Source/LexerParser/cmGccDepfileLexer.cxx2210
-rw-r--r--Source/LexerParser/cmGccDepfileLexer.h687
-rw-r--r--Source/LexerParser/cmGccDepfileLexer.in.l72
-rw-r--r--Source/LexerParser/cmListFileLexer.c14
-rw-r--r--Source/LexerParser/cmListFileLexer.in.l14
-rw-r--r--Source/QtDialog/CMakeLists.txt4
-rw-r--r--Source/QtDialog/CMakeSetup.cxx6
-rw-r--r--Source/QtDialog/CMakeSetupDialog.cxx28
-rw-r--r--Source/QtDialog/CMakeSetupDialog.h4
-rw-r--r--Source/QtDialog/FirstConfigure.cxx49
-rw-r--r--Source/QtDialog/FirstConfigure.h5
-rw-r--r--Source/QtDialog/QCMake.cxx48
-rw-r--r--Source/QtDialog/QCMake.h3
-rw-r--r--Source/bindexplib.cxx71
-rw-r--r--Source/cmAddCustomCommandCommand.cxx11
-rw-r--r--Source/cmAddCustomTargetCommand.cxx7
-rw-r--r--Source/cmAddDependenciesCommand.cxx2
-rw-r--r--Source/cmAddLibraryCommand.cxx5
-rw-r--r--Source/cmAddSubDirectoryCommand.cxx8
-rw-r--r--Source/cmAddTestCommand.cxx6
-rw-r--r--Source/cmAffinity.cxx2
-rw-r--r--Source/cmAlgorithms.h106
-rw-r--r--Source/cmArchiveWrite.cxx33
-rw-r--r--Source/cmArchiveWrite.h5
-rw-r--r--Source/cmArgumentParser.cxx1
-rw-r--r--Source/cmArgumentParser.h3
-rw-r--r--Source/cmAuxSourceDirectoryCommand.cxx7
-rw-r--r--Source/cmBinUtilsLinuxELFLinker.cxx15
-rw-r--r--Source/cmBuildCommand.cxx2
-rw-r--r--Source/cmBuildNameCommand.cxx4
-rw-r--r--Source/cmCMakeCommand.cxx81
-rw-r--r--Source/cmCMakeCommand.h20
-rw-r--r--Source/cmCPluginAPI.cxx51
-rw-r--r--Source/cmCPluginAPI.h4
-rw-r--r--Source/cmCTest.cxx343
-rw-r--r--Source/cmCTest.h32
-rw-r--r--Source/cmCacheManager.cxx331
-rw-r--r--Source/cmCacheManager.h197
-rw-r--r--Source/cmCallVisualStudioMacro.cxx38
-rw-r--r--Source/cmCommandArgumentParserHelper.cxx39
-rw-r--r--Source/cmCommandArgumentParserHelper.h3
-rw-r--r--Source/cmCommands.cxx5
-rw-r--r--Source/cmCommonTargetGenerator.cxx104
-rw-r--r--Source/cmCommonTargetGenerator.h42
-rw-r--r--Source/cmComputeComponentGraph.cxx2
-rw-r--r--Source/cmComputeLinkDepends.cxx6
-rw-r--r--Source/cmComputeLinkDepends.h3
-rw-r--r--Source/cmComputeLinkInformation.cxx113
-rw-r--r--Source/cmComputeLinkInformation.h11
-rw-r--r--Source/cmComputeTargetDepends.cxx72
-rw-r--r--Source/cmComputeTargetDepends.h4
-rw-r--r--Source/cmConditionEvaluator.cxx11
-rw-r--r--Source/cmConfigureFileCommand.cxx25
-rw-r--r--Source/cmConnection.cxx11
-rw-r--r--Source/cmConnection.h2
-rw-r--r--Source/cmConvertMSBuildXMLToJSON.py9
-rw-r--r--Source/cmCoreTryCompile.cxx57
-rw-r--r--Source/cmCryptoHash.cxx6
-rw-r--r--Source/cmCurl.h2
-rw-r--r--Source/cmCustomCommand.cxx22
-rw-r--r--Source/cmCustomCommand.h13
-rw-r--r--Source/cmCustomCommandGenerator.cxx24
-rw-r--r--Source/cmDefinePropertyCommand.cxx2
-rw-r--r--Source/cmDepends.cxx35
-rw-r--r--Source/cmDepends.h12
-rw-r--r--Source/cmDependsC.cxx37
-rw-r--r--Source/cmDependsC.h7
-rw-r--r--Source/cmDependsFortran.cxx50
-rw-r--r--Source/cmDependsFortran.h7
-rw-r--r--Source/cmDependsJavaParserHelper.cxx11
-rw-r--r--Source/cmDependsJavaParserHelper.h3
-rw-r--r--Source/cmDocumentationSection.h5
-rw-r--r--Source/cmDynamicLoader.cxx22
-rw-r--r--Source/cmELF.cxx11
-rw-r--r--Source/cmExecuteProcessCommand.cxx30
-rw-r--r--Source/cmExportBuildAndroidMKGenerator.cxx9
-rw-r--r--Source/cmExportBuildFileGenerator.cxx9
-rw-r--r--Source/cmExportBuildFileGenerator.h5
-rw-r--r--Source/cmExportCommand.cxx44
-rw-r--r--Source/cmExportFileGenerator.cxx88
-rw-r--r--Source/cmExportFileGenerator.h2
-rw-r--r--Source/cmExportInstallAndroidMKGenerator.cxx4
-rw-r--r--Source/cmExportInstallFileGenerator.cxx15
-rw-r--r--Source/cmExportLibraryDependenciesCommand.cxx19
-rw-r--r--Source/cmExportTryCompileFileGenerator.cxx15
-rw-r--r--Source/cmExprParserHelper.h2
-rw-r--r--Source/cmExternalMakefileProjectGenerator.h9
-rw-r--r--Source/cmExtraCodeBlocksGenerator.cxx38
-rw-r--r--Source/cmExtraCodeLiteGenerator.cxx25
-rw-r--r--Source/cmExtraEclipseCDT4Generator.cxx93
-rw-r--r--Source/cmExtraEclipseCDT4Generator.h2
-rw-r--r--Source/cmExtraKateGenerator.cxx60
-rw-r--r--Source/cmExtraKateGenerator.h8
-rw-r--r--Source/cmExtraSublimeTextGenerator.cxx43
-rw-r--r--Source/cmExtraSublimeTextGenerator.h3
-rw-r--r--Source/cmFLTKWrapUICommand.cxx16
-rw-r--r--Source/cmFileAPI.h6
-rw-r--r--Source/cmFileAPICMakeFiles.cxx5
-rw-r--r--Source/cmFileAPICMakeFiles.h2
-rw-r--r--Source/cmFileAPICache.cxx7
-rw-r--r--Source/cmFileAPICache.h2
-rw-r--r--Source/cmFileAPICodemodel.cxx59
-rw-r--r--Source/cmFileAPICodemodel.h2
-rw-r--r--Source/cmFileCommand.cxx398
-rw-r--r--Source/cmFileLock.cxx25
-rw-r--r--Source/cmFileLock.h2
-rw-r--r--Source/cmFileLockPool.cxx52
-rw-r--r--Source/cmFileLockPool.h14
-rw-r--r--Source/cmFileMonitor.cxx35
-rw-r--r--Source/cmFileMonitor.h5
-rw-r--r--Source/cmFindBase.cxx150
-rw-r--r--Source/cmFindBase.h42
-rw-r--r--Source/cmFindCommon.cxx22
-rw-r--r--Source/cmFindCommon.h9
-rw-r--r--Source/cmFindLibraryCommand.cxx80
-rw-r--r--Source/cmFindPackageCommand.cxx181
-rw-r--r--Source/cmFindPackageCommand.h4
-rw-r--r--Source/cmFindPathCommand.cxx29
-rw-r--r--Source/cmFindPathCommand.h4
-rw-r--r--Source/cmFindProgramCommand.cxx31
-rw-r--r--Source/cmForEachCommand.cxx425
-rw-r--r--Source/cmFunctionBlocker.cxx2
-rw-r--r--Source/cmFunctionCommand.cxx83
-rw-r--r--Source/cmGccDepfileLexerHelper.cxx126
-rw-r--r--Source/cmGccDepfileLexerHelper.h40
-rw-r--r--Source/cmGccDepfileReader.cxx18
-rw-r--r--Source/cmGccDepfileReader.h10
-rw-r--r--Source/cmGccDepfileReaderTypes.h17
-rw-r--r--Source/cmGeneratedFileStream.cxx4
-rw-r--r--Source/cmGeneratorExpression.cxx44
-rw-r--r--Source/cmGeneratorExpression.h18
-rw-r--r--Source/cmGeneratorExpressionContext.cxx1
-rw-r--r--Source/cmGeneratorExpressionContext.h1
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.cxx83
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.h12
-rw-r--r--Source/cmGeneratorExpressionEvaluator.cxx21
-rw-r--r--Source/cmGeneratorExpressionEvaluator.h16
-rw-r--r--Source/cmGeneratorExpressionNode.cxx264
-rw-r--r--Source/cmGeneratorExpressionParser.cxx66
-rw-r--r--Source/cmGeneratorExpressionParser.h10
-rw-r--r--Source/cmGeneratorTarget.cxx1639
-rw-r--r--Source/cmGeneratorTarget.h155
-rw-r--r--Source/cmGetCMakePropertyCommand.cxx12
-rw-r--r--Source/cmGetDirectoryPropertyCommand.cxx15
-rw-r--r--Source/cmGetFilenameComponentCommand.cxx4
-rw-r--r--Source/cmGetPipes.cxx3
-rw-r--r--Source/cmGetPropertyCommand.cxx87
-rw-r--r--Source/cmGetSourceFilePropertyCommand.cxx52
-rw-r--r--Source/cmGetTargetPropertyCommand.cxx4
-rw-r--r--Source/cmGhsMultiTargetGenerator.cxx112
-rw-r--r--Source/cmGlobVerificationManager.cxx2
-rw-r--r--Source/cmGlobalBorlandMakefileGenerator.cxx13
-rw-r--r--Source/cmGlobalBorlandMakefileGenerator.h11
-rw-r--r--Source/cmGlobalCommonGenerator.cxx13
-rw-r--r--Source/cmGlobalGenerator.cxx386
-rw-r--r--Source/cmGlobalGenerator.h72
-rw-r--r--Source/cmGlobalGeneratorFactory.h14
-rw-r--r--Source/cmGlobalGhsMultiGenerator.cxx128
-rw-r--r--Source/cmGlobalGhsMultiGenerator.h14
-rw-r--r--Source/cmGlobalJOMMakefileGenerator.cxx2
-rw-r--r--Source/cmGlobalJOMMakefileGenerator.h6
-rw-r--r--Source/cmGlobalMSYSMakefileGenerator.h7
-rw-r--r--Source/cmGlobalMinGWMakefileGenerator.h8
-rw-r--r--Source/cmGlobalNMakeMakefileGenerator.cxx2
-rw-r--r--Source/cmGlobalNMakeMakefileGenerator.h7
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx1134
-rw-r--r--Source/cmGlobalNinjaGenerator.h271
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx441
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.h37
-rw-r--r--Source/cmGlobalVisualStudio10Generator.cxx87
-rw-r--r--Source/cmGlobalVisualStudio10Generator.h15
-rw-r--r--Source/cmGlobalVisualStudio11Generator.cxx32
-rw-r--r--Source/cmGlobalVisualStudio11Generator.h3
-rw-r--r--Source/cmGlobalVisualStudio12Generator.cxx24
-rw-r--r--Source/cmGlobalVisualStudio12Generator.h3
-rw-r--r--Source/cmGlobalVisualStudio14Generator.cxx31
-rw-r--r--Source/cmGlobalVisualStudio14Generator.h3
-rw-r--r--Source/cmGlobalVisualStudio71Generator.cxx27
-rw-r--r--Source/cmGlobalVisualStudio71Generator.h12
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx65
-rw-r--r--Source/cmGlobalVisualStudio7Generator.h19
-rw-r--r--Source/cmGlobalVisualStudio8Generator.cxx104
-rw-r--r--Source/cmGlobalVisualStudio8Generator.h6
-rw-r--r--Source/cmGlobalVisualStudio9Generator.cxx32
-rw-r--r--Source/cmGlobalVisualStudio9Generator.h4
-rw-r--r--Source/cmGlobalVisualStudioGenerator.cxx58
-rw-r--r--Source/cmGlobalVisualStudioGenerator.h2
-rw-r--r--Source/cmGlobalVisualStudioVersionedGenerator.cxx46
-rw-r--r--Source/cmGlobalVisualStudioVersionedGenerator.h5
-rw-r--r--Source/cmGlobalWatcomWMakeGenerator.cxx12
-rw-r--r--Source/cmGlobalWatcomWMakeGenerator.h9
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx278
-rw-r--r--Source/cmGlobalXCodeGenerator.h17
-rw-r--r--Source/cmGraphAdjacencyList.h6
-rw-r--r--Source/cmGraphVizWriter.cxx719
-rw-r--r--Source/cmGraphVizWriter.h93
-rw-r--r--Source/cmIDEOptions.cxx6
-rw-r--r--Source/cmIfCommand.cxx3
-rw-r--r--Source/cmIncludeCommand.cxx35
-rw-r--r--Source/cmIncludeDirectoryCommand.cxx7
-rw-r--r--Source/cmIncludeExternalMSProjectCommand.cxx17
-rw-r--r--Source/cmInstallCommand.cxx179
-rw-r--r--Source/cmInstallCommandArguments.cxx2
-rw-r--r--Source/cmInstallDirectoryGenerator.cxx16
-rw-r--r--Source/cmInstallDirectoryGenerator.h21
-rw-r--r--Source/cmInstallExportGenerator.cxx25
-rw-r--r--Source/cmInstallExportGenerator.h27
-rw-r--r--Source/cmInstallFilesCommand.cxx22
-rw-r--r--Source/cmInstallFilesGenerator.cxx15
-rw-r--r--Source/cmInstallFilesGenerator.h18
-rw-r--r--Source/cmInstallGenerator.cxx15
-rw-r--r--Source/cmInstallGenerator.h14
-rw-r--r--Source/cmInstallProgramsCommand.cxx22
-rw-r--r--Source/cmInstallScriptGenerator.cxx12
-rw-r--r--Source/cmInstallScriptGenerator.h9
-rw-r--r--Source/cmInstallSubdirectoryGenerator.cxx12
-rw-r--r--Source/cmInstallSubdirectoryGenerator.h6
-rw-r--r--Source/cmInstallTargetGenerator.cxx22
-rw-r--r--Source/cmInstallTargetGenerator.h20
-rw-r--r--Source/cmInstalledFile.cxx23
-rw-r--r--Source/cmInstalledFile.h8
-rw-r--r--Source/cmJsonObjects.cxx45
-rw-r--r--Source/cmJsonObjects.h2
-rw-r--r--Source/cmLinkItem.cxx15
-rw-r--r--Source/cmLinkItem.h22
-rw-r--r--Source/cmLinkItemGraphVisitor.cxx142
-rw-r--r--Source/cmLinkItemGraphVisitor.h75
-rw-r--r--Source/cmLinkLibrariesCommand.cxx2
-rw-r--r--Source/cmLinkLineComputer.cxx30
-rw-r--r--Source/cmLinkLineComputer.h2
-rw-r--r--Source/cmLinkLineDeviceComputer.cxx13
-rw-r--r--Source/cmListCommand.cxx29
-rw-r--r--Source/cmListFileCache.cxx51
-rw-r--r--Source/cmListFileCache.h3
-rw-r--r--Source/cmLoadCacheCommand.cxx8
-rw-r--r--Source/cmLoadCommandCommand.cxx19
-rw-r--r--Source/cmLocalCommonGenerator.cxx19
-rw-r--r--Source/cmLocalCommonGenerator.h8
-rw-r--r--Source/cmLocalGenerator.cxx1465
-rw-r--r--Source/cmLocalGenerator.h148
-rw-r--r--Source/cmLocalGhsMultiGenerator.cxx7
-rw-r--r--Source/cmLocalNinjaGenerator.cxx182
-rw-r--r--Source/cmLocalNinjaGenerator.h24
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx240
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.h10
-rw-r--r--Source/cmLocalVisualStudio10Generator.cxx13
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx244
-rw-r--r--Source/cmLocalVisualStudio7Generator.h13
-rw-r--r--Source/cmLocalVisualStudioGenerator.cxx9
-rw-r--r--Source/cmLocalXCodeGenerator.cxx4
-rw-r--r--Source/cmMachO.cxx31
-rw-r--r--Source/cmMacroCommand.cxx9
-rw-r--r--Source/cmMakefile.cxx1084
-rw-r--r--Source/cmMakefile.h220
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx96
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx133
-rw-r--r--Source/cmMakefileProfilingData.cxx114
-rw-r--r--Source/cmMakefileProfilingData.h29
-rw-r--r--Source/cmMakefileTargetGenerator.cxx407
-rw-r--r--Source/cmMakefileTargetGenerator.h27
-rw-r--r--Source/cmMakefileUtilityTargetGenerator.cxx3
-rw-r--r--Source/cmMarkAsAdvancedCommand.cxx62
-rw-r--r--Source/cmMathCommand.cxx2
-rw-r--r--Source/cmMessageCommand.cxx134
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx614
-rw-r--r--Source/cmNinjaNormalTargetGenerator.h27
-rw-r--r--Source/cmNinjaTargetGenerator.cxx623
-rw-r--r--Source/cmNinjaTargetGenerator.h114
-rw-r--r--Source/cmNinjaUtilityTargetGenerator.cxx55
-rw-r--r--Source/cmNinjaUtilityTargetGenerator.h4
-rw-r--r--Source/cmOSXBundleGenerator.cxx93
-rw-r--r--Source/cmOSXBundleGenerator.h31
-rw-r--r--Source/cmOptionCommand.cxx4
-rw-r--r--Source/cmOrderDirectories.cxx29
-rw-r--r--Source/cmOrderDirectories.h6
-rw-r--r--Source/cmOutputConverter.cxx34
-rw-r--r--Source/cmOutputConverter.h10
-rw-r--r--Source/cmOutputRequiredFilesCommand.cxx61
-rw-r--r--Source/cmPipeConnection.h2
-rw-r--r--Source/cmPolicies.cxx2
-rw-r--r--Source/cmPolicies.h33
-rw-r--r--Source/cmProcessOutput.cxx23
-rw-r--r--Source/cmProjectCommand.cxx13
-rw-r--r--Source/cmPropertyDefinition.cxx26
-rw-r--r--Source/cmPropertyDefinition.h11
-rw-r--r--Source/cmPropertyDefinitionMap.cxx18
-rw-r--r--Source/cmPropertyDefinitionMap.h4
-rw-r--r--Source/cmPropertyMap.cxx16
-rw-r--r--Source/cmPropertyMap.h6
-rw-r--r--Source/cmQTWrapCPPCommand.cxx3
-rw-r--r--Source/cmQtAutoGen.cxx9
-rw-r--r--Source/cmQtAutoGenGlobalInitializer.cxx46
-rw-r--r--Source/cmQtAutoGenGlobalInitializer.h2
-rw-r--r--Source/cmQtAutoGenInitializer.cxx353
-rw-r--r--Source/cmQtAutoGenInitializer.h5
-rw-r--r--Source/cmQtAutoGenerator.cxx4
-rw-r--r--Source/cmQtAutoGenerator.h2
-rw-r--r--Source/cmQtAutoMocUic.cxx241
-rw-r--r--Source/cmQtAutoRcc.cxx5
-rw-r--r--Source/cmRST.cxx10
-rw-r--r--Source/cmRulePlaceholderExpander.cxx18
-rw-r--r--Source/cmRulePlaceholderExpander.h1
-rw-r--r--Source/cmRuntimeDependencyArchive.cxx5
-rw-r--r--Source/cmScriptGenerator.h2
-rw-r--r--Source/cmSearchPath.cxx8
-rw-r--r--Source/cmSearchPath.h2
-rw-r--r--Source/cmSeparateArgumentsCommand.cxx2
-rw-r--r--Source/cmServer.cxx38
-rw-r--r--Source/cmServer.h11
-rw-r--r--Source/cmServerConnection.cxx2
-rw-r--r--Source/cmServerProtocol.cxx24
-rw-r--r--Source/cmServerProtocol.h2
-rw-r--r--Source/cmSetCommand.cxx8
-rw-r--r--Source/cmSetDirectoryPropertiesCommand.cxx40
-rw-r--r--Source/cmSetPropertyCommand.cxx335
-rw-r--r--Source/cmSetPropertyCommand.h29
-rw-r--r--Source/cmSetSourceFilesPropertiesCommand.cxx170
-rw-r--r--Source/cmSetTargetPropertiesCommand.cxx69
-rw-r--r--Source/cmSetTestsPropertiesCommand.cxx74
-rw-r--r--Source/cmSiteNameCommand.cxx3
-rw-r--r--Source/cmSourceFile.cxx45
-rw-r--r--Source/cmSourceFile.h11
-rw-r--r--Source/cmSourceFileLocation.cxx7
-rw-r--r--Source/cmSourceGroup.cxx11
-rw-r--r--Source/cmSourceGroup.h3
-rw-r--r--Source/cmSourceGroupCommand.cxx26
-rw-r--r--Source/cmStandardLexer.h15
-rw-r--r--Source/cmState.cxx196
-rw-r--r--Source/cmState.h33
-rw-r--r--Source/cmStateDirectory.cxx43
-rw-r--r--Source/cmStateDirectory.h8
-rw-r--r--Source/cmStateSnapshot.cxx9
-rw-r--r--Source/cmString.hxx215
-rw-r--r--Source/cmStringAlgorithms.cxx2
-rw-r--r--Source/cmStringAlgorithms.h2
-rw-r--r--Source/cmStringCommand.cxx25
-rw-r--r--Source/cmSubcommandTable.h3
-rw-r--r--Source/cmSystemTools.cxx49
-rw-r--r--Source/cmTarget.cxx329
-rw-r--r--Source/cmTarget.h33
-rw-r--r--Source/cmTargetCompileDefinitionsCommand.cxx2
-rw-r--r--Source/cmTargetCompileOptionsCommand.cxx11
-rw-r--r--Source/cmTargetDepend.h4
-rw-r--r--Source/cmTargetIncludeDirectoriesCommand.cxx3
-rw-r--r--Source/cmTargetLinkLibrariesCommand.cxx204
-rw-r--r--Source/cmTargetPrecompileHeadersCommand.cxx5
-rw-r--r--Source/cmTargetPropCommandBase.cxx17
-rw-r--r--Source/cmTargetPropertyComputer.cxx1
-rw-r--r--Source/cmTargetPropertyComputer.h32
-rw-r--r--Source/cmTargetSourcesCommand.cxx3
-rw-r--r--Source/cmTest.cxx11
-rw-r--r--Source/cmTest.h2
-rw-r--r--Source/cmTestGenerator.cxx16
-rw-r--r--Source/cmTimestamp.cxx10
-rw-r--r--Source/cmTryRunCommand.cxx5
-rw-r--r--Source/cmUVHandlePtr.cxx2
-rw-r--r--Source/cmUVHandlePtr.h2
-rw-r--r--Source/cmUVProcessChain.cxx2
-rw-r--r--Source/cmUVProcessChain.h4
-rw-r--r--Source/cmUVSignalHackRAII.h2
-rw-r--r--Source/cmUVStreambuf.h2
-rw-r--r--Source/cmUtilitySourceCommand.cxx12
-rw-r--r--Source/cmVSSetupHelper.h3
-rw-r--r--Source/cmVariableWatch.cxx14
-rw-r--r--Source/cmVariableWatch.h4
-rw-r--r--Source/cmVariableWatchCommand.cxx73
-rw-r--r--Source/cmVersion.h2
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx980
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h19
-rw-r--r--Source/cmVisualStudioGeneratorOptions.cxx43
-rw-r--r--Source/cmVisualStudioGeneratorOptions.h13
-rw-r--r--Source/cmVisualStudioSlnParser.cxx10
-rw-r--r--Source/cmVisualStudioSlnParser.h5
-rw-r--r--Source/cmWhileCommand.cxx3
-rw-r--r--Source/cmWorkerPool.cxx2
-rw-r--r--Source/cmWorkingDirectory.h2
-rw-r--r--Source/cmWriteFileCommand.cxx2
-rw-r--r--Source/cmXCode21Object.cxx13
-rw-r--r--Source/cmXCode21Object.h8
-rw-r--r--Source/cmXCodeObject.h9
-rw-r--r--Source/cmXCodeScheme.cxx50
-rw-r--r--Source/cmXCodeScheme.h6
-rw-r--r--Source/cmXMLParser.cxx4
-rw-r--r--Source/cmXMLWriter.h2
-rw-r--r--Source/cm_get_date.c4
-rw-r--r--Source/cmake.cxx563
-rw-r--r--Source/cmake.h114
-rw-r--r--Source/cmakemain.cxx51
-rw-r--r--Source/cmcldeps.cxx58
-rw-r--r--Source/cmcmd.cxx335
-rw-r--r--Source/cmcmd.h3
-rw-r--r--Source/ctest.cxx13
-rw-r--r--Source/kwsys/Base64.c5
-rw-r--r--Source/kwsys/CMakeLists.txt1332
-rw-r--r--Source/kwsys/CTestCustom.cmake.in4
-rw-r--r--Source/kwsys/CommandLineArguments.cxx44
-rw-r--r--Source/kwsys/Directory.cxx18
-rw-r--r--Source/kwsys/Directory.hxx.in10
-rw-r--r--Source/kwsys/Encoding.hxx.in2
-rw-r--r--Source/kwsys/EncodingCXX.cxx18
-rw-r--r--Source/kwsys/ExtraTest.cmake.in2
-rw-r--r--Source/kwsys/FStream.hxx.in14
-rw-r--r--Source/kwsys/Glob.cxx12
-rw-r--r--Source/kwsys/MD5.c30
-rw-r--r--Source/kwsys/Process.h.in4
-rw-r--r--Source/kwsys/ProcessUNIX.c227
-rw-r--r--Source/kwsys/ProcessWin32.c2
-rw-r--r--Source/kwsys/RegularExpression.cxx7
-rw-r--r--Source/kwsys/RegularExpression.hxx.in17
-rw-r--r--Source/kwsys/System.c2
-rw-r--r--Source/kwsys/SystemInformation.cxx235
-rw-r--r--Source/kwsys/SystemTools.cxx408
-rw-r--r--Source/kwsys/SystemTools.hxx.in33
-rw-r--r--Source/kwsys/Terminal.c9
-rw-r--r--Source/kwsys/kwsysPlatformTests.cmake300
-rw-r--r--Source/kwsys/testCommandLineArguments.cxx6
-rw-r--r--Source/kwsys/testCommandLineArguments1.cxx10
-rw-r--r--Source/kwsys/testDynamicLoader.cxx2
-rw-r--r--Source/kwsys/testDynload.c2
-rw-r--r--Source/kwsys/testEncoding.cxx27
-rw-r--r--Source/kwsys/testFStream.cxx2
-rw-r--r--Source/kwsys/testHashSTL.cxx16
-rw-r--r--Source/kwsys/testProcess.c13
-rw-r--r--Source/kwsys/testSystemTools.cxx115
-rw-r--r--Source/kwsys/testSystemTools.h.in2
-rw-r--r--Templates/MSBuild/FlagTables/v10_Cuda.json20
-rw-r--r--Templates/TestDriver.cxx.in7
-rw-r--r--Tests/Assembler/CMakeLists.txt8
-rw-r--r--Tests/BuildDepends/CMakeLists.txt22
-rw-r--r--Tests/BuildDepends/Project/CMakeLists.txt8
-rw-r--r--Tests/CFBundleTest/VerifyResult.cmake2
-rw-r--r--Tests/CMakeCommands/target_link_libraries/SubDirB/CMakeLists.txt6
-rw-r--r--Tests/CMakeLib/CMakeLists.txt4
-rw-r--r--Tests/CMakeLib/testArgumentParser.cxx3
-rw-r--r--Tests/CMakeLib/testCMExtAlgorithm.cxx118
-rw-r--r--Tests/CMakeLib/testCMExtMemory.cxx65
-rw-r--r--Tests/CMakeLib/testCTestBinPacker.cxx2
-rw-r--r--Tests/CMakeLib/testGccDepfileReader.cxx131
-rw-r--r--Tests/CMakeLib/testGccDepfileReader_data/deps1.d20
-rw-r--r--Tests/CMakeLib/testGccDepfileReader_data/deps1.txt26
-rw-r--r--Tests/CMakeLib/testGccDepfileReader_data/deps2.d1
-rw-r--r--Tests/CMakeLib/testGccDepfileReader_data/deps2.txt5
-rw-r--r--Tests/CMakeLib/testGccDepfileReader_data/deps3.d2
-rw-r--r--Tests/CMakeLib/testGccDepfileReader_data/deps3.txt11
-rw-r--r--Tests/CMakeLib/testString.cxx15
-rw-r--r--Tests/CMakeLib/testUTF8.cxx2
-rw-r--r--Tests/CMakeLib/testUVProcessChain.cxx2
-rw-r--r--Tests/CMakeLib/testUVRAII.cxx2
-rw-r--r--Tests/CMakeLib/testUVStreambuf.cxx3
-rw-r--r--Tests/CMakeLists.txt128
-rw-r--r--Tests/CMakeOnly/AllFindModules/CMakeLists.txt2
-rw-r--r--Tests/CMakeOnly/CMakeLists.txt11
-rw-r--r--Tests/CMakeOnly/CheckOBJCCompilerFlag/CMakeLists.txt18
-rw-r--r--Tests/CMakeOnly/CheckOBJCXXCompilerFlag/CMakeLists.txt16
-rw-r--r--Tests/CMakeOnly/CheckStructHasMember/CMakeLists.txt6
-rw-r--r--Tests/CMakeOnly/ProjectIncludeBeforeAny/CMakeLists.txt5
-rw-r--r--Tests/CMakeOnly/ProjectIncludeBeforeAny/include.cmake9
-rw-r--r--Tests/CMakeOnly/Test.cmake.in8
-rw-r--r--Tests/CMakeTestMultipleConfigures/RunCMake.cmake6
-rw-r--r--Tests/CMakeTests/CMakeLists.txt3
-rw-r--r--Tests/CMakeTests/FileDownloadTest.cmake.in83
-rw-r--r--Tests/CMakeTests/FileTestScript.cmake2
-rw-r--r--Tests/CMakeTests/ListTest.cmake.in23
-rw-r--r--Tests/CPackComponentsDEB/CMakeLists.txt2
-rw-r--r--Tests/CPackComponentsDEB/RunCPackVerifyResult.cmake2
-rw-r--r--Tests/CPackNSISGenerator/CMakeLists.txt21
-rw-r--r--Tests/CPackNSISGenerator/RunCPackVerifyResult.cmake54
-rw-r--r--Tests/CPackNSISGenerator/header-icon.bmpbin0 -> 28166 bytes-rw-r--r--Tests/CPackNSISGenerator/header-image.bmpbin0 -> 28166 bytes-rw-r--r--Tests/CPackNSISGenerator/install.icobin0 -> 838 bytes-rw-r--r--Tests/CPackNSISGenerator/main.cpp4
-rw-r--r--Tests/CPackNSISGenerator/uninstall.icobin0 -> 838 bytes-rw-r--r--Tests/CPackWiXGenerator/myotherapp.cpp2
-rw-r--r--Tests/CSharpOnly/CMakeLists.txt4
-rw-r--r--Tests/CSharpOnly/csharponly.cs4
-rw-r--r--Tests/CSharpOnly/nested/lib1.cs13
-rw-r--r--Tests/CTestConfig/dashboard.cmake.in2
-rw-r--r--Tests/CTestConfig/script.cmake.in9
-rw-r--r--Tests/CTestCoverageCollectGCOV/test.cmake.in146
-rw-r--r--Tests/Complex/CMakeLists.txt2
-rw-r--r--Tests/Complex/Library/CMakeLists.txt2
-rw-r--r--Tests/ComplexOneConfig/CMakeLists.txt2
-rw-r--r--Tests/ComplexOneConfig/Library/CMakeLists.txt2
-rw-r--r--Tests/ConfigSources/CMakeLists.txt38
-rw-r--r--Tests/ConfigSources/main.cpp9
-rw-r--r--Tests/Contracts/VTK/CMakeLists.txt2
-rw-r--r--Tests/Contracts/VTK/Dashboard.cmake.in4
-rw-r--r--Tests/Cuda/CMakeLists.txt18
-rw-r--r--Tests/Cuda/CXXStandardSetTwice/CMakeLists.txt13
-rw-r--r--Tests/Cuda/CXXStandardSetTwice/main.cu (renamed from Tests/Cuda/MixedStandardLevels/main.cu)0
-rw-r--r--Tests/Cuda/Complex/CMakeLists.txt31
-rw-r--r--Tests/Cuda/Complex/dynamic.cu11
-rw-r--r--Tests/Cuda/Complex/main.cpp1
-rw-r--r--Tests/Cuda/Complex/mixed.cu6
-rw-r--r--Tests/Cuda/IncludePathNoToolkit/CMakeLists.txt (renamed from Tests/Cuda/ToolkitInclude/CMakeLists.txt)6
-rw-r--r--Tests/Cuda/IncludePathNoToolkit/main.cpp (renamed from Tests/Cuda/ToolkitInclude/main.cpp)0
-rw-r--r--Tests/Cuda/MixedStandardLevels/CMakeLists.txt14
-rw-r--r--Tests/Cuda/MixedStandardLevels1/CMakeLists.txt13
-rw-r--r--Tests/Cuda/MixedStandardLevels1/lib.cpp7
-rw-r--r--Tests/Cuda/MixedStandardLevels1/main.cu9
-rw-r--r--Tests/Cuda/MixedStandardLevels2/CMakeLists.txt13
-rw-r--r--Tests/Cuda/MixedStandardLevels2/lib.cpp7
-rw-r--r--Tests/Cuda/MixedStandardLevels2/main.cu11
-rw-r--r--Tests/Cuda/MixedStandardLevels3/CMakeLists.txt12
-rw-r--r--Tests/Cuda/MixedStandardLevels3/lib.cpp7
-rw-r--r--Tests/Cuda/MixedStandardLevels3/main.cu5
-rw-r--r--Tests/Cuda/MixedStandardLevels4/CMakeLists.txt13
-rw-r--r--Tests/Cuda/MixedStandardLevels4/lib.cpp16
-rw-r--r--Tests/Cuda/MixedStandardLevels4/main.cu5
-rw-r--r--Tests/Cuda/MixedStandardLevels5/CMakeLists.txt12
-rw-r--r--Tests/Cuda/MixedStandardLevels5/lib.cpp13
-rw-r--r--Tests/Cuda/MixedStandardLevels5/main.cu8
-rw-r--r--Tests/Cuda/ProperDeviceLibraries/CMakeLists.txt2
-rw-r--r--Tests/Cuda/SharedRuntimePlusToolkit/CMakeLists.txt35
-rw-r--r--Tests/Cuda/SharedRuntimePlusToolkit/curand.cpp65
-rw-r--r--Tests/Cuda/SharedRuntimePlusToolkit/main.cpp23
-rw-r--r--Tests/Cuda/SharedRuntimePlusToolkit/mixed.cpp16
-rw-r--r--Tests/Cuda/SharedRuntimePlusToolkit/nppif.cpp92
-rw-r--r--Tests/Cuda/SharedRuntimePlusToolkit/shared.cpp16
-rw-r--r--Tests/Cuda/SharedRuntimePlusToolkit/static.cpp16
-rw-r--r--Tests/Cuda/StaticRuntimePlusToolkit/CMakeLists.txt29
-rw-r--r--Tests/Cuda/StaticRuntimePlusToolkit/curand.cpp59
-rw-r--r--Tests/Cuda/StaticRuntimePlusToolkit/main.cpp11
-rw-r--r--Tests/Cuda/StaticRuntimePlusToolkit/mixed.cpp8
-rw-r--r--Tests/Cuda/StaticRuntimePlusToolkit/nppif.cpp86
-rw-r--r--Tests/Cuda/StaticRuntimePlusToolkit/shared.cpp8
-rw-r--r--Tests/Cuda/StaticRuntimePlusToolkit/static.cpp8
-rw-r--r--Tests/Cuda/Toolkit/CMakeLists.txt38
-rw-r--r--Tests/Cuda/Toolkit/main.cpp8
-rw-r--r--Tests/Cuda/WithC/CMakeLists.txt2
-rw-r--r--Tests/CudaOnly/Architecture/CMakeLists.txt5
-rw-r--r--Tests/CudaOnly/Architecture/main.cu9
-rw-r--r--Tests/CudaOnly/CMakeLists.txt29
-rw-r--r--Tests/CudaOnly/CircularLinkLine/CMakeLists.txt2
-rw-r--r--Tests/CudaOnly/CompileFlags/CMakeLists.txt16
-rw-r--r--Tests/CudaOnly/CompileFlags/main.cu16
-rw-r--r--Tests/CudaOnly/DontResolveDeviceSymbols/CMakeLists.txt2
-rw-r--r--Tests/CudaOnly/EnableStandard/CMakeLists.txt5
-rw-r--r--Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt6
-rw-r--r--Tests/CudaOnly/RuntimeControls/CMakeLists.txt59
-rw-r--r--Tests/CudaOnly/RuntimeControls/file1.cu18
-rw-r--r--Tests/CudaOnly/RuntimeControls/file2.cu18
-rw-r--r--Tests/CudaOnly/RuntimeControls/main.cu81
-rw-r--r--Tests/CudaOnly/RuntimeControls/no_runtime.cmake14
-rw-r--r--Tests/CudaOnly/RuntimeControls/uses_static_runtime.cmake14
-rw-r--r--Tests/CudaOnly/RuntimeControls/verify_runtime.cmake16
-rw-r--r--Tests/CudaOnly/SeparateCompilation/CMakeLists.txt10
-rw-r--r--Tests/CudaOnly/SharedRuntimePlusToolkit/CMakeLists.txt42
-rw-r--r--Tests/CudaOnly/SharedRuntimePlusToolkit/curand.cu65
-rw-r--r--Tests/CudaOnly/SharedRuntimePlusToolkit/main.cu23
-rw-r--r--Tests/CudaOnly/SharedRuntimePlusToolkit/mixed.cu16
-rw-r--r--Tests/CudaOnly/SharedRuntimePlusToolkit/nppif.cu92
-rw-r--r--Tests/CudaOnly/SharedRuntimePlusToolkit/shared.cu16
-rw-r--r--Tests/CudaOnly/SharedRuntimePlusToolkit/static.cu16
-rw-r--r--Tests/CudaOnly/Standard98/CMakeLists.txt15
-rw-r--r--Tests/CudaOnly/Standard98/main.cu8
-rw-r--r--Tests/CudaOnly/StaticRuntimePlusToolkit/CMakeLists.txt29
-rw-r--r--Tests/CudaOnly/StaticRuntimePlusToolkit/curand.cu59
-rw-r--r--Tests/CudaOnly/StaticRuntimePlusToolkit/main.cu11
-rw-r--r--Tests/CudaOnly/StaticRuntimePlusToolkit/mixed.cu8
-rw-r--r--Tests/CudaOnly/StaticRuntimePlusToolkit/nppif.cu86
-rw-r--r--Tests/CudaOnly/StaticRuntimePlusToolkit/shared.cu8
-rw-r--r--Tests/CudaOnly/StaticRuntimePlusToolkit/static.cu8
-rw-r--r--Tests/CudaOnly/Toolkit/CMakeLists.txt44
-rw-r--r--Tests/CudaOnly/Toolkit/main.cu8
-rw-r--r--Tests/CudaOnly/WithDefs/CMakeLists.txt15
-rw-r--r--Tests/CustComDepend/CMakeLists.txt4
-rw-r--r--Tests/CustomCommand/CMakeLists.txt44
-rw-r--r--Tests/CustomCommand/mac_fw.c4
-rw-r--r--Tests/EnforceConfig.cmake.in1
-rw-r--r--Tests/ExportImport/CMakeLists.txt2
-rw-r--r--Tests/ExportImport/Export/CMakeLists.txt19
-rw-r--r--Tests/ExportImport/Export/SubDirLinkA/CMakeLists.txt2
-rw-r--r--Tests/ExportImport/Import/A/CMakeLists.txt13
-rw-r--r--Tests/ExportImport/InitialCache.cmake.in1
-rw-r--r--Tests/ExternalProject/CMakeLists.txt81
-rw-r--r--Tests/ExternalProject/gitrepo-sub-rec.tgzbin0 -> 9008 bytes-rw-r--r--Tests/FindBLAS/CMakeLists.txt10
-rw-r--r--Tests/FindBLAS/Test/CMakeLists.txt13
-rw-r--r--Tests/FindBLAS/Test/main.c14
-rw-r--r--Tests/FindDoxygen/StampFile/CMakeLists.txt29
-rw-r--r--Tests/FindGTest/Test/CMakeLists.txt4
-rw-r--r--Tests/FindLAPACK/CMakeLists.txt10
-rw-r--r--Tests/FindLAPACK/Test/CMakeLists.txt13
-rw-r--r--Tests/FindLAPACK/Test/main.c20
-rw-r--r--Tests/FindLibArchive/CMakeLists.txt10
-rw-r--r--Tests/FindLibArchive/Test/CMakeLists.txt14
-rw-r--r--Tests/FindLibArchive/Test/main.c7
-rw-r--r--Tests/FindLibXml2/Test/CMakeLists.txt4
-rw-r--r--Tests/FindLibXslt/CMakeLists.txt10
-rw-r--r--Tests/FindLibXslt/Test/CMakeLists.txt45
-rw-r--r--Tests/FindLibXslt/Test/libexslt.c16
-rw-r--r--Tests/FindLibXslt/Test/libxslt.c24
-rw-r--r--Tests/FindPackageModeMakefileTest/CMakeLists.txt8
-rw-r--r--Tests/FindPackageModeMakefileTest/Makefile.in3
-rw-r--r--Tests/FindPython/ArtifactsInteractive/CMakeLists.txt24
-rw-r--r--Tests/FindPython/CMakeLists.txt450
-rw-r--r--Tests/FindPython/CustomFailureMessage/CMakeLists.txt79
-rw-r--r--Tests/FindPython/CustomFailureMessage/Check/CMakeLists.txt5
-rw-r--r--Tests/FindPython/ExactVersion/CMakeLists.txt56
-rw-r--r--Tests/FindPython/Implementation/CMakeLists.txt37
-rw-r--r--Tests/FindPython/IronPython/CMakeLists.txt31
-rw-r--r--Tests/FindPython/IronPython2/CMakeLists.txt31
-rw-r--r--Tests/FindPython/PyPy/CMakeLists.txt37
-rw-r--r--Tests/FindPython/PyPy2/CMakeLists.txt37
-rw-r--r--Tests/FindPython/PyPy3/CMakeLists.txt37
-rw-r--r--Tests/FindPython/Python/CMakeLists.txt32
-rw-r--r--Tests/FindPython/Python2/CMakeLists.txt9
-rw-r--r--Tests/FindPython/Python2Embedded/CMakeLists.txt15
-rw-r--r--Tests/FindPython/Python2Module/CMakeLists.txt37
-rw-r--r--Tests/FindPython/Python3/CMakeLists.txt15
-rw-r--r--Tests/FindPython/Python3Embedded/CMakeLists.txt15
-rw-r--r--Tests/FindPython/Python3Module/CMakeLists.txt37
-rw-r--r--Tests/FindPython/SOABI/CMakeLists.txt22
-rw-r--r--Tests/FindPython/VirtualEnv/CMakeLists.txt5
-rw-r--r--Tests/FindPython/VirtualEnvConda/CMakeLists.txt46
-rw-r--r--Tests/FindPython/VirtualEnvConda/VirtualEnvDefault.cmake6
-rw-r--r--Tests/FindPython/VirtualEnvConda/VirtualEnvOnly.cmake16
-rw-r--r--Tests/FindPython/VirtualEnvConda/VirtualEnvStandard.cmake7
-rw-r--r--Tests/FindRuby/CMakeLists.txt57
-rw-r--r--Tests/FindRuby/Fail/CMakeLists.txt5
-rw-r--r--Tests/FindRuby/FailExact/CMakeLists.txt8
-rw-r--r--Tests/FindRuby/Rvm/CMakeLists.txt75
-rw-r--r--Tests/FindRuby/Rvm/RvmDefault.cmake17
-rw-r--r--Tests/FindRuby/Rvm/RvmOnly.cmake41
-rw-r--r--Tests/FindRuby/Rvm/RvmStandard.cmake9
-rw-r--r--Tests/FindRuby/Test/CMakeLists.txt14
-rw-r--r--Tests/FindRuby/Test/ruby_version.c7
-rw-r--r--Tests/FindX11/Test/CMakeLists.txt11
-rw-r--r--Tests/FortranModules/CMakeLists.txt2
-rw-r--r--Tests/FortranModules/Executable/CMakeLists.txt2
-rw-r--r--Tests/FortranOnly/CMakeLists.txt54
-rw-r--r--Tests/IncludeDirectories/CMakeLists.txt35
-rw-r--r--Tests/IncludeDirectories/main.cpp14
-rw-r--r--Tests/InterfaceLibrary/CMakeLists.txt8
-rw-r--r--Tests/JavaExportImport/CMakeLists.txt2
-rw-r--r--Tests/LinkDirectory/CMakeLists.txt2
-rw-r--r--Tests/LinkDirectory/External/CMakeLists.txt14
-rw-r--r--Tests/MSManifest/CMakeLists.txt3
-rw-r--r--Tests/MSManifest/Subdir/CMakeLists.txt7
-rw-r--r--Tests/MSManifest/Subdir2/CMakeLists.txt13
-rw-r--r--Tests/MSManifest/Subdir2/check.cmake22
-rw-r--r--Tests/MSManifest/Subdir2/main.c4
-rw-r--r--Tests/MSManifest/Subdir2/test_manifest1.in5
-rw-r--r--Tests/MSManifest/Subdir2/test_manifest2.in12
-rw-r--r--Tests/MSManifest/Subdir2/test_manifest3.in9
-rw-r--r--Tests/MacRuntimePath/CMakeLists.txt2
-rw-r--r--Tests/ObjectLibrary/CMakeLists.txt2
-rw-r--r--Tests/ObjectLibrary/Transitive/CMakeLists.txt12
-rw-r--r--Tests/ObjectLibrary/Transitive/FooObject.c4
-rw-r--r--Tests/ObjectLibrary/Transitive/FooStatic.c4
-rw-r--r--Tests/ObjectLibrary/Transitive/Transitive.c7
-rw-r--r--Tests/OutDir/CMakeLists.txt4
-rw-r--r--Tests/OutDir/OutDir.cmake6
-rw-r--r--Tests/Preprocess/preprocess.c12
-rw-r--r--Tests/Preprocess/preprocess.cxx15
-rw-r--r--Tests/Properties/CMakeLists.txt139
-rw-r--r--Tests/Properties/SubDir2/CMakeLists.txt25
-rw-r--r--Tests/Qt4Autogen/CMakeLists.txt2
-rw-r--r--Tests/Qt5Autogen/CMakeLists.txt2
-rw-r--r--Tests/QtAutogen/MocCMP0100/CMakeLists.txt9
-rw-r--r--Tests/QtAutogen/MocCMP0100/NEW/CMakeLists.txt10
-rw-r--r--Tests/QtAutogen/MocCMP0100/OLD/CMakeLists.txt31
-rw-r--r--Tests/QtAutogen/MocCMP0100/Obj.cpp31
-rw-r--r--Tests/QtAutogen/MocCMP0100/Obj.hh20
-rw-r--r--Tests/QtAutogen/MocCMP0100/Obj2.cpp31
-rw-r--r--Tests/QtAutogen/MocCMP0100/Obj2.hh20
-rw-r--r--Tests/QtAutogen/MocCMP0100/main.cpp9
-rw-r--r--Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleA.hpp2
-rw-r--r--Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleB.hpp2
-rw-r--r--Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleC.hpp2
-rw-r--r--Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleD.hpp2
-rw-r--r--Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleEInclude.hpp2
-rw-r--r--Tests/QtAutogen/RerunMocPlugin/MocPlugin/UtilityMacros.hpp4
-rw-r--r--Tests/QtAutogen/SameName/CMakeLists.txt6
-rw-r--r--Tests/QtAutogen/SameName/main.cpp2
-rw-r--r--Tests/QtAutogen/SameName/object.hh13
-rw-r--r--Tests/QtAutogen/Tests.cmake1
-rw-r--r--Tests/RunCMake/AutoExportDll/AIXExportExplicit-build-result.txt (renamed from Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-result.txt)0
-rw-r--r--Tests/RunCMake/AutoExportDll/AIXExportExplicit-build-stdout.txt1
-rw-r--r--Tests/RunCMake/AutoExportDll/AIXExportExplicit.cmake7
-rw-r--r--Tests/RunCMake/AutoExportDll/AIXExportExplicitLib.c8
-rw-r--r--Tests/RunCMake/AutoExportDll/AIXExportExplicitLib.exp1
-rw-r--r--Tests/RunCMake/AutoExportDll/AIXExportExplicitMain.c7
-rw-r--r--Tests/RunCMake/AutoExportDll/AutoExport.cmake6
-rw-r--r--Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake11
-rw-r--r--Tests/RunCMake/AutoExportDll/cppCLI.cxx22
-rw-r--r--Tests/RunCMake/AutoExportDll/say.cxx8
-rw-r--r--Tests/RunCMake/BuildDepends/ExternalProject/CMakeLists.txt14
-rw-r--r--Tests/RunCMake/BuildDepends/ExternalProjectCacheArgs-build1-stdout.txt2
-rw-r--r--Tests/RunCMake/BuildDepends/ExternalProjectCacheArgs-build2-stdout.txt2
-rw-r--r--Tests/RunCMake/BuildDepends/ExternalProjectCacheArgs.cmake19
-rw-r--r--Tests/RunCMake/BuildDepends/ExternalProjectCacheArgs.step1.cmake3
-rw-r--r--Tests/RunCMake/BuildDepends/ExternalProjectCacheArgs.step2.cmake3
-rw-r--r--Tests/RunCMake/BuildDepends/GNU-AS-stdout.txt4
-rw-r--r--Tests/RunCMake/BuildDepends/GNU-AS.cmake13
-rw-r--r--Tests/RunCMake/BuildDepends/GNU-AS.step1.cmake1
-rw-r--r--Tests/RunCMake/BuildDepends/GNU-AS.step2.cmake1
-rw-r--r--Tests/RunCMake/BuildDepends/RunCMakeTest.cmake10
-rw-r--r--Tests/RunCMake/BuildDepends/gnu_as.s1
-rw-r--r--Tests/RunCMake/CMP0037/RunCMakeTest.cmake25
-rw-r--r--Tests/RunCMake/CMP0068/CMP0068-OLD-stderr.txt10
-rw-r--r--Tests/RunCMake/CMP0069/CMP0069-OLD-stderr.txt10
-rw-r--r--Tests/RunCMake/CMP0102/CMP0102-Common.cmake2
-rw-r--r--Tests/RunCMake/CMP0102/CMP0102-NEW.cmake13
-rw-r--r--Tests/RunCMake/CMP0102/CMP0102-OLD.cmake18
-rw-r--r--Tests/RunCMake/CMP0102/CMP0102-WARN-Default.cmake16
-rw-r--r--Tests/RunCMake/CMP0102/CMP0102-WARN-stderr.txt10
-rw-r--r--Tests/RunCMake/CMP0102/CMP0102-WARN.cmake18
-rw-r--r--Tests/RunCMake/CMP0102/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0102/RunCMakeTest.cmake6
-rw-r--r--Tests/RunCMake/CMP0104/CMP0104-Common.cmake2
-rw-r--r--Tests/RunCMake/CMP0104/CMP0104-NEW.cmake6
-rw-r--r--Tests/RunCMake/CMP0104/CMP0104-OLD.cmake12
-rw-r--r--Tests/RunCMake/CMP0104/CMP0104-WARN-stderr.txt8
-rw-r--r--Tests/RunCMake/CMP0104/CMP0104-WARN.cmake1
-rw-r--r--Tests/RunCMake/CMP0104/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0104/RunCMakeTest.cmake5
-rw-r--r--Tests/RunCMake/CMP0104/main.cu3
-rw-r--r--Tests/RunCMake/CMP0106/CMP0106-Common.cmake10
-rw-r--r--Tests/RunCMake/CMP0106/CMP0106-NEW-result.txt (renamed from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt)0
-rw-r--r--Tests/RunCMake/CMP0106/CMP0106-NEW-stderr.txt9
-rw-r--r--Tests/RunCMake/CMP0106/CMP0106-NEW.cmake4
-rw-r--r--Tests/RunCMake/CMP0106/CMP0106-OLD.cmake9
-rw-r--r--Tests/RunCMake/CMP0106/CMP0106-WARN-ParaView-stderr.txt8
-rw-r--r--Tests/RunCMake/CMP0106/CMP0106-WARN-ParaView.cmake2
-rw-r--r--Tests/RunCMake/CMP0106/CMP0106-WARN-VTK-stderr.txt9
-rw-r--r--Tests/RunCMake/CMP0106/CMP0106-WARN-VTK.cmake2
-rw-r--r--Tests/RunCMake/CMP0106/CMP0106-WARN-stderr.txt37
-rw-r--r--Tests/RunCMake/CMP0106/CMP0106-WARN.cmake2
-rw-r--r--Tests/RunCMake/CMP0106/CMakeLists.txt7
-rw-r--r--Tests/RunCMake/CMP0106/RunCMakeTest.cmake7
-rw-r--r--Tests/RunCMake/CMP0106/subdir/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/CMakeLists.txt72
-rw-r--r--Tests/RunCMake/CPack/CPackTestHelpers.cmake2
-rw-r--r--Tests/RunCMake/CPack/DragNDrop/Helpers.cmake54
-rw-r--r--Tests/RunCMake/CPack/DragNDrop/Prerequirements.cmake8
-rw-r--r--Tests/RunCMake/CPack/DragNDrop/packaging_COMPONENT_default.cmake3
-rw-r--r--Tests/RunCMake/CPack/RunCMakeTest.cmake5
-rw-r--r--Tests/RunCMake/CPack/tests/CUSTOM_NAMES/ExpectedFiles.cmake3
-rw-r--r--Tests/RunCMake/CPack/tests/CUSTOM_NAMES/test.cmake3
-rw-r--r--Tests/RunCMake/CPack/tests/EXTERNAL/expected-json-1.0.txt3
-rw-r--r--Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/VerifyResult.cmake4
-rw-r--r--Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/test.cmake16
-rw-r--r--Tests/RunCMake/CPack/tests/PROJECT_META/ExpectedFiles.cmake9
-rw-r--r--Tests/RunCMake/CPack/tests/PROJECT_META/VerifyResult.cmake30
-rw-r--r--Tests/RunCMake/CPack/tests/PROJECT_META/test.cmake11
-rw-r--r--Tests/RunCMake/CPack/tests/THREADED/ExpectedFiles.cmake2
-rw-r--r--Tests/RunCMake/CPack/tests/THREADED/test.cmake7
-rw-r--r--Tests/RunCMake/CPack/tests/THREADED_ALL/ExpectedFiles.cmake2
-rw-r--r--Tests/RunCMake/CPack/tests/THREADED_ALL/test.cmake7
-rw-r--r--Tests/RunCMake/CTest/CMakeCTestArguments-test-check.cmake4
-rw-r--r--Tests/RunCMake/CTest/CMakeCTestArguments.cmake2
-rw-r--r--Tests/RunCMake/CTest/RunCMakeTest.cmake13
-rw-r--r--Tests/RunCMake/CTestCommandLine/CMakeLists.txt.in4
-rw-r--r--Tests/RunCMake/CTestCommandLine/MemCheckSan.cmake7
-rw-r--r--Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake123
-rw-r--r--Tests/RunCMake/CTestCommandLine/check-configuration-type-stderr.txt2
-rw-r--r--Tests/RunCMake/CTestCommandLine/no-tests-script_error-result.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/no-tests-script_error-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/no-tests-script_legacy-result.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/no-tests-script_legacy-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/no-tests_bad-result.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/no-tests_bad-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/no-tests_error-result.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/no-tests_error-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/no-tests_legacy-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-after-timeout-cmake.cmake15
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-after-timeout-ctest-stdout.txt15
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-opt-after-timeout-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-opt-bad1-result.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-opt-bad1-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-opt-bad2-result.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-opt-bad2-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-opt-bad3-result.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-opt-bad3-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-opt-bad4-result.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-opt-bad4-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-opt-until-fail-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-opt-until-pass-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-until-pass-cmake.cmake15
-rw-r--r--Tests/RunCMake/CTestCommandLine/repeat-until-pass-ctest-stdout.txt15
-rw-r--r--Tests/RunCMake/CTestCommandLine/stop-on-failure-result.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/stop-on-failure-stderr.txt1
-rw-r--r--Tests/RunCMake/CTestCommandLine/stop-on-failure-stdout.txt10
-rw-r--r--Tests/RunCMake/CTestCommandLine/test.cmake.in19
-rw-r--r--Tests/RunCMake/CTestCommandLine/test1-pass.cmake13
-rw-r--r--Tests/RunCMake/CTestCommandLine/test1-timeout.cmake14
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/ResourceCommon.cmake2
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/RunCMakeTest.cmake28
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/checkfree1-ctest-s-res-cache-check.cmake1
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/checkfree1-ctest-s-res-variable-check.cmake1
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/ctresalloc.cxx2
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cache-check.cmake3
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cache-result.txt1
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cache-stderr.txt14
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-stderr.txt12
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-variable-check.cmake3
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-variable-result.txt1
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-variable-stderr.txt14
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/notenough2-ctest-s-res-stderr.txt9
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/notenough3-ctest-s-res-stderr.txt19
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/test.cmake.in14
-rw-r--r--Tests/RunCMake/CTestTimeout/Basic-stdout.txt6
-rw-r--r--Tests/RunCMake/CTestTimeout/CMakeLists.txt.in15
-rw-r--r--Tests/RunCMake/CTestTimeout/Fork-stdout.txt6
-rw-r--r--Tests/RunCMake/CTestTimeout/RunCMakeTest.cmake22
-rw-r--r--Tests/RunCMake/CTestTimeout/TestTimeout.c24
-rw-r--r--Tests/RunCMake/CTestTimeout/test.cmake.in16
-rw-r--r--Tests/RunCMake/CheckIPOSupported/cmp0069-is-old-stderr.txt13
-rw-r--r--Tests/RunCMake/CommandLine/E_cat_directory-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_cat_directory-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_cat_good_cat-stdout.txt3
-rw-r--r--Tests/RunCMake/CommandLine/E_cat_non_existing_file-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_cat_non_existing_file-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_cat_non_readable_file-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_cat_non_readable_file-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_cat_option_not_handled-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_cat_option_not_handled-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_bad_argument-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_bad_argument-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_directory_link_existing-check.cmake3
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_directory_link_existing-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_empty_file_specified-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_empty_file_specified.cmake8
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_file_force_existing-check.cmake3
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_file_force_existing-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_file_force_non_existing-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_file_link_existing-check.cmake3
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_file_link_existing-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_file_link_non_existing-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_file_non_force_existing-check.cmake3
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_file_non_force_existing-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_file_non_force_non_existing-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_file_non_force_non_existing-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_file_recursive_existing-check.cmake3
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_file_recursive_existing-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_file_recursive_non_existing-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_file_recursive_non_existing-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_force_recursive_directory_with_files-check.cmake3
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_force_recursive_directory_with_files-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_force_recursive_non_existing_file-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_no_file_specified-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_no_file_specified-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_non_recursive_directory-two-directories-check.cmake3
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_non_recursive_directory-two-directories-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_non_recursive_directory-two-directories-stderr.txt2
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_recursive_directory-two-directories-check.cmake3
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_recursive_directory-two-directories-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_recursive_directory_link_existing-check.cmake3
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_recursive_directory_link_existing-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_recursive_file_link_existing-check.cmake3
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_recursive_file_link_existing-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_rm_recursive_file_link_non_existing-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/P_arbitrary_args.cmake3
-rw-r--r--Tests/RunCMake/CommandLine/ProfilingTest-check.cmake18
-rw-r--r--Tests/RunCMake/CommandLine/ProfilingTest.cmake1
-rw-r--r--Tests/RunCMake/CommandLine/RunCMakeTest.cmake186
-rw-r--r--Tests/RunCMake/CommandLine/cmake_depends/test_UTF-16LE.hbin58 -> 59 bytes-rw-r--r--Tests/RunCMake/CommandLine/env-export-compile-commands-override-check.cmake3
-rw-r--r--Tests/RunCMake/CommandLine/env-export-compile-commands-set-check.cmake3
-rw-r--r--Tests/RunCMake/CommandLine/env-export-compile-commands-unset-check.cmake3
-rw-r--r--Tests/RunCMake/CommandLine/env-export-compile-commands/CMakeLists.txt7
-rw-r--r--Tests/RunCMake/CommandLine/llvm_rc_empty_preprocessor-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/llvm_rc_empty_preprocessor-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/llvm_rc_failing_first_command-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/llvm_rc_failing_first_command-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/llvm_rc_failing_second_command-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/llvm_rc_failing_second_command-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/llvm_rc_no_---result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/llvm_rc_no_---stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/llvm_rc_no_args-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/llvm_rc_no_args-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/profiling-all-params-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/profiling-all-params-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/profiling-invalid-format-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/profiling-invalid-format-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/profiling-missing-format-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/profiling-missing-format-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/profiling-missing-output-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/profiling-missing-output-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/trace-json-v1-check.cmake11
-rwxr-xr-xTests/RunCMake/CommandLine/trace-json-v1-check.py76
-rw-r--r--Tests/RunCMake/CommandLine/trace-json-v1-expand-check.cmake11
-rw-r--r--Tests/RunCMake/CommandLine/trace-json-v1-expand.cmake1
-rw-r--r--Tests/RunCMake/CommandLine/trace-json-v1.cmake5
-rw-r--r--Tests/RunCMake/CompilerLauncher/C-common.cmake3
-rw-r--r--Tests/RunCMake/CompilerLauncher/C-env-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/CompilerLauncher/C-env-launch-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/CompilerLauncher/C-env.cmake1
-rw-r--r--Tests/RunCMake/CompilerLauncher/C-launch-env.cmake3
-rw-r--r--Tests/RunCMake/CompilerLauncher/C.cmake4
-rw-r--r--Tests/RunCMake/CompilerLauncher/CUDA-common.cmake4
-rw-r--r--Tests/RunCMake/CompilerLauncher/CUDA-env-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/CompilerLauncher/CUDA-env-launch-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/CompilerLauncher/CUDA-env.cmake1
-rw-r--r--Tests/RunCMake/CompilerLauncher/CUDA-launch-env.cmake3
-rw-r--r--Tests/RunCMake/CompilerLauncher/CUDA.cmake4
-rw-r--r--Tests/RunCMake/CompilerLauncher/CXX-common.cmake3
-rw-r--r--Tests/RunCMake/CompilerLauncher/CXX-env-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/CompilerLauncher/CXX-env-launch-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/CompilerLauncher/CXX-env.cmake1
-rw-r--r--Tests/RunCMake/CompilerLauncher/CXX-launch-env.cmake3
-rw-r--r--Tests/RunCMake/CompilerLauncher/CXX.cmake4
-rw-r--r--Tests/RunCMake/CompilerLauncher/Fortran-common.cmake3
-rw-r--r--Tests/RunCMake/CompilerLauncher/Fortran-env-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/CompilerLauncher/Fortran-env-launch-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/CompilerLauncher/Fortran-env.cmake1
-rw-r--r--Tests/RunCMake/CompilerLauncher/Fortran-launch-env.cmake3
-rw-r--r--Tests/RunCMake/CompilerLauncher/Fortran.cmake4
-rw-r--r--Tests/RunCMake/CompilerLauncher/OBJC-common.cmake3
-rw-r--r--Tests/RunCMake/CompilerLauncher/OBJC-env-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/CompilerLauncher/OBJC-env-launch-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/CompilerLauncher/OBJC-env.cmake1
-rw-r--r--Tests/RunCMake/CompilerLauncher/OBJC-launch-env.cmake3
-rw-r--r--Tests/RunCMake/CompilerLauncher/OBJC.cmake4
-rw-r--r--Tests/RunCMake/CompilerLauncher/OBJCXX-common.cmake3
-rw-r--r--Tests/RunCMake/CompilerLauncher/OBJCXX-env-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/CompilerLauncher/OBJCXX-env-launch-Build-stdout.txt1
-rw-r--r--Tests/RunCMake/CompilerLauncher/OBJCXX-env.cmake1
-rw-r--r--Tests/RunCMake/CompilerLauncher/OBJCXX-launch-env.cmake3
-rw-r--r--Tests/RunCMake/CompilerLauncher/OBJCXX.cmake4
-rw-r--r--Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake11
-rw-r--r--Tests/RunCMake/Configure/NoCMAKE_CROSS_CONFIGS-result.txt1
-rw-r--r--Tests/RunCMake/Configure/NoCMAKE_CROSS_CONFIGS-stderr.txt11
-rw-r--r--Tests/RunCMake/Configure/NoCMAKE_CROSS_CONFIGS.cmake1
-rw-r--r--Tests/RunCMake/Configure/NoCMAKE_DEFAULT_BUILD_TYPE-result.txt1
-rw-r--r--Tests/RunCMake/Configure/NoCMAKE_DEFAULT_BUILD_TYPE-stderr.txt11
-rw-r--r--Tests/RunCMake/Configure/NoCMAKE_DEFAULT_BUILD_TYPE.cmake1
-rw-r--r--Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS-result.txt1
-rw-r--r--Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS-stderr.txt11
-rw-r--r--Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS.cmake1
-rw-r--r--Tests/RunCMake/Configure/RunCMakeTest.cmake6
-rw-r--r--Tests/RunCMake/ExportCompileCommands/BeforeProject-check.cmake4
-rw-r--r--Tests/RunCMake/ExportCompileCommands/BeforeProject.cmake3
-rw-r--r--Tests/RunCMake/ExportCompileCommands/BeforeProjectBEFORE.cmake1
-rw-r--r--Tests/RunCMake/ExportCompileCommands/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/ExportCompileCommands/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/ExportCompileCommands/empty.c0
-rw-r--r--Tests/RunCMake/ExternalProject/Add_StepDependencies_iface_step-stderr.txt2
-rw-r--r--Tests/RunCMake/FPHSA/FindNameMismatch.cmake4
-rw-r--r--Tests/RunCMake/FPHSA/FindNameMismatchOld.cmake4
-rw-r--r--Tests/RunCMake/FPHSA/FindNameMismatchSuppressed.cmake6
-rw-r--r--Tests/RunCMake/FPHSA/FindNameMismatchSuppressedArg.cmake4
-rw-r--r--Tests/RunCMake/FPHSA/FindNameMismatchSuppressedCompat.cmake6
-rw-r--r--Tests/RunCMake/FPHSA/FindUseComponents.cmake15
-rw-r--r--Tests/RunCMake/FPHSA/NameMismatch-stderr.txt23
-rw-r--r--Tests/RunCMake/FPHSA/NameMismatch.cmake7
-rw-r--r--Tests/RunCMake/FPHSA/RunCMakeTest.cmake9
-rw-r--r--Tests/RunCMake/FPHSA/all_optional_components.cmake14
-rw-r--r--Tests/RunCMake/FPHSA/required_and_optional_components.cmake14
-rw-r--r--Tests/RunCMake/FPHSA/required_components.cmake11
-rw-r--r--Tests/RunCMake/FPHSA/required_components_with_vars.cmake1
-rw-r--r--Tests/RunCMake/FetchContent/DownloadFile.cmake9
-rw-r--r--Tests/RunCMake/FetchContent/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/FetchContent/dummyFile.txt1
-rw-r--r--Tests/RunCMake/FileAPI/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/FileAPI/check_index.py5
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-check.py4782
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/directories/alias.json15
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/directories/custom.json15
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/directories/cxx.json19
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/directories/dir.json12
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/directories/dir_dir.json10
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/directories/external.json14
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/directories/imported.json18
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/directories/object.json17
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json28
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/projects/alias.json14
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/projects/codemodel-v2.json28
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/projects/custom.json14
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/projects/cxx.json18
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/projects/external.json13
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/projects/imported.json17
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/projects/object.json16
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_alias.json83
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_custom.json79
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_cxx.json99
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_external.json79
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_imported.json95
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_object.json91
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_top.json179
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_alias_exe.json107
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_exe.json143
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_lib.json108
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_object_exe.json154
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_object_lib.json82
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_exe.json143
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_lib.json123
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_exe.json143
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_lib.json108
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/custom_exe.json107
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/custom_tgt.json87
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_alias_exe.json107
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json213
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_lib.json84
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_object_exe.json154
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_object_lib.json82
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_exe.json107
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_lib.json99
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_static_exe.json107
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_static_lib.json84
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/generated_exe.json303
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/interface_exe.json152
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_exe.json90
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_interface_exe.json90
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_object_exe.json90
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_shared_exe.json90
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_static_exe.json90
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_alias.json70
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_custom.json70
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_cxx.json70
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_external.json70
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_imported.json70
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_object.json70
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_top.json70
-rw-r--r--Tests/RunCMake/File_Archive/7zip.cmake7
-rw-r--r--Tests/RunCMake/File_Archive/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/File_Archive/RunCMakeTest.cmake17
-rw-r--r--Tests/RunCMake/File_Archive/gnutar-gz.cmake8
-rw-r--r--Tests/RunCMake/File_Archive/gnutar.cmake7
-rw-r--r--Tests/RunCMake/File_Archive/pax-xz.cmake8
-rw-r--r--Tests/RunCMake/File_Archive/pax-zstd.cmake8
-rw-r--r--Tests/RunCMake/File_Archive/pax.cmake7
-rw-r--r--Tests/RunCMake/File_Archive/paxr-bz2.cmake8
-rw-r--r--Tests/RunCMake/File_Archive/paxr.cmake7
-rw-r--r--Tests/RunCMake/File_Archive/roundtrip.cmake92
-rw-r--r--Tests/RunCMake/File_Archive/unsupported-format-result.txt1
-rw-r--r--Tests/RunCMake/File_Archive/unsupported-format-stderr.txt5
-rw-r--r--Tests/RunCMake/File_Archive/unsupported-format.cmake5
-rw-r--r--Tests/RunCMake/File_Archive/zip-filtered.cmake26
-rw-r--r--Tests/RunCMake/File_Archive/zip-with-bad-type-result.txt1
-rw-r--r--Tests/RunCMake/File_Archive/zip-with-bad-type-stderr.txt5
-rw-r--r--Tests/RunCMake/File_Archive/zip-with-bad-type.cmake6
-rw-r--r--Tests/RunCMake/File_Archive/zip.cmake7
-rw-r--r--Tests/RunCMake/File_Configure/BadArg-result.txt1
-rw-r--r--Tests/RunCMake/File_Configure/BadArg-stderr.txt4
-rw-r--r--Tests/RunCMake/File_Configure/BadArg.cmake1
-rw-r--r--Tests/RunCMake/File_Configure/BadArgGeneratorExpressionContent-result.txt1
-rw-r--r--Tests/RunCMake/File_Configure/BadArgGeneratorExpressionContent-stderr.txt5
-rw-r--r--Tests/RunCMake/File_Configure/BadArgGeneratorExpressionContent.cmake4
-rw-r--r--Tests/RunCMake/File_Configure/BadArgGeneratorExpressionOutput-result.txt1
-rw-r--r--Tests/RunCMake/File_Configure/BadArgGeneratorExpressionOutput-stderr.txt5
-rw-r--r--Tests/RunCMake/File_Configure/BadArgGeneratorExpressionOutput.cmake4
-rw-r--r--Tests/RunCMake/File_Configure/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/File_Configure/DirOutput-stderr.txt1
-rw-r--r--Tests/RunCMake/File_Configure/DirOutput.cmake4
-rw-r--r--Tests/RunCMake/File_Configure/DirOutput.txt1
-rw-r--r--Tests/RunCMake/File_Configure/NewLineStyle-NoArg-result.txt1
-rw-r--r--Tests/RunCMake/File_Configure/NewLineStyle-NoArg-stderr.txt5
-rw-r--r--Tests/RunCMake/File_Configure/NewLineStyle-NoArg.cmake6
-rw-r--r--Tests/RunCMake/File_Configure/NewLineStyle-ValidArg.cmake20
-rw-r--r--Tests/RunCMake/File_Configure/NewLineStyle-WrongArg-result.txt1
-rw-r--r--Tests/RunCMake/File_Configure/NewLineStyle-WrongArg-stderr.txt5
-rw-r--r--Tests/RunCMake/File_Configure/NewLineStyle-WrongArg.cmake6
-rw-r--r--Tests/RunCMake/File_Configure/RunCMakeTest.cmake9
-rw-r--r--Tests/RunCMake/File_Generate/CMP0070-OLD-stderr.txt10
-rw-r--r--Tests/RunCMake/FindPkgConfig/FindPkgConfig_CMAKE_APPBUNDLE_PATH.cmake48
-rw-r--r--Tests/RunCMake/FindPkgConfig/FindPkgConfig_CMAKE_FRAMEWORK_PATH.cmake48
-rw-r--r--Tests/RunCMake/FindPkgConfig/FindPkgConfig_extract_frameworks.cmake13
-rw-r--r--Tests/RunCMake/FindPkgConfig/FindPkgConfig_extract_frameworks_target.cmake29
-rw-r--r--Tests/RunCMake/FindPkgConfig/PkgConfigDoesNotExist-stdout.txt6
-rw-r--r--Tests/RunCMake/FindPkgConfig/PkgConfigDoesNotExist.cmake4
-rw-r--r--Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/FindPkgConfig/pc-bletch/lib/pkgconfig/bletch-framework.pc9
-rw-r--r--Tests/RunCMake/FindSWIG/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/FindSWIG/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/FindSWIG/components-stdout.txt6
-rw-r--r--Tests/RunCMake/FindSWIG/components.cmake9
-rw-r--r--Tests/RunCMake/FindSWIG/missing-components-result.txt1
-rw-r--r--Tests/RunCMake/FindSWIG/missing-components-stderr.txt1
-rw-r--r--Tests/RunCMake/FindSWIG/missing-components.cmake3
-rw-r--r--Tests/RunCMake/Framework/FrameworkMultiConfigPostfix-build-final-check.cmake45
-rw-r--r--Tests/RunCMake/Framework/FrameworkMultiConfigPostfix.cmake25
-rw-r--r--Tests/RunCMake/Framework/RunCMakeTest.cmake36
-rw-r--r--Tests/RunCMake/GNUInstallDirs/NoSystem-stderr.txt8
-rw-r--r--Tests/RunCMake/GNUInstallDirs/NoSystem.cmake2
-rw-r--r--Tests/RunCMake/GNUInstallDirs/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/GenerateExportHeader/exportheader_test.cpp6
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_custom_command-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_custom_command-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_custom_command.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_custom_target-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_custom_target-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_custom_target.cmake3
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_executable-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_executable-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_executable.cmake1
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_library-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_library-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_library.cmake1
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_test-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_test-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_test.cmake5
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-install-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-install-stderr.txt7
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-install.cmake5
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-link_depends-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-link_depends-stderr.txt7
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-link_depends.cmake7
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_compile_definitions-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_compile_definitions-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_compile_definitions.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_compile_options-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_compile_options-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_compile_options.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_include_directories-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_include_directories-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_include_directories.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_link_directories-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_link_directories-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_link_directories.cmake7
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_link_libraries-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_link_libraries-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_link_libraries.cmake7
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_sources-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_sources-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_sources.cmake2
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-add_custom_command-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-add_custom_command-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-add_custom_command.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-add_custom_target-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-add_custom_target-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-add_custom_target.cmake3
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-add_executable-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-add_executable-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-add_executable.cmake1
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-add_library-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-add_library-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-add_library.cmake1
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-add_test-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-add_test-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-add_test.cmake5
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-install-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-install-stderr.txt7
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-install.cmake5
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-link_depends-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-link_depends-stderr.txt7
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-link_depends.cmake7
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-target_compile_definitions-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-target_compile_definitions-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-target_compile_definitions.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-target_compile_options-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-target_compile_options-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-target_compile_options.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-target_include_directories-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-target_include_directories-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-target_include_directories.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-target_link_directories-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-target_link_directories-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-target_link_directories.cmake7
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-target_link_libraries-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-target_link_libraries-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-target_link_libraries.cmake7
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-target_sources-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-target_sources-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/HOST_LINK-target_sources.cmake2
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_command-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_command-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_command.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_target-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_target-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_target.cmake3
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_executable-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_executable-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_executable.cmake1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_library-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_library-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_library.cmake1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_test-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_test-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_test.cmake5
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-file_generate-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-file_generate-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-file_generate.cmake6
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-install-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-install-stderr.txt10
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-install.cmake5
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-target_sources-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-target_sources-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-target_sources.cmake2
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-unknown-lang.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage1-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage1-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage1.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage2-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage2-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage2.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage3-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage3-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage3.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage4-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage4-stderr.txt8
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage4.cmake7
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_command-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_command-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_command.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_target-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_target-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_target.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_executable-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_executable-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_executable.cmake5
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_library-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_library-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_library.cmake2
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_test-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_test-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_test.cmake5
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-file_generate-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-file_generate-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-file_generate.cmake6
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-install-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-install-stderr.txt10
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-install.cmake5
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-target_sources-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-target_sources-stderr.txt8
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-target_sources.cmake2
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-unknown-lang.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage1-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage1-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage1.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage2-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage2-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage2.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage3-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage3-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage3.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake55
-rw-r--r--Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/GeneratorToolset/TestToolsetVCTargetsPathOnly-stdout.txt2
-rw-r--r--Tests/RunCMake/GeneratorToolset/TestToolsetVCTargetsPathOnly.cmake2
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTest-configuration-debug-stdout.txt5
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTest-configuration-release-stdout.txt5
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-build-result.txt1
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-build-stdout.txt (renamed from Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-stdout.txt)0
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-test-result.txt1
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-test-stderr.txt2
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-test-stdout.txt18
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTest-discovery-PRE_TEST-timeout-test-stderr.txt8
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTest-discovery-PRE_TEST-timeout-test-stdout.txt1
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTest-skip-timeout-stdout.txt10
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTest-test1-stdout.txt40
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTest-test2-stdout.txt44
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTest.cmake8
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTestDiscoveryMultiConfig.cmake14
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTestDiscoveryTimeout.cmake14
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTestXML-result-check.cmake4
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTestXML.cmake11
-rw-r--r--Tests/RunCMake/GoogleTest/RunCMakeTest.cmake132
-rw-r--r--Tests/RunCMake/GoogleTest/configuration_gtest.cpp23
-rw-r--r--Tests/RunCMake/GoogleTest/fake_gtest.cpp4
-rw-r--r--Tests/RunCMake/GoogleTest/skip_test.cpp18
-rw-r--r--Tests/RunCMake/GoogleTest/timeout_test.cpp7
-rw-r--r--Tests/RunCMake/GoogleTest/xml_output.cpp26
-rw-r--r--Tests/RunCMake/Graphviz/CMakeGraphVizOptions.cmake.in1
-rw-r--r--Tests/RunCMake/Graphviz/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/Graphviz/GraphvizTestProject.cmake58
-rw-r--r--Tests/RunCMake/Graphviz/RunCMakeTest.cmake82
-rw-r--r--Tests/RunCMake/Graphviz/default_options-check.cmake5
-rw-r--r--Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_custom_targets.dot52
-rw-r--r--Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_default_options.dot50
-rw-r--r--Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_dependers_files.dot50
-rw-r--r--Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_executables.dot44
-rw-r--r--Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_external_libs.dot46
-rw-r--r--Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_graphic_libs.dot35
-rw-r--r--Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_interface_libs.dot43
-rw-r--r--Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_module_libs.dot44
-rw-r--r--Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_object_libs.dot48
-rw-r--r--Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_per_target_files.dot50
-rw-r--r--Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_shared_libs.dot44
-rw-r--r--Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_static_libs.dot42
-rw-r--r--Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_unknown_libs.dot48
-rw-r--r--Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_header.dot50
-rw-r--r--Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_name.dot50
-rw-r--r--Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_node_prefix.dot50
-rw-r--r--Tests/RunCMake/Graphviz/no_dependers_files-check.cmake4
-rw-r--r--Tests/RunCMake/Graphviz/no_executables-check.cmake5
-rw-r--r--Tests/RunCMake/Graphviz/no_external_libs-check.cmake5
-rw-r--r--Tests/RunCMake/Graphviz/no_graphic_libs-check.cmake5
-rw-r--r--Tests/RunCMake/Graphviz/no_interface_libs-check.cmake5
-rw-r--r--Tests/RunCMake/Graphviz/no_module_libs-check.cmake5
-rw-r--r--Tests/RunCMake/Graphviz/no_object_libs-check.cmake5
-rw-r--r--Tests/RunCMake/Graphviz/no_per_target_files-check.cmake5
-rw-r--r--Tests/RunCMake/Graphviz/no_shared_libs-check.cmake5
-rw-r--r--Tests/RunCMake/Graphviz/no_static_libs-check.cmake5
-rw-r--r--Tests/RunCMake/Graphviz/no_unknown_libs-check.cmake5
-rw-r--r--Tests/RunCMake/Graphviz/set_graph_header-check.cmake5
-rw-r--r--Tests/RunCMake/Graphviz/set_graph_name-check.cmake5
-rw-r--r--Tests/RunCMake/Graphviz/set_node_prefix-check.cmake5
-rw-r--r--Tests/RunCMake/Graphviz/test_project/core_library.c3
-rw-r--r--Tests/RunCMake/Graphviz/test_project/graphic_library.c3
-rw-r--r--Tests/RunCMake/Graphviz/test_project/main.c4
-rw-r--r--Tests/RunCMake/Graphviz/test_project/module.c3
-rw-r--r--Tests/RunCMake/Graphviz/test_project/third_party_project/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/INSTALL_NAME_DIR/CMakeLists.txt4
-rw-r--r--Tests/RunCMake/INSTALL_NAME_DIR/INSTALL_NAME_DIR.cmake15
-rw-r--r--Tests/RunCMake/INSTALL_NAME_DIR/RunCMakeTest.cmake69
-rw-r--r--Tests/RunCMake/INSTALL_NAME_DIR/empty-install-check.cmake1
-rw-r--r--Tests/RunCMake/INSTALL_NAME_DIR/empty.cmake3
-rw-r--r--Tests/RunCMake/INSTALL_NAME_DIR/empty_genex-install-check.cmake1
-rw-r--r--Tests/RunCMake/INSTALL_NAME_DIR/empty_genex.cmake3
-rw-r--r--Tests/RunCMake/INSTALL_NAME_DIR/none-install-check.cmake1
-rw-r--r--Tests/RunCMake/INSTALL_NAME_DIR/none.cmake3
-rw-r--r--Tests/RunCMake/INSTALL_NAME_DIR/prefix_genex-install-check.cmake6
-rw-r--r--Tests/RunCMake/INSTALL_NAME_DIR/prefix_genex.cmake3
-rw-r--r--Tests/RunCMake/INSTALL_NAME_DIR/simple-install-check.cmake1
-rw-r--r--Tests/RunCMake/INSTALL_NAME_DIR/simple.cmake3
-rw-r--r--Tests/RunCMake/INSTALL_NAME_DIR/simple_genex-install-check.cmake1
-rw-r--r--Tests/RunCMake/INSTALL_NAME_DIR/simple_genex.cmake3
-rw-r--r--Tests/RunCMake/INSTALL_NAME_DIR/test.c3
-rw-r--r--Tests/RunCMake/Languages/LINKER_LANGUAGE-genex-result.txt1
-rw-r--r--Tests/RunCMake/Languages/LINKER_LANGUAGE-genex-stderr.txt (renamed from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-stderr.txt)2
-rw-r--r--Tests/RunCMake/Languages/LINKER_LANGUAGE-genex.cmake (renamed from Tests/RunCMake/Languages/LINK_LANGUAGE-genex.cmake)0
-rw-r--r--Tests/RunCMake/Languages/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/MacOSVersions/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/MacOSVersions/MacOSVersions-build-check.cmake27
-rw-r--r--Tests/RunCMake/MacOSVersions/MacOSVersions.cmake9
-rw-r--r--Tests/RunCMake/MacOSVersions/RunCMakeTest.cmake11
-rw-r--r--Tests/RunCMake/MacOSVersions/foo.c4
-rw-r--r--Tests/RunCMake/Make/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/MaxRecursionDepth/variable_watch-default-script-stderr.txt4
-rw-r--r--Tests/RunCMake/MaxRecursionDepth/variable_watch-default-stderr.txt4
-rw-r--r--Tests/RunCMake/MaxRecursionDepth/variable_watch-invalid-var-script-stderr.txt4
-rw-r--r--Tests/RunCMake/MaxRecursionDepth/variable_watch-invalid-var-stderr.txt4
-rw-r--r--Tests/RunCMake/MaxRecursionDepth/variable_watch-var-script-stderr.txt10
-rw-r--r--Tests/RunCMake/MaxRecursionDepth/variable_watch-var-stderr.txt10
-rw-r--r--Tests/RunCMake/Ninja/ChangeBuildType.cmake12
-rw-r--r--Tests/RunCMake/Ninja/CustomCommandJobPool.cmake1
-rw-r--r--Tests/RunCMake/Ninja/RunCMakeTest.cmake18
-rwxr-xr-xTests/RunCMake/Ninja/SelectCompiler/1/gcc2
-rwxr-xr-xTests/RunCMake/Ninja/SelectCompiler/2/cc2
-rw-r--r--Tests/RunCMake/Ninja/SelectCompilerUNIX-result.txt1
-rw-r--r--Tests/RunCMake/Ninja/SelectCompilerUNIX-stderr.txt6
-rw-r--r--Tests/RunCMake/Ninja/SelectCompilerUNIX.cmake3
-rw-r--r--Tests/RunCMake/Ninja/SelectCompilerWindows-result.txt1
-rw-r--r--Tests/RunCMake/Ninja/SelectCompilerWindows-stderr.txt6
-rw-r--r--Tests/RunCMake/Ninja/SelectCompilerWindows.cmake3
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/AdditionalCleanFiles-all-clean-ninja-check.cmake4
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/AdditionalCleanFiles-check.cmake8
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/AdditionalCleanFiles-release-clean-build-check.cmake6
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/AdditionalCleanFiles.cmake3
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/AutoMocExecutable.cmake10
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Clean-release-build-check.cmake16
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Clean-release-clean-build-check.cmake7
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Clean-release-notall-ninja-check.cmake16
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Clean.cmake17
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Common.cmake62
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CudaSimple-all-clean-build-check.cmake21
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CudaSimple-debug-target-build-check.cmake28
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CudaSimple.cmake22
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfile-check.cmake5
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfile.cmake9
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-debug-build-check.cmake38
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-debug-clean-ninja-check.cmake37
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-debug-generated-stdout.txt12
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-debug-in-release-graph-build-check.cmake43
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-debug-in-release-graph-clean-ninja-check.cmake35
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-debug-in-release-graph-generated-stdout.txt12
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-release-clean-build-check.cmake29
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-release-generated-stdout.txt12
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-release-in-debug-graph-generated-stdout.txt12
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-release-in-debug-graph-ninja-check.cmake44
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-release-ninja-check.cmake46
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator.cmake56
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-debug-command-ninja-check.cmake6
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-debug-in-release-graph-postbuild-build-check.cmake8
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-debug-target-build-check.cmake8
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-debug-targetpostbuild-build-check.cmake12
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-minsizerel-command-ninja-check.cmake5
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-release-command-build-check.cmake5
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-release-postbuild-ninja-check.cmake11
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-release-target-ninja-check.cmake7
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-release-targetpostbuild-ninja-check.cmake13
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets.cmake39
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargetsSubdir/CMakeLists.txt1
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/DefaultBuildFileConfig.cmake1
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Framework.cmake22
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/FrameworkDependencyAutogen.cmake20
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Install-debug-in-release-graph-install-ninja-check.cmake31
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Install-release-install-build-check.cmake23
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Install.cmake10
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/InvalidCrossConfigs-result.txt1
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/InvalidCrossConfigs-stderr.txt5
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/InvalidCrossConfigs.cmake0
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/InvalidDefaultBuildFileConfig-result.txt1
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/InvalidDefaultBuildFileConfig-stderr.txt6
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/InvalidDefaultBuildFileConfig.cmake0
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsCross-result.txt1
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsCross-stderr.txt5
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsCross.cmake0
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoCross-result.txt1
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoCross-stderr.txt6
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoCross.cmake0
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/NoUnusedVariables.cmake1
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/PostfixAndLocation-debug-in-release-graph-build-check.cmake7
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/PostfixAndLocation-release-in-release-graph-build-check.cmake5
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/PostfixAndLocation.cmake18
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Qt5-debug-in-release-graph-build-check.cmake7
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Qt5.cmake30
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake303
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Simple-all-clean-again-ninja-check.cmake25
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Simple-all-clean-build-check.cmake25
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Simple-all-configs-build-check.cmake47
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Simple-all-subdir-build-check.cmake49
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Simple-all-top-ninja-check.cmake56
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Simple-debug-in-release-graph-top-build-check.cmake53
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Simple-debug-subdir-build-check.cmake31
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Simple-debug-target-build-check.cmake31
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Simple-debug-target-ninja-check.cmake33
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Simple-default-build-file-all-ninja-check.cmake49
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Simple-default-build-file-clean-minsizerel-ninja-check.cmake41
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Simple-default-build-file-clean-ninja-check.cmake49
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Simple-default-build-file-ninja-check.cmake51
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Simple-minsizerel-top-ninja-check.cmake51
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Simple-reconfigure-config-ninja-stdout.txt4
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Simple-reconfigure-noconfig-ninja-stdout.txt4
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Simple-release-file-ninja-check.cmake39
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Simple-release-filename-build-check.cmake36
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Simple-release-in-minsizerel-graph-subdir-ninja-check.cmake37
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/Simple.cmake13
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-all-all-in-release-graph-build-check.cmake45
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-all-in-relwithdebinfo-graph-build-check.cmake45
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-all-relwithdebinfo-in-release-graph-build-check.cmake45
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-all-relwithdebinfo-in-release-graph-build-result.txt1
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-all-relwithdebinfo-in-release-graph-build-stderr.txt1
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-clean-all-in-release-graph-ninja-check.cmake31
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-debug-in-release-graph-build-check.cmake37
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-release-in-release-graph-ninja-check.cmake31
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-release-in-relwithdebinfo-graph-ninja-check.cmake44
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-relwithdebinfo-in-release-graph-build-check.cmake37
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-relwithdebinfo-in-release-graph-build-result.txt1
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-relwithdebinfo-in-release-graph-build-stderr.txt1
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-relwithdebinfo-in-relwithdebinfo-graph-ninja-check.cmake43
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs.cmake1
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAlias-all-ninja-check.cmake56
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAlias-clean-ninja-check.cmake25
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAlias-target-ninja-check.cmake49
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAlias.cmake1
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAliasList-all-configs-build-check.cmake39
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAliasList-all-relwithdebinfo-ninja-check.cmake46
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAliasList-clean-configs-ninja-check.cmake32
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAliasList-target-configs-ninja-check.cmake37
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAliasList.cmake1
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAliasListCross-target-configs-ninja-check.cmake37
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAliasListCross.cmake1
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-all-ninja-result.txt1
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-all-ninja-stderr.txt1
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-clean-build-result.txt1
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-clean-build-stderr.txt1
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-target-ninja-result.txt1
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-target-ninja-stderr.txt1
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-debug-target-build-check.cmake31
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-debug-target-ninja-check.cmake32
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-all-build-result.txt1
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-all-build-stderr.txt1
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-clean-build-result.txt1
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-clean-build-stderr.txt1
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-target-ninja-result.txt1
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-target-ninja-stderr.txt1
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleNoCross.cmake1
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/SimpleSubdir/CMakeLists.txt4
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/WriteFile.cmake1
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/badmoc.c7
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/empty.c0
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/generator.c101
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/generatorlib.c24
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/generatorobj.c24
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/main.c4
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/main.cu15
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/qt5.cxx9
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/qt5.h5
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/simplelib.c6
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/simplelib.cu9
-rw-r--r--Tests/RunCMake/ObjectLibrary/b.c2
-rw-r--r--Tests/RunCMake/ObjectLibrary/requires.c2
-rw-r--r--Tests/RunCMake/ParseImplicitData/mingw.org-C-GNU-4.9.3.input2
-rw-r--r--Tests/RunCMake/ParseImplicitData/mingw.org-CXX-GNU-4.9.3.input2
-rw-r--r--Tests/RunCMake/PrecompileHeaders/DisabledPch-check.cmake3
-rw-r--r--Tests/RunCMake/PrecompileHeaders/PchDebugGenex-check.cmake17
-rw-r--r--Tests/RunCMake/PrecompileHeaders/PchDebugGenex.cmake9
-rw-r--r--Tests/RunCMake/PrecompileHeaders/PchInterface-check.cmake4
-rw-r--r--Tests/RunCMake/PrecompileHeaders/PchMultilanguage-check.cmake4
-rw-r--r--Tests/RunCMake/PrecompileHeaders/PchPrologueEpilogue-check.cmake3
-rw-r--r--Tests/RunCMake/PrecompileHeaders/PchWarnInvalid-check.cmake22
-rw-r--r--Tests/RunCMake/PrecompileHeaders/PchWarnInvalid.cmake16
-rw-r--r--Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake13
-rw-r--r--Tests/RunCMake/PrecompileHeaders/empty.c2
-rw-r--r--Tests/RunCMake/RunCMake.cmake29
-rw-r--r--Tests/RunCMake/RuntimePath/Relative.cmake17
-rw-r--r--Tests/RunCMake/RuntimePath/RunCMakeTest.cmake12
-rw-r--r--Tests/RunCMake/RuntimePath/SymlinkImplicitCheck.cmake2
-rw-r--r--Tests/RunCMake/Swift/L.swift1
-rw-r--r--Tests/RunCMake/Swift/RunCMakeTest.cmake10
-rw-r--r--Tests/RunCMake/Swift/SwiftMultiArch-result.txt1
-rw-r--r--Tests/RunCMake/Swift/SwiftMultiArch-stderr.txt4
-rw-r--r--Tests/RunCMake/Swift/SwiftMultiArch.cmake4
-rw-r--r--Tests/RunCMake/Swift/SwiftSimple.cmake2
-rw-r--r--Tests/RunCMake/Syntax/CommandEOF-stderr.txt2
-rw-r--r--Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt3
-rw-r--r--Tests/RunCMake/TargetProperties/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/TargetProperties/Deprecation-stderr.txt9
-rw-r--r--Tests/RunCMake/TargetProperties/Deprecation.cmake5
-rw-r--r--Tests/RunCMake/TargetProperties/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/TargetProperties/empty.cpp4
-rw-r--r--Tests/RunCMake/TargetSources/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/UnityBuild/RunCMakeTest.cmake6
-rw-r--r--Tests/RunCMake/UnityBuild/f.c5
-rw-r--r--Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_group-check.cmake42
-rw-r--r--Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_group.cmake39
-rw-r--r--Tests/RunCMake/UnityBuild/unitybuild_c_batch-check.cmake5
-rw-r--r--Tests/RunCMake/UnityBuild/unitybuild_c_batch.cmake15
-rw-r--r--Tests/RunCMake/UnityBuild/unitybuild_c_group-check.cmake11
-rw-r--r--Tests/RunCMake/UnityBuild/unitybuild_c_group.cmake17
-rw-r--r--Tests/RunCMake/UnityBuild/unitybuild_c_no_unity_build_group-check.cmake5
-rw-r--r--Tests/RunCMake/UnityBuild/unitybuild_c_no_unity_build_group.cmake16
-rw-r--r--Tests/RunCMake/UnityBuild/unitybuild_cxx_group-check.cmake27
-rw-r--r--Tests/RunCMake/UnityBuild/unitybuild_cxx_group.cmake27
-rw-r--r--Tests/RunCMake/UnityBuild/unitybuild_invalid_mode-result.txt1
-rw-r--r--Tests/RunCMake/UnityBuild/unitybuild_invalid_mode-stderr.txt5
-rw-r--r--Tests/RunCMake/UnityBuild/unitybuild_invalid_mode.cmake12
-rw-r--r--Tests/RunCMake/VS10Project/CSharpSourceGroup/foo.cs3
-rw-r--r--Tests/RunCMake/VS10Project/CSharpSourceGroup/images/empty.bmp0
-rw-r--r--Tests/RunCMake/VS10Project/CSharpSourceGroup/nested/baz.cs3
-rw-r--r--Tests/RunCMake/VS10Project/RunCMakeTest.cmake19
-rw-r--r--Tests/RunCMake/VS10Project/UnityBuildNativeGrouped-check.cmake56
-rw-r--r--Tests/RunCMake/VS10Project/UnityBuildNativeGrouped.cmake20
-rw-r--r--Tests/RunCMake/VS10Project/UnityBuildPre2017Grouped-check.cmake59
-rw-r--r--Tests/RunCMake/VS10Project/UnityBuildPre2017Grouped.cmake20
-rw-r--r--Tests/RunCMake/VS10Project/VSDotnetTargetFrameworkVersion.cmake10
-rw-r--r--Tests/RunCMake/VS10Project/VsCSharpDefines-check.cmake8
-rw-r--r--Tests/RunCMake/VS10Project/VsCSharpDocumentationFile-check.cmake26
-rw-r--r--Tests/RunCMake/VS10Project/VsCSharpDocumentationFile.cmake8
-rw-r--r--Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake22
-rw-r--r--Tests/RunCMake/VS10Project/VsCsharpSourceGroup.cmake16
-rw-r--r--Tests/RunCMake/VS10Project/VsCsharpSourceGroupHelpers.cmake15
-rw-r--r--Tests/RunCMake/VS10Project/VsDeployEnabled-check.cmake58
-rw-r--r--Tests/RunCMake/VS10Project/VsDeployEnabled.cmake12
-rw-r--r--Tests/RunCMake/VS10Project/VsDotnetTargetFramework-check.cmake40
-rw-r--r--Tests/RunCMake/VS10Project/VsDotnetTargetFramework.cmake11
-rw-r--r--Tests/RunCMake/VS10Project/VsDotnetTargetFrameworkVersion-check.cmake40
-rw-r--r--Tests/RunCMake/VS10Project/VsGlobals-check.cmake93
-rw-r--r--Tests/RunCMake/VS10Project/VsGlobals.cmake7
-rw-r--r--Tests/RunCMake/VS10Project/VsPlatformToolset-check.cmake36
-rw-r--r--Tests/RunCMake/VS10Project/VsPlatformToolset.cmake6
-rw-r--r--Tests/RunCMake/VS10Project/VsPrecompileHeaders-check.cmake2
-rw-r--r--Tests/RunCMake/VS10Project/VsSettings-check.cmake23
-rw-r--r--Tests/RunCMake/VS10Project/VsSettings.cmake5
-rw-r--r--Tests/RunCMake/VS10Project/VsSourceSettingsTool-check.cmake34
-rw-r--r--Tests/RunCMake/VS10Project/VsSourceSettingsTool.cmake5
-rw-r--r--Tests/RunCMake/VS10Project/VsVCTargetsPath-check.cmake32
-rw-r--r--Tests/RunCMake/VS10Project/VsVCTargetsPath.cmake3
-rw-r--r--Tests/RunCMake/VS10Project/VsWinRTByDefault-check.cmake66
-rw-r--r--Tests/RunCMake/VS10Project/VsWinRTByDefault.cmake16
-rw-r--r--Tests/RunCMake/VS10Project/shader.hlsl1
-rw-r--r--Tests/RunCMake/VS10Project/shader2.hlsl1
-rw-r--r--Tests/RunCMake/XcodeProject/RunCMakeTest.cmake31
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeGenerateTopLevelProjectOnlyWithObjectLibrary.cmake3
-rw-r--r--Tests/RunCMake/XcodeProject/XcodePrecompileHeaders-check.cmake2
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeRemoveExcessiveISystem.cmake52
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeSchemaProperty-check.cmake1
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeSchemaProperty.cmake1
-rw-r--r--Tests/RunCMake/XcodeProject/foo.swift2
-rw-r--r--Tests/RunCMake/XcodeProject/subproject_with_object_lib/CMakeLists.txt7
-rw-r--r--Tests/RunCMake/XcodeProject/subproject_with_object_lib/dummy.cpp5
-rw-r--r--Tests/RunCMake/XcodeProject/use_cmath.cpp6
-rw-r--r--Tests/RunCMake/add_link_options/GENEX_LINK_LANG.cmake16
-rw-r--r--Tests/RunCMake/add_link_options/LINKER_expansion-list.cmake2
-rw-r--r--Tests/RunCMake/add_link_options/LINKER_expansion-validation.cmake5
-rw-r--r--Tests/RunCMake/add_link_options/LINK_OPTIONS-exe-check.cmake5
-rw-r--r--Tests/RunCMake/add_link_options/LINK_OPTIONS-mod-check.cmake5
-rw-r--r--Tests/RunCMake/add_link_options/LINK_OPTIONS-shared-check.cmake5
-rw-r--r--Tests/RunCMake/add_link_options/LinkOptionsLib.cxx7
-rw-r--r--Tests/RunCMake/add_link_options/RunCMakeTest.cmake15
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-exe-check.cmake2
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-exe-result.txt1
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-mod-check.cmake2
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-mod-result.txt1
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_c-check.cmake5
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_c-result.txt1
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_cxx-check.cmake5
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_cxx-result.txt1
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-validation.cmake17
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE.cmake17
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-exe-check.cmake2
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-exe-result.txt1
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-mod-check.cmake2
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-mod-result.txt1
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_c-check.cmake5
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_c-result.txt1
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_cxx-check.cmake5
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_cxx-result.txt1
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-validation.cmake23
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID.cmake19
-rw-r--r--Tests/RunCMake/cmake_command/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/cmake_command/RunCMakeTest.cmake14
-rw-r--r--Tests/RunCMake/cmake_command/cmake_command_eval_message-stderr.txt1
-rw-r--r--Tests/RunCMake/cmake_command/cmake_command_eval_message.cmake1
-rw-r--r--Tests/RunCMake/cmake_command/cmake_command_eval_message_fatal_error-result.txt1
-rw-r--r--Tests/RunCMake/cmake_command/cmake_command_eval_message_fatal_error-stderr.txt5
-rw-r--r--Tests/RunCMake/cmake_command/cmake_command_eval_message_fatal_error.cmake5
-rw-r--r--Tests/RunCMake/cmake_command/cmake_command_eval_no_code-result.txt1
-rw-r--r--Tests/RunCMake/cmake_command/cmake_command_eval_no_code-stderr.txt2
-rw-r--r--Tests/RunCMake/cmake_command/cmake_command_eval_no_code.cmake1
-rw-r--r--Tests/RunCMake/cmake_command/cmake_command_eval_no_parameters-result.txt1
-rw-r--r--Tests/RunCMake/cmake_command/cmake_command_eval_no_parameters-stderr.txt2
-rw-r--r--Tests/RunCMake/cmake_command/cmake_command_eval_no_parameters.cmake1
-rw-r--r--Tests/RunCMake/cmake_command/cmake_command_eval_variable_outside_message-stderr.txt1
-rw-r--r--Tests/RunCMake/cmake_command/cmake_command_eval_variable_outside_message.cmake2
-rw-r--r--Tests/RunCMake/cmake_command/cmake_command_invoke_message-stderr.txt1
-rw-r--r--Tests/RunCMake/cmake_command/cmake_command_invoke_message.cmake1
-rw-r--r--Tests/RunCMake/cmake_command/cmake_command_invoke_message_fatal_error-result.txt1
-rw-r--r--Tests/RunCMake/cmake_command/cmake_command_invoke_message_fatal_error-stderr.txt5
-rw-r--r--Tests/RunCMake/cmake_command/cmake_command_invoke_message_fatal_error.cmake1
-rw-r--r--Tests/RunCMake/cmake_command/cmake_command_invoke_no_parameters-result.txt1
-rw-r--r--Tests/RunCMake/cmake_command/cmake_command_invoke_no_parameters-stderr.txt2
-rw-r--r--Tests/RunCMake/cmake_command/cmake_command_invoke_no_parameters.cmake1
-rw-r--r--Tests/RunCMake/cmake_command/cmake_command_invoke_preserve_arguments-stderr.txt6
-rw-r--r--Tests/RunCMake/cmake_command/cmake_command_invoke_preserve_arguments.cmake12
-rw-r--r--Tests/RunCMake/cmake_command/cmake_command_invoke_unknown_function-result.txt1
-rw-r--r--Tests/RunCMake/cmake_command/cmake_command_invoke_unknown_function-stderr.txt2
-rw-r--r--Tests/RunCMake/cmake_command/cmake_command_invoke_unknown_function.cmake1
-rw-r--r--Tests/RunCMake/cmake_command/cmake_command_no_parameters-result.txt1
-rw-r--r--Tests/RunCMake/cmake_command/cmake_command_no_parameters-stderr.txt2
-rw-r--r--Tests/RunCMake/cmake_command/cmake_command_no_parameters.cmake1
-rw-r--r--Tests/RunCMake/cmake_command/cmake_command_unknown_meta_operation-result.txt1
-rw-r--r--Tests/RunCMake/cmake_command/cmake_command_unknown_meta_operation-stderr.txt2
-rw-r--r--Tests/RunCMake/cmake_command/cmake_command_unknown_meta_operation.cmake1
-rw-r--r--Tests/RunCMake/configure_file/RerunCMake.cmake6
-rw-r--r--Tests/RunCMake/configure_file/RerunCMake/CMakeLists.txt5
-rw-r--r--Tests/RunCMake/configure_file/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/ctest_labels_for_subprojects/CTestScriptVariableCommandLine-stderr.txt3
-rw-r--r--Tests/RunCMake/ctest_memcheck/testAddressLeakSanitizer.cmake2
-rw-r--r--Tests/RunCMake/ctest_memcheck/testAddressSanitizer.cmake2
-rw-r--r--Tests/RunCMake/ctest_memcheck/testLeakSanitizer.cmake2
-rw-r--r--Tests/RunCMake/ctest_memcheck/testMemorySanitizer.cmake2
-rw-r--r--Tests/RunCMake/ctest_memcheck/testThreadSanitizer.cmake2
-rw-r--r--Tests/RunCMake/ctest_memcheck/testUndefinedBehaviorSanitizer.cmake2
-rw-r--r--Tests/RunCMake/ctest_start/NoStartTimeNightly-result.txt1
-rw-r--r--Tests/RunCMake/ctest_start/NoStartTimeNightly-stderr.txt4
-rw-r--r--Tests/RunCMake/ctest_start/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/ctest_start/test.cmake.in4
-rw-r--r--Tests/RunCMake/ctest_test/RunCMakeTest.cmake34
-rw-r--r--Tests/RunCMake/ctest_test/TestRepeatAfterTimeout-stdout.txt10
-rw-r--r--Tests/RunCMake/ctest_test/TestRepeatAfterTimeout.cmake10
-rw-r--r--Tests/RunCMake/ctest_test/TestRepeatBad1-result.txt1
-rw-r--r--Tests/RunCMake/ctest_test/TestRepeatBad1-stderr.txt1
-rw-r--r--Tests/RunCMake/ctest_test/TestRepeatBad2-result.txt1
-rw-r--r--Tests/RunCMake/ctest_test/TestRepeatBad2-stderr.txt1
-rw-r--r--Tests/RunCMake/ctest_test/TestRepeatUntilFail-stdout.txt13
-rw-r--r--Tests/RunCMake/ctest_test/TestRepeatUntilFail.cmake9
-rw-r--r--Tests/RunCMake/ctest_test/TestRepeatUntilPass-stdout.txt10
-rw-r--r--Tests/RunCMake/ctest_test/TestRepeatUntilPass.cmake9
-rw-r--r--Tests/RunCMake/ctest_test/stop-on-failure-stdout.txt13
-rw-r--r--Tests/RunCMake/execute_process/EchoVariable-stderr.txt3
-rw-r--r--Tests/RunCMake/execute_process/EchoVariable-stdout.txt1
-rw-r--r--Tests/RunCMake/execute_process/EchoVariable.cmake23
-rw-r--r--Tests/RunCMake/execute_process/EchoVariableOutput.cmake2
-rw-r--r--Tests/RunCMake/execute_process/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/exit_code.c3
-rw-r--r--Tests/RunCMake/export/Repeat-CMP0103-NEW-result.txt1
-rw-r--r--Tests/RunCMake/export/Repeat-CMP0103-NEW-stderr.txt17
-rw-r--r--Tests/RunCMake/export/Repeat-CMP0103-NEW.cmake2
-rw-r--r--Tests/RunCMake/export/Repeat-CMP0103-OLD.cmake2
-rw-r--r--Tests/RunCMake/export/Repeat-CMP0103-WARN-stderr.txt26
-rw-r--r--Tests/RunCMake/export/Repeat-CMP0103-WARN.cmake1
-rw-r--r--Tests/RunCMake/export/Repeat.cmake5
-rw-r--r--Tests/RunCMake/export/Repeat/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/export/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/file/DOWNLOAD-tls-cainfo-not-set-result.txt1
-rw-r--r--Tests/RunCMake/file/DOWNLOAD-tls-cainfo-not-set-stderr.txt4
-rw-r--r--Tests/RunCMake/file/DOWNLOAD-tls-cainfo-not-set.cmake1
-rw-r--r--Tests/RunCMake/file/DOWNLOAD-tls-verify-not-set-result.txt1
-rw-r--r--Tests/RunCMake/file/DOWNLOAD-tls-verify-not-set-stderr.txt4
-rw-r--r--Tests/RunCMake/file/DOWNLOAD-tls-verify-not-set.cmake1
-rw-r--r--Tests/RunCMake/file/GLOB-CONFIGURE_DEPENDS-CMP0009-RerunCMake-build-stdout.txt1
-rw-r--r--Tests/RunCMake/file/GLOB-CONFIGURE_DEPENDS-CMP0009-RerunCMake-rebuild-stdout.txt1
-rw-r--r--Tests/RunCMake/file/GLOB-CONFIGURE_DEPENDS-CMP0009-RerunCMake-stdout.txt1
-rw-r--r--Tests/RunCMake/file/GLOB-CONFIGURE_DEPENDS-CMP0009-RerunCMake.cmake10
-rw-r--r--Tests/RunCMake/file/RunCMakeTest.cmake27
-rw-r--r--Tests/RunCMake/file/UPLOAD-tls-cainfo-not-set-result.txt1
-rw-r--r--Tests/RunCMake/file/UPLOAD-tls-cainfo-not-set-stderr.txt4
-rw-r--r--Tests/RunCMake/file/UPLOAD-tls-cainfo-not-set.cmake1
-rw-r--r--Tests/RunCMake/file/UPLOAD-tls-verify-not-set-result.txt1
-rw-r--r--Tests/RunCMake/file/UPLOAD-tls-verify-not-set-stderr.txt4
-rw-r--r--Tests/RunCMake/file/UPLOAD-tls-verify-not-set.cmake1
-rw-r--r--Tests/RunCMake/find_file/PrefixInPATH-stderr.txt13
-rw-r--r--Tests/RunCMake/find_file/PrefixInPATH.cmake6
-rw-r--r--Tests/RunCMake/find_file/Required-result.txt1
-rw-r--r--Tests/RunCMake/find_file/Required-stderr.txt4
-rw-r--r--Tests/RunCMake/find_file/Required-stdout.txt1
-rw-r--r--Tests/RunCMake/find_file/Required.cmake12
-rw-r--r--Tests/RunCMake/find_file/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/find_library/FromPATHEnv-stderr.txt28
-rw-r--r--Tests/RunCMake/find_library/FromPATHEnv.cmake13
-rw-r--r--Tests/RunCMake/find_library/PrefixInPATH-stderr.txt14
-rw-r--r--Tests/RunCMake/find_library/PrefixInPATH.cmake6
-rw-r--r--Tests/RunCMake/find_library/Required-result.txt1
-rw-r--r--Tests/RunCMake/find_library/Required-stderr.txt4
-rw-r--r--Tests/RunCMake/find_library/Required-stdout.txt1
-rw-r--r--Tests/RunCMake/find_library/Required.cmake14
-rw-r--r--Tests/RunCMake/find_library/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/find_package/FromPATHEnv-stderr.txt20
-rw-r--r--Tests/RunCMake/find_package/FromPATHEnv.cmake6
-rw-r--r--Tests/RunCMake/find_package/MissingConfigDebug-stderr.txt18
-rw-r--r--Tests/RunCMake/find_package/MissingConfigDebug.cmake4
-rw-r--r--Tests/RunCMake/find_package/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/find_path/FromPATHEnv-stderr.txt27
-rw-r--r--Tests/RunCMake/find_path/FromPATHEnv.cmake12
-rw-r--r--Tests/RunCMake/find_path/Required-result.txt1
-rw-r--r--Tests/RunCMake/find_path/Required-stderr.txt4
-rw-r--r--Tests/RunCMake/find_path/Required-stdout.txt1
-rw-r--r--Tests/RunCMake/find_path/Required.cmake12
-rw-r--r--Tests/RunCMake/find_path/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/find_program/EnvAndHints-stderr.txt28
-rw-r--r--Tests/RunCMake/find_program/EnvAndHints.cmake2
-rw-r--r--Tests/RunCMake/find_program/ExeNoRead-stdout.txt1
-rw-r--r--Tests/RunCMake/find_program/ExeNoRead.cmake4
-rw-r--r--Tests/RunCMake/find_program/Required-result.txt1
-rw-r--r--Tests/RunCMake/find_program/Required-stderr.txt4
-rw-r--r--Tests/RunCMake/find_program/Required-stdout.txt1
-rw-r--r--Tests/RunCMake/find_program/Required.cmake12
-rw-r--r--Tests/RunCMake/find_program/RunCMakeTest.cmake5
-rw-r--r--Tests/RunCMake/foreach/RunCMakeTest.cmake18
-rw-r--r--Tests/RunCMake/foreach/foreach-ITEMS-multiple-iter-vars-test-result.txt1
-rw-r--r--Tests/RunCMake/foreach/foreach-ITEMS-multiple-iter-vars-test-stderr.txt4
-rw-r--r--Tests/RunCMake/foreach/foreach-ITEMS-multiple-iter-vars-test.cmake2
-rw-r--r--Tests/RunCMake/foreach/foreach-ITEMS-with-ZIP_LISTS-mix-test-result.txt1
-rw-r--r--Tests/RunCMake/foreach/foreach-ITEMS-with-ZIP_LISTS-mix-test-stderr.txt4
-rw-r--r--Tests/RunCMake/foreach/foreach-ITEMS-with-ZIP_LISTS-mix-test.cmake2
-rw-r--r--Tests/RunCMake/foreach/foreach-LISTS-multiple-iter-vars-test-result.txt1
-rw-r--r--Tests/RunCMake/foreach/foreach-LISTS-multiple-iter-vars-test-stderr.txt4
-rw-r--r--Tests/RunCMake/foreach/foreach-LISTS-multiple-iter-vars-test.cmake2
-rw-r--r--Tests/RunCMake/foreach/foreach-LISTS-with-ZIP_LISTS-mix-test-result.txt1
-rw-r--r--Tests/RunCMake/foreach/foreach-LISTS-with-ZIP_LISTS-mix-test-stderr.txt4
-rw-r--r--Tests/RunCMake/foreach/foreach-LISTS-with-ZIP_LISTS-mix-test.cmake2
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-invalid-test-result.txt1
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-invalid-test-stderr.txt4
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-invalid-test.cmake2
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-1-result.txt1
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-1-stderr.txt4
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-1.cmake2
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-1-result.txt1
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-1-stderr.txt4
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-1.cmake2
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-2-result.txt1
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-2-stderr.txt4
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-2.cmake2
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-1-result.txt1
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-1-stderr.txt4
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-1.cmake2
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-2-result.txt1
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-2-stderr.txt4
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-2.cmake2
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-3-result.txt1
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-3-stderr.txt4
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-3.cmake2
-rw-r--r--Tests/RunCMake/foreach/foreach-ZIP_LISTS-iter-vars-mismatch-test-1-result.txt1
-rw-r--r--Tests/RunCMake/foreach/foreach-ZIP_LISTS-iter-vars-mismatch-test-1-stderr.txt4
-rw-r--r--Tests/RunCMake/foreach/foreach-ZIP_LISTS-iter-vars-mismatch-test-1.cmake2
-rw-r--r--Tests/RunCMake/foreach/foreach-ZIP_LISTS-iter-vars-mismatch-test-2-result.txt1
-rw-r--r--Tests/RunCMake/foreach/foreach-ZIP_LISTS-iter-vars-mismatch-test-2-stderr.txt4
-rw-r--r--Tests/RunCMake/foreach/foreach-ZIP_LISTS-iter-vars-mismatch-test-2.cmake2
-rw-r--r--Tests/RunCMake/foreach/foreach-ZIP_LISTS-multiple-iter-vars-test-stdout.txt6
-rw-r--r--Tests/RunCMake/foreach/foreach-ZIP_LISTS-multiple-iter-vars-test.cmake42
-rw-r--r--Tests/RunCMake/foreach/foreach-ZIP_LISTS-test-stdout.txt19
-rw-r--r--Tests/RunCMake/foreach/foreach-ZIP_LISTS-test.cmake68
-rw-r--r--Tests/RunCMake/foreach/foreach-ZIP_LISTS-with-ITEMS-mix-test-result.txt1
-rw-r--r--Tests/RunCMake/foreach/foreach-ZIP_LISTS-with-ITEMS-mix-test-stderr.txt4
-rw-r--r--Tests/RunCMake/foreach/foreach-ZIP_LISTS-with-ITEMS-mix-test.cmake2
-rw-r--r--Tests/RunCMake/foreach/foreach-ZIP_LISTS-with-LISTS-mix-test-result.txt1
-rw-r--r--Tests/RunCMake/foreach/foreach-ZIP_LISTS-with-LISTS-mix-test-stderr.txt4
-rw-r--r--Tests/RunCMake/foreach/foreach-ZIP_LISTS-with-LISTS-mix-test.cmake2
-rw-r--r--Tests/RunCMake/foreach/foreach-all-test-stdout.txt44
-rw-r--r--Tests/RunCMake/foreach/foreach-all-test.cmake67
-rw-r--r--Tests/RunCMake/function/CMAKE_CURRENT_FUNCTION-stdout.txt7
-rw-r--r--Tests/RunCMake/function/CMAKE_CURRENT_FUNCTION.cmake94
-rw-r--r--Tests/RunCMake/function/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/function/DummyMacro.cmake20
-rw-r--r--Tests/RunCMake/function/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/get_filename_component/KnownComponents.cmake8
-rwxr-xr-xTests/RunCMake/get_filename_component/KnownComponents.sh1
-rw-r--r--Tests/RunCMake/get_property/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/get_property/source_properties_failures-result.txt1
-rw-r--r--Tests/RunCMake/get_property/source_properties_failures-stderr.txt66
-rw-r--r--Tests/RunCMake/get_property/source_properties_failures.cmake14
-rw-r--r--Tests/RunCMake/include_external_msproject/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/include_external_msproject/SkipGetTargetFrameworkProperties-check.cmake21
-rw-r--r--Tests/RunCMake/include_external_msproject/SkipGetTargetFrameworkProperties.cmake5
-rw-r--r--Tests/RunCMake/install/RunCMakeTest.cmake11
-rw-r--r--Tests/RunCMake/install/TARGETS-FILE_RPATH_CHANGE-new_rpath-stderr.txt4
-rw-r--r--Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-variable-propagation-all-result.txt1
-rw-r--r--Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-variable-propagation-all-stderr.txt6
-rw-r--r--Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-variable-propagation-dev-result.txt1
-rw-r--r--Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-variable-propagation-dev-stderr.txt6
-rw-r--r--Tests/RunCMake/install/file-GET_RUNTIME_DEPENDENCIES-variable-propagation.cmake17
-rw-r--r--Tests/RunCMake/load_cache/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/load_cache/NewForm_Project.cmake16
-rw-r--r--Tests/RunCMake/load_cache/NewForm_Script.cmake16
-rw-r--r--Tests/RunCMake/load_cache/OldForm_Script-result.txt1
-rw-r--r--Tests/RunCMake/load_cache/OldForm_Script-stderr.txt2
-rw-r--r--Tests/RunCMake/load_cache/OldForm_Script.cmake13
-rw-r--r--Tests/RunCMake/load_cache/RunCMakeTest.cmake13
-rw-r--r--Tests/RunCMake/message/RunCMakeTest.cmake25
-rw-r--r--Tests/RunCMake/message/message-checks-stderr.txt3
-rw-r--r--Tests/RunCMake/message/message-checks-stdout.txt10
-rw-r--r--Tests/RunCMake/message/message-checks.cmake13
-rw-r--r--Tests/RunCMake/message/message-context-cache-stdout.txt8
-rw-r--r--Tests/RunCMake/message/message-context-cli-stdout.txt8
-rw-r--r--Tests/RunCMake/message/message-context-cli-wins-cache-stdout.txt5
-rw-r--r--Tests/RunCMake/message/message-context.cmake27
-rw-r--r--Tests/RunCMake/message/message-log-level-debug-stdout.txt2
-rw-r--r--Tests/RunCMake/message/message-log-level-default-stdout.txt2
-rw-r--r--Tests/RunCMake/message/message-log-level-override-stderr.txt12
-rw-r--r--Tests/RunCMake/message/message-log-level-override-stdout.txt3
-rw-r--r--Tests/RunCMake/message/message-log-level-status-stdout.txt2
-rw-r--r--Tests/RunCMake/message/message-log-level-trace-stdout.txt2
-rw-r--r--Tests/RunCMake/message/message-log-level-verbose-stdout.txt2
-rw-r--r--Tests/RunCMake/message/message-loglevel-debug-stdout.txt2
-rw-r--r--Tests/RunCMake/message/message-loglevel-default-stdout.txt2
-rw-r--r--Tests/RunCMake/message/message-loglevel-status-stdout.txt2
-rw-r--r--Tests/RunCMake/message/message-loglevel-trace-stdout.txt2
-rw-r--r--Tests/RunCMake/message/message-loglevel-verbose-stdout.txt2
-rw-r--r--Tests/RunCMake/pseudo_cppcheck.c3
-rw-r--r--Tests/RunCMake/set_property/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/set_property/SOURCE_FILE-result.txt1
-rw-r--r--Tests/RunCMake/set_property/SOURCE_FILE-stderr.txt22
-rw-r--r--Tests/RunCMake/set_property/SOURCE_FILE.cmake4
-rw-r--r--Tests/RunCMake/string/Hex.cmake20
-rw-r--r--Tests/RunCMake/string/HexNotEnoughArgs-result.txt1
-rw-r--r--Tests/RunCMake/string/HexNotEnoughArgs-stderr.txt4
-rw-r--r--Tests/RunCMake/string/HexNotEnoughArgs.cmake1
-rw-r--r--Tests/RunCMake/string/HexTooManyArgs-result.txt1
-rw-r--r--Tests/RunCMake/string/HexTooManyArgs-stderr.txt4
-rw-r--r--Tests/RunCMake/string/HexTooManyArgs.cmake1
-rw-r--r--Tests/RunCMake/string/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/target_compile_options/BEFORE_keyword.cmake8
-rw-r--r--Tests/RunCMake/target_compile_options/CMP0101-BEFORE_keyword-NEW-result.txt1
-rw-r--r--Tests/RunCMake/target_compile_options/CMP0101-BEFORE_keyword-OLD-result.txt1
-rw-r--r--Tests/RunCMake/target_compile_options/CMP0101-BEFORE_keyword-OLD-stdout.txt1
-rw-r--r--Tests/RunCMake/target_compile_options/CMP0101-BEFORE_keyword.cmake15
-rw-r--r--Tests/RunCMake/target_compile_options/CMP0101.c9
-rw-r--r--Tests/RunCMake/target_compile_options/RunCMakeTest.cmake18
-rw-r--r--Tests/RunCMake/target_link_directories/CMP0099-NEW-basic-check.cmake4
-rw-r--r--Tests/RunCMake/target_link_directories/CMP0099-NEW-basic-result.txt1
-rw-r--r--Tests/RunCMake/target_link_directories/CMP0099-NEW.cmake4
-rw-r--r--Tests/RunCMake/target_link_directories/CMP0099-OLD-basic-check.cmake4
-rw-r--r--Tests/RunCMake/target_link_directories/CMP0099-OLD-basic-result.txt1
-rw-r--r--Tests/RunCMake/target_link_directories/CMP0099-OLD.cmake4
-rw-r--r--Tests/RunCMake/target_link_directories/CMP0099.cmake14
-rw-r--r--Tests/RunCMake/target_link_directories/RunCMakeTest.cmake41
-rw-r--r--Tests/RunCMake/target_link_directories/exe.c4
-rw-r--r--Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-LINKER_LANGUAGE-check.cmake5
-rw-r--r--Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-LINKER_LANGUAGE-result.txt1
-rw-r--r--Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-basic-check.cmake2
-rw-r--r--Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-basic-result.txt1
-rw-r--r--Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-interface-check.cmake4
-rw-r--r--Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-interface-result.txt1
-rw-r--r--Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-validation.cmake20
-rw-r--r--Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE.cmake23
-rw-r--r--Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-LINKER_LANGUAGE-check.cmake5
-rw-r--r--Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-LINKER_LANGUAGE-result.txt1
-rw-r--r--Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-basic-check.cmake2
-rw-r--r--Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-basic-result.txt1
-rw-r--r--Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-interface-check.cmake4
-rw-r--r--Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-interface-result.txt1
-rw-r--r--Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-validation.cmake26
-rw-r--r--Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID.cmake29
-rw-r--r--Tests/RunCMake/target_link_directories/lib.c7
-rw-r--r--Tests/RunCMake/target_link_libraries/CMP0079-iface-NEW-stdout.txt2
-rw-r--r--Tests/RunCMake/target_link_libraries/CMP0079-iface-OLD-stdout.txt2
-rw-r--r--Tests/RunCMake/target_link_libraries/CMP0079-iface-WARN-stderr.txt20
-rw-r--r--Tests/RunCMake/target_link_libraries/CMP0079-iface-WARN-stdout.txt2
-rw-r--r--Tests/RunCMake/target_link_libraries/CMP0079-iface/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-bogus-stderr.txt2
-rw-r--r--Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-bogus.cmake2
-rw-r--r--Tests/RunCMake/target_link_libraries/CMP0079-link-NEW-stdout.txt2
-rw-r--r--Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake54
-rw-r--r--Tests/RunCMake/target_link_libraries/func.c7
-rw-r--r--Tests/RunCMake/target_link_libraries/func.cxx7
-rw-r--r--Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE-bad-mix-lang-result.txt1
-rw-r--r--Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE-bad-mix-lang-stderr.txt2
-rw-r--r--Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE-bad-mix-lang.cmake8
-rw-r--r--Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE-bad-usage-result.txt1
-rw-r--r--Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE-bad-usage-stderr.txt8
-rw-r--r--Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE-bad-usage.cmake4
-rw-r--r--Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE.cmake72
-rw-r--r--Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-bad-mix-lang-result.txt1
-rw-r--r--Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-bad-mix-lang-stderr.txt2
-rw-r--r--Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-bad-mix-lang.cmake8
-rw-r--r--Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-basic-result.txt1
-rw-r--r--Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-exe_c-result.txt1
-rw-r--r--Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-exe_cxx-result.txt1
-rw-r--r--Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-interface-result.txt1
-rw-r--r--Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-no_language-result.txt1
-rw-r--r--Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID.cmake73
-rw-r--r--Tests/RunCMake/target_link_libraries/lib.c10
-rw-r--r--Tests/RunCMake/target_link_libraries/main.c12
-rw-r--r--Tests/RunCMake/target_link_libraries/main.cxx12
-rw-r--r--Tests/RunCMake/target_link_options/CMP0099-NEW-basic-check.cmake4
-rw-r--r--Tests/RunCMake/target_link_options/CMP0099-NEW-basic-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/CMP0099-NEW.cmake4
-rw-r--r--Tests/RunCMake/target_link_options/CMP0099-OLD-basic-check.cmake4
-rw-r--r--Tests/RunCMake/target_link_options/CMP0099-OLD-basic-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/CMP0099-OLD.cmake4
-rw-r--r--Tests/RunCMake/target_link_options/CMP0099.cmake19
-rw-r--r--Tests/RunCMake/target_link_options/LINKER_expansion.cmake11
-rw-r--r--Tests/RunCMake/target_link_options/LinkOptionsDevice.cu14
-rw-r--r--Tests/RunCMake/target_link_options/RunCMakeTest.cmake50
-rw-r--r--Tests/RunCMake/target_link_options/genex_DEVICE_LINK-CMP0105_NEW-check.cmake4
-rw-r--r--Tests/RunCMake/target_link_options/genex_DEVICE_LINK-CMP0105_NEW-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/genex_DEVICE_LINK-device-check.cmake3
-rw-r--r--Tests/RunCMake/target_link_options/genex_DEVICE_LINK-device-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/genex_DEVICE_LINK-interface-check.cmake3
-rw-r--r--Tests/RunCMake/target_link_options/genex_DEVICE_LINK-interface-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/genex_DEVICE_LINK-no_device-check.cmake3
-rw-r--r--Tests/RunCMake/target_link_options/genex_DEVICE_LINK-no_device-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/genex_DEVICE_LINK-private-check.cmake3
-rw-r--r--Tests/RunCMake/target_link_options/genex_DEVICE_LINK-private-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/genex_DEVICE_LINK-validation.cmake22
-rw-r--r--Tests/RunCMake/target_link_options/genex_DEVICE_LINK.cmake48
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-LINKER_LANGUAGE-check.cmake5
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-LINKER_LANGUAGE-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-exe-check.cmake2
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-exe-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-interface-check.cmake5
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-interface-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-mod-check.cmake2
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-mod-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-shared_c-check.cmake5
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-shared_c-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-validation.cmake17
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE.cmake32
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-LINKER_LANGUAGE-check.cmake5
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-LINKER_LANGUAGE-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-exe-check.cmake2
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-exe-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-interface-check.cmake5
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-interface-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-mod-check.cmake2
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-mod-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-shared_c-check.cmake5
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-shared_c-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-validation.cmake23
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID.cmake41
-rw-r--r--Tests/RunCMake/try_compile/CleanupNoFollowSymlink.cmake21
-rw-r--r--Tests/RunCMake/try_compile/RunCMakeTest.cmake10
-rw-r--r--Tests/SourceGroups/CMakeLists.txt6
-rw-r--r--Tests/SourceGroups/main.c4
-rw-r--r--Tests/SourceGroups/nested.c4
-rw-r--r--Tests/StagingPrefix/CMakeLists.txt2
-rw-r--r--Tests/SubDir/Examples/example1/CMakeLists.txt2
-rw-r--r--Tests/SubDirSpaces/Some Examples/example1/CMakeLists.txt2
-rw-r--r--Tests/SwiftOnly/CMakeLists.txt24
-rw-r--r--Tests/SwiftOnly/L.swift1
-rw-r--r--Tests/SwiftOnly/M.swift2
-rw-r--r--Tests/SwiftOnly/N.swift2
-rw-r--r--Tests/TryCompile/CMakeLists.txt2
-rw-r--r--Tests/UseSWIG/BasicConfiguration.cmake3
-rw-r--r--Tests/UseSWIG/BasicFortran/CMakeLists.txt23
-rw-r--r--Tests/UseSWIG/CMakeLists.txt15
-rw-r--r--Tests/UseSWIG/runme.f9077
-rw-r--r--Tests/VSMidl/CMakeLists.txt4
-rw-r--r--Tests/VSWinStorePhone/CMakeLists.txt7
-rw-r--r--Tests/VSWinStorePhone/EnsurePropertiesSet.cmake45
-rw-r--r--Tests/VSWindowsFormsResx/WindowsFormsResx/MyForm.cpp2
-rw-r--r--Utilities/CMakeLists.txt2
-rwxr-xr-xUtilities/GitSetup/setup-user15
-rw-r--r--Utilities/IWYU/mapping.imp66
-rw-r--r--Utilities/KWIML/CMakeLists.txt1
-rw-r--r--Utilities/KWIML/include/kwiml/abi.h6
-rw-r--r--Utilities/Release/.gitattributes1
-rw-r--r--Utilities/Release/README.rst46
-rw-r--r--Utilities/Release/create-cmake-release.cmake4
-rw-r--r--Utilities/Release/linux/x86_64/Dockerfile4
-rw-r--r--Utilities/Release/linux/x86_64/deps/Dockerfile8
-rw-r--r--Utilities/Release/linux/x86_64/test/cache-ninja.txt4
-rwxr-xr-xUtilities/Release/push.bash3
-rw-r--r--Utilities/Release/win/x86/Dockerfile23
-rw-r--r--Utilities/Release/win/x86/base/Dockerfile30
-rwxr-xr-xUtilities/Release/win/x86/base/msvc-i386.bat1
-rwxr-xr-xUtilities/Release/win/x86/base/msvc-x86_64.bat1
-rwxr-xr-xUtilities/Release/win/x86/build.bat19
-rw-r--r--Utilities/Release/win/x86/cache-i386.txt45
-rw-r--r--Utilities/Release/win/x86/cache-x86_64.txt45
-rw-r--r--Utilities/Release/win/x86/deps/Dockerfile127
-rwxr-xr-xUtilities/Release/win/x86/deps/qt-build.bat47
-rw-r--r--Utilities/Release/win/x86/deps/qt-install.patch26
-rwxr-xr-xUtilities/Release/win/x86/pack.bat12
-rw-r--r--Utilities/Release/win/x86/test/Dockerfile37
-rwxr-xr-xUtilities/Release/win/x86/test/test-ninja.bat19
-rwxr-xr-xUtilities/Release/win/x86/test/test-nmake.bat19
-rw-r--r--Utilities/Release/win32_release.cmake52
-rw-r--r--Utilities/Release/win64_release.cmake52
-rw-r--r--Utilities/Scripts/BoostScanDeps.cmake8
-rwxr-xr-xUtilities/Scripts/regenerate-lexers.bash3
-rwxr-xr-xUtilities/Scripts/update-bzip2.bash27
-rwxr-xr-xUtilities/Scripts/update-curl.bash6
-rwxr-xr-xUtilities/Scripts/update-libarchive.bash3
-rwxr-xr-xUtilities/Scripts/update-librhash.bash3
-rwxr-xr-xUtilities/Scripts/update-nghttp2.bash30
-rw-r--r--Utilities/Sphinx/CMakeLists.txt2
-rw-r--r--Utilities/Sphinx/CTestConfig.cmake14
-rw-r--r--Utilities/Sphinx/cmake.py5
-rwxr-xr-xUtilities/Sphinx/create_identifiers.py1
-rw-r--r--Utilities/cm3p/Setup.Configuration.h8
-rw-r--r--Utilities/cm3p/archive.h (renamed from Utilities/cm_libarchive.h)10
-rw-r--r--Utilities/cm3p/archive_entry.h14
-rw-r--r--Utilities/cm3p/bzlib.h (renamed from Utilities/cm_bzlib.h)8
-rw-r--r--Utilities/cm3p/curl/curl.h (renamed from Utilities/cm_curl.h)8
-rw-r--r--Utilities/cm3p/expat.h (renamed from Utilities/cm_expat.h)8
-rw-r--r--Utilities/cm3p/json/reader.h (renamed from Utilities/cm_jsoncpp_writer.h)8
-rw-r--r--Utilities/cm3p/json/value.h (renamed from Utilities/cm_jsoncpp_value.h)8
-rw-r--r--Utilities/cm3p/json/writer.h (renamed from Utilities/cm_jsoncpp_reader.h)8
-rw-r--r--Utilities/cm3p/kwiml/abi.h (renamed from Utilities/cm_kwiml.h)10
-rw-r--r--Utilities/cm3p/kwiml/int.h14
-rw-r--r--Utilities/cm3p/lzma.h (renamed from Utilities/cm_lzma.h)8
-rw-r--r--Utilities/cm3p/rhash.h (renamed from Utilities/cm_rhash.h)8
-rw-r--r--Utilities/cm3p/uv.h (renamed from Utilities/cm_uv.h)8
-rw-r--r--Utilities/cm3p/zlib.h (renamed from Utilities/cm_zlib.h)8
-rw-r--r--Utilities/cm3p/zstd.h (renamed from Utilities/cm_zstd.h)8
-rw-r--r--Utilities/cmbzip2/.gitattributes1
-rw-r--r--Utilities/cmbzip2/CHANGES319
-rw-r--r--Utilities/cmbzip2/CMakeLists.txt9
-rw-r--r--Utilities/cmbzip2/LICENSE6
-rw-r--r--Utilities/cmbzip2/Makefile-libbz2_so59
-rw-r--r--Utilities/cmbzip2/README36
-rw-r--r--Utilities/cmbzip2/README.COMPILATION.PROBLEMS58
-rw-r--r--Utilities/cmbzip2/README.XML.STUFF45
-rw-r--r--Utilities/cmbzip2/blocksort.c12
-rw-r--r--Utilities/cmbzip2/bz-common.xsl39
-rw-r--r--Utilities/cmbzip2/bz-fo.xsl276
-rw-r--r--Utilities/cmbzip2/bz-html.xsl20
-rw-r--r--Utilities/cmbzip2/bzdiff76
-rw-r--r--Utilities/cmbzip2/bzdiff.147
-rw-r--r--Utilities/cmbzip2/bzgrep75
-rw-r--r--Utilities/cmbzip2/bzgrep.156
-rw-r--r--Utilities/cmbzip2/bzip.css74
-rw-r--r--Utilities/cmbzip2/bzip2.1454
-rw-r--r--Utilities/cmbzip2/bzip2.1.preformatted399
-rw-r--r--Utilities/cmbzip2/bzip2.c112
-rw-r--r--Utilities/cmbzip2/bzip2.txt391
-rw-r--r--Utilities/cmbzip2/bzip2recover.c18
-rw-r--r--Utilities/cmbzip2/bzlib.c13
-rw-r--r--Utilities/cmbzip2/bzlib.h4
-rw-r--r--Utilities/cmbzip2/bzlib_private.h23
-rw-r--r--Utilities/cmbzip2/bzmore61
-rw-r--r--Utilities/cmbzip2/bzmore.1152
-rw-r--r--Utilities/cmbzip2/compress.c18
-rw-r--r--Utilities/cmbzip2/crctable.c4
-rw-r--r--Utilities/cmbzip2/decompress.c34
-rw-r--r--Utilities/cmbzip2/dlltest.c350
-rw-r--r--Utilities/cmbzip2/entities.xml9
-rwxr-xr-xUtilities/cmbzip2/format.pl68
-rw-r--r--Utilities/cmbzip2/huffman.c4
-rw-r--r--Utilities/cmbzip2/libbz2.def27
-rw-r--r--Utilities/cmbzip2/libbz2.libbin60774 -> 0 bytes-rw-r--r--Utilities/cmbzip2/makefile.msc63
-rw-r--r--Utilities/cmbzip2/manual.html2540
-rw-r--r--Utilities/cmbzip2/manual.pdfbin289422 -> 0 bytes-rw-r--r--Utilities/cmbzip2/manual.ps82900
-rw-r--r--Utilities/cmbzip2/manual.xml2964
-rw-r--r--Utilities/cmbzip2/mk251.c4
-rw-r--r--Utilities/cmbzip2/randtable.c4
-rw-r--r--Utilities/cmbzip2/sample1.rb2bin32558 -> 0 bytes-rw-r--r--Utilities/cmbzip2/sample1.refbin98869 -> 0 bytes-rw-r--r--Utilities/cmbzip2/sample1.tstbin98869 -> 0 bytes-rw-r--r--Utilities/cmbzip2/sample2.rb2bin74143 -> 0 bytes-rw-r--r--Utilities/cmbzip2/sample2.refbin212610 -> 0 bytes-rw-r--r--Utilities/cmbzip2/sample2.tstbin212610 -> 0 bytes-rw-r--r--Utilities/cmbzip2/sample3.rb2bin237 -> 0 bytes-rw-r--r--Utilities/cmbzip2/sample3.ref30007
-rw-r--r--Utilities/cmbzip2/sample3.tst30007
-rw-r--r--Utilities/cmbzip2/spewG.c6
-rw-r--r--Utilities/cmbzip2/unzcrash.c4
-rw-r--r--Utilities/cmbzip2/words09
-rw-r--r--Utilities/cmbzip2/words14
-rw-r--r--Utilities/cmbzip2/words25
-rw-r--r--Utilities/cmbzip2/words330
-rwxr-xr-xUtilities/cmbzip2/xmlproc.sh114
-rw-r--r--Utilities/cmcurl/CMake/CurlSymbolHiding.cmake10
-rw-r--r--Utilities/cmcurl/CMake/CurlTests.c4
-rw-r--r--Utilities/cmcurl/CMake/FindBearSSL.cmake9
-rw-r--r--Utilities/cmcurl/CMake/FindCARES.cmake26
-rw-r--r--Utilities/cmcurl/CMake/FindGSS.cmake8
-rw-r--r--Utilities/cmcurl/CMake/FindLibSSH2.cmake29
-rw-r--r--Utilities/cmcurl/CMake/FindNGHTTP2.cmake4
-rw-r--r--Utilities/cmcurl/CMake/FindNSS.cmake17
-rw-r--r--Utilities/cmcurl/CMake/OtherTests.cmake4
-rw-r--r--Utilities/cmcurl/CMake/Platforms/WindowsCache.cmake1
-rw-r--r--Utilities/cmcurl/CMake/Utilities.cmake5
-rw-r--r--Utilities/cmcurl/CMake/cmake_uninstall.cmake.in2
-rw-r--r--Utilities/cmcurl/CMakeLists.txt137
-rw-r--r--Utilities/cmcurl/COPYING2
-rw-r--r--Utilities/cmcurl/include/curl/curl.h762
-rw-r--r--Utilities/cmcurl/include/curl/curlver.h16
-rw-r--r--Utilities/cmcurl/include/curl/easy.h6
-rw-r--r--Utilities/cmcurl/include/curl/mprintf.h8
-rw-r--r--Utilities/cmcurl/include/curl/multi.h77
-rw-r--r--Utilities/cmcurl/include/curl/stdcheaders.h8
-rw-r--r--Utilities/cmcurl/include/curl/system.h57
-rw-r--r--Utilities/cmcurl/include/curl/typecheck-gcc.h555
-rw-r--r--Utilities/cmcurl/include/curl/urlapi.h8
-rw-r--r--Utilities/cmcurl/lib/CMakeLists.txt9
-rw-r--r--Utilities/cmcurl/lib/Makefile.inc38
-rw-r--r--Utilities/cmcurl/lib/altsvc.c297
-rw-r--r--Utilities/cmcurl/lib/altsvc.h34
-rw-r--r--Utilities/cmcurl/lib/asyn-ares.c29
-rw-r--r--Utilities/cmcurl/lib/asyn-thread.c136
-rw-r--r--Utilities/cmcurl/lib/asyn.h3
-rw-r--r--Utilities/cmcurl/lib/base64.c4
-rw-r--r--Utilities/cmcurl/lib/conncache.c82
-rw-r--r--Utilities/cmcurl/lib/conncache.h30
-rw-r--r--Utilities/cmcurl/lib/connect.c241
-rw-r--r--Utilities/cmcurl/lib/connect.h3
-rw-r--r--Utilities/cmcurl/lib/cookie.c99
-rw-r--r--Utilities/cmcurl/lib/cookie.h2
-rw-r--r--Utilities/cmcurl/lib/curl_base64.h2
-rw-r--r--Utilities/cmcurl/lib/curl_config.h.cmake56
-rw-r--r--Utilities/cmcurl/lib/curl_des.c2
-rw-r--r--Utilities/cmcurl/lib/curl_des.h2
-rw-r--r--Utilities/cmcurl/lib/curl_endian.c2
-rw-r--r--Utilities/cmcurl/lib/curl_endian.h5
-rw-r--r--Utilities/cmcurl/lib/curl_fnmatch.h2
-rw-r--r--Utilities/cmcurl/lib/curl_gethostname.h2
-rw-r--r--Utilities/cmcurl/lib/curl_hmac.h9
-rw-r--r--Utilities/cmcurl/lib/curl_ldap.h2
-rw-r--r--Utilities/cmcurl/lib/curl_md4.h15
-rw-r--r--Utilities/cmcurl/lib/curl_md5.h6
-rw-r--r--Utilities/cmcurl/lib/curl_memrchr.h2
-rw-r--r--Utilities/cmcurl/lib/curl_multibyte.c2
-rw-r--r--Utilities/cmcurl/lib/curl_multibyte.h13
-rw-r--r--Utilities/cmcurl/lib/curl_ntlm_core.c112
-rw-r--r--Utilities/cmcurl/lib/curl_ntlm_core.h8
-rw-r--r--Utilities/cmcurl/lib/curl_ntlm_wb.c112
-rw-r--r--Utilities/cmcurl/lib/curl_path.c2
-rw-r--r--Utilities/cmcurl/lib/curl_rtmp.c14
-rw-r--r--Utilities/cmcurl/lib/curl_rtmp.h2
-rw-r--r--Utilities/cmcurl/lib/curl_sasl.c26
-rw-r--r--Utilities/cmcurl/lib/curl_setup.h46
-rw-r--r--Utilities/cmcurl/lib/curl_setup_once.h28
-rw-r--r--Utilities/cmcurl/lib/curl_sha256.h9
-rw-r--r--Utilities/cmcurl/lib/curl_sspi.c2
-rw-r--r--Utilities/cmcurl/lib/curl_sspi.h2
-rw-r--r--Utilities/cmcurl/lib/curl_threads.c2
-rw-r--r--Utilities/cmcurl/lib/curl_threads.h2
-rw-r--r--Utilities/cmcurl/lib/dict.h2
-rw-r--r--Utilities/cmcurl/lib/doh.c232
-rw-r--r--Utilities/cmcurl/lib/doh.h9
-rw-r--r--Utilities/cmcurl/lib/dotdot.c2
-rw-r--r--Utilities/cmcurl/lib/dotdot.h2
-rw-r--r--Utilities/cmcurl/lib/easy.c202
-rw-r--r--Utilities/cmcurl/lib/easyif.h2
-rw-r--r--Utilities/cmcurl/lib/file.c8
-rw-r--r--Utilities/cmcurl/lib/file.h2
-rw-r--r--Utilities/cmcurl/lib/formdata.c2
-rw-r--r--Utilities/cmcurl/lib/ftp.c493
-rw-r--r--Utilities/cmcurl/lib/ftp.h10
-rw-r--r--Utilities/cmcurl/lib/ftplistparser.c2
-rw-r--r--Utilities/cmcurl/lib/ftplistparser.h2
-rw-r--r--Utilities/cmcurl/lib/getenv.c47
-rw-r--r--Utilities/cmcurl/lib/getinfo.c8
-rw-r--r--Utilities/cmcurl/lib/getinfo.h2
-rw-r--r--Utilities/cmcurl/lib/gopher.h2
-rw-r--r--Utilities/cmcurl/lib/hash.h4
-rw-r--r--Utilities/cmcurl/lib/hmac.c39
-rw-r--r--Utilities/cmcurl/lib/hostcheck.c2
-rw-r--r--Utilities/cmcurl/lib/hostcheck.h2
-rw-r--r--Utilities/cmcurl/lib/hostip.c94
-rw-r--r--Utilities/cmcurl/lib/hostip.h46
-rw-r--r--Utilities/cmcurl/lib/hostip4.c284
-rw-r--r--Utilities/cmcurl/lib/hostip6.c29
-rw-r--r--Utilities/cmcurl/lib/hostsyn.c2
-rw-r--r--Utilities/cmcurl/lib/http.c302
-rw-r--r--Utilities/cmcurl/lib/http.h50
-rw-r--r--Utilities/cmcurl/lib/http2.c216
-rw-r--r--Utilities/cmcurl/lib/http2.h10
-rw-r--r--Utilities/cmcurl/lib/http_chunks.c28
-rw-r--r--Utilities/cmcurl/lib/http_chunks.h13
-rw-r--r--Utilities/cmcurl/lib/http_negotiate.c4
-rw-r--r--Utilities/cmcurl/lib/http_ntlm.c9
-rw-r--r--Utilities/cmcurl/lib/http_proxy.c15
-rw-r--r--Utilities/cmcurl/lib/imap.c28
-rw-r--r--Utilities/cmcurl/lib/imap.h2
-rw-r--r--Utilities/cmcurl/lib/inet_ntop.c2
-rw-r--r--Utilities/cmcurl/lib/inet_ntop.h2
-rw-r--r--Utilities/cmcurl/lib/inet_pton.c2
-rw-r--r--Utilities/cmcurl/lib/inet_pton.h2
-rw-r--r--Utilities/cmcurl/lib/krb5.c10
-rw-r--r--Utilities/cmcurl/lib/ldap.c26
-rw-r--r--Utilities/cmcurl/lib/llist.c53
-rw-r--r--Utilities/cmcurl/lib/llist.h5
-rw-r--r--Utilities/cmcurl/lib/md4.c247
-rw-r--r--Utilities/cmcurl/lib/md5.c69
-rw-r--r--Utilities/cmcurl/lib/memdebug.h2
-rw-r--r--Utilities/cmcurl/lib/mime.c21
-rw-r--r--Utilities/cmcurl/lib/mime.h8
-rw-r--r--Utilities/cmcurl/lib/mprintf.c4
-rw-r--r--Utilities/cmcurl/lib/multi.c626
-rw-r--r--Utilities/cmcurl/lib/multihandle.h26
-rw-r--r--Utilities/cmcurl/lib/multiif.h15
-rw-r--r--Utilities/cmcurl/lib/netrc.c153
-rw-r--r--Utilities/cmcurl/lib/non-ascii.c2
-rw-r--r--Utilities/cmcurl/lib/nonblock.c2
-rw-r--r--Utilities/cmcurl/lib/nonblock.h2
-rw-r--r--Utilities/cmcurl/lib/openldap.c28
-rw-r--r--Utilities/cmcurl/lib/parsedate.c38
-rw-r--r--Utilities/cmcurl/lib/parsedate.h8
-rw-r--r--Utilities/cmcurl/lib/pingpong.c13
-rw-r--r--Utilities/cmcurl/lib/pingpong.h5
-rw-r--r--Utilities/cmcurl/lib/pop3.c23
-rw-r--r--Utilities/cmcurl/lib/pop3.h2
-rw-r--r--Utilities/cmcurl/lib/progress.c262
-rw-r--r--Utilities/cmcurl/lib/quic.h57
-rw-r--r--Utilities/cmcurl/lib/rand.c5
-rw-r--r--Utilities/cmcurl/lib/rand.h5
-rw-r--r--Utilities/cmcurl/lib/rename.c62
-rw-r--r--Utilities/cmcurl/lib/rename.h27
-rw-r--r--Utilities/cmcurl/lib/rtsp.c11
-rw-r--r--Utilities/cmcurl/lib/rtsp.h2
-rw-r--r--Utilities/cmcurl/lib/security.c12
-rw-r--r--Utilities/cmcurl/lib/select.c215
-rw-r--r--Utilities/cmcurl/lib/select.h16
-rw-r--r--Utilities/cmcurl/lib/sendf.c23
-rw-r--r--Utilities/cmcurl/lib/setopt.c82
-rw-r--r--Utilities/cmcurl/lib/setopt.h5
-rw-r--r--Utilities/cmcurl/lib/setup-os400.h6
-rw-r--r--Utilities/cmcurl/lib/sha256.c193
-rw-r--r--Utilities/cmcurl/lib/slist.c2
-rw-r--r--Utilities/cmcurl/lib/slist.h2
-rw-r--r--Utilities/cmcurl/lib/smb.c21
-rw-r--r--Utilities/cmcurl/lib/smtp.c353
-rw-r--r--Utilities/cmcurl/lib/smtp.h7
-rw-r--r--Utilities/cmcurl/lib/sockaddr.h2
-rw-r--r--Utilities/cmcurl/lib/socketpair.c121
-rw-r--r--Utilities/cmcurl/lib/socketpair.h36
-rw-r--r--Utilities/cmcurl/lib/socks.c1158
-rw-r--r--Utilities/cmcurl/lib/socks.h15
-rw-r--r--Utilities/cmcurl/lib/socks_gssapi.c6
-rw-r--r--Utilities/cmcurl/lib/socks_sspi.c5
-rw-r--r--Utilities/cmcurl/lib/splay.h8
-rw-r--r--Utilities/cmcurl/lib/strcase.c88
-rw-r--r--Utilities/cmcurl/lib/strcase.h3
-rw-r--r--Utilities/cmcurl/lib/strdup.c2
-rw-r--r--Utilities/cmcurl/lib/strerror.c587
-rw-r--r--Utilities/cmcurl/lib/strerror.h7
-rw-r--r--Utilities/cmcurl/lib/strtok.c2
-rw-r--r--Utilities/cmcurl/lib/strtok.h2
-rw-r--r--Utilities/cmcurl/lib/strtoofft.c2
-rw-r--r--Utilities/cmcurl/lib/system_win32.c45
-rw-r--r--Utilities/cmcurl/lib/system_win32.h13
-rw-r--r--Utilities/cmcurl/lib/telnet.c4
-rw-r--r--Utilities/cmcurl/lib/telnet.h2
-rw-r--r--Utilities/cmcurl/lib/tftp.c77
-rw-r--r--Utilities/cmcurl/lib/tftp.h2
-rw-r--r--Utilities/cmcurl/lib/timeval.c27
-rw-r--r--Utilities/cmcurl/lib/timeval.h10
-rw-r--r--Utilities/cmcurl/lib/transfer.c65
-rw-r--r--Utilities/cmcurl/lib/transfer.h7
-rw-r--r--Utilities/cmcurl/lib/url.c656
-rw-r--r--Utilities/cmcurl/lib/url.h25
-rw-r--r--Utilities/cmcurl/lib/urlapi-int.h3
-rw-r--r--Utilities/cmcurl/lib/urlapi.c237
-rw-r--r--Utilities/cmcurl/lib/urldata.h562
-rw-r--r--Utilities/cmcurl/lib/vauth/cram.c2
-rw-r--r--Utilities/cmcurl/lib/vauth/digest.c85
-rw-r--r--Utilities/cmcurl/lib/vauth/digest.h2
-rw-r--r--Utilities/cmcurl/lib/vauth/digest_sspi.c15
-rw-r--r--Utilities/cmcurl/lib/vauth/krb5_gssapi.c10
-rw-r--r--Utilities/cmcurl/lib/vauth/krb5_sspi.c26
-rw-r--r--Utilities/cmcurl/lib/vauth/ntlm.c13
-rw-r--r--Utilities/cmcurl/lib/vauth/ntlm_sspi.c14
-rw-r--r--Utilities/cmcurl/lib/vauth/spnego_gssapi.c6
-rw-r--r--Utilities/cmcurl/lib/vauth/spnego_sspi.c23
-rw-r--r--Utilities/cmcurl/lib/vauth/vauth.h2
-rw-r--r--Utilities/cmcurl/lib/version.c83
-rw-r--r--Utilities/cmcurl/lib/vquic/ngtcp2.c1769
-rw-r--r--Utilities/cmcurl/lib/vquic/ngtcp2.h63
-rw-r--r--Utilities/cmcurl/lib/vquic/quiche.c807
-rw-r--r--Utilities/cmcurl/lib/vquic/quiche.h49
-rw-r--r--Utilities/cmcurl/lib/vssh/libssh.c (renamed from Utilities/cmcurl/lib/ssh-libssh.c)160
-rw-r--r--Utilities/cmcurl/lib/vssh/libssh2.c (renamed from Utilities/cmcurl/lib/ssh.c)314
-rw-r--r--Utilities/cmcurl/lib/vssh/ssh.h (renamed from Utilities/cmcurl/lib/ssh.h)29
-rw-r--r--Utilities/cmcurl/lib/vssh/wolfssh.c1156
-rw-r--r--Utilities/cmcurl/lib/vssh/wolfssh.h27
-rw-r--r--Utilities/cmcurl/lib/vtls/bearssl.c866
-rw-r--r--Utilities/cmcurl/lib/vtls/bearssl.h (renamed from Utilities/cmcurl/lib/vtls/polarssl.h)16
-rw-r--r--Utilities/cmcurl/lib/vtls/gskit.c102
-rw-r--r--Utilities/cmcurl/lib/vtls/gskit.h2
-rw-r--r--Utilities/cmcurl/lib/vtls/gtls.c12
-rw-r--r--Utilities/cmcurl/lib/vtls/mbedtls.c23
-rw-r--r--Utilities/cmcurl/lib/vtls/mbedtls.h2
-rw-r--r--Utilities/cmcurl/lib/vtls/mbedtls_threadlock.c (renamed from Utilities/cmcurl/lib/vtls/polarssl_threadlock.c)38
-rw-r--r--Utilities/cmcurl/lib/vtls/mbedtls_threadlock.h (renamed from Utilities/cmcurl/lib/vtls/polarssl_threadlock.h)28
-rw-r--r--Utilities/cmcurl/lib/vtls/mesalink.c71
-rw-r--r--Utilities/cmcurl/lib/vtls/nss.c51
-rw-r--r--Utilities/cmcurl/lib/vtls/openssl.c451
-rw-r--r--Utilities/cmcurl/lib/vtls/polarssl.c931
-rw-r--r--Utilities/cmcurl/lib/vtls/schannel.c22
-rw-r--r--Utilities/cmcurl/lib/vtls/schannel_verify.c177
-rw-r--r--Utilities/cmcurl/lib/vtls/sectransp.c37
-rw-r--r--Utilities/cmcurl/lib/vtls/vtls.c76
-rw-r--r--Utilities/cmcurl/lib/vtls/vtls.h9
-rw-r--r--Utilities/cmcurl/lib/vtls/wolfssl.c (renamed from Utilities/cmcurl/lib/vtls/cyassl.c)231
-rw-r--r--Utilities/cmcurl/lib/vtls/wolfssl.h (renamed from Utilities/cmcurl/lib/vtls/cyassl.h)14
-rw-r--r--Utilities/cmcurl/lib/x509asn1.c4
-rw-r--r--Utilities/cmcurl/lib/x509asn1.h6
-rw-r--r--Utilities/cmexpat/lib/siphash.h2
-rw-r--r--Utilities/cmlibarchive/CMakeLists.txt489
-rw-r--r--Utilities/cmlibarchive/COPYING9
-rw-r--r--Utilities/cmlibarchive/build/cmake/FindMbedTLS.cmake13
-rw-r--r--Utilities/cmlibarchive/build/cmake/config.h.in15
-rw-r--r--Utilities/cmlibarchive/build/version2
-rw-r--r--Utilities/cmlibarchive/libarchive/CMakeLists.txt40
-rw-r--r--Utilities/cmlibarchive/libarchive/archive.h12
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_acl.c88
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_acl_private.h6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_blake2.h195
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_blake2_impl.h161
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_blake2s_ref.c367
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_blake2sp_ref.c359
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_cmdline_private.h6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_crc32.h5
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_cryptor.c69
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_cryptor_private.h24
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_digest.c228
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_digest_private.h43
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_disk_acl_sunos.c6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_endian.h11
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry.37
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry.c318
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry.h15
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_acl.380
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_locale.h6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_misc.363
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_paths.310
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_perms.312
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_private.h9
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_stat.36
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_time.36
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_getdate.c151
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_getdate.h6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_hmac.c51
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_hmac_private.h12
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_match.c33
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_openssl_evp_private.h5
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_openssl_hmac_private.h5
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_options_private.h4
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_pack_dev.c6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_pack_dev.h6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_pathmatch.h6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_platform.h2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_platform_acl.h6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_platform_xattr.h6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_ppmd7.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_ppmd7_private.h6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_ppmd8.c1287
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_ppmd8_private.h148
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_ppmd_private.h6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_private.h11
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_random_private.h6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_rb.h21
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read.36
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read.c14
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_add_passphrase.310
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_data.34
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_disk.313
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c11
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c113
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_disk_private.h6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c182
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_extract.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_filter.34
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_format.36
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_free.36
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_header.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_new.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_open.34
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_open_file.c3
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_private.h9
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_set_format.c3
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_set_options.341
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_bzip2.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_gzip.c72
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c10
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_lzop.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_uu.c30
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_xz.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_zstd.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c28
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_all.c1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_ar.c9
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_by_code.c3
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_cpio.c3
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c19
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c206
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c16
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c90
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c4103
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_raw.c4
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c29
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c11
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c70
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c1085
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_string.c45
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_string.h6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_string_composition.h6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_util.316
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_util.c236
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_version_details.c8
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_windows.c3
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_windows.h13
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write.36
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write.c91
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_b64encode.c12
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_bzip2.c12
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_compress.c22
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_gzip.c11
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_lz4.c11
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_lzop.c10
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_program.c12
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_uuencode.c12
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_xz.c18
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_zstd.c14
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_blocksize.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_data.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_disk.312
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c423
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_disk_private.h6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_disk_set_standard_lookup.c6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c377
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_filter.34
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_finish_entry.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_format.34
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_free.34
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_header.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_new.32
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_open.34
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_private.h14
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format.c45
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c12
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_ar.c6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio.c4
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_newc.c4
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_gnutar.c20
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_iso9660.c34
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_mtree.c20
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c145
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_private.h42
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_shar.c11
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_ustar.c39
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_v7tar.c40
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_warc.c18
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c86
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c49
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_options.3285
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_passphrase.312
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_xxhash.h5
-rw-r--r--Utilities/cmlibarchive/libarchive/config_freebsd.h1
-rw-r--r--Utilities/cmlibarchive/libarchive/filter_fork.h6
-rw-r--r--Utilities/cmlibarchive/libarchive/libarchive_changes.35
-rw-r--r--Utilities/cmlibarchive/libarchive/libarchive_internals.34
-rw-r--r--Utilities/cmlibarchive/libarchive/mtree.57
-rw-r--r--Utilities/cmlibarchive/libarchive/tar.59
-rw-r--r--Utilities/cmlibrhash/CMakeLists.txt2
-rw-r--r--Utilities/cmlibrhash/COPYING22
-rw-r--r--Utilities/cmlibrhash/README7
-rw-r--r--Utilities/cmlibrhash/librhash/algorithms.c146
-rw-r--r--Utilities/cmlibrhash/librhash/algorithms.h49
-rw-r--r--Utilities/cmlibrhash/librhash/byte_order.c53
-rw-r--r--Utilities/cmlibrhash/librhash/byte_order.h147
-rw-r--r--Utilities/cmlibrhash/librhash/hex.c170
-rw-r--r--Utilities/cmlibrhash/librhash/hex.h13
-rw-r--r--Utilities/cmlibrhash/librhash/md5.c26
-rw-r--r--Utilities/cmlibrhash/librhash/md5.h6
-rw-r--r--Utilities/cmlibrhash/librhash/rhash.c320
-rw-r--r--Utilities/cmlibrhash/librhash/rhash.h393
-rw-r--r--Utilities/cmlibrhash/librhash/sha1.c26
-rw-r--r--Utilities/cmlibrhash/librhash/sha1.h6
-rw-r--r--Utilities/cmlibrhash/librhash/sha256.c30
-rw-r--r--Utilities/cmlibrhash/librhash/sha256.h8
-rw-r--r--Utilities/cmlibrhash/librhash/sha3.c108
-rw-r--r--Utilities/cmlibrhash/librhash/sha3.h14
-rw-r--r--Utilities/cmlibrhash/librhash/sha512.c30
-rw-r--r--Utilities/cmlibrhash/librhash/sha512.h8
-rw-r--r--Utilities/cmlibrhash/librhash/ustd.h34
-rw-r--r--Utilities/cmlibrhash/librhash/util.h2
-rw-r--r--Utilities/cmlibuv/include/uv.h139
-rw-r--r--Utilities/cmlibuv/include/uv/errno.h5
-rw-r--r--Utilities/cmlibuv/include/uv/unix.h22
-rw-r--r--Utilities/cmlibuv/include/uv/version.h6
-rw-r--r--Utilities/cmlibuv/include/uv/win.h3
-rw-r--r--Utilities/cmlibuv/src/random.c123
-rw-r--r--Utilities/cmlibuv/src/threadpool.c8
-rw-r--r--Utilities/cmlibuv/src/timer.c11
-rw-r--r--Utilities/cmlibuv/src/unix/aix-common.c142
-rw-r--r--Utilities/cmlibuv/src/unix/aix.c182
-rw-r--r--Utilities/cmlibuv/src/unix/android-ifaddrs.c3
-rw-r--r--Utilities/cmlibuv/src/unix/async.c115
-rw-r--r--Utilities/cmlibuv/src/unix/atomic-ops.h12
-rw-r--r--Utilities/cmlibuv/src/unix/bsd-ifaddrs.c2
-rw-r--r--Utilities/cmlibuv/src/unix/bsd-proctitle.c7
-rw-r--r--Utilities/cmlibuv/src/unix/cmake-bootstrap.c6
-rw-r--r--Utilities/cmlibuv/src/unix/core.c295
-rw-r--r--Utilities/cmlibuv/src/unix/cygwin.c5
-rw-r--r--Utilities/cmlibuv/src/unix/darwin-proctitle.c156
-rw-r--r--Utilities/cmlibuv/src/unix/darwin-stub.h97
-rw-r--r--Utilities/cmlibuv/src/unix/darwin.c17
-rw-r--r--Utilities/cmlibuv/src/unix/freebsd.c34
-rw-r--r--Utilities/cmlibuv/src/unix/fs.c430
-rw-r--r--Utilities/cmlibuv/src/unix/fsevents.c65
-rw-r--r--Utilities/cmlibuv/src/unix/haiku.c9
-rw-r--r--Utilities/cmlibuv/src/unix/ibmi.c264
-rw-r--r--Utilities/cmlibuv/src/unix/internal.h48
-rw-r--r--Utilities/cmlibuv/src/unix/kqueue.c44
-rw-r--r--Utilities/cmlibuv/src/unix/linux-core.c101
-rw-r--r--Utilities/cmlibuv/src/unix/linux-inotify.c67
-rw-r--r--Utilities/cmlibuv/src/unix/linux-syscalls.c214
-rw-r--r--Utilities/cmlibuv/src/unix/linux-syscalls.h80
-rw-r--r--Utilities/cmlibuv/src/unix/netbsd.c30
-rw-r--r--Utilities/cmlibuv/src/unix/no-proctitle.c3
-rw-r--r--Utilities/cmlibuv/src/unix/openbsd.c63
-rw-r--r--Utilities/cmlibuv/src/unix/os390-syscalls.c117
-rw-r--r--Utilities/cmlibuv/src/unix/os390-syscalls.h6
-rw-r--r--Utilities/cmlibuv/src/unix/os390.c9
-rw-r--r--Utilities/cmlibuv/src/unix/pipe.c8
-rw-r--r--Utilities/cmlibuv/src/unix/posix-poll.c2
-rw-r--r--Utilities/cmlibuv/src/unix/process.c80
-rw-r--r--Utilities/cmlibuv/src/unix/proctitle.c71
-rw-r--r--Utilities/cmlibuv/src/unix/random-devurandom.c93
-rw-r--r--Utilities/cmlibuv/src/unix/random-getentropy.c57
-rw-r--r--Utilities/cmlibuv/src/unix/random-getrandom.c88
-rw-r--r--Utilities/cmlibuv/src/unix/random-sysctl-linux.c99
-rw-r--r--Utilities/cmlibuv/src/unix/signal.c25
-rw-r--r--Utilities/cmlibuv/src/unix/stream.c13
-rw-r--r--Utilities/cmlibuv/src/unix/sunos.c10
-rw-r--r--Utilities/cmlibuv/src/unix/tcp.c29
-rw-r--r--Utilities/cmlibuv/src/unix/thread.c18
-rw-r--r--Utilities/cmlibuv/src/unix/tty.c37
-rw-r--r--Utilities/cmlibuv/src/unix/udp.c391
-rw-r--r--Utilities/cmlibuv/src/uv-common.c81
-rw-r--r--Utilities/cmlibuv/src/uv-common.h11
-rw-r--r--Utilities/cmlibuv/src/win/core.c21
-rw-r--r--Utilities/cmlibuv/src/win/error.c2
-rw-r--r--Utilities/cmlibuv/src/win/fs-event.c33
-rw-r--r--Utilities/cmlibuv/src/win/fs-fd-hash-inl.h178
-rw-r--r--Utilities/cmlibuv/src/win/fs.c906
-rw-r--r--Utilities/cmlibuv/src/win/internal.h2
-rw-r--r--Utilities/cmlibuv/src/win/pipe.c151
-rw-r--r--Utilities/cmlibuv/src/win/poll.c183
-rw-r--r--Utilities/cmlibuv/src/win/process.c13
-rw-r--r--Utilities/cmlibuv/src/win/signal.c5
-rw-r--r--Utilities/cmlibuv/src/win/stream.c7
-rw-r--r--Utilities/cmlibuv/src/win/tcp.c38
-rw-r--r--Utilities/cmlibuv/src/win/tty.c502
-rw-r--r--Utilities/cmlibuv/src/win/udp.c170
-rw-r--r--Utilities/cmlibuv/src/win/util.c293
-rw-r--r--Utilities/cmlibuv/src/win/winapi.c9
-rw-r--r--Utilities/cmlibuv/src/win/winapi.h21
-rw-r--r--Utilities/cmlibuv/src/win/winsock.c47
-rw-r--r--Utilities/cmlibuv/src/win/winsock.h8
-rw-r--r--Utilities/cmnghttp2/.gitattributes1
-rw-r--r--Utilities/cmnghttp2/CMakeLists.txt52
-rw-r--r--Utilities/cmnghttp2/COPYING23
-rw-r--r--Utilities/cmnghttp2/cmakeconfig.h.in18
-rw-r--r--Utilities/cmnghttp2/lib/includes/nghttp2/nghttp2.h5487
-rw-r--r--Utilities/cmnghttp2/lib/includes/nghttp2/nghttp2ver.h42
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_buf.c525
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_buf.h412
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_callbacks.c175
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_callbacks.h125
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_debug.c60
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_debug.h43
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_frame.c1134
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_frame.h624
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_hd.c2351
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_hd.h439
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_hd_huffman.c144
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_hd_huffman.h72
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_hd_huffman_data.c4980
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_helper.c629
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_helper.h122
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_http.c530
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_http.h97
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_int.h58
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_map.c189
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_map.h144
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_mem.c74
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_mem.h45
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_net.h91
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_npn.c57
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_npn.h34
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_option.c123
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_option.h131
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_outbound_item.c127
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_outbound_item.h166
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_pq.c184
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_pq.h130
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_priority_spec.c52
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_priority_spec.h42
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_queue.c85
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_queue.h51
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_rcbuf.c102
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_rcbuf.h80
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_session.c7780
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_session.h901
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_stream.c1001
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_stream.h437
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_submit.c814
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_submit.h34
-rw-r--r--Utilities/cmnghttp2/lib/nghttp2_version.c38
-rw-r--r--Utilities/cmzlib/CMakeLists.txt5
-rw-r--r--Utilities/std/.gitattributes3
-rw-r--r--Utilities/std/CMakeLists.txt7
-rw-r--r--Utilities/std/cm/bits/erase_if.hxx29
-rw-r--r--Utilities/std/cm/bits/string_view.cxx2
-rw-r--r--Utilities/std/cm/deque40
-rw-r--r--Utilities/std/cm/list39
-rw-r--r--Utilities/std/cm/map44
-rw-r--r--Utilities/std/cm/memory37
-rw-r--r--Utilities/std/cm/set43
-rw-r--r--Utilities/std/cm/shared_mutex2
-rw-r--r--Utilities/std/cm/string42
-rw-r--r--Utilities/std/cm/type_traits63
-rw-r--r--Utilities/std/cm/unordered_map45
-rw-r--r--Utilities/std/cm/unordered_set45
-rw-r--r--Utilities/std/cm/vector40
-rw-r--r--Utilities/std/cmext/algorithm251
-rw-r--r--Utilities/std/cmext/iterator51
-rw-r--r--Utilities/std/cmext/memory40
-rw-r--r--Utilities/std/cmext/string_view (renamed from Source/cm_static_string_view.hxx)9
-rw-r--r--Utilities/std/cmext/type_traits88
-rwxr-xr-xbootstrap187
-rw-r--r--cmake_uninstall.cmake.in2
3242 files changed, 121329 insertions, 184214 deletions
diff --git a/.clang-format b/.clang-format
index 0c7d6b0..8c015ef 100644
--- a/.clang-format
+++ b/.clang-format
@@ -22,7 +22,9 @@ IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^[<"]cmConfigure\.h'
Priority: -1
- - Regex: '^(<|")cm/'
+ - Regex: '^<queue>'
+ Priority: 1
+ - Regex: '^(<|")cm(ext)?/'
Priority: 2
- Regex: '^(<|")windows\.h'
Priority: 3
@@ -30,16 +32,18 @@ IncludeCategories:
Priority: 5
- Regex: '^(<|")Qt?[A-Z]'
Priority: 6
- - Regex: '^(<|")cmsys/'
+ - Regex: '^<cmtp/'
Priority: 7
- - Regex: '^(<|")cm_'
+ - Regex: '^(<|")cmsys/'
Priority: 8
- - Regex: '^(<|")cm[A-Z][^.]+\.h'
+ - Regex: '^(<|")cm_'
Priority: 9
+ - Regex: '^(<|")cm[A-Z][^.]+\.h'
+ Priority: 10
- Regex: '^<[^.]+\.h'
Priority: 4
- Regex: '^<'
Priority: 1
- Regex: '.*'
- Priority: 10
+ Priority: 11
...
diff --git a/.clang-tidy b/.clang-tidy
index a520679..10819ef 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -13,9 +13,11 @@ modernize-*,\
-modernize-avoid-c-arrays,\
-modernize-use-nodiscard,\
-modernize-use-noexcept,\
+-modernize-use-trailing-return-type,\
-modernize-use-transparent-functors,\
performance-*,\
readability-*,\
+-readability-convert-member-functions-to-static,\
-readability-function-size,\
-readability-identifier-naming,\
-readability-implicit-bool-conversion,\
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..0a55ca3
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,125 @@
+.only_settings: &only_settings
+ - merge_requests
+ - branches@cmake/cmake
+ - tags@cmake/cmake
+
+.fedora31: &fedora31
+ image: "kitware/cmake:ci-fedora31-x86_64-2020-05-05"
+
+ variables:
+ GIT_CLONE_PATH: "$CI_BUILDS_DIR/gitlab-kitware-cmake ci"
+
+.debian10: &debian10
+ image: "kitware/cmake:ci-debian10-x86_64-2020-04-27"
+
+ variables:
+ GIT_CLONE_PATH: "$CI_BUILDS_DIR/gitlab-kitware-cmake ci"
+
+.debian10_iwyu: &debian10_iwyu
+ extends: .debian10
+
+ variables:
+ CMAKE_CONFIGURATION: debian10_iwyu
+ CTEST_NO_WARNINGS_ALLOWED: 1
+
+.fedora31_tidy: &fedora31_tidy
+ extends: .fedora31
+
+ variables:
+ CMAKE_CONFIGURATION: fedora31_tidy
+ CTEST_NO_WARNINGS_ALLOWED: 1
+
+.fedora31_sphinx: &fedora31_sphinx
+ extends: .fedora31
+
+ variables:
+ CMAKE_CONFIGURATION: fedora31_sphinx
+ CTEST_NO_WARNINGS_ALLOWED: 1
+ CTEST_SOURCE_SUBDIRECTORY: "Utilities/Sphinx"
+
+before_script:
+ - .gitlab/ci/cmake.sh
+ - .gitlab/ci/ninja.sh
+ - export PATH=$PWD/.gitlab:$PWD/.gitlab/cmake/bin:$PATH
+ - cmake --version
+ - ninja --version
+
+.cmake_build_unix: &cmake_build_unix
+ stage: build
+ only: *only_settings
+ tags:
+ - build
+ - docker
+ - linux
+
+ script:
+ - .gitlab/ci/sccache.sh
+ - sccache --start-server
+ - sccache --show-stats
+ - "$LAUNCHER ctest -VV -S .gitlab/ci/ctest_configure.cmake"
+ - "$LAUNCHER ctest -VV -S .gitlab/ci/ctest_build.cmake"
+ - sccache --show-stats
+
+ interruptible: true
+
+stages:
+ - build
+ - test
+
+build:debian10-iwyu:
+ <<:
+ - *debian10_iwyu
+ stage: build
+ only: *only_settings
+ tags:
+ - build
+ - docker
+ - linux
+
+ script:
+ - .gitlab/ci/sccache.sh
+ - sccache --start-server
+ - sccache --show-stats
+ - "$LAUNCHER ctest -VV -S .gitlab/ci/ctest_configure.cmake"
+ - "$LAUNCHER ctest -VV -S .gitlab/ci/ctest_build.cmake"
+ - sccache --show-stats
+ interruptible: true
+
+build:fedora31-tidy:
+ <<:
+ - *fedora31_tidy
+ stage: build
+ only: *only_settings
+ tags:
+ - build
+ - docker
+ - linux
+
+ script:
+ - .gitlab/ci/sccache.sh
+ - sccache --start-server
+ - sccache --show-stats
+ - "$LAUNCHER ctest -VV -S .gitlab/ci/ctest_configure.cmake"
+ - "$LAUNCHER ctest -VV -S .gitlab/ci/ctest_build.cmake"
+ - sccache --show-stats
+ interruptible: true
+
+build:fedora31-sphinx:
+ <<:
+ - *fedora31_sphinx
+ stage: build
+ only: *only_settings
+ tags:
+ - build
+ - docker
+ - linux
+ - linux-3.17 # Needed to be able to load Fedora's Qt libraries.
+
+ script:
+ - .gitlab/ci/sccache.sh
+ - sccache --start-server
+ - sccache --show-stats
+ - "$LAUNCHER ctest -VV -S .gitlab/ci/ctest_configure.cmake"
+ - "$LAUNCHER ctest -VV -S .gitlab/ci/ctest_build.cmake"
+ - sccache --show-stats
+ interruptible: true
diff --git a/.gitlab/ci/cmake.sh b/.gitlab/ci/cmake.sh
new file mode 100755
index 0000000..4b2f53f
--- /dev/null
+++ b/.gitlab/ci/cmake.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+set -e
+
+readonly version="3.17.2"
+readonly sha256sum="dc57f3cc448ca67fc8776b4ad4c22b087b9c6a8e459938b9622b8c7f4ef6b21e"
+readonly filename="cmake-$version-Linux-x86_64"
+readonly tarball="$filename.tar.gz"
+
+cd .gitlab
+
+echo "$sha256sum $tarball" > cmake.sha256sum
+curl -OL "https://github.com/Kitware/CMake/releases/download/v$version/$tarball"
+sha256sum --check cmake.sha256sum
+tar xf "$tarball"
+mv "$filename" cmake
diff --git a/.gitlab/ci/configure_common.cmake b/.gitlab/ci/configure_common.cmake
new file mode 100644
index 0000000..fc2aaae
--- /dev/null
+++ b/.gitlab/ci/configure_common.cmake
@@ -0,0 +1,3 @@
+set(CTEST_USE_LAUNCHERS "ON" CACHE STRING "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_sccache.cmake")
diff --git a/.gitlab/ci/configure_debian10_iwyu.cmake b/.gitlab/ci/configure_debian10_iwyu.cmake
new file mode 100644
index 0000000..1daa581
--- /dev/null
+++ b/.gitlab/ci/configure_debian10_iwyu.cmake
@@ -0,0 +1,4 @@
+set(CMake_RUN_IWYU ON CACHE BOOL "")
+set(IWYU_COMMAND "/usr/bin/include-what-you-use-6.0" CACHE FILEPATH "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_common.cmake")
diff --git a/.gitlab/ci/configure_fedora31_sphinx.cmake b/.gitlab/ci/configure_fedora31_sphinx.cmake
new file mode 100644
index 0000000..dfc9b8c
--- /dev/null
+++ b/.gitlab/ci/configure_fedora31_sphinx.cmake
@@ -0,0 +1,8 @@
+set(SPHINX_INFO ON CACHE BOOL "")
+set(SPHINX_MAN ON CACHE BOOL "")
+set(SPHINX_HTML ON CACHE BOOL "")
+set(SPHINX_SINGLEHTML ON CACHE BOOL "")
+set(SPHINX_QTHELP ON CACHE BOOL "")
+set(SPHINX_TEXT ON CACHE BOOL "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_common.cmake")
diff --git a/.gitlab/ci/configure_fedora31_tidy.cmake b/.gitlab/ci/configure_fedora31_tidy.cmake
new file mode 100644
index 0000000..f41ad82
--- /dev/null
+++ b/.gitlab/ci/configure_fedora31_tidy.cmake
@@ -0,0 +1,3 @@
+set(CMake_RUN_CLANG_TIDY ON CACHE BOOL "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_common.cmake")
diff --git a/.gitlab/ci/configure_sccache.cmake b/.gitlab/ci/configure_sccache.cmake
new file mode 100644
index 0000000..261bb28
--- /dev/null
+++ b/.gitlab/ci/configure_sccache.cmake
@@ -0,0 +1,2 @@
+set(CMAKE_C_COMPILER_LAUNCHER "sccache" CACHE STRING "")
+set(CMAKE_CXX_COMPILER_LAUNCHER "sccache" CACHE STRING "")
diff --git a/.gitlab/ci/ctest_build.cmake b/.gitlab/ci/ctest_build.cmake
new file mode 100644
index 0000000..28bdb35
--- /dev/null
+++ b/.gitlab/ci/ctest_build.cmake
@@ -0,0 +1,30 @@
+cmake_minimum_required(VERSION 3.8)
+
+include("${CMAKE_CURRENT_LIST_DIR}/gitlab_ci.cmake")
+
+# Read the files from the build directory.
+ctest_read_custom_files("${CTEST_BINARY_DIRECTORY}")
+
+# Pick up from where the configure left off.
+ctest_start(APPEND)
+
+if (CTEST_CMAKE_GENERATOR STREQUAL "Unix Makefiles")
+ include(ProcessorCount)
+ ProcessorCount(nproc)
+ set(CTEST_BUILD_FLAGS "-j${nproc}")
+endif ()
+
+ctest_build(
+ NUMBER_WARNINGS num_warnings
+ RETURN_VALUE build_result)
+ctest_submit(PARTS Build)
+
+if (build_result)
+ message(FATAL_ERROR
+ "Failed to build")
+endif ()
+
+if ("$ENV{CTEST_NO_WARNINGS_ALLOWED}" AND num_warnings GREATER 0)
+ message(FATAL_ERROR
+ "Found ${num_warnings} warnings (treating as fatal).")
+endif ()
diff --git a/.gitlab/ci/ctest_configure.cmake b/.gitlab/ci/ctest_configure.cmake
new file mode 100644
index 0000000..55cad13
--- /dev/null
+++ b/.gitlab/ci/ctest_configure.cmake
@@ -0,0 +1,32 @@
+cmake_minimum_required(VERSION 3.8)
+
+include("${CMAKE_CURRENT_LIST_DIR}/gitlab_ci.cmake")
+
+set(cmake_args
+ -C "${CMAKE_CURRENT_LIST_DIR}/configure_$ENV{CMAKE_CONFIGURATION}.cmake")
+
+# Create an entry in CDash.
+ctest_start(Experimental TRACK "${ctest_track}")
+
+# Gather update information.
+find_package(Git)
+set(CTEST_UPDATE_VERSION_ONLY ON)
+set(CTEST_UPDATE_COMMAND "${GIT_EXECUTABLE}")
+ctest_update()
+
+# Configure the project.
+ctest_configure(
+ OPTIONS "${cmake_args}"
+ RETURN_VALUE configure_result)
+
+# Read the files from the build directory.
+ctest_read_custom_files("${CTEST_BINARY_DIRECTORY}")
+
+# We can now submit because we've configured. This is a cmb-superbuild-ism.
+ctest_submit(PARTS Update)
+ctest_submit(PARTS Configure)
+
+if (configure_result)
+ message(FATAL_ERROR
+ "Failed to configure")
+endif ()
diff --git a/.gitlab/ci/ctest_exclusions.cmake b/.gitlab/ci/ctest_exclusions.cmake
new file mode 100644
index 0000000..5bb03ca
--- /dev/null
+++ b/.gitlab/ci/ctest_exclusions.cmake
@@ -0,0 +1,6 @@
+set(test_exclusions
+)
+string(REPLACE ";" "|" test_exclusions "${test_exclusions}")
+if (test_exclusions)
+ set(test_exclusions "(${test_exclusions})")
+endif ()
diff --git a/.gitlab/ci/ctest_test.cmake b/.gitlab/ci/ctest_test.cmake
new file mode 100644
index 0000000..569139d
--- /dev/null
+++ b/.gitlab/ci/ctest_test.cmake
@@ -0,0 +1,24 @@
+cmake_minimum_required(VERSION 3.8)
+
+include("${CMAKE_CURRENT_LIST_DIR}/gitlab_ci.cmake")
+
+# Read the files from the build directory.
+ctest_read_custom_files("${CTEST_BINARY_DIRECTORY}")
+
+# Pick up from where the configure left off.
+ctest_start(APPEND)
+
+include(ProcessorCount)
+ProcessorCount(nproc)
+
+include("${CMAKE_CURRENT_LIST_DIR}/ctest_exclusions.cmake")
+ctest_test(
+ PARALLEL_LEVEL "${nproc}"
+ RETURN_VALUE test_result
+ EXCLUDE "${test_exclusions}")
+ctest_submit(PARTS Test)
+
+if (test_result)
+ message(FATAL_ERROR
+ "Failed to test")
+endif ()
diff --git a/.gitlab/ci/docker/debian10/Dockerfile b/.gitlab/ci/docker/debian10/Dockerfile
new file mode 100644
index 0000000..e8c3851
--- /dev/null
+++ b/.gitlab/ci/docker/debian10/Dockerfile
@@ -0,0 +1,15 @@
+FROM debian:10 as iwyu-build
+MAINTAINER Ben Boeckel <ben.boeckel@kitware.com>
+
+COPY install_iwyu.sh /root/install_iwyu.sh
+RUN sh /root/install_iwyu.sh
+
+FROM debian:10
+MAINTAINER Ben Boeckel <ben.boeckel@kitware.com>
+
+COPY install_deps.sh /root/install_deps.sh
+RUN sh /root/install_deps.sh
+
+COPY --from=iwyu-build /root/iwyu.tar.gz /root/iwyu.tar.gz
+RUN tar -C / -xf /root/iwyu.tar.gz
+RUN ln -s /usr/lib/llvm-6.0/bin/include-what-you-use /usr/bin/include-what-you-use-6.0
diff --git a/.gitlab/ci/docker/debian10/install_deps.sh b/.gitlab/ci/docker/debian10/install_deps.sh
new file mode 100755
index 0000000..9c32d64
--- /dev/null
+++ b/.gitlab/ci/docker/debian10/install_deps.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+set -e
+
+apt-get update
+
+# Install build requirements.
+apt-get install -y \
+ libssl-dev
+
+# Install development tools.
+apt-get install -y \
+ g++ \
+ curl \
+ git
+
+# Install iwyu runtime deps.
+apt-get install -y \
+ clang-6.0 \
+ libncurses6
+
+apt-get clean
diff --git a/.gitlab/ci/docker/debian10/install_iwyu.sh b/.gitlab/ci/docker/debian10/install_iwyu.sh
new file mode 100755
index 0000000..54d26ef
--- /dev/null
+++ b/.gitlab/ci/docker/debian10/install_iwyu.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+set -e
+
+# Install development tools.
+apt-get update
+apt-get install -y \
+ clang-6.0 \
+ libclang-6.0-dev \
+ llvm-6.0-dev \
+ libz-dev \
+ g++ \
+ cmake \
+ ninja-build \
+ git
+
+cd /root
+git clone "https://github.com/include-what-you-use/include-what-you-use.git"
+cd include-what-you-use
+readonly llvm_version="$( clang-6.0 --version | head -n1 | cut -d' ' -f3 | cut -d. -f-2 )"
+git checkout "clang_$llvm_version"
+mkdir build
+cd build
+
+cmake -GNinja \
+ -DCMAKE_BUILD_TYPE=Release \
+ "-DCMAKE_INSTALL_PREFIX=/usr/lib/llvm-$llvm_version" \
+ "-DIWYU_LLVM_ROOT_PATH=/usr/lib/llvm-$llvm_version" \
+ ..
+ninja
+DESTDIR=/root/iwyu-destdir ninja install
+tar -C /root/iwyu-destdir -cf /root/iwyu.tar.gz .
diff --git a/.gitlab/ci/docker/fedora31/Dockerfile b/.gitlab/ci/docker/fedora31/Dockerfile
new file mode 100644
index 0000000..5588a85
--- /dev/null
+++ b/.gitlab/ci/docker/fedora31/Dockerfile
@@ -0,0 +1,5 @@
+FROM fedora:31
+MAINTAINER Ben Boeckel <ben.boeckel@kitware.com>
+
+COPY install_deps.sh /root/install_deps.sh
+RUN sh /root/install_deps.sh
diff --git a/.gitlab/ci/docker/fedora31/install_deps.sh b/.gitlab/ci/docker/fedora31/install_deps.sh
new file mode 100755
index 0000000..7f8da57
--- /dev/null
+++ b/.gitlab/ci/docker/fedora31/install_deps.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+# Install build requirements.
+dnf install -y \
+ openssl-devel
+
+# Install development tools.
+dnf install --setopt=install_weak_deps=False -y \
+ clang-tools-extra \
+ gcc-c++ \
+ git-core
+
+# Install documentation tools.
+dnf install --setopt=install_weak_deps=False -y \
+ python3-sphinx \
+ texinfo \
+ qt5-qttools-devel
+
+dnf clean all
diff --git a/.gitlab/ci/gitlab_ci.cmake b/.gitlab/ci/gitlab_ci.cmake
new file mode 100644
index 0000000..b49f51d
--- /dev/null
+++ b/.gitlab/ci/gitlab_ci.cmake
@@ -0,0 +1,49 @@
+if (NOT DEFINED "ENV{GITLAB_CI}")
+ message(FATAL_ERROR
+ "This script assumes it is being run inside of GitLab-CI")
+endif ()
+
+# Set up the source and build paths.
+set(CTEST_SOURCE_DIRECTORY "$ENV{CI_PROJECT_DIR}")
+if (NOT "$ENV{CTEST_SOURCE_SUBDIRECTORY}" STREQUAL "")
+ string(APPEND CTEST_SOURCE_DIRECTORY "/$ENV{CTEST_SOURCE_SUBDIRECTORY}")
+endif ()
+set(CTEST_BINARY_DIRECTORY "${CTEST_SOURCE_DIRECTORY}/build")
+
+if ("$ENV{CMAKE_CONFIGURATION}" STREQUAL "")
+ message(FATAL_ERROR
+ "The CMAKE_CONFIGURATION environment variable is required to know what "
+ "cache initialization file to use.")
+endif ()
+
+# Set the build metadata.
+set(CTEST_BUILD_NAME "$ENV{CI_PROJECT_NAME}-$ENV{CMAKE_CONFIGURATION}")
+set(CTEST_SITE "gitlab-ci")
+
+# Default to Release builds.
+if (NOT "$ENV{CMAKE_BUILD_TYPE}" STREQUAL "")
+ set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_BUILD_TYPE}")
+endif ()
+if (NOT CTEST_BUILD_CONFIGURATION)
+ set(CTEST_BUILD_CONFIGURATION "Release")
+endif ()
+
+# Default to using Ninja.
+if (NOT "$ENV{CMAKE_GENERATOR}" STREQUAL "")
+ set(CTEST_CMAKE_GENERATOR "$ENV{CMAKE_GENERATOR}")
+endif ()
+if (NOT CTEST_CMAKE_GENERATOR)
+ set(CTEST_CMAKE_GENERATOR "Ninja")
+endif ()
+
+# Determine the track to submit to.
+set(ctest_track "Experimental")
+if (NOT "$ENV{CI_MERGE_REQUEST_ID}" STREQUAL "")
+ set(ctest_track "merge-requests")
+elseif ("$ENV{CI_PROJECT_PATH}" STREQUAL "cmb/smtk")
+ if ("$ENV{CI_COMMIT_REF_NAME}" STREQUAL "master")
+ set(ctest_track "master")
+ elseif ("$ENV{CI_COMMIT_REF_NAME}" STREQUAL "release")
+ set(ctest_track "release")
+ endif ()
+endif ()
diff --git a/.gitlab/ci/ninja.sh b/.gitlab/ci/ninja.sh
new file mode 100755
index 0000000..31da12b
--- /dev/null
+++ b/.gitlab/ci/ninja.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+set -e
+
+readonly version="1.10.0"
+readonly sha256sum="6566836ddf3d72ca06685b34814e0c6fa0f0943542d651d0dab3150f10307c82"
+readonly filename="ninja-linux"
+readonly tarball="$filename.zip"
+
+cd .gitlab
+
+echo "$sha256sum $tarball" > ninja.sha256sum
+curl -OL "https://github.com/ninja-build/ninja/releases/download/v$version/$tarball"
+sha256sum --check ninja.sha256sum
+./cmake/bin/cmake -E tar xf "$tarball"
diff --git a/.gitlab/ci/sccache.sh b/.gitlab/ci/sccache.sh
new file mode 100755
index 0000000..c88cdcc
--- /dev/null
+++ b/.gitlab/ci/sccache.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+set -e
+
+readonly version="0.2.12"
+readonly sha256sum="26fd04c1273952cc2a0f359a71c8a1857137f0ee3634058b3f4a63b69fc8eb7f"
+readonly filename="sccache-$version-x86_64-unknown-linux-musl"
+readonly tarball="$filename.tar.gz"
+
+cd .gitlab
+
+echo "$sha256sum $tarball" > sccache.sha256sum
+curl -OL "https://github.com/mozilla/sccache/releases/download/$version/$tarball"
+sha256sum --check sccache.sha256sum
+tar xf "$tarball"
+mv "$filename/sccache" .
diff --git a/Auxiliary/CMakeLists.txt b/Auxiliary/CMakeLists.txt
index 53cf2c5..a833c79 100644
--- a/Auxiliary/CMakeLists.txt
+++ b/Auxiliary/CMakeLists.txt
@@ -1,4 +1,4 @@
-install(DIRECTORY vim/indent vim/syntax DESTINATION ${CMAKE_DATA_DIR}/editors/vim)
-install(FILES cmake-mode.el DESTINATION ${CMAKE_DATA_DIR}/editors/emacs)
+install(DIRECTORY vim/indent vim/syntax DESTINATION ${CMAKE_XDGDATA_DIR}/vim/vimfiles)
+install(FILES cmake-mode.el DESTINATION ${CMAKE_XDGDATA_DIR}/emacs/site-lisp)
install(FILES cmake.m4 DESTINATION ${CMAKE_XDGDATA_DIR}/aclocal)
add_subdirectory (bash-completion)
diff --git a/Auxiliary/bash-completion/CMakeLists.txt b/Auxiliary/bash-completion/CMakeLists.txt
index c0a8899..06d22c2 100644
--- a/Auxiliary/bash-completion/CMakeLists.txt
+++ b/Auxiliary/bash-completion/CMakeLists.txt
@@ -1,8 +1,16 @@
-# Always install completion file in local dir
-# in order to be sure to always be able to install
-# in a local user directory rooted in a single directory.
-# packager should either patch that out or
-# add symlinks to the files in appropriate places
-# /etc/bash_completion.d/
-# DATADIR/completions (may be /usr/share/<package>/completions
-install(FILES cmake cpack ctest DESTINATION ${CMAKE_DATA_DIR}/completions)
+# We need to integrate into the system install, or this will silently fail to
+# accomplish anything at all, and packagers won't even know it exists. Use the
+# `<sharedir>/bash-completion/completions/` hierarchy by default, rooted in
+# CMake's XDGDATA_DIR definition of the sharedir. This works with installation
+# to `/usr` or `/usr/local` (or any prefix which bash-completion is configured
+# with) as well as a simple installation by a local user into their home
+# directory *if* the prefix is `$HOME/.local` since `.local/share/` is part of
+# the bash-completion search path too.
+# For more complex installations, packagers can set CMAKE_BASH_COMP_DIR to
+# another system location.
+
+set(CMAKE_BASH_COMP_DIR_DEFAULT ${CMAKE_XDGDATA_DIR}/bash-completion/completions)
+if (NOT CMAKE_BASH_COMP_DIR)
+ set(CMAKE_BASH_COMP_DIR "${CMAKE_BASH_COMP_DIR_DEFAULT}")
+endif()
+install(FILES cmake cpack ctest DESTINATION ${CMAKE_BASH_COMP_DIR})
diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim
index 5de117b..0676f7e 100644
--- a/Auxiliary/vim/syntax/cmake.vim
+++ b/Auxiliary/vim/syntax/cmake.vim
@@ -101,6 +101,7 @@ syn keyword cmakeProperty contained
\ CLEAN_NO_CUSTOM
\ CMAKE_CONFIGURE_DEPENDS
\ CMAKE_CXX_KNOWN_FEATURES
+ \ CMAKE_CUDA_KNOWN_FEATURES
\ CMAKE_C_KNOWN_FEATURES
\ CMAKE_ROLE
\ COMMON_LANGUAGE_RUNTIME
@@ -220,6 +221,7 @@ syn keyword cmakeProperty contained
\ JOB_POOLS
\ JOB_POOL_COMPILE
\ JOB_POOL_LINK
+ \ JOB_POOL_PRECOMPILE_HEADER
\ KEEP_EXTENSION
\ LABELS
\ LANGUAGE
@@ -725,6 +727,7 @@ syn keyword cmakeVariable contained
\ CMAKE_CUDA_COMPILER_AR
\ CMAKE_CUDA_COMPILER_ARCHITECTURE_ID
\ CMAKE_CUDA_COMPILER_EXTERNAL_TOOLCHAIN
+ \ CMAKE_CUDA_COMPILE_FEATURES
\ CMAKE_CUDA_COMPILER_ID
\ CMAKE_CUDA_COMPILER_LAUNCHER
\ CMAKE_CUDA_COMPILER_LOADED
@@ -1064,6 +1067,7 @@ syn keyword cmakeVariable contained
\ CMAKE_JOB_POOLS
\ CMAKE_JOB_POOL_COMPILE
\ CMAKE_JOB_POOL_LINK
+ \ CMAKE_JOB_POOL_PRECOMPILE_HEADER
\ CMAKE_Java
\ CMAKE_Java_ANDROID_TOOLCHAIN_MACHINE
\ CMAKE_Java_ANDROID_TOOLCHAIN_PREFIX
@@ -2862,6 +2866,11 @@ syn keyword cmakeKWtarget_link_options contained
\ _LINKER_WRAPPER_FLAG
\ _LINKER_WRAPPER_FLAG_SEP
+syn keyword cmakeKWtarget_precompile_headers contained
+ \ INTERFACE
+ \ PRIVATE
+ \ PUBLIC
+
syn keyword cmakeKWtarget_sources contained
\ ALIAS
\ IMPORTED
@@ -3166,6 +3175,7 @@ syn keyword cmakeCommand
\ target_link_directories
\ target_link_libraries
\ target_link_options
+ \ target_precompile_headers
\ target_sources
\ try_compile
\ try_run
@@ -3322,6 +3332,7 @@ hi def link cmakeKWtarget_include_directories ModeMsg
hi def link cmakeKWtarget_link_directories ModeMsg
hi def link cmakeKWtarget_link_libraries ModeMsg
hi def link cmakeKWtarget_link_options ModeMsg
+hi def link cmakeKWtarget_precompile_headers ModeMsg
hi def link cmakeKWtarget_sources ModeMsg
hi def link cmakeKWtry_compile ModeMsg
hi def link cmakeKWtry_run ModeMsg
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5762099..e6aaf60 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -154,7 +154,7 @@ macro(CMAKE_HANDLE_SYSTEM_LIBRARIES)
# Allow the user to enable/disable all system utility library options by
# defining CMAKE_USE_SYSTEM_LIBRARIES or CMAKE_USE_SYSTEM_LIBRARY_${util}.
- set(UTILITIES BZIP2 CURL EXPAT FORM JSONCPP LIBARCHIVE LIBLZMA LIBRHASH LIBUV ZLIB ZSTD)
+ set(UTILITIES BZIP2 CURL EXPAT FORM JSONCPP LIBARCHIVE LIBLZMA LIBRHASH LIBUV NGHTTP2 ZLIB ZSTD)
foreach(util ${UTILITIES})
if(NOT DEFINED CMAKE_USE_SYSTEM_LIBRARY_${util}
AND DEFINED CMAKE_USE_SYSTEM_LIBRARIES)
@@ -192,6 +192,8 @@ macro(CMAKE_HANDLE_SYSTEM_LIBRARIES)
"${CMAKE_USE_SYSTEM_LIBRARY_ZSTD}" "NOT CMAKE_USE_SYSTEM_LIBARCHIVE" ON)
CMAKE_DEPENDENT_OPTION(CMAKE_USE_SYSTEM_LIBLZMA "Use system-installed liblzma"
"${CMAKE_USE_SYSTEM_LIBRARY_LIBLZMA}" "NOT CMAKE_USE_SYSTEM_LIBARCHIVE" ON)
+ CMAKE_DEPENDENT_OPTION(CMAKE_USE_SYSTEM_NGHTTP2 "Use system-installed nghttp2"
+ "${CMAKE_USE_SYSTEM_LIBRARY_NGHTTP2}" "NOT CMAKE_USE_SYSTEM_CURL" ON)
option(CMAKE_USE_SYSTEM_FORM "Use system-installed libform" "${CMAKE_USE_SYSTEM_LIBRARY_FORM}")
option(CMAKE_USE_SYSTEM_JSONCPP "Use system-installed jsoncpp" "${CMAKE_USE_SYSTEM_LIBRARY_JSONCPP}")
option(CMAKE_USE_SYSTEM_LIBRHASH "Use system-installed librhash" "${CMAKE_USE_SYSTEM_LIBRARY_LIBRHASH}")
@@ -264,7 +266,6 @@ macro(CMAKE_SETUP_TESTING)
${CMake_BINARY_DIR}/Testing/HTML/TestingResults/Icons/Logo.gif COPYONLY)
endif()
mark_as_advanced(DART_ROOT)
- mark_as_advanced(CURL_TESTING)
endmacro()
@@ -375,10 +376,13 @@ macro (CMAKE_BUILD_UTILITIES)
include_directories(SYSTEM "${CMake_SOURCE_DIR}/Utilities/std")
endif()
- include_directories(
- ${CMake_BINARY_DIR}/Utilities
- ${CMake_SOURCE_DIR}/Utilities
- )
+ include_directories("${CMake_BINARY_DIR}/Utilities")
+ if ((CMAKE_SYSTEM_NAME STREQUAL "AIX" OR CMAKE_SYSTEM_NAME STREQUAL "OS400") AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ # using -isystem option generate error "template with C linkage"
+ include_directories("${CMake_SOURCE_DIR}/Utilities")
+ else()
+ include_directories(SYSTEM "${CMake_SOURCE_DIR}/Utilities")
+ endif()
#---------------------------------------------------------------------
# Build CMake std library for CMake and CTest.
@@ -466,9 +470,19 @@ macro (CMAKE_BUILD_UTILITIES)
set(CURL_CA_PATH "" CACHE PATH "Path to SSL CA Certificate Directory")
mark_as_advanced(CURL_CA_BUNDLE CURL_CA_PATH)
endif()
+ if(NOT CMAKE_USE_SYSTEM_NGHTTP2)
+ # Tell curl's FindNGHTTP2 module to use our library.
+ set(NGHTTP2_LIBRARY cmnghttp2)
+ set(NGHTTP2_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Utilities/cmnghttp2/lib/includes)
+ endif()
add_subdirectory(Utilities/cmcurl)
CMAKE_SET_TARGET_FOLDER(cmcurl "Utilities/3rdParty")
CMAKE_SET_TARGET_FOLDER(LIBCURL "Utilities/3rdParty")
+ if(NOT CMAKE_USE_SYSTEM_NGHTTP2)
+ # Configure after curl to re-use some check results.
+ add_subdirectory(Utilities/cmnghttp2)
+ CMAKE_SET_TARGET_FOLDER(cmnghttp2 "Utilities/3rdParty")
+ endif()
endif()
#---------------------------------------------------------------------
@@ -548,21 +562,25 @@ macro (CMAKE_BUILD_UTILITIES)
set(ZLIB_INCLUDE_DIR ${CMAKE_ZLIB_INCLUDES})
set(ZLIB_LIBRARY ${CMAKE_ZLIB_LIBRARIES})
add_definitions(-DLIBARCHIVE_STATIC)
+ set(ENABLE_MBEDTLS OFF CACHE INTERNAL "Enable use of mbed TLS")
set(ENABLE_NETTLE OFF CACHE INTERNAL "Enable use of Nettle")
set(ENABLE_OPENSSL ${CMAKE_USE_OPENSSL} CACHE INTERNAL "Enable use of OpenSSL")
+ set(ENABLE_LIBB2 OFF CACHE INTERNAL "Enable the use of the system LIBB2 library if found")
set(ENABLE_LZMA ON CACHE INTERNAL "Enable the use of the system LZMA library if found")
set(ENABLE_LZ4 OFF CACHE INTERNAL "Enable the use of the system LZ4 library if found")
set(ENABLE_LZO OFF CACHE INTERNAL "Enable the use of the system LZO library if found")
set(ENABLE_ZLIB ON CACHE INTERNAL "Enable the use of the system ZLIB library if found")
set(ENABLE_BZip2 ON CACHE INTERNAL "Enable the use of the system BZip2 library if found")
+ set(ENABLE_ZSTD ON CACHE INTERNAL "Enable the use of the system zstd library if found")
set(ENABLE_LIBXML2 OFF CACHE INTERNAL "Enable the use of the system libxml2 library if found")
- set(ENABLE_EXPAT ON CACHE INTERNAL "Enable the use of the system EXPAT library if found")
+ set(ENABLE_EXPAT OFF CACHE INTERNAL "Enable the use of the system EXPAT library if found")
set(ENABLE_PCREPOSIX OFF CACHE INTERNAL "Enable the use of the system PCREPOSIX library if found")
set(ENABLE_LibGCC OFF CACHE INTERNAL "Enable the use of the system LibGCC library if found")
set(ENABLE_XATTR OFF CACHE INTERNAL "Enable extended attribute support")
set(ENABLE_ACL OFF CACHE INTERNAL "Enable ACL support")
set(ENABLE_ICONV OFF CACHE INTERNAL "Enable iconv support")
set(ENABLE_CNG OFF CACHE INTERNAL "Enable the use of CNG(Crypto Next Generation)")
+ SET(POSIX_REGEX_LIB "" CACHE INTERNAL "Choose what library should provide POSIX regular expression support")
add_subdirectory(Utilities/cmlibarchive)
CMAKE_SET_TARGET_FOLDER(cmlibarchive "Utilities/3rdParty")
set(CMAKE_TAR_LIBRARIES cmlibarchive ${BZIP2_LIBRARIES})
@@ -671,10 +689,6 @@ if(NOT CMake_TEST_EXTERNAL_CMAKE)
set(LIBRARY_OUTPUT_PATH "" CACHE INTERNAL
"Where to put the libraries for CMake")
- # The CMake executables usually do not need any rpath to run in the build or
- # install tree.
- set(CMAKE_SKIP_RPATH ON CACHE INTERNAL "CMake does not need RPATHs.")
-
# Load install destinations.
include(Source/CMakeInstallDestinations.cmake)
@@ -714,19 +728,6 @@ if(NOT CMake_TEST_EXTERNAL_CMAKE)
# build the utilities (a macro defined in this file)
CMAKE_BUILD_UTILITIES()
- # On NetBSD ncurses is required, since curses doesn't have the wsyncup()
- # function. ncurses is installed via pkgsrc, so the library is in /usr/pkg/lib,
- # which isn't in the default linker search path. So without RPATH ccmake
- # doesn't run and the build doesn't succeed since ccmake is executed for
- # generating the documentation.
- if(BUILD_CursesDialog)
- get_filename_component(_CURSES_DIR "${CURSES_LIBRARY}" PATH)
- set(CURSES_NEED_RPATH FALSE)
- if(NOT "${_CURSES_DIR}" STREQUAL "/lib" AND NOT "${_CURSES_DIR}" STREQUAL "/usr/lib" AND NOT "${_CURSES_DIR}" STREQUAL "/lib64" AND NOT "${_CURSES_DIR}" STREQUAL "/usr/lib64")
- set(CURSES_NEED_RPATH TRUE)
- endif()
- endif()
-
if(BUILD_QtDialog)
if(APPLE)
set(CMAKE_BUNDLE_VERSION
@@ -739,28 +740,15 @@ if(NOT CMake_TEST_EXTERNAL_CMAKE)
set(CMAKE_INSTALL_PREFIX
"${CMAKE_INSTALL_PREFIX}CMake.app/Contents")
endif()
-
- set(QT_NEED_RPATH FALSE)
- if(NOT "${QT_LIBRARY_DIR}" STREQUAL "/lib" AND NOT "${QT_LIBRARY_DIR}" STREQUAL "/usr/lib" AND NOT "${QT_LIBRARY_DIR}" STREQUAL "/lib64" AND NOT "${QT_LIBRARY_DIR}" STREQUAL "/usr/lib64")
- set(QT_NEED_RPATH TRUE)
- endif()
endif()
-
- # The same might be true on other systems for other libraries.
- # Then only enable RPATH if we have are building at least with cmake 2.4,
- # since this one has much better RPATH features than cmake 2.2.
- # The executables are then built with the RPATH for the libraries outside
- # the build tree, which is both the build and the install RPATH.
- if (UNIX)
- if( CMAKE_USE_SYSTEM_CURL OR CMAKE_USE_SYSTEM_ZLIB
- OR CMAKE_USE_SYSTEM_EXPAT OR CURSES_NEED_RPATH OR QT_NEED_RPATH)
- set(CMAKE_SKIP_RPATH OFF CACHE INTERNAL "CMake built with RPATH.")
- set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
- set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
- endif()
- endif ()
-
+ if(UNIX)
+ # Install executables with the RPATH set for libraries outside the build tree.
+ # This is also suitable for binaries in the build tree. Avoid re-link on install.
+ set(CMAKE_INSTALL_RPATH_USE_LINK_PATH ON CACHE BOOL "Install with RPATH set to find custom-built libraries.")
+ set(CMAKE_BUILD_WITH_INSTALL_RPATH ON CACHE BOOL "Build with RPATH set to match install-tree RPATH.")
+ mark_as_advanced(CMAKE_INSTALL_RPATH_USE_LINK_PATH CMAKE_BUILD_WITH_INSTALL_RPATH)
+ endif()
# add the uninstall support
configure_file(
@@ -841,7 +829,7 @@ if(NOT CMake_TEST_EXTERNAL_CMAKE)
PATTERN "*.sh*" PERMISSIONS OWNER_READ OWNER_EXECUTE OWNER_WRITE
GROUP_READ GROUP_EXECUTE
WORLD_READ WORLD_EXECUTE
- PATTERN "ExportImportList"
+ REGEX "/(ExportImportList|cpp)$"
PERMISSIONS OWNER_READ OWNER_EXECUTE OWNER_WRITE
GROUP_READ GROUP_EXECUTE
WORLD_READ WORLD_EXECUTE
diff --git a/CTestConfig.cmake b/CTestConfig.cmake
index 020582e..9ec9e8f 100644
--- a/CTestConfig.cmake
+++ b/CTestConfig.cmake
@@ -1,6 +1,8 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
+# If changing this file, also update Utilities/Sphinx/CTestConfig.cmake
+
set(CTEST_PROJECT_NAME "CMake")
set(CTEST_NIGHTLY_START_TIME "1:00:00 UTC")
diff --git a/CTestCustom.cmake.in b/CTestCustom.cmake.in
index d3ab9d3..5b78f2e 100644
--- a/CTestCustom.cmake.in
+++ b/CTestCustom.cmake.in
@@ -64,6 +64,7 @@ list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION
"ld: warning .*/libgcc.a archive's cputype"
"ld: warning: ignoring file .*/libgcc.a, file was built for archive which is not the architecture being linked"
"ld: warning: in .*/libgcc.a, file is not of required architecture"
+ "ld: warning: symbol .(deflate|inflate)_copyright. has differing sizes" # system libz and QtCore disagree
"warning.*This version of Mac OS X is unsupported"
"clang.*: warning: argument unused during compilation: .-g"
"note: in expansion of macro" # diagnostic context note
@@ -72,6 +73,7 @@ list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION
"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
"IPA warning: function.*multiply defined in"
+ "LICENSE WARNING" # PGI license expiry. Not useful in nightly testing.
# Ignore compiler summary warning, assuming prior text has matched some
# other warning expression:
@@ -79,7 +81,7 @@ list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION
"compilation completed with warnings" # PGI
"[0-9]+ Warning\\(s\\) detected" # SunPro
-# scanbuild exceptions
+ # scanbuild exceptions
"char_traits.h:.*: warning: Null pointer argument in call to string length function"
"stl_construct.h:.*: warning: Forming reference to null pointer"
".*stl_uninitialized.h:75:19: warning: Forming reference to null pointer.*"
@@ -98,6 +100,9 @@ list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION
"liblzma/common/index_encoder.c:[0-9]+:[0-9]+: warning: Value stored to .* during its initialization is never read"
"libuv/src/.*:[0-9]+:[0-9]+: warning: Dereference of null pointer"
"libuv/src/.*:[0-9]+:[0-9]+: warning: The left operand of '==' is a garbage value"
+ "libuv/src/.*:[0-9]+:[0-9]+: warning: 1st function call argument is an uninitialized value"
+ "nghttp2/lib/.*:[0-9]+:[0-9]+: warning: Dereference of null pointer"
+ "nghttp2/lib/.*:[0-9]+:[0-9]+: warning: Value stored to .* is never read"
)
if(NOT "@CMAKE_GENERATOR@" MATCHES "Xcode")
diff --git a/Copyright.txt b/Copyright.txt
index f236214..b867d01 100644
--- a/Copyright.txt
+++ b/Copyright.txt
@@ -1,5 +1,5 @@
CMake - Cross Platform Makefile Generator
-Copyright 2000-2019 Kitware, Inc. and Contributors
+Copyright 2000-2020 Kitware, Inc. and Contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -99,6 +99,7 @@ The following individuals and institutions are among the Contributors:
* Sebastian Holtermann <sebholt@xwmw.org>
* Stephen Kelly <steveire@gmail.com>
* Sylvain Joubert <joubert.sy@gmail.com>
+* The Qt Company Ltd.
* Thomas Sondergaard <ts@medical-insight.com>
* Tobias Hunger <tobias.hunger@qt.io>
* Todd Gamblin <tgamblin@llnl.gov>
diff --git a/Help/command/DEVICE_LINK_OPTIONS.txt b/Help/command/DEVICE_LINK_OPTIONS.txt
new file mode 100644
index 0000000..012e9b1
--- /dev/null
+++ b/Help/command/DEVICE_LINK_OPTIONS.txt
@@ -0,0 +1,10 @@
+
+When a device link step is involved, which is controlled by
+:prop_tgt:`CUDA_SEPARABLE_COMPILATION` and
+:prop_tgt:`CUDA_RESOLVE_DEVICE_SYMBOLS` properties, the raw options will be
+delivered to the host and device link steps (wrapped in ``-Xcompiler`` or
+equivalent for device link). Options wrapped with ``$<DEVICE_LINK:...>``
+:manual:`generator expression <cmake-generator-expressions(7)>` will be used
+only for the device link step. Options wrapped with ``$<HOST_LINK:...>``
+:manual:`generator expression <cmake-generator-expressions(7)>` will be used
+only for the host link step.
diff --git a/Help/command/FIND_XXX.txt b/Help/command/FIND_XXX.txt
index 42bf52b..cebe051 100644
--- a/Help/command/FIND_XXX.txt
+++ b/Help/command/FIND_XXX.txt
@@ -15,6 +15,7 @@ The general signature is:
[PATHS path1 [path2 ... ENV var]]
[PATH_SUFFIXES suffix1 [suffix2 ...]]
[DOC "cache documentation string"]
+ [REQUIRED]
[NO_DEFAULT_PATH]
[NO_PACKAGE_ROOT_PATH]
[NO_CMAKE_PATH]
@@ -31,8 +32,9 @@ A cache entry named by ``<VAR>`` is created to store the result
of this command.
If the |SEARCH_XXX| is found the result is stored in the variable
and the search will not be repeated unless the variable is cleared.
-If nothing is found, the result will be
-``<VAR>-NOTFOUND``, and the search will be attempted again the
+If nothing is found, the result will be ``<VAR>-NOTFOUND``.
+The ``REQUIRED`` option stops processing with an error message if nothing
+is found, otherwise the search will be attempted again the
next time |FIND_XXX| is invoked with the same variable.
Options include:
@@ -57,6 +59,9 @@ Options include:
``DOC``
Specify the documentation string for the ``<VAR>`` cache entry.
+``REQUIRED``
+ Stop processing with an error message if nothing is found.
+
If ``NO_DEFAULT_PATH`` is specified, then no additional paths are
added to the search.
If ``NO_DEFAULT_PATH`` is not specified, the search process is as follows:
diff --git a/Help/command/add_custom_command.rst b/Help/command/add_custom_command.rst
index aba3742..9279748 100644
--- a/Help/command/add_custom_command.rst
+++ b/Help/command/add_custom_command.rst
@@ -68,6 +68,9 @@ The options are:
order-only dependencies to ensure the byproducts will be
available before their dependents build.
+ The :ref:`Makefile Generators` will remove ``BYPRODUCTS`` and other
+ :prop_sf:`GENERATED` files during ``make clean``.
+
``COMMAND``
Specify the command-line(s) to execute at build time.
If more than one ``COMMAND`` is specified they will be executed in order,
@@ -112,24 +115,42 @@ The options are:
build time.
``DEPENDS``
- Specify files on which the command depends. If any dependency is
- an ``OUTPUT`` of another custom command in the same directory
- (``CMakeLists.txt`` file) CMake automatically brings the other
+ Specify files on which the command depends. Each argument is converted
+ to a dependency as follows:
+
+ 1. If the argument is the name of a target (created by the
+ :command:`add_custom_target`, :command:`add_executable`, or
+ :command:`add_library` command) a target-level dependency is
+ created to make sure the target is built before any target
+ using this custom command. Additionally, if the target is an
+ executable or library, a file-level dependency is created to
+ cause the custom command to re-run whenever the target is
+ recompiled.
+
+ 2. If the argument is an absolute path, a file-level dependency
+ is created on that path.
+
+ 3. If the argument is the name of a source file that has been
+ added to a target or on which a source file property has been set,
+ a file-level dependency is created on that source file.
+
+ 4. If the argument is a relative path and it exists in the current
+ source directory, a file-level dependency is created on that
+ file in the current source directory.
+
+ 5. Otherwise, a file-level dependency is created on that path relative
+ to the current binary directory.
+
+ If any dependency is an ``OUTPUT`` of another custom command in the same
+ directory (``CMakeLists.txt`` file), CMake automatically brings the other
custom command into the target in which this command is built.
A target-level dependency is added if any dependency is listed as
``BYPRODUCTS`` of a target or any of its build events in the same
directory to ensure the byproducts will be available.
- If ``DEPENDS`` is not specified the command will run whenever
+
+ If ``DEPENDS`` is not specified, the command will run whenever
the ``OUTPUT`` is missing; if the command does not actually
- create the ``OUTPUT`` then the rule will always run.
- If ``DEPENDS`` specifies any target (created by the
- :command:`add_custom_target`, :command:`add_executable`, or
- :command:`add_library` command) a target-level dependency is
- created to make sure the target is built before any target
- using this custom command. Additionally, if the target is an
- executable or library a file-level dependency is created to
- cause the custom command to re-run whenever the target is
- recompiled.
+ create the ``OUTPUT``, the rule will always run.
Arguments to ``DEPENDS`` may use
:manual:`generator expressions <cmake-generator-expressions(7)>`.
diff --git a/Help/command/add_custom_target.rst b/Help/command/add_custom_target.rst
index 2d5f5f0..56ab414 100644
--- a/Help/command/add_custom_target.rst
+++ b/Help/command/add_custom_target.rst
@@ -49,6 +49,9 @@ The options are:
order-only dependencies to ensure the byproducts will be
available before their dependents build.
+ The :ref:`Makefile Generators` will remove ``BYPRODUCTS`` and other
+ :prop_sf:`GENERATED` files during ``make clean``.
+
``COMMAND``
Specify the command-line(s) to execute at build time.
If more than one ``COMMAND`` is specified they will be executed in order,
diff --git a/Help/command/add_link_options.rst b/Help/command/add_link_options.rst
index a83005b..faa4afb 100644
--- a/Help/command/add_link_options.rst
+++ b/Help/command/add_link_options.rst
@@ -26,6 +26,8 @@ the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
manual for available expressions. See the :manual:`cmake-buildsystem(7)`
manual for more on defining buildsystem properties.
+.. include:: DEVICE_LINK_OPTIONS.txt
+
.. include:: OPTIONS_SHELL.txt
.. include:: LINK_OPTIONS_LINKER.txt
diff --git a/Help/command/cmake_command.rst b/Help/command/cmake_command.rst
new file mode 100644
index 0000000..08b7832
--- /dev/null
+++ b/Help/command/cmake_command.rst
@@ -0,0 +1,90 @@
+cmake_command
+-------------
+
+Call meta-operations on CMake commands.
+
+Synopsis
+^^^^^^^^
+
+.. parsed-literal::
+
+ cmake_command(`INVOKE`_ <command> [<args>...])
+ cmake_command(`EVAL`_ CODE <code>...)
+
+Introduction
+^^^^^^^^^^^^
+
+This command will call meta-operations on built-in CMake commands or
+those created via the :command:`macro` or :command:`function` commands.
+
+``cmake_command`` does not introduce a new variable or policy scope.
+
+Invoking Commands
+^^^^^^^^^^^^^^^^^
+
+.. _INVOKE:
+
+.. code-block:: cmake
+
+ cmake_command(INVOKE <command> [<args>...])
+
+Invokes the named ``<command>`` with the given arguments (if any).
+For example, the code:
+
+.. code-block:: cmake
+
+ set(message_command "message")
+ cmake_command(INVOKE ${message_command} STATUS "Hello World!")
+
+is equivalent to
+
+.. code-block:: cmake
+
+ message(STATUS "Hello World!")
+
+Evaluating Code
+^^^^^^^^^^^^^^^
+
+.. _EVAL:
+
+.. code-block:: cmake
+
+ cmake_command(EVAL CODE <code>...)
+
+Evaluates the ``<code>...`` as CMake code.
+
+For example, the code:
+
+.. code-block:: cmake
+
+ set(A TRUE)
+ set(B TRUE)
+ set(C TRUE)
+ set(condition "(A AND B) OR C")
+
+ cmake_command(EVAL CODE "
+ if (${condition})
+ message(STATUS TRUE)
+ else()
+ message(STATUS FALSE)
+ endif()"
+ )
+
+is equivalent to
+
+.. code-block:: cmake
+
+ set(A TRUE)
+ set(B TRUE)
+ set(C TRUE)
+ set(condition "(A AND B) OR C")
+
+ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/eval.cmake "
+ if (${condition})
+ message(STATUS TRUE)
+ else()
+ message(STATUS FALSE)
+ endif()"
+ )
+
+ include(${CMAKE_CURRENT_BINARY_DIR}/eval.cmake)
diff --git a/Help/command/ctest_test.rst b/Help/command/ctest_test.rst
index 7a3393b..3589296 100644
--- a/Help/command/ctest_test.rst
+++ b/Help/command/ctest_test.rst
@@ -20,9 +20,11 @@ Perform the :ref:`CTest Test Step` as a :ref:`Dashboard Client`.
[RESOURCE_SPEC_FILE <file>]
[TEST_LOAD <threshold>]
[SCHEDULE_RANDOM <ON|OFF>]
+ [STOP_ON_FAILURE]
[STOP_TIME <time-of-day>]
[RETURN_VALUE <result-var>]
[CAPTURE_CMAKE_ERROR <result-var>]
+ [REPEAT <mode>:<n>]
[QUIET]
)
@@ -95,10 +97,32 @@ The options are:
and then the ``--test-load`` command-line argument to :manual:`ctest(1)`.
See also the ``TestLoad`` setting in the :ref:`CTest Test Step`.
+``REPEAT <mode>:<n>``
+ Run tests repeatedly based on the given ``<mode>`` up to ``<n>`` times.
+ The modes are:
+
+ ``UNTIL_FAIL``
+ Require each test to run ``<n>`` times without failing in order to pass.
+ This is useful in finding sporadic failures in test cases.
+
+ ``UNTIL_PASS``
+ Allow each test to run up to ``<n>`` times in order to pass.
+ Repeats tests if they fail for any reason.
+ This is useful in tolerating sporadic failures in test cases.
+
+ ``AFTER_TIMEOUT``
+ Allow each test to run up to ``<n>`` times in order to pass.
+ Repeats tests only if they timeout.
+ This is useful in tolerating sporadic timeouts in test cases
+ on busy machines.
+
``SCHEDULE_RANDOM <ON|OFF>``
Launch tests in a random order. This may be useful for detecting
implicit test dependencies.
+``STOP_ON_FAILURE``
+ Stop the execution of the tests once one has failed.
+
``STOP_TIME <time-of-day>``
Specify a time of day at which the tests should all stop running.
diff --git a/Help/command/execute_process.rst b/Help/command/execute_process.rst
index 14f879d..b32025f 100644
--- a/Help/command/execute_process.rst
+++ b/Help/command/execute_process.rst
@@ -21,7 +21,9 @@ Execute one or more child processes.
[COMMAND_ECHO <where>]
[OUTPUT_STRIP_TRAILING_WHITESPACE]
[ERROR_STRIP_TRAILING_WHITESPACE]
- [ENCODING <name>])
+ [ENCODING <name>]
+ [ECHO_OUTPUT_VARIABLE]
+ [ECHO_ERROR_VARIABLE])
Runs the given sequence of one or more commands.
@@ -105,6 +107,15 @@ Options:
for this encoding. In CMake 3.11.0, ``UTF-8`` was added for consistency with
the `UTF-8 RFC <https://www.ietf.org/rfc/rfc3629>`_ naming convention.
+``ECHO_OUTPUT_VARIABLE``, ``ECHO_ERROR_VARIABLE``
+ The standard output or standard error will not be exclusively redirected to
+ the configured variables.
+
+ The output will be duplicated, it will be sent into the configured variables
+ and also on standard output or standard error.
+
+ This is analogous to the ``tee`` Unix command.
+
If more than one ``OUTPUT_*`` or ``ERROR_*`` option is given for the
same pipe the precedence is not specified.
If no ``OUTPUT_*`` or ``ERROR_*`` options are given the output will
diff --git a/Help/command/file.rst b/Help/command/file.rst
index b186177..bb560a9 100644
--- a/Help/command/file.rst
+++ b/Help/command/file.rst
@@ -19,6 +19,7 @@ Synopsis
file({`WRITE`_ | `APPEND`_} <filename> <content>...)
file({`TOUCH`_ | `TOUCH_NOCREATE`_} [<file>...])
file(`GENERATE`_ OUTPUT <output-file> [...])
+ file(`CONFIGURE`_ OUTPUT <output-file> CONTENT <content> [...])
`Filesystem`_
file({`GLOB`_ | `GLOB_RECURSE`_} <out-var> [...] [<globbing-expr>...])
@@ -41,6 +42,10 @@ Synopsis
`Locking`_
file(`LOCK`_ <path> [...])
+ `Archiving`_
+ file(`ARCHIVE_CREATE`_ OUTPUT <archive> FILES <files> [...])
+ file(`ARCHIVE_EXTRACT`_ INPUT <archive> DESTINATION <dir> [...])
+
Reading
^^^^^^^
@@ -54,7 +59,9 @@ Reading
Read content from a file called ``<filename>`` and store it in a
``<variable>``. Optionally start from the given ``<offset>`` and
read at most ``<max-in>`` bytes. The ``HEX`` option causes data to
-be converted to a hexadecimal representation (useful for binary data).
+be converted to a hexadecimal representation (useful for binary data). If the
+``HEX`` option is specified, letters in the output (``a`` through ``f``) are in
+lowercase.
.. _STRINGS:
@@ -395,8 +402,8 @@ dependency resolution:
Determines the path to the tool to use for dependency resolution. This is the
actual path to ``objdump``, ``dumpbin``, or ``otool``.
- If this variable is not specified, it is determined automatically by system
- introspection.
+ If this variable is not specified, it is determined by the value of
+ ``CMAKE_OBJDUMP`` if set, else by system introspection.
Writing
^^^^^^^
@@ -482,6 +489,45 @@ generation phase. The output file will not yet have been written when the
``file(GENERATE)`` command returns, it is written only after processing all
of a project's ``CMakeLists.txt`` files.
+.. _CONFIGURE:
+
+.. code-block:: cmake
+
+ file(CONFIGURE OUTPUT output-file
+ CONTENT content
+ [ESCAPE_QUOTES] [@ONLY]
+ [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF] ])
+
+Generate an output file using the input given by ``CONTENT`` and substitute
+variable values referenced as ``@VAR@`` or ``${VAR}`` contained therein. The
+substitution rules behave the same as the :command:`configure_file` command.
+In order to match :command:`configure_file`'s behavior, generator expressions
+are not supported for both ``OUTPUT`` and ``CONTENT``.
+
+The arguments are:
+
+``OUTPUT <output-file>``
+ Specify the output file name to generate. A relative path is treated with
+ respect to the value of :variable:`CMAKE_CURRENT_BINARY_DIR`. See policy
+ :policy:`CMP0070`.
+ ``<output-file>`` does not support generator expressions.
+
+``CONTENT <content>``
+ Use the content given explicitly as input.
+ ``<content>`` does not support generator expressions.
+
+``ESCAPE_QUOTES``
+ Escape any substituted quotes with backslashes (C-style).
+
+``@ONLY``
+ Restrict variable replacement to references of the form ``@VAR@``.
+ This is useful for configuring scripts that use ``${VAR}`` syntax.
+
+``NEWLINE_STYLE <style>``
+ Specify the newline style for the output file. Specify
+ ``UNIX`` or ``LF`` for ``\n`` newlines, or specify
+ ``DOS``, ``WIN32``, or ``CRLF`` for ``\r\n`` newlines.
+
Filesystem
^^^^^^^^^^
@@ -540,7 +586,7 @@ are only traversed if ``FOLLOW_SYMLINKS`` is given or policy
By default ``GLOB_RECURSE`` omits directories from result list - setting
``LIST_DIRECTORIES`` to true adds directories to result list.
If ``FOLLOW_SYMLINKS`` is given or policy :policy:`CMP0009` is not set to
-``OLD`` then ``LIST_DIRECTORIES`` treats symlinks as directories.
+``NEW`` then ``LIST_DIRECTORIES`` treats symlinks as directories.
Examples of recursive globbing include::
@@ -790,6 +836,18 @@ Options to both ``DOWNLOAD`` and ``UPLOAD`` are:
If neither ``NETRC`` option is given CMake will check variables
``CMAKE_NETRC`` and ``CMAKE_NETRC_FILE``, respectively.
+``TLS_VERIFY <ON|OFF>``
+ Specify whether to verify the server certificate for ``https://`` URLs.
+ The default is to *not* verify.
+
+``TLS_CAINFO <file>``
+ Specify a custom Certificate Authority file for ``https://`` URLs.
+
+For ``https://`` URLs CMake must be built with OpenSSL support. ``TLS/SSL``
+certificates are not checked by default. Set ``TLS_VERIFY`` to ``ON`` to
+check certificates. If neither ``TLS`` option is given CMake will check
+variables ``CMAKE_TLS_VERIFY`` and ``CMAKE_TLS_CAINFO``, respectively.
+
Additional options to ``DOWNLOAD`` are:
``EXPECTED_HASH ALGO=<value>``
@@ -801,19 +859,6 @@ Additional options to ``DOWNLOAD`` are:
``EXPECTED_MD5 <value>``
Historical short-hand for ``EXPECTED_HASH MD5=<value>``.
-``TLS_VERIFY <ON|OFF>``
- Specify whether to verify the server certificate for ``https://`` URLs.
- The default is to *not* verify.
-
-``TLS_CAINFO <file>``
- Specify a custom Certificate Authority file for ``https://`` URLs.
-
-For ``https://`` URLs CMake must be built with OpenSSL support. ``TLS/SSL``
-certificates are not checked by default. Set ``TLS_VERIFY`` to ``ON`` to
-check certificates and/or use ``EXPECTED_HASH`` to verify downloaded content.
-If neither ``TLS`` option is given CMake will check variables
-``CMAKE_TLS_VERIFY`` and ``CMAKE_TLS_CAINFO``, respectively.
-
Locking
^^^^^^^
@@ -846,3 +891,62 @@ child directory or file.
Trying to lock file twice is not allowed. Any intermediate directories and
file itself will be created if they not exist. ``GUARD`` and ``TIMEOUT``
options ignored on ``RELEASE`` operation.
+
+Archiving
+^^^^^^^^^
+
+.. _ARCHIVE_CREATE:
+
+.. code-block:: cmake
+
+ file(ARCHIVE_CREATE OUTPUT <archive>
+ [FILES <files>]
+ [DIRECTORY <dirs>]
+ [FORMAT <format>]
+ [TYPE <type>]
+ [MTIME <mtime>]
+ [VERBOSE])
+
+Creates an archive specifed by ``OUTPUT`` with the content of ``FILES`` and
+``DIRECTORY``.
+
+To specify the format of the archive set the ``FORMAT`` option.
+Supported formats are: ``7zip``, ``gnutar``, ``pax``, ``paxr``, ``raw``,
+(restricted pax, default), and ``zip``.
+
+To specify the type of compression set the ``TYPE`` option.
+Supported compression types are: ``None``, ``BZip2``, ``GZip``, ``XZ``,
+and ``Zstd``.
+
+.. note::
+ With ``FORMAT`` set to ``raw`` only one file will be compressed with the
+ compression type specified by ``TYPE``.
+
+With ``VERBOSE`` the command will produce verbose output.
+
+To specify the modification time recorded in tarball entries use
+the ``MTIME`` option.
+
+.. _ARCHIVE_EXTRACT:
+
+.. code-block:: cmake
+
+ file(ARCHIVE_EXTRACT INPUT <archive>
+ [FILES <files>]
+ [DIRECTORY <dirs>]
+ [DESTINATION <dir>]
+ [LIST_ONLY]
+ [VERBOSE])
+
+Extracts or lists the content of an archive specified by ``INPUT``.
+
+The directory where the content of the archive will be extracted can
+be specified via ``DESTINATION``. If the directory does not exit, it
+will be created.
+
+To select which files and directories will be extracted or listed
+use ``FILES`` and ``DIRECTORY`` options.
+
+``LIST_ONLY`` will only list the files in the archive.
+
+With ``VERBOSE`` the command will produce verbose output.
diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst
index 64a16f3..6753268 100644
--- a/Help/command/find_package.rst
+++ b/Help/command/find_package.rst
@@ -302,23 +302,23 @@ enabled.
are intended to be used on the command line with a ``-DVAR=value``.
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``::
+ :variable:`CMAKE_FIND_USE_CMAKE_PATH` to ``FALSE``:
- CMAKE_PREFIX_PATH
- CMAKE_FRAMEWORK_PATH
- CMAKE_APPBUNDLE_PATH
+ * :variable:`CMAKE_PREFIX_PATH`
+ * :variable:`CMAKE_FRAMEWORK_PATH`
+ * :variable:`CMAKE_APPBUNDLE_PATH`
3. Search paths specified in cmake-specific environment variables.
These are intended to be set in the user's shell configuration,
and therefore use the host's native path separator
(``;`` on Windows and ``:`` on UNIX).
This can be skipped if ``NO_CMAKE_ENVIRONMENT_PATH`` is passed or by setting
- the :variable:`CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH` to ``FALSE``::
+ the :variable:`CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH` to ``FALSE``:
- <PackageName>_DIR
- CMAKE_PREFIX_PATH
- CMAKE_FRAMEWORK_PATH
- CMAKE_APPBUNDLE_PATH
+ * ``<PackageName>_DIR``
+ * :envvar:`CMAKE_PREFIX_PATH`
+ * ``CMAKE_FRAMEWORK_PATH``
+ * ``CMAKE_APPBUNDLE_PATH``
4. Search paths specified by the ``HINTS`` option. These should be paths
computed by system introspection, such as a hint provided by the
diff --git a/Help/command/foreach.rst b/Help/command/foreach.rst
index ae2afb2..a01a104 100644
--- a/Help/command/foreach.rst
+++ b/Help/command/foreach.rst
@@ -47,7 +47,7 @@ of undocumented behavior that may change in future releases.
.. code-block:: cmake
- foreach(loop_var IN [LISTS [<lists>]] [ITEMS [<items>]])
+ foreach(<loop_var> IN [LISTS [<lists>]] [ITEMS [<items>]])
In this variant, ``<lists>`` is a whitespace or semicolon
separated list of list-valued variables. The ``foreach``
@@ -82,3 +82,46 @@ yields
-- X=6
-- X=7
-- X=8
+
+
+.. code-block:: cmake
+
+ foreach(<loop_var>... IN ZIP_LISTS <lists>)
+
+In this variant, ``<lists>`` is a whitespace or semicolon
+separated list of list-valued variables. The ``foreach``
+command iterates over each list simultaneously setting the
+iteration variables as follows:
+
+- if the only ``loop_var`` given, then it sets a series of
+ ``loop_var_N`` variables to the current item from the
+ corresponding list;
+- if multiple variable names passed, their count should match
+ the lists variables count;
+- if any of the lists are shorter, the corresponding iteration
+ variable is not defined for the current iteration.
+
+.. code-block:: cmake
+
+ list(APPEND English one two three four)
+ list(APPEND Bahasa satu dua tiga)
+
+ foreach(num IN ZIP_LISTS English Bahasa)
+ message(STATUS "num_0=${num_0}, num_1=${num_1}")
+ endforeach()
+
+ foreach(en ba IN ZIP_LISTS English Bahasa)
+ message(STATUS "en=${en}, ba=${ba}")
+ endforeach()
+
+yields
+::
+
+ -- num_0=one, num_1=satu
+ -- num_0=two, num_1=dua
+ -- num_0=three, num_1=tiga
+ -- num_0=four, num_1=
+ -- en=one, ba=satu
+ -- en=two, ba=dua
+ -- en=three, ba=tiga
+ -- en=four, ba=
diff --git a/Help/command/function.rst b/Help/command/function.rst
index 53ba754..30938b3 100644
--- a/Help/command/function.rst
+++ b/Help/command/function.rst
@@ -44,11 +44,15 @@ can be invoked through any of
foo()
Foo()
FOO()
+ cmake_command(INVOKE foo)
and so on. However, it is strongly recommended to stay with the
case chosen in the function definition. Typically functions use
all-lowercase names.
+The :command:`cmake_command(INVOKE ...)` command can also be used to invoke the
+function.
+
Arguments
^^^^^^^^^
diff --git a/Help/command/get_property.rst b/Help/command/get_property.rst
index c0f9b46..80d97fd 100644
--- a/Help/command/get_property.rst
+++ b/Help/command/get_property.rst
@@ -10,6 +10,7 @@ Get a property.
DIRECTORY [<dir>] |
TARGET <target> |
SOURCE <source> |
+ [<TARGET_DIRECTORY ... | DIRECTORY ...>] |
INSTALL <file> |
TEST <test> |
CACHE <entry> |
@@ -49,6 +50,15 @@ It must be one of the following:
``VARIABLE``
Scope is unique and does not accept a name.
+In the ``SOURCE`` case, the queried source file scope can be changed by
+specifying one of the additional options: ``DIRECTORY`` or ``TARGET_DIRECTORY``.
+
+``DIRECTORY`` takes a path to a processed directory, and the source file property
+will be read from that directory scope.
+
+``TARGET_DIRECTORY`` takes the name of an existing target. The source file
+property will be read from this target's directory scope.
+
The required ``PROPERTY`` option is immediately followed by the name of
the property to get. If the property is not set an empty value is
returned, although some properties support inheriting from a parent scope
diff --git a/Help/command/get_source_file_property.rst b/Help/command/get_source_file_property.rst
index decec19..893a1b6 100644
--- a/Help/command/get_source_file_property.rst
+++ b/Help/command/get_source_file_property.rst
@@ -5,7 +5,7 @@ Get a property for a source file.
.. code-block:: cmake
- get_source_file_property(VAR file property)
+ get_source_file_property(VAR file [<TARGET_DIRECTORY ... | DIRECTORY ...>] property)
Gets a property from a source file. The value of the property is
stored in the variable ``VAR``. If the source property is not found, the
@@ -15,6 +15,15 @@ or not (see :command:`define_property`). Non-inherited properties will set
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.
+The queried source file scope can be changed by specifying one of the
+additional options: ``DIRECTORY`` or ``TARGET_DIRECTORY``.
+
+``DIRECTORY`` takes a path to a processed directory, and the source file property
+will be read from that directory scope.
+
+``TARGET_DIRECTORY`` takes the name of an existing target. The source file
+property will be read from this target's directory scope.
+
Use :command:`set_source_files_properties` to set property values. Source
file properties usually control how the file is built. One property that is
always there is :prop_sf:`LOCATION`.
diff --git a/Help/command/install.rst b/Help/command/install.rst
index 5affc5b..c8df7d9 100644
--- a/Help/command/install.rst
+++ b/Help/command/install.rst
@@ -18,10 +18,12 @@ Synopsis
Introduction
^^^^^^^^^^^^
-This command generates installation rules for a project. Rules
-specified by calls to this command within a source directory are
-executed in order during installation. The order across directories
-is not defined.
+This command generates installation rules for a project. Install rules
+specified by calls to the ``install()`` command within a source directory
+are executed in order during installation. Install rules in subdirectories
+added by calls to the :command:`add_subdirectory` command are interleaved
+with those in the parent directory to run in the order declared (see
+policy :policy:`CMP0082`).
There are multiple signatures for this command. Some of them define
installation options for files and targets. Options common to
@@ -30,13 +32,20 @@ signatures that specify them. The common options are:
``DESTINATION``
Specify the directory on disk to which a file will be installed.
- If a full path (with a leading slash or drive letter) is given
- it is used directly. If a relative path is given it is interpreted
- relative to the value of the :variable:`CMAKE_INSTALL_PREFIX` variable.
+ Arguments can be relative or absolute paths.
+
+ If a relative path is given it is interpreted relative to the value
+ of the :variable:`CMAKE_INSTALL_PREFIX` variable.
The prefix can be relocated at install time using the ``DESTDIR``
mechanism explained in the :variable:`CMAKE_INSTALL_PREFIX` variable
documentation.
+ If an absolute path (with a leading slash or drive letter) is given
+ it is used verbatim.
+
+ As absolute paths are not supported by :manual:`cpack <cpack(1)>` installer
+ generators, it is preferable to use relative paths throughout.
+
``PERMISSIONS``
Specify permissions for installed files. Valid permissions are
``OWNER_READ``, ``OWNER_WRITE``, ``OWNER_EXECUTE``, ``GROUP_READ``,
@@ -119,31 +128,38 @@ Installing Targets
)
The ``TARGETS`` form specifies rules for installing targets from a
-project. There are several kinds of target files that may be installed:
+project. There are several kinds of target :ref:`Output Artifacts`
+that may be installed:
``ARCHIVE``
- Static libraries are treated as ``ARCHIVE`` targets, except those
- marked with the ``FRAMEWORK`` property on macOS (see ``FRAMEWORK``
- below.) For DLL platforms (all Windows-based systems including
- Cygwin), the DLL import library is treated as an ``ARCHIVE`` target.
- On AIX, the linker import file created for executables with
- :prop_tgt:`ENABLE_EXPORTS` is treated as an ``ARCHIVE`` target.
+ Target artifacts of this kind include:
+
+ * *Static libraries*
+ (except on macOS when marked as ``FRAMEWORK``, see below);
+ * *DLL import libraries*
+ (on all Windows-based systems including Cygwin; they have extension
+ ``.lib``, in contrast to the ``.dll`` libraries that go to ``RUNTIME``);
+ * On AIX, the *linker import file* created for executables with
+ :prop_tgt:`ENABLE_EXPORTS` enabled.
``LIBRARY``
- Module libraries are always treated as ``LIBRARY`` targets. For non-
- DLL platforms shared libraries are treated as ``LIBRARY`` targets,
- except those marked with the ``FRAMEWORK`` property on macOS (see
- ``FRAMEWORK`` below.)
+ Target artifacts of this kind include:
+
+ * *Shared libraries*, except
+
+ - DLLs (these go to ``RUNTIME``, see below),
+ - on macOS when marked as ``FRAMEWORK`` (see below).
``RUNTIME``
- Executables are treated as ``RUNTIME`` objects, except those marked
- with the ``MACOSX_BUNDLE`` property on macOS (see ``BUNDLE`` below.)
- For DLL platforms (all Windows-based systems including Cygwin), the
- DLL part of a shared library is treated as a ``RUNTIME`` target.
+ Target artifacts of this kind include:
+
+ * *Executables*
+ (except on macOS when marked as ``MACOSX_BUNDLE``, see ``BUNDLE`` below);
+ * DLLs (on all Windows-based systems including Cygwin; note that the
+ accompanying import libraries are of kind ``ARCHIVE``).
``OBJECTS``
- Object libraries (a simple group of object files) are always treated
- as ``OBJECTS`` targets.
+ Object files associated with *object libraries*.
``FRAMEWORK``
Both static and shared libraries marked with the ``FRAMEWORK``
@@ -630,6 +646,13 @@ present, causes the contents of the properties matching
``(IMPORTED_)?LINK_INTERFACE_LIBRARIES(_<CONFIG>)?`` to be exported, when
policy :policy:`CMP0022` is ``NEW``.
+.. note::
+ The installed ``<export-name>.cmake`` file may come with additional
+ per-configuration ``<export-name>-*.cmake`` files to be loaded by
+ globbing. Do not use an export name that is the same as the package
+ name in combination with installing a ``<package-name>-config.cmake``
+ file or the latter may be incorrectly matched by the glob and loaded.
+
When a ``COMPONENT`` option is given, the listed ``<component>`` implicitly
depends on all components mentioned in the export set. The exported
``<name>.cmake`` file will require each of the exported components to be
@@ -684,6 +707,11 @@ executable from the installation tree using the imported target name
Generated Installation Script
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+.. note::
+
+ Use of this feature is not recommended. Please consider using the
+ ``--install`` argument of :manual:`cmake(1)` 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
diff --git a/Help/command/list.rst b/Help/command/list.rst
index 50bf417..4d339a0 100644
--- a/Help/command/list.rst
+++ b/Help/command/list.rst
@@ -308,6 +308,13 @@ The ``<compare>`` option should be one of:
* ``STRING``: Sorts a list of strings alphabetically. This is the
default behavior if the ``COMPARE`` option is not given.
* ``FILE_BASENAME``: Sorts a list of pathnames of files by their basenames.
+* ``NATURAL``: Sorts a list of strings using natural order
+ (see ``strverscmp(3)`` manual), i.e. such that contiguous digits
+ are compared as whole numbers.
+ For example: the following list `10.0 1.1 2.1 8.0 2.0 3.1`
+ will be sorted as `1.1 2.0 2.1 3.1 8.0 10.0` if the ``NATURAL``
+ comparison is selected where it will be sorted as
+ `1.1 10.0 2.0 2.1 3.1 8.0` with the ``STRING`` comparison.
Use the ``CASE`` keyword to select a case sensitive or case insensitive
sort mode. The ``<case>`` option should be one of:
diff --git a/Help/command/macro.rst b/Help/command/macro.rst
index 05e5d79..65159f4 100644
--- a/Help/command/macro.rst
+++ b/Help/command/macro.rst
@@ -42,11 +42,15 @@ can be invoked through any of
foo()
Foo()
FOO()
+ cmake_command(INVOKE foo)
and so on. However, it is strongly recommended to stay with the
case chosen in the macro definition. Typically macros use
all-lowercase names.
+The :command:`cmake_command(INVOKE ...)` command can also be used to invoke the
+macro.
+
Arguments
^^^^^^^^^
@@ -91,6 +95,12 @@ just terminate execution of the macro; rather, control is returned
from the scope of the macro call. To avoid confusion, it is recommended
to avoid :command:`return()` in macros altogether.
+Unlike a function, the :variable:`CMAKE_CURRENT_FUNCTION`,
+:variable:`CMAKE_CURRENT_FUNCTION_LIST_DIR`,
+:variable:`CMAKE_CURRENT_FUNCTION_LIST_FILE`,
+:variable:`CMAKE_CURRENT_FUNCTION_LIST_LINE` variables are not
+set for a macro.
+
.. _`Argument Caveats`:
Argument Caveats
diff --git a/Help/command/mark_as_advanced.rst b/Help/command/mark_as_advanced.rst
index 5712fb4..e52e623 100644
--- a/Help/command/mark_as_advanced.rst
+++ b/Help/command/mark_as_advanced.rst
@@ -22,3 +22,9 @@ If neither ``FORCE`` nor ``CLEAR`` is specified,
new values will be marked as advanced, but if a
variable already has an advanced/non-advanced state,
it will not be changed.
+
+.. note::
+
+ Policy :policy:`CMP0102` affects the behavior of the ``mark_as_advanced``
+ call. When set to ``NEW``, variables passed to this command which are not
+ already in the cache are ignored. See policy :policy:`CMP0102`.
diff --git a/Help/command/message.rst b/Help/command/message.rst
index c614286..6bc0e4c 100644
--- a/Help/command/message.rst
+++ b/Help/command/message.rst
@@ -1,13 +1,33 @@
message
-------
-Display a message to the user.
+Log a message.
+
+Synopsis
+^^^^^^^^
+
+.. parsed-literal::
+
+ `General messages`_
+ message([<mode>] "message text" ...)
+
+ `Reporting checks`_
+ message(<checkState> "message text" ...)
+
+
+General messages
+^^^^^^^^^^^^^^^^
.. code-block:: cmake
- message([<mode>] "message to display" ...)
+ message([<mode>] "message text" ...)
+
+Record the specified message text in the log. If more than one message
+string is given, they are concatenated into a single message with no
+separator between the strings.
-The optional ``<mode>`` keyword determines the type of message:
+The optional ``<mode>`` keyword determines the type of message, which
+influences the way the message is handled:
``FATAL_ERROR``
CMake Error, stop processing and generation.
@@ -59,12 +79,104 @@ 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.
+To make a log level persist between CMake runs, the
+:variable:`CMAKE_MESSAGE_LOG_LEVEL` variable can be set instead.
+Note that the command line option takes precedence over the cache variable.
-Messages of log levels ``NOTICE`` and below will also have each line preceded
+Messages of log levels ``NOTICE`` and below will have each line preceded
by the content of the :variable:`CMAKE_MESSAGE_INDENT` variable (converted to
a single string by concatenating its list items). For ``STATUS`` to ``TRACE``
messages, this indenting content will be inserted after the hyphens.
+Messages of log levels ``NOTICE`` and below can also have each line preceded
+with context of the form ``[some.context.example]``. The content between the
+square brackets is obtained by converting the :variable:`CMAKE_MESSAGE_CONTEXT`
+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``
+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.
+
CMake Warning and Error message text displays using a simple markup
language. Non-indented text is formatted in line-wrapped paragraphs
delimited by newlines. Indented text is considered pre-formatted.
+
+
+Reporting checks
+^^^^^^^^^^^^^^^^
+
+A common pattern in CMake output is a message indicating the start of some
+sort of check, followed by another message reporting the result of that check.
+For example:
+
+.. code-block:: cmake
+
+ message(STATUS "Looking for someheader.h")
+ #... do the checks, set checkSuccess with the result
+ if(checkSuccess)
+ message(STATUS "Looking for someheader.h - found")
+ else()
+ message(STATUS "Looking for someheader.h - not found")
+ endif()
+
+This can be more robustly and conveniently expressed using the ``CHECK_...``
+keyword form of the ``message()`` command:
+
+.. code-block:: cmake
+
+ message(<checkState> "message" ...)
+
+where ``<checkState>`` must be one of the following:
+
+ ``CHECK_START``
+ Record a concise message about the check about to be performed.
+
+ ``CHECK_PASS``
+ Record a successful result for a check.
+
+ ``CHECK_FAIL``
+ Record an unsuccessful result for a check.
+
+When recording a check result, the command repeats the message from the most
+recently started check for which no result has yet been reported, then some
+separator characters and then the message text provided after the
+``CHECK_PASS`` or ``CHECK_FAIL`` keyword. Check messages are always reported
+at ``STATUS`` log level.
+
+Checks may be nested and every ``CHECK_START`` should have exactly one
+matching ``CHECK_PASS`` or ``CHECK_FAIL``.
+The :variable:`CMAKE_MESSAGE_INDENT` variable can also be used to add
+indenting to nested checks if desired. For example:
+
+.. code-block:: cmake
+
+ message(CHECK_START "Finding my things")
+ list(APPEND CMAKE_MESSAGE_INDENT " ")
+ unset(missingComponents)
+
+ message(CHECK_START "Finding partA")
+ # ... do check, assume we find A
+ message(CHECK_PASS "found")
+
+ message(CHECK_START "Finding partB")
+ # ... do check, assume we don't find B
+ list(APPEND missingComponents B)
+ message(CHECK_FAIL "not found")
+
+ list(POP_BACK CMAKE_MESSAGE_INDENT)
+ if(missingComponents)
+ message(CHECK_FAIL "missing components: ${missingComponents}")
+ else()
+ message(CHECK_PASS "all components found")
+ endif()
+
+Output from the above would appear something like the following::
+
+ -- Finding my things
+ -- Finding partA
+ -- Finding partA - found
+ -- Finding partB
+ -- Finding partB - not found
+ -- Finding my things - missing components: B
diff --git a/Help/command/option.rst b/Help/command/option.rst
index 8956307..02b8dac 100644
--- a/Help/command/option.rst
+++ b/Help/command/option.rst
@@ -9,7 +9,7 @@ Provide an option that the user can optionally select.
Provides an option for the user to select as ``ON`` or ``OFF``.
If no initial ``<value>`` is provided, ``OFF`` is used.
-If ``<variable>`` is already set as a normal variable
+If ``<variable>`` is already set as a normal or cache variable,
then the command does nothing (see policy :policy:`CMP0077`).
If you have options that depend on the values of other options, see
diff --git a/Help/command/project.rst b/Help/command/project.rst
index 3951456..b6093d3 100644
--- a/Help/command/project.rst
+++ b/Help/command/project.rst
@@ -102,9 +102,12 @@ options are intended for use as default values in package metadata and documenta
Code Injection
^^^^^^^^^^^^^^
-If the :variable:`CMAKE_PROJECT_INCLUDE_BEFORE` variable is set, the file
-pointed to by that variable will be included as the first step of the
+If the :variable:`CMAKE_PROJECT_INCLUDE_BEFORE` or
+:variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE` variables are set,
+the files they point to will be included as the first step of the
``project()`` command.
+If both are set, then :variable:`CMAKE_PROJECT_INCLUDE_BEFORE` will be
+included before :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE`.
If the :variable:`CMAKE_PROJECT_INCLUDE` or
:variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE` variables are set, the files
diff --git a/Help/command/separate_arguments.rst b/Help/command/separate_arguments.rst
index fbca859..ab3d5c1 100644
--- a/Help/command/separate_arguments.rst
+++ b/Help/command/separate_arguments.rst
@@ -19,7 +19,7 @@ They are specified by the ``<mode>`` argument which must
be one of the following keywords:
``UNIX_COMMAND``
- Arguments are separated by by unquoted whitespace.
+ Arguments are separated by unquoted whitespace.
Both single-quote and double-quote pairs are respected.
A backslash escapes the next literal character (``\"`` is ``"``);
there are no special escapes (``\n`` is just ``n``).
diff --git a/Help/command/set_property.rst b/Help/command/set_property.rst
index ec08c8f..de28be3 100644
--- a/Help/command/set_property.rst
+++ b/Help/command/set_property.rst
@@ -8,7 +8,8 @@ Set a named property in a given scope.
set_property(<GLOBAL |
DIRECTORY [<dir>] |
TARGET [<target1> ...] |
- SOURCE [<src1> ...] |
+ SOURCE [<src1> ...]
+ [<TARGET_DIRECTORY ... | DIRECTORY ...>] |
INSTALL [<file1> ...] |
TEST [<test1> ...] |
CACHE [<entry1> ...] >
@@ -34,8 +35,16 @@ It must be one of the following:
``SOURCE``
Scope may name zero or more source files. Note that source
- file properties are visible only to targets added in the same
+ file properties are by default visible only to targets added in the same
directory (``CMakeLists.txt``).
+ The file properties can be made visible in a different directory by specifying
+ one of the additional options: ``TARGET_DIRECTORY`` or ``DIRECTORY``.
+
+ ``DIRECTORY`` takes a list of processed directories paths, and sets the file
+ properties in those directory scopes.
+
+ ``TARGET_DIRECTORY`` takes a list of existing targets. The file
+ properties will be set in these targets' directory scopes.
See also the :command:`set_source_files_properties` command.
``INSTALL``
@@ -66,7 +75,8 @@ the property to set. Remaining arguments are used to compose the
property value in the form of a semicolon-separated list.
If the ``APPEND`` option is given the list is appended to any existing
-property value. If the ``APPEND_STRING`` option is given the string is
+property value (except that empty values are ignored and not appended).
+If the ``APPEND_STRING`` option is given the string is
appended to any existing property value as string, i.e. it results in a
longer string and not a list of strings. When using ``APPEND`` or
``APPEND_STRING`` with a property defined to support ``INHERITED``
diff --git a/Help/command/set_source_files_properties.rst b/Help/command/set_source_files_properties.rst
index ab95d70..8adfb9e 100644
--- a/Help/command/set_source_files_properties.rst
+++ b/Help/command/set_source_files_properties.rst
@@ -6,12 +6,25 @@ Source files can have properties that affect how they are built.
.. code-block:: cmake
set_source_files_properties([file1 [file2 [...]]]
+ [<TARGET_DIRECTORY ... | DIRECTORY ...>]
PROPERTIES prop1 value1
[prop2 value2 [...]])
Sets properties associated with source files using a key/value paired
list.
+Note that source file properties are by default visible only to
+targets added in the same directory (``CMakeLists.txt``).
+
+The file properties can be made visible in a different directory by specifying
+one of the additional options: ``TARGET_DIRECTORY`` or ``DIRECTORY``.
+
+``DIRECTORY`` takes a list of processed directories paths, and sets the file
+properties in those directory scopes.
+
+``TARGET_DIRECTORY`` takes a list of existing targets. The file
+properties will be set in these targets' directory scopes.
+
See also the :command:`set_property(SOURCE)` command.
See :ref:`Source File Properties` for the list of properties known
diff --git a/Help/command/source_group.rst b/Help/command/source_group.rst
index 6623c98..5ae9e51 100644
--- a/Help/command/source_group.rst
+++ b/Help/command/source_group.rst
@@ -37,11 +37,13 @@ explicitly lists the file with ``FILES`` will be favored, if any.
If no group explicitly lists the file, the *last* group whose
regular expression matches the file will be favored.
-The ``<name>`` of the group and ``<prefix>`` argument may contain backslashes
-to specify subgroups:
+The ``<name>`` of the group and ``<prefix>`` argument may contain forward
+slashes or backslashes to specify subgroups. Backslashes need to be escaped
+appropriately:
.. code-block:: cmake
+ source_group(base/subdir ...)
source_group(outer\\inner ...)
source_group(TREE <root> PREFIX sources\\inc ...)
diff --git a/Help/command/string.rst b/Help/command/string.rst
index 81a2061..cfcf914 100644
--- a/Help/command/string.rst
+++ b/Help/command/string.rst
@@ -11,8 +11,6 @@ Synopsis
`Search and Replace`_
string(`FIND`_ <string> <substring> <out-var> [...])
string(`REPLACE`_ <match-string> <replace-string> <out-var> <input>...)
-
- `Regular Expressions`_
string(`REGEX MATCH`_ <match-regex> <out-var> <input>...)
string(`REGEX MATCHALL`_ <match-regex> <out-var> <input>...)
string(`REGEX REPLACE`_ <match-regex> <replace-expr> <out-var> <input>...)
@@ -38,6 +36,7 @@ Synopsis
`Generation`_
string(`ASCII`_ <number>... <out-var>)
+ string(`HEX`_ <string> <out-var>)
string(`CONFIGURE`_ <string> <out-var> [...])
string(`MAKE_C_IDENTIFIER`_ <string> <out-var>)
string(`RANDOM`_ [<option>...] <out-var>)
@@ -47,6 +46,9 @@ Synopsis
Search and Replace
^^^^^^^^^^^^^^^^^^
+Search and Replace With Plain Strings
+"""""""""""""""""""""""""""""""""""""
+
.. _FIND:
.. code-block:: cmake
@@ -74,8 +76,8 @@ so strings containing multi-byte characters may lead to unexpected results.
Replace all occurrences of ``<match_string>`` in the ``<input>``
with ``<replace_string>`` and store the result in the ``<output_variable>``.
-Regular Expressions
-^^^^^^^^^^^^^^^^^^^
+Search and Replace With Regular Expressions
+"""""""""""""""""""""""""""""""""""""""""""
.. _`REGEX MATCH`:
@@ -87,6 +89,7 @@ Regular Expressions
Match the ``<regular_expression>`` once and store the match in the
``<output_variable>``.
All ``<input>`` arguments are concatenated before matching.
+Regular expressions are specified in the subsection just below.
.. _`REGEX MATCHALL`:
@@ -353,6 +356,16 @@ Generation
Convert all numbers into corresponding ASCII characters.
+.. _HEX:
+
+.. code-block:: cmake
+
+ string(HEX <string> <output_variable>)
+
+Convert each byte in the input ``<string>`` to its hexadecimal representation
+and store the concatenated hex digits in the ``<output_variable>``. Letters in
+the output (``a`` through ``f``) are in lowercase.
+
.. _CONFIGURE:
.. code-block:: cmake
diff --git a/Help/command/target_compile_features.rst b/Help/command/target_compile_features.rst
index 9271cd5..c5401e6 100644
--- a/Help/command/target_compile_features.rst
+++ b/Help/command/target_compile_features.rst
@@ -8,9 +8,9 @@ Add expected compiler features to a target.
target_compile_features(<target> <PRIVATE|PUBLIC|INTERFACE> <feature> [...])
Specifies compiler features required when compiling a given target. If the
-feature is not listed in the :variable:`CMAKE_C_COMPILE_FEATURES` variable
-or :variable:`CMAKE_CXX_COMPILE_FEATURES` variable,
-then an error will be reported by CMake. If the use of the feature requires
+feature is not listed in the :variable:`CMAKE_C_COMPILE_FEATURES`,
+:variable:`CMAKE_CUDA_COMPILE_FEATURES`, or :variable:`CMAKE_CXX_COMPILE_FEATURES`
+variables, then an error will be reported by CMake. If the use of the feature requires
an additional compiler flag, such as ``-std=gnu++11``, the flag will be added
automatically.
diff --git a/Help/command/target_link_options.rst b/Help/command/target_link_options.rst
index b5abbc4..89038e3 100644
--- a/Help/command/target_link_options.rst
+++ b/Help/command/target_link_options.rst
@@ -43,6 +43,8 @@ with the syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)`
manual for available expressions. See the :manual:`cmake-buildsystem(7)`
manual for more on defining buildsystem properties.
+.. include:: DEVICE_LINK_OPTIONS.txt
+
.. include:: OPTIONS_SHELL.txt
.. include:: LINK_OPTIONS_LINKER.txt
diff --git a/Help/cpack_gen/archive.rst b/Help/cpack_gen/archive.rst
index d455f4b..3656aa2 100644
--- a/Help/cpack_gen/archive.rst
+++ b/Help/cpack_gen/archive.rst
@@ -1,8 +1,8 @@
CPack Archive Generator
-----------------------
-Archive CPack generator that supports packaging of sources and binaries in
-different formats:
+CPack generator for packaging files into an archive, which can have
+any of the following formats:
- 7Z - 7zip - (.7z)
- TBZ2 (.tar.bz2)
@@ -12,25 +12,64 @@ different formats:
- TZST (.tar.zst)
- ZIP (.zip)
+When this generator is called from ``CPackSourceConfig.cmake`` (or through
+the ``package_source`` target), then the generated archive will contain all
+files in the project directory, except those specified in
+:variable:`CPACK_SOURCE_IGNORE_FILES`. The following is one example of
+packaging all source files of a project:
+
+.. code-block:: cmake
+
+ set(CPACK_SOURCE_GENERATOR "TGZ")
+ set(CPACK_SOURCE_IGNORE_FILES
+ \\.git/
+ build/
+ ".*~$"
+ )
+ set(CPACK_VERBATIM_VARIABLES YES)
+ include(CPack)
+
+When this generator is called from ``CPackConfig.cmake`` (or through the
+``package`` target), then the generated archive will contain all files
+that have been installed via CMake's :command:`install` command (and the
+deprecated commands :command:`install_files`, :command:`install_programs`,
+and :command:`install_targets`).
+
Variables specific to CPack Archive generator
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. variable:: CPACK_ARCHIVE_FILE_NAME
CPACK_ARCHIVE_<component>_FILE_NAME
- Package file name without extension which is added automatically depending
- on the archive format.
-
- * Mandatory : YES
- * Default : ``<CPACK_PACKAGE_FILE_NAME>[-<component>].<extension>`` with
- spaces replaced by '-'
+ Package file name without extension. The extension is determined from the
+ archive format (see list above) and automatically appended to the file name.
+ The default is ``<CPACK_PACKAGE_FILE_NAME>[-<component>]``, with spaces
+ replaced by '-'.
.. variable:: CPACK_ARCHIVE_COMPONENT_INSTALL
- Enable component packaging for CPackArchive
+ Enable component packaging. If enabled (ON), then the archive generator
+ creates multiple packages. The default is OFF, which means that a single
+ package containing files of all components is generated.
+
+Variables used by CPack Archive generator
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+These variables are used by the Archive generator, but are also available to
+CPack generators which are essentially archives at their core. These include:
+
+ - :cpack_gen:`CPack Cygwin Generator`
+ - :cpack_gen:`CPack FreeBSD Generator`
+
+.. variable:: CPACK_ARCHIVE_THREADS
+
+ The number of threads to use when performing the compression. If set to
+ ``0``, the number of available cores on the machine will be used instead.
+ The default is ``1`` which limits compression to a single thread. Note that
+ not all compression modes support threading in all environments. Currently,
+ only the XZ compression may support it.
- * Mandatory : NO
- * Default : OFF
+.. note::
- If enabled (ON) multiple packages are generated. By default a single package
- containing files of all components is generated.
+ Official CMake binaries available on ``cmake.org`` ship with a ``liblzma``
+ that does not support parallel compression.
diff --git a/Help/cpack_gen/cygwin.rst b/Help/cpack_gen/cygwin.rst
index 1c5f7af..c65653e 100644
--- a/Help/cpack_gen/cygwin.rst
+++ b/Help/cpack_gen/cygwin.rst
@@ -3,6 +3,11 @@ CPack Cygwin Generator
Cygwin CPack generator (Cygwin).
+Variables affecting the CPack Cygwin generator
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ - :variable:`CPACK_ARCHIVE_THREADS`
+
Variables specific to CPack Cygwin generator
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/Help/cpack_gen/dmg.rst b/Help/cpack_gen/dmg.rst
index 1e37889..cede0f2 100644
--- a/Help/cpack_gen/dmg.rst
+++ b/Help/cpack_gen/dmg.rst
@@ -54,10 +54,12 @@ on macOS:
Directory where license and menu files for different languages are stored.
Setting this causes CPack to look for a ``<language>.menu.txt`` and
- ``<language>.license.txt`` file for every language defined in
- ``CPACK_DMG_SLA_LANGUAGES``. If both this variable and
+ ``<language>.license.txt`` or ``<language>.license.rtf`` file for every
+ language defined in ``CPACK_DMG_SLA_LANGUAGES``. If both this variable and
``CPACK_RESOURCE_FILE_LICENSE`` are set, CPack will only look for the menu
- files and use the same license file for all languages.
+ files and use the same license file for all languages. If both
+ ``<language>.license.txt`` and ``<language>.license.rtf`` exist, the ``.txt``
+ file will be used.
.. variable:: CPACK_DMG_SLA_LANGUAGES
@@ -81,6 +83,13 @@ on macOS:
``<language>.menu.txt`` and ``<language>.license.txt`` in the directory
specified by the :variable:`CPACK_DMG_SLA_DIR` variable.
+.. variable:: CPACK_DMG_<component>_FILE_NAME
+
+ File name when packaging ``<component>`` as its own DMG
+ (``CPACK_COMPONENTS_GROUPING`` set to IGNORE).
+
+ - Default: ``CPACK_PACKAGE_FILE_NAME-<component>``
+
.. variable:: CPACK_COMMAND_HDIUTIL
Path to the ``hdiutil(1)`` command used to operate on disk image files on
diff --git a/Help/cpack_gen/freebsd.rst b/Help/cpack_gen/freebsd.rst
index a8dd320..47a7784 100644
--- a/Help/cpack_gen/freebsd.rst
+++ b/Help/cpack_gen/freebsd.rst
@@ -3,6 +3,11 @@ CPack FreeBSD Generator
The built in (binary) CPack FreeBSD (pkg) generator (Unix only)
+Variables affecting the CPack FreeBSD (pkg) generator
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ - :variable:`CPACK_ARCHIVE_THREADS`
+
Variables specific to CPack FreeBSD (pkg) generator
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/Help/cpack_gen/ifw.rst b/Help/cpack_gen/ifw.rst
index feccd3d..776bb46 100644
--- a/Help/cpack_gen/ifw.rst
+++ b/Help/cpack_gen/ifw.rst
@@ -1,78 +1,28 @@
CPack IFW Generator
-------------------
-See :module:`CPackIFW` for details on the CPackIFW module.
+Configure and run the Qt Installer Framework to generate a Qt installer.
-.. _QtIFW: http://doc.qt.io/qtinstallerframework/index.html
+.. only:: html
+ .. contents::
Overview
^^^^^^^^
-CPack ``IFW`` generator helps you to create online and offline
-binary cross-platform installers with a graphical user interface.
+This :manual:`cpack generator <cpack-generators(7)>` generates
+configuration and meta information for the `Qt Installer Framework
+<http://doc.qt.io/qtinstallerframework/index.html>`_ (QtIFW),
+and runs QtIFW tools to generate a Qt installer.
-CPack IFW generator prepares project installation and generates configuration
-and meta information for QtIFW_ tools.
+QtIFW provides tools and utilities to create installers for
+the platforms supported by `Qt <https://www.qt.io>`_: Linux,
+Microsoft Windows, and macOS.
-The QtIFW_ provides a set of tools and utilities to create
-installers for the supported desktop Qt platforms: Linux, Microsoft Windows,
-and macOS.
-
-You should also install QtIFW_ to use CPack ``IFW`` generator.
-
-Hints
-^^^^^
-
-Generally, the CPack ``IFW`` generator automatically finds QtIFW_ tools,
-but if you don't use a default path for installation of the QtIFW_ tools,
-the path may be specified in either a CMake or an environment variable:
-
-.. variable:: CPACK_IFW_ROOT
-
- An CMake variable which specifies the location of the QtIFW_ tool suite.
-
- The variable will be cached in the ``CPackConfig.cmake`` file and used at
- CPack runtime.
-
-.. variable:: QTIFWDIR
-
- An environment variable which specifies the location of the QtIFW_ tool
- suite.
-
-.. note::
- The specified path should not contain "bin" at the end
- (for example: "D:\\DevTools\\QtIFW2.0.5").
-
-The :variable:`CPACK_IFW_ROOT` variable has a higher priority and overrides
-the value of the :variable:`QTIFWDIR` variable.
-
-Internationalization
-^^^^^^^^^^^^^^^^^^^^
-
-Some variables and command arguments support internationalization via
-CMake script. This is an optional feature.
-
-Installers created by QtIFW_ tools have built-in support for
-internationalization and many phrases are localized to many languages,
-but this does not apply to the description of the your components and groups
-that will be distributed.
-
-Localization of the description of your components and groups is useful for
-users of your installers.
-
-A localized variable or argument can contain a single default value, and a
-set of pairs the name of the locale and the localized value.
-
-For example:
-
-.. code-block:: cmake
-
- set(LOCALIZABLE_VARIABLE "Default value"
- en "English value"
- en_US "American value"
- en_GB "Great Britain value"
- )
+To make use of this generator, QtIFW needs to be installed.
+The :module:`CPackIFW` module looks for the location of the
+QtIFW command-line utilities, and defines several commands to
+control the behavior of this generator.
Variables
^^^^^^^^^
@@ -162,6 +112,8 @@ Package
Default target directory for installation.
By default used
"@ApplicationsDir@/:variable:`CPACK_PACKAGE_INSTALL_DIRECTORY`"
+ (variables embedded in '@' are expanded by the
+ `QtIFW scripting engine <https://doc.qt.io/qtinstallerframework/scripting.html>`_).
You can use predefined variables.
@@ -185,7 +137,7 @@ Package
Filename of the generated maintenance tool.
The platform-specific executable file extension is appended.
- By default used QtIFW_ defaults (``maintenancetool``).
+ By default used QtIFW defaults (``maintenancetool``).
.. variable:: CPACK_IFW_PACKAGE_REMOVE_TARGET_DIR
@@ -197,19 +149,19 @@ Package
Filename for the configuration of the generated maintenance tool.
- By default used QtIFW_ defaults (``maintenancetool.ini``).
+ By default used QtIFW defaults (``maintenancetool.ini``).
.. variable:: CPACK_IFW_PACKAGE_ALLOW_NON_ASCII_CHARACTERS
Set to ``ON`` if the installation path can contain non-ASCII characters.
- Is ``ON`` for QtIFW_ less 2.0 tools.
+ Is ``ON`` for QtIFW less 2.0 tools.
.. variable:: CPACK_IFW_PACKAGE_ALLOW_SPACE_IN_PATH
Set to ``OFF`` if the installation path cannot contain space characters.
- Is ``ON`` for QtIFW_ less 2.0 tools.
+ Is ``ON`` for QtIFW less 2.0 tools.
.. variable:: CPACK_IFW_PACKAGE_CONTROL_SCRIPT
@@ -266,57 +218,113 @@ Components
Additional prepared repository dirs that will be used to resolve and
repack dependent components. This feature available only
- since QtIFW_ 3.1.
+ since QtIFW 3.1.
-Tools
-"""""
+QtIFW Tools
+"""""""""""
.. variable:: CPACK_IFW_FRAMEWORK_VERSION
- The version of used QtIFW_ tools.
+ The version of used QtIFW tools.
-.. variable:: CPACK_IFW_BINARYCREATOR_EXECUTABLE
+The following variables provide the locations of the QtIFW
+command-line tools as discovered by the module :module:`CPackIFW`.
+These variables are cached, and may be configured if needed.
- The path to "binarycreator" command line client.
+.. variable:: CPACK_IFW_BINARYCREATOR_EXECUTABLE
- This variable is cached and may be configured if needed.
+ The path to ``binarycreator``.
.. variable:: CPACK_IFW_REPOGEN_EXECUTABLE
- The path to "repogen" command line client.
-
- This variable is cached and may be configured if needed.
+ The path to ``repogen``.
.. variable:: CPACK_IFW_INSTALLERBASE_EXECUTABLE
- The path to "installerbase" installer executable base.
-
- This variable is cached and may be configured if needed.
+ The path to ``installerbase``.
.. variable:: CPACK_IFW_DEVTOOL_EXECUTABLE
- The path to "devtool" command line client.
+ The path to ``devtool``.
+
+Hints for Finding QtIFW
+"""""""""""""""""""""""
+
+Generally, the CPack ``IFW`` generator automatically finds QtIFW tools,
+but if you don't use a default path for installation of the QtIFW tools,
+the path may be specified in either a CMake or an environment variable:
+
+.. variable:: CPACK_IFW_ROOT
+
+ An CMake variable which specifies the location of the QtIFW tool suite.
+
+ The variable will be cached in the ``CPackConfig.cmake`` file and used at
+ CPack runtime.
+
+.. variable:: QTIFWDIR
+
+ An environment variable which specifies the location of the QtIFW tool
+ suite.
+
+.. note::
+ The specified path should not contain "bin" at the end
+ (for example: "D:\\DevTools\\QtIFW2.0.5").
- This variable is cached and may be configured if needed.
+The :variable:`CPACK_IFW_ROOT` variable has a higher priority and overrides
+the value of the :variable:`QTIFWDIR` variable.
+Other Settings
+^^^^^^^^^^^^^^
Online installer
-^^^^^^^^^^^^^^^^
+""""""""""""""""
+
+By default, this generator generates an *offline installer*. This means that
+that all packaged files are fully contained in the installer executable.
-By default CPack IFW generator makes offline installer. This means that all
-components will be packaged into a binary file.
+In contrast, an *online installer* will download some or all components from
+a remote server.
-To make a component downloaded, you must set the ``DOWNLOADED`` option in
-:command:`cpack_add_component`.
+The ``DOWNLOADED`` option in the :command:`cpack_add_component` command
+specifies that a component is to be downloaded. Alternatively, the ``ALL``
+option in the :command:`cpack_configure_downloads` command specifies that
+`all` components are to be be downloaded.
-Then you would use the command :command:`cpack_configure_downloads`.
-If you set ``ALL`` option all components will be downloaded.
+The :command:`cpack_ifw_add_repository` command and the
+:variable:`CPACK_IFW_DOWNLOAD_ALL` variable allow for more specific
+configuration.
-You also can use command :command:`cpack_ifw_add_repository` and
-variable :variable:`CPACK_IFW_DOWNLOAD_ALL` for more specific configuration.
+When there are online components, CPack will write them to archive files.
+The help page of the :module:`CPackComponent` module, especially the section
+on the :command:`cpack_configure_downloads` function, explains how to make
+these files accessible from a download URL.
-CPack IFW generator creates "repository" dir in current binary dir. You
-would copy content of this dir to specified ``site`` (``url``).
+Internationalization
+""""""""""""""""""""
+
+Some variables and command arguments support internationalization via
+CMake script. This is an optional feature.
+
+Installers created by QtIFW tools have built-in support for
+internationalization and many phrases are localized to many languages,
+but this does not apply to the description of the your components and groups
+that will be distributed.
+
+Localization of the description of your components and groups is useful for
+users of your installers.
+
+A localized variable or argument can contain a single default value, and a
+set of pairs the name of the locale and the localized value.
+
+For example:
+
+.. code-block:: cmake
+
+ set(LOCALIZABLE_VARIABLE "Default value"
+ en "English value"
+ en_US "American value"
+ en_GB "Great Britain value"
+ )
See Also
^^^^^^^^
@@ -335,5 +343,5 @@ Qt Installer Framework Manual:
* Promoting Updates:
http://doc.qt.io/qtinstallerframework/ifw-updates.html
-Download Qt Installer Framework for you platform from Qt site:
+Download Qt Installer Framework for your platform from Qt site:
http://download.qt.io/official_releases/qt-installer-framework
diff --git a/Help/cpack_gen/nsis.rst b/Help/cpack_gen/nsis.rst
index cd2aea6..0dd876e 100644
--- a/Help/cpack_gen/nsis.rst
+++ b/Help/cpack_gen/nsis.rst
@@ -1,7 +1,9 @@
CPack NSIS Generator
--------------------
-CPack Nullsoft Scriptable Install System (NSIS) generator specific options
+CPack Nullsoft Scriptable Install System (NSIS) generator specific options.
+
+The NSIS generator requires NSIS 3.0 or newer.
Variables specific to CPack NSIS generator
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -128,3 +130,32 @@ on Windows Nullsoft Scriptable Install System.
set(CPACK_NSIS_MENU_LINKS
"doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cmake.html"
"CMake Help" "https://cmake.org" "CMake Web Site")
+
+.. variable:: CPACK_NSIS_UNINSTALL_NAME
+
+ Specify the name of the program to uninstall the version.
+ Default is ``Uninstall``.
+
+.. variable:: CPACK_NSIS_WELCOME_TITLE
+
+ The title to display on the top of the page for the welcome page.
+
+.. variable:: CPACK_NSIS_WELCOME_TITLE_3LINES
+
+ Display the title in the welcome page on 3 lines instead of 2.
+
+.. variable:: CPACK_NSIS_FINISH_TITLE
+
+ The title to display on the top of the page for the finish page.
+
+.. variable:: CPACK_NSIS_FINISH_TITLE_3LINES
+
+ Display the title in the finish page on 3 lines instead of 2.
+
+.. variable:: CPACK_NSIS_MUI_HEADERIMAGE
+
+ The image to display on the header of installers pages.
+
+.. variable:: CPACK_NSIS_MANIFEST_DPI_AWARE
+
+ If set, declares that the installer is DPI-aware.
diff --git a/Help/cpack_gen/packagemaker.rst b/Help/cpack_gen/packagemaker.rst
index e9464b7..c2a450e 100644
--- a/Help/cpack_gen/packagemaker.rst
+++ b/Help/cpack_gen/packagemaker.rst
@@ -3,6 +3,11 @@ CPack PackageMaker Generator
PackageMaker CPack generator (macOS).
+.. deprecated:: 3.17
+
+ Xcode no longer distributes the PackageMaker tools.
+ This CPack generator will be removed in a future version of CPack.
+
Variables specific to CPack PackageMaker generator
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -15,9 +20,60 @@ macOS using PackageMaker:
compatible with. Different versions of macOS support different
features. For example, CPack can only build component-based installers for
macOS 10.4 or newer, and can only build installers that download
- component son-the-fly for macOS 10.5 or newer. If left blank, this value
+ components on-the-fly for macOS 10.5 or newer. If left blank, this value
will be set to the minimum version of macOS that supports the requested
features. Set this variable to some value (e.g., 10.4) only if you want to
guarantee that your installer will work on that version of macOS, and
don't mind missing extra features available in the installer shipping with
later versions of macOS.
+
+.. variable:: CPACK_PACKAGEMAKER_BACKGROUND
+
+ Adds a background to Distribtion XML if specified. The value contains the
+ path to image in ``Resources`` directory.
+
+.. variable:: CPACK_PACKAGEMAKER_BACKGROUND_ALIGNMENT
+
+ Adds an ``alignment`` attribute to the background in Distribution XML.
+ Refer to Apple documentation for valid values.
+
+.. variable:: CPACK_PACKAGEMAKER_BACKGROUND_SCALING
+
+ Adds a ``scaling`` attribute to the background in Distribution XML.
+ Refer to Apple documentation for valid values.
+
+.. variable:: CPACK_PACKAGEMAKER_BACKGROUND_MIME_TYPE
+
+ Adds a ``mime-type`` attribute to the background in Distribution XML.
+ The option contains MIME type of an image.
+
+.. variable:: CPACK_PACKAGEMAKER_BACKGROUND_UTI
+
+ Adds an ``uti`` attribute to the background in Distribution XML.
+ The option contains UTI type of an image.
+
+.. variable:: CPACK_PACKAGEMAKER_BACKGROUND_DARKAQUA
+
+ Adds a background for the Dark Aqua theme to Distribution XML if
+ specified. The value contains the path to image in ``Resources``
+ directory.
+
+.. variable:: CPACK_PACKAGEMAKER_BACKGROUND_DARKAQUA_ALIGNMENT
+
+ Does the same as :variable:`CPACK_PACKAGEMAKER_BACKGROUND_ALIGNMENT` option,
+ but for the dark theme.
+
+.. variable:: CPACK_PACKAGEMAKER_BACKGROUND_DARKAQUA_SCALING
+
+ Does the same as :variable:`CPACK_PACKAGEMAKER_BACKGROUND_SCALING` option,
+ but for the dark theme.
+
+.. variable:: CPACK_PACKAGEMAKER_BACKGROUND_DARKAQUA_MIME_TYPE
+
+ Does the same as :variable:`CPACK_PACKAGEMAKER_BACKGROUND_MIME_TYPE` option,
+ but for the dark theme.
+
+.. variable:: CPACK_PACKAGEMAKER_BACKGROUND_DARKAQUA_UTI
+
+ Does the same as :variable:`CPACK_PACKAGEMAKER_BACKGROUND_UTI` option,
+ but for the dark theme.
diff --git a/Help/cpack_gen/productbuild.rst b/Help/cpack_gen/productbuild.rst
index d22fcd4..82b79ae 100644
--- a/Help/cpack_gen/productbuild.rst
+++ b/Help/cpack_gen/productbuild.rst
@@ -58,7 +58,6 @@ macOS using ProductBuild:
component name. No ``postinstall`` script is added if this variable is not
defined for a given component.
-
.. variable:: CPACK_PRODUCTBUILD_RESOURCES_DIR
If specified the productbuild generator copies files from this directory
@@ -66,3 +65,54 @@ macOS using ProductBuild:
before the :variable:`CPACK_RESOURCE_FILE_WELCOME`,
:variable:`CPACK_RESOURCE_FILE_README`, and
:variable:`CPACK_RESOURCE_FILE_LICENSE` files are copied.
+
+.. variable:: CPACK_PRODUCTBUILD_BACKGROUND
+
+ Adds a background to Distribtion XML if specified. The value contains the
+ path to image in ``Resources`` directory.
+
+.. variable:: CPACK_PRODUCTBUILD_BACKGROUND_ALIGNMENT
+
+ Adds an ``alignment`` attribute to the background in Distribution XML.
+ Refer to Apple documentation for valid values.
+
+.. variable:: CPACK_PRODUCTBUILD_BACKGROUND_SCALING
+
+ Adds a ``scaling`` attribute to the background in Distribution XML.
+ Refer to Apple documentation for valid values.
+
+.. variable:: CPACK_PRODUCTBUILD_BACKGROUND_MIME_TYPE
+
+ Adds a ``mime-type`` attribute to the background in Distribution XML.
+ The option contains MIME type of an image.
+
+.. variable:: CPACK_PRODUCTBUILD_BACKGROUND_UTI
+
+ Adds an ``uti`` attribute to the background in Distribution XML.
+ The option contains UTI type of an image.
+
+.. variable:: CPACK_PRODUCTBUILD_BACKGROUND_DARKAQUA
+
+ Adds a background for the Dark Aqua theme to Distribution XML if
+ specified. The value contains the path to image in ``Resources``
+ directory.
+
+.. variable:: CPACK_PRODUCTBUILD_BACKGROUND_DARKAQUA_ALIGNMENT
+
+ Does the same as :variable:`CPACK_PRODUCTBUILD_BACKGROUND_ALIGNMENT` option,
+ but for the dark theme.
+
+.. variable:: CPACK_PRODUCTBUILD_BACKGROUND_DARKAQUA_SCALING
+
+ Does the same as :variable:`CPACK_PRODUCTBUILD_BACKGROUND_SCALING` option,
+ but for the dark theme.
+
+.. variable:: CPACK_PRODUCTBUILD_BACKGROUND_DARKAQUA_MIME_TYPE
+
+ Does the same as :variable:`CPACK_PRODUCTBUILD_BACKGROUND_MIME_TYPE` option,
+ but for the dark theme.
+
+.. variable:: CPACK_PRODUCTBUILD_BACKGROUND_DARKAQUA_UTI
+
+ Does the same as :variable:`CPACK_PRODUCTBUILD_BACKGROUND_UTI` option,
+ but for the dark theme.
diff --git a/Help/cpack_gen/rpm.rst b/Help/cpack_gen/rpm.rst
index 2693c7b..66d5464 100644
--- a/Help/cpack_gen/rpm.rst
+++ b/Help/cpack_gen/rpm.rst
@@ -473,38 +473,42 @@ List of CPack RPM generator specific variables:
.. variable:: CPACK_RPM_PRE_INSTALL_SCRIPT_FILE
CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE
+ CPACK_RPM_PRE_TRANS_SCRIPT_FILE
- Path to file containing pre (un)install script.
+ Path to file containing pre install/uninstall/transaction script.
* Mandatory : NO
* Default : -
- May be used to embed a pre (un)installation script in the spec file.
+ May be used to embed a pre installation/uninstallation/transaction script in the spec file.
The referred script file (or both) will be read and directly
put after the ``%pre`` or ``%preun`` section
- If :variable:`CPACK_RPM_COMPONENT_INSTALL` is set to ON the (un)install
+ If :variable:`CPACK_RPM_COMPONENT_INSTALL` is set to ON the install/uninstall/transaction
script for each component can be overridden with
- ``CPACK_RPM_<COMPONENT>_PRE_INSTALL_SCRIPT_FILE`` and
- ``CPACK_RPM_<COMPONENT>_PRE_UNINSTALL_SCRIPT_FILE``.
+ ``CPACK_RPM_<COMPONENT>_PRE_INSTALL_SCRIPT_FILE``,
+ ``CPACK_RPM_<COMPONENT>_PRE_UNINSTALL_SCRIPT_FILE``, and
+ ``CPACK_RPM_<COMPONENT>_PRE_TRANS_SCRIPT_FILE``
One may verify which scriptlet has been included with::
rpm -qp --scripts package.rpm
.. variable:: CPACK_RPM_POST_INSTALL_SCRIPT_FILE
CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE
+ CPACK_RPM_POST_TRANS_SCRIPT_FILE
- Path to file containing post (un)install script.
+ Path to file containing post install/uninstall/transaction script.
* Mandatory : NO
* Default : -
- May be used to embed a post (un)installation script in the spec file.
+ May be used to embed a post installation/uninstallation/transaction script in the spec file.
The referred script file (or both) will be read and directly
put after the ``%post`` or ``%postun`` section.
- If :variable:`CPACK_RPM_COMPONENT_INSTALL` is set to ON the (un)install
+ If :variable:`CPACK_RPM_COMPONENT_INSTALL` is set to ON the install/uninstall/transaction
script for each component can be overridden with
- ``CPACK_RPM_<COMPONENT>_POST_INSTALL_SCRIPT_FILE`` and
- ``CPACK_RPM_<COMPONENT>_POST_UNINSTALL_SCRIPT_FILE``.
+ ``CPACK_RPM_<COMPONENT>_POST_INSTALL_SCRIPT_FILE``,
+ ``CPACK_RPM_<COMPONENT>_POST_UNINSTALL_SCRIPT_FILE``, and
+ ``CPACK_RPM_<COMPONENT>_POST_TRANS_SCRIPT_FILE``
One may verify which scriptlet has been included with::
rpm -qp --scripts package.rpm
diff --git a/Help/dev/maint.rst b/Help/dev/maint.rst
index 44e2273..a1c1a6f 100644
--- a/Help/dev/maint.rst
+++ b/Help/dev/maint.rst
@@ -14,6 +14,11 @@ Review a Merge Request
The `CMake Review Process`_ requires a maintainer to issue the ``Do: merge``
command to integrate a merge request. Please check at least the following:
+* If the MR source branch (or part of it) should be backported
+ to the ``release`` branch (and is already based on a commit
+ contained in the ``release`` branch), add a ``Backport: release`` or
+ ``Backport: release:<commit-ish>`` trailing line to the MR description.
+
* If the MR source branch is not named well for the change it makes
(e.g. it is just ``master`` or the patch changed during review),
add a ``Topic-rename: <topic>`` trailing line to the MR description
@@ -38,9 +43,10 @@ command to integrate a merge request. Please check at least the following:
of various nightly builders.)
* Ensure that the MR targets the ``master`` branch. A MR intended for
- the ``release`` branch should be based on ``release`` but still merged
- to ``master`` first (via ``Do: merge``). A maintainer may then merge
- the MR topic to ``release`` manually.
+ the ``release`` branch should be based on ``release`` but still target
+ ``master``. Use the above-mentioned ``Backport: release`` line to tell
+ ``Do: merge`` to merge to both. If a MR is merged without the backport
+ line, a maintainer may still merge the MR topic to ``release`` manually.
Maintain Current Release
========================
@@ -51,6 +57,12 @@ using a local branch named ``release-$ver``, where ``$ver`` is the version
number of the current release in the form ``$major.$minor``. It is always
merged into ``master`` before publishing.
+To merge an open MR to the ``release`` branch, edit its description to
+use the ``Backport: release`` line mentioned above and then ``Do: merge``
+normally. To update the ``release`` branch manually (e.g. to merge a
+``$topic`` branch that was merged without the backport line), use the
+following procedure.
+
Before merging a ``$topic`` branch into ``release``, verify that the
``$topic`` branch has already been merged to ``master`` via the usual
``Do: merge`` process. Then, to merge the ``$topic`` branch into
diff --git a/Help/dev/review.rst b/Help/dev/review.rst
index cbde6fe..8ec41d2 100644
--- a/Help/dev/review.rst
+++ b/Help/dev/review.rst
@@ -53,6 +53,10 @@ in GitLab to track the state of a MR:
to a period of inactivity. See the `Expire`_ step. Use this label
after closing a MR for this reason.
+* ``workflow:external-discussion`` indicates that the MR has been closed
+ pending discussion elsewhere. See the `External Discussion`_ step.
+ Use this label after closing a MR for this reason.
+
The workflow status labels are intended to be mutually exclusive,
so please remove any existing workflow label when adding one.
@@ -429,6 +433,21 @@ Additionally, ``Do: merge`` extracts configuration from trailing lines
in the MR description (the following have no effect if used in a MR
comment instead):
+* ``Backport: release[:<commit-ish>]``: merge the topic branch into
+ the ``release`` branch to backport the change. This is allowed
+ only if the topic branch is based on a commit in ``release`` already.
+ If only part of the topic branch should be backported, specify it as
+ ``:<commit-ish>``. The ``<commit-ish>`` may use `git rev-parse`_
+ syntax to reference commits relative to the topic ``HEAD``.
+ See additional `backport instructions`_ for details.
+ For example:
+
+ ``Backport: release``
+ Merge the topic branch head into both ``release`` and ``master``.
+ ``Backport: release:HEAD~1^2``
+ Merge the topic branch head's parent's second parent commit into
+ the ``release`` branch. Merge the topic branch head to ``master``.
+
* ``Topic-rename: <topic>``: substitute ``<topic>`` for the name of
the MR topic branch in the constructed merge commit message.
It is also used in merge commits constructed by ``Do: stage``.
@@ -436,6 +455,8 @@ comment instead):
rename set in the MR description.
.. _`CMake GitLab Project Masters`: https://gitlab.kitware.com/cmake/cmake/settings/members
+.. _`backport instructions`: https://gitlab.kitware.com/utils/git-workflow/wikis/Backport-topics
+.. _`git rev-parse`: https://git-scm.com/docs/git-rev-parse
Close
-----
diff --git a/Help/dev/source.rst b/Help/dev/source.rst
index 0f7488b..0ccb8f4 100644
--- a/Help/dev/source.rst
+++ b/Help/dev/source.rst
@@ -23,12 +23,157 @@ format only a subset of files, such as those that are locally modified.
C++ Subset Permitted
====================
-CMake requires compiling as C++11 or above. However, in order to support
-building on older toolchains some constructs need to be handled with care:
+CMake requires compiling as C++11 in order to support building on older
+toolchains. However, to facilitate development, some standard library
+features from more recent C++ standards are supported through a compatibility
+layer. These features are defined under the namespace ``cm`` and headers
+are accessible under the ``cm/`` directory. The headers under ``cm/`` can
+be used in place of the standard ones when extended features are needed.
+For example ``<cm/memory>`` can be used in place of ``<memory>``.
-* Do not use ``std::auto_ptr``.
+Available features are:
- The ``std::auto_ptr`` template is deprecated in C++11. Use ``std::unique_ptr``.
+* From ``C++14``:
+
+ * ``<cm/iterator>``:
+ ``cm::make_reverse_iterator``, ``cm::cbegin``, ``cm::cend``,
+ ``cm::rbegin``, ``cm::rend``, ``cm::crbegin``, ``cm::crend``
+
+ * ``<cm/memory>``:
+ ``cm::make_unique``
+
+ * ``<cm/shared_mutex>``:
+ ``cm::shared_lock``
+
+ * ``<cm/type_traits>``:
+ ``cm::enable_if_t``
+
+* From ``C++17``:
+
+ * ``<cm/algorithm>``:
+ ``cm::clamp``
+
+ * ``<cm/iterator>``:
+ ``cm::size``, ``cm::empty``, ``cm::data``
+
+ * ``<cm/optional>``:
+ ``cm::nullopt_t``, ``cm::nullopt``, ``cm::optional``,
+ ``cm::make_optional``, ``cm::bad_optional_access``
+
+ * ``<cm/shared_mutex>``:
+ ``cm::shared_mutex``
+
+ * ``<cm/string_view>``:
+ ``cm::string_view``
+
+ * ``<cm/type_traits>``:
+ ``cm::bool_constant``, ``cm::invoke_result_t``, ``cm::invoke_result``,
+ ``cm::void_t``
+
+ * ``<cm/utility>``:
+ ``cm::in_place_t``, ``cm::in_place``
+
+* From ``C++20``:
+
+ * ``<cm/deque>``:
+ ``cm::erase``, ``cm::erase_if``
+
+ * ``<cm/list>``:
+ ``cm::erase``, ``cm::erase_if``
+
+ * ``<cm/map>`` :
+ ``cm::erase_if``
+
+ * ``<cm/set>`` :
+ ``cm::erase_if``
+
+ * ``<cm/string>``:
+ ``cm::erase``, ``cm::erase_if``
+
+ * ``<cm/unordered_map>``:
+ ``cm::erase_if``
+
+ * ``<cm/unordered_set>``:
+ ``cm::erase_if``
+
+ * ``<cm/vector>``:
+ ``cm::erase``, ``cm::erase_if``
+
+Additionally, some useful non-standard extensions to the C++ standard library
+are available in headers under the directory ``cmext/`` in namespace ``cm``.
+These are:
+
+* ``<cmext/algorithm>``:
+
+ * ``cm::append``:
+ Append elements to a sequential container.
+
+ * ``cm::contains``:
+ Checks if element or key is contained in container.
+
+* ``<cmext/iterator>``:
+
+ * ``cm::is_terator``:
+ Checks if a type is an iterator type.
+
+ * ``cm::is_input_iterator``:
+ Checks if a type is an input iterator type.
+
+ * ``cm::is_range``:
+ Checks if a type is a range type: functions ``std::begin()`` and
+ ``std::end()`` apply.
+
+ * ``cm::is_input_range``:
+ Checks if a type is an input range type: functions ``std::begin()`` and
+ ``std::end()`` apply and return an input iterator.
+
+* ``<cmext/memory>``:
+
+ * ``cm::static_reference_cast``:
+ Apply a ``static_cast`` to a smart pointer.
+
+ * ``cm::dynamic_reference_cast``:
+ Apply a ``dynamic_cast`` to a smart pointer.
+
+* ``<cmext/type_traits>``:
+
+ * ``cm::is_container``:
+ Checks if a type is a container type.
+
+ * ``cm::is_associative_container``:
+ Checks if a type is an associative container type.
+
+ * ``cm::is_unordered_associative_container``:
+ Checks if a type is an unordered associative container type.
+
+ * ``cm::is_sequence_container``:
+ Checks if a type is a sequence container type.
+
+ * ``cm::is_unique_ptr``:
+ Checks if a type is a ``std::unique_ptr`` type.
+
+Dynamic Memory Management
+=========================
+
+To ensure efficient memory management, i.e. no memory leaks, it is required
+to use smart pointers. Any dynamic memory allocation must be handled by a
+smart pointer such as ``std::unique_ptr`` or ``std::shared_ptr``.
+
+It is allowed to pass raw pointers between objects to enable objects sharing.
+A raw pointer **must** not be deleted. Only the object(s) owning the smart
+pointer are allowed to delete dynamically allocated memory.
+
+Third Parties
+=============
+
+To build CMake, some third parties are needed. Under ``Utilities``
+directory, are versions of these third parties which can be used as an
+alternate to the ones provided by the system.
+
+To enable the selection of the third parties between the system and CMake ones,
+in CMake sources, third parties headers must be prefixed by ``cm3p/``
+(for example: ``<cm3p/json/reader.h>``). These wrappers are located under
+``Utilities/cm3p`` directory.
Source Tree Layout
==================
@@ -69,6 +214,15 @@ The CMake source tree is organized as follows.
* ``Utilities/``:
Scripts, third-party source code.
+ * ``Utilities/std/cm``:
+ Support files for various C++ standards.
+
+ * ``Utilities/std/cmext``:
+ Extensions to the C++ STL.
+
+ * ``Utilities/cm3p``:
+ Public headers for third parties needed to build CMake.
+
* ``Utilities/Sphinx/``:
Sphinx configuration to build CMake user documentation.
diff --git a/Help/envvar/CCMAKE_COLORS.rst b/Help/envvar/CCMAKE_COLORS.rst
new file mode 100644
index 0000000..d4750c3
--- /dev/null
+++ b/Help/envvar/CCMAKE_COLORS.rst
@@ -0,0 +1,34 @@
+CCMAKE_COLORS
+-------------
+
+Determines what colors are used by the CMake curses interface,
+when run on a terminal that supports colors.
+The syntax follows the same conventions as ``LS_COLORS``;
+that is, a list of key/value pairs separated by ``:``.
+
+Keys are a single letter corresponding to a CMake cache variable type:
+
+- ``s``: A ``STRING``.
+- ``p``: A ``FILEPATH``.
+- ``c``: A value which has an associated list of choices.
+- ``y``: A ``BOOL`` which has a true-like value (e.g. ``ON``, ``YES``).
+- ``n``: A ``BOOL`` which has a false-like value (e.g. ``OFF``, ``NO``).
+
+Values are an integer number that specifies what color to use.
+``0`` is black (you probably don't want to use that).
+Others are determined by your terminal's color support.
+Most (color) terminals will support at least 8 or 16 colors.
+Some will support up to 256 colors. The colors will likely match
+`this chart <https://upload.wikimedia.org/wikipedia/commons/1/15/Xterm_256color_chart.svg>`_,
+although the first 16 colors may match the original
+`CGA color palette <https://en.wikipedia.org/wiki/Color_Graphics_Adapter#Color_palette>`_.
+(Many modern terminal emulators also allow their color palette,
+at least for the first 16 colors, to be configured by the user.)
+
+Note that fairly minimal checking is done for bad colors
+(although a value higher than what curses believes your terminal supports
+will be silently ignored) or bad syntax.
+
+For example::
+
+ CCMAKE_COLORS='s=39:p=220:c=207:n=196:y=46'
diff --git a/Help/envvar/CMAKE_EXPORT_COMPILE_COMMANDS.rst b/Help/envvar/CMAKE_EXPORT_COMPILE_COMMANDS.rst
new file mode 100644
index 0000000..e9e0810
--- /dev/null
+++ b/Help/envvar/CMAKE_EXPORT_COMPILE_COMMANDS.rst
@@ -0,0 +1,9 @@
+CMAKE_EXPORT_COMPILE_COMMANDS
+-----------------------------
+
+.. include:: ENV_VAR.txt
+
+The default value for :variable:`CMAKE_EXPORT_COMPILE_COMMANDS` when there
+is no explicit configuration given on the first run while creating a new
+build tree. On later runs in an existing build tree the value persists in
+the cache as :variable:`CMAKE_EXPORT_COMPILE_COMMANDS`.
diff --git a/Help/envvar/CMAKE_LANG_COMPILER_LAUNCHER.rst b/Help/envvar/CMAKE_LANG_COMPILER_LAUNCHER.rst
new file mode 100644
index 0000000..4f91e9a
--- /dev/null
+++ b/Help/envvar/CMAKE_LANG_COMPILER_LAUNCHER.rst
@@ -0,0 +1,10 @@
+CMAKE_<LANG>_COMPILER_LAUNCHER
+------------------------------
+
+.. include:: ENV_VAR.txt
+
+Default compiler launcher to use for the specified language. Will only be used
+by CMake to initialize the variable on the first configuration. Afterwards, it
+is available through the cache setting of the variable of the same name. For
+any configuration run (including the first), the environment variable will be
+ignored if the :variable:`CMAKE_<LANG>_COMPILER_LAUNCHER` variable is defined.
diff --git a/Help/envvar/CMAKE_PREFIX_PATH.rst b/Help/envvar/CMAKE_PREFIX_PATH.rst
new file mode 100644
index 0000000..276fdd6
--- /dev/null
+++ b/Help/envvar/CMAKE_PREFIX_PATH.rst
@@ -0,0 +1,17 @@
+CMAKE_PREFIX_PATH
+-----------------
+
+.. include:: ENV_VAR.txt
+
+The ``CMAKE_PREFIX_PATH`` environment variable may be set to a list of
+directories specifying installation *prefixes* to be searched by the
+:command:`find_package`, :command:`find_program`, :command:`find_library`,
+:command:`find_file`, and :command:`find_path` commands. Each command will
+add appropriate subdirectories (like ``bin``, ``lib``, or ``include``)
+as specified in its own documentation.
+
+This variable may hold a single prefix or a list of prefixes separated
+by ``:`` on UNIX or ``;`` on Windows (the same as the ``PATH`` environment
+variable convention on those platforms).
+
+See also the :variable:`CMAKE_PREFIX_PATH` CMake variable.
diff --git a/Help/generator/Ninja Multi-Config.rst b/Help/generator/Ninja Multi-Config.rst
new file mode 100644
index 0000000..f480eb8
--- /dev/null
+++ b/Help/generator/Ninja Multi-Config.rst
@@ -0,0 +1,87 @@
+Ninja Multi-Config
+------------------
+
+Generates multiple ``build-<Config>.ninja`` files.
+
+This generator is very much like the :generator:`Ninja` generator, but with
+some key differences. Only these differences will be discussed in this
+document.
+
+Unlike the :generator:`Ninja` generator, ``Ninja Multi-Config`` generates
+multiple configurations at once with :variable:`CMAKE_CONFIGURATION_TYPES`
+instead of only one configuration with :variable:`CMAKE_BUILD_TYPE`. One
+``build-<Config>.ninja`` file will be generated for each of these
+configurations (with ``<Config>`` being the configuration name.) These files
+are intended to be run with ``ninja -f build-<Config>.ninja``. A
+``build.ninja`` file is also generated, using the configuration from either
+:variable:`CMAKE_DEFAULT_BUILD_TYPE` or the first item from
+:variable:`CMAKE_CONFIGURATION_TYPES`.
+
+``cmake --build . --config <Config>`` will always use ``build-<Config>.ninja``
+to build. If no ``--config`` argument is specified, ``cmake --build .`` will
+default to ``build-Debug.ninja``, unless a ``build.ninja`` is generated (see
+below), in which case that will be used instead.
+
+Each ``build-<Config>.ninja`` file contains ``<target>`` targets as well as
+``<target>:<Config>`` targets, where ``<Config>`` is the same as the
+configuration specified in ``build-<Config>.ninja`` Additionally, if
+cross-config mode is enabled, ``build-<Config>.ninja`` may contain
+``<target>:<OtherConfig>`` targets, where ``<OtherConfig>`` is a cross-config,
+as well as ``<target>:all``, which builds the target in all cross-configs. See
+below for how to enable cross-config mode.
+
+The ``Ninja Multi-Config`` generator recognizes the following variables:
+
+:variable:`CMAKE_CONFIGURATION_TYPES`
+ Specifies the total set of configurations to build.
+
+:variable:`CMAKE_CROSS_CONFIGS`
+ Specifies a :ref:`semicolon-separated list <CMake Language Lists>` of
+ configurations available from all ``build-<Config>.ninja`` files.
+
+:variable:`CMAKE_DEFAULT_BUILD_TYPE`
+ Specifies the configuration to use by default in a ``build.ninja`` file.
+
+:variable:`CMAKE_DEFAULT_CONFIGS`
+ Specifies a :ref:`semicolon-separated list <CMake Language Lists>` of
+ configurations to build for a target in ``build.ninja``
+ if no ``:<Config>`` suffix is specified.
+
+Consider the following example:
+
+.. code-block:: cmake
+
+ cmake_minimum_required(VERSION 3.16)
+ project(MultiConfigNinja C)
+
+ add_executable(generator generator.c)
+ add_custom_command(OUTPUT generated.c COMMAND generator generated.c)
+ add_library(generated ${CMAKE_BINARY_DIR}/generated.c)
+
+Now assume you configure the project with ``Ninja Multi-Config`` and run one of
+the following commands:
+
+.. code-block:: shell
+
+ ninja -f build-Debug.ninja generated
+ # OR
+ cmake --build . --config Debug --target generated
+
+This would build the ``Debug`` configuration of ``generator``, which would be
+used to generate ``generated.c``, which would be used to build the ``Debug``
+configuration of ``generated``.
+
+But if :variable:`CMAKE_CROSS_CONFIGS` is set to ``all``, and you run the
+following instead:
+
+.. code-block:: shell
+
+ ninja -f build-Release.ninja generated:Debug
+ # OR
+ cmake --build . --config Release --target generated:Debug
+
+This would build the ``Release`` configuration of ``generator``, which would be
+used to generate ``generated.c``, which would be used to build the ``Debug``
+configuration of ``generated``. This is useful for running a release-optimized
+version of a generator utility while still building the debug version of the
+targets built with the generated code.
diff --git a/Help/generator/Ninja.rst b/Help/generator/Ninja.rst
index c75d2c4..08ee81b 100644
--- a/Help/generator/Ninja.rst
+++ b/Help/generator/Ninja.rst
@@ -1,7 +1,7 @@
Ninja
-----
-Generates build.ninja files.
+Generates ``build.ninja`` files.
A ``build.ninja`` file is generated into the build tree. Use the ninja
program to build the project through the ``all`` target and install the
@@ -33,8 +33,10 @@ Fortran Support
^^^^^^^^^^^^^^^
The ``Ninja`` generator conditionally supports Fortran when the ``ninja``
-tool has the required features. As of this version of CMake the needed
-features have not been integrated into upstream Ninja. Kitware maintains
-a branch of Ninja with the required features on `github.com/Kitware/ninja`_.
+tool is at least version 1.10 (which has the required features).
-.. _`github.com/Kitware/ninja`: https://github.com/Kitware/ninja/tree/features-for-fortran#readme
+See Also
+^^^^^^^^
+
+The :generator:`Ninja Multi-Config` generator is similar to the ``Ninja``
+generator, but generates multiple configurations at once.
diff --git a/Help/guide/tutorial/Complete/CMakeLists.txt b/Help/guide/tutorial/Complete/CMakeLists.txt
index eca79d9..4d8a3ad 100644
--- a/Help/guide/tutorial/Complete/CMakeLists.txt
+++ b/Help/guide/tutorial/Complete/CMakeLists.txt
@@ -3,6 +3,8 @@ cmake_minimum_required(VERSION 3.15)
# set the project name and version
project(Tutorial VERSION 1.0)
+set(CMAKE_DEBUG_POSTFIX d)
+
add_library(tutorial_compiler_flags INTERFACE)
target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
@@ -37,6 +39,8 @@ add_subdirectory(MathFunctions)
# add the executable
add_executable(Tutorial tutorial.cxx)
+set_target_properties(Tutorial PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
+
target_link_libraries(Tutorial PUBLIC MathFunctions)
# add the binary tree to the search path for include files
diff --git a/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt
index dfa84c9..c911625 100644
--- a/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt
@@ -17,7 +17,7 @@ if(USE_MYMATH)
# first we add the executable that generates the table
add_executable(MakeTable MakeTable.cxx)
- target_link_libraries(MakeTable tutorial_compiler_flags)
+ target_link_libraries(MakeTable PRIVATE tutorial_compiler_flags)
# add the command to generate the source code
add_custom_command(
diff --git a/Help/guide/tutorial/MultiPackage/MultiCPackConfig.cmake b/Help/guide/tutorial/Complete/MultiCPackConfig.cmake
index 403b633..c2583df 100644
--- a/Help/guide/tutorial/MultiPackage/MultiCPackConfig.cmake
+++ b/Help/guide/tutorial/Complete/MultiCPackConfig.cmake
@@ -1,4 +1,3 @@
-
include("release/CPackConfig.cmake")
set(CPACK_INSTALL_CMAKE_PROJECTS
diff --git a/Help/guide/tutorial/Complete/tutorial.cxx b/Help/guide/tutorial/Complete/tutorial.cxx
index 586d183..a4f44d5 100644
--- a/Help/guide/tutorial/Complete/tutorial.cxx
+++ b/Help/guide/tutorial/Complete/tutorial.cxx
@@ -1,6 +1,5 @@
// A simple program that computes the square root of a number
#include <iostream>
-#include <sstream>
#include <string>
#include "MathFunctions.h"
@@ -9,6 +8,7 @@
int main(int argc, char* argv[])
{
if (argc < 2) {
+ // report version
std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
<< Tutorial_VERSION_MINOR << std::endl;
std::cout << "Usage: " << argv[0] << " number" << std::endl;
@@ -18,8 +18,8 @@ int main(int argc, char* argv[])
// convert input to double
const double inputValue = std::stod(argv[1]);
- // calculate square root
const double outputValue = mathfunctions::sqrt(inputValue);
+
std::cout << "The square root of " << inputValue << " is " << outputValue
<< std::endl;
return 0;
diff --git a/Help/guide/tutorial/Consumer/CMakeLists.txt b/Help/guide/tutorial/Consumer/CMakeLists.txt
deleted file mode 100644
index a0e4598..0000000
--- a/Help/guide/tutorial/Consumer/CMakeLists.txt
+++ /dev/null
@@ -1,51 +0,0 @@
-cmake_minimum_required(VERSION 3.10)
-
-if(NOT DEFINED CMAKE_CXX_STANDARD)
- set(CMAKE_CXX_STANDARD 11)
- set(CMAKE_CXX_STANDARD_REQUIRED True)
-endif()
-
-
-function(find_external_dependency name)
- set(${name}_ROOT "" CACHE PATH "Root directory to find ${name}")
- mark_as_advanced(${name}_DIR)
- find_package(${name} PATHS ${${name}_ROOT} REQUIRED)
-endfunction()
-
-
-project(Consumer)
-
-find_external_dependency(MathFunctions)
-
-add_library(consumer consumer.cxx)
-target_link_libraries(consumer PUBLIC MathFunctions)
-
-# install the consumer library
-install(TARGETS consumer DESTINATION bin EXPORT ConsumerTargets)
-
-# install the configuration targets
-install(EXPORT ConsumerTargets
- FILE ConsumerTargets.cmake
- DESTINATION lib/cmake/Consumer
-)
-
-include(CMakePackageConfigHelpers)
-# generate the config file that is includes the exports
-configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in
- "${CMAKE_CURRENT_BINARY_DIR}/ConsumerConfig.cmake"
- INSTALL_DESTINATION "lib/cmake/example"
- NO_SET_AND_CHECK_MACRO
- NO_CHECK_REQUIRED_COMPONENTS_MACRO
- )
-
-# install the configuration file
-install(FILES
- ${CMAKE_CURRENT_BINARY_DIR}/ConsumerConfig.cmake
- DESTINATION lib/cmake/Consumer
- )
-
-# generate the export targets for the build tree
-# needs to be after the install(TARGETS ) command
-export(EXPORT ConsumerTargets
- FILE "${CMAKE_CURRENT_BINARY_DIR}/ConsumerTargets.cmake"
-)
diff --git a/Help/guide/tutorial/Consumer/Config.cmake.in b/Help/guide/tutorial/Consumer/Config.cmake.in
deleted file mode 100644
index 0b3f1e4..0000000
--- a/Help/guide/tutorial/Consumer/Config.cmake.in
+++ /dev/null
@@ -1,14 +0,0 @@
-
-@PACKAGE_INIT@
-
-include(CMakeFindDependencyMacro)
-
-function(find_external_dependency name)
- set(${name}_ROOT "" CACHE PATH "Root directory to find ${name}")
- mark_as_advanced(${name}_DIR)
- find_dependency(${name} PATHS ${${name}_ROOT} REQUIRED)
-endfunction()
-
-find_external_dependency(MathFunctions)
-
-include ( "${CMAKE_CURRENT_LIST_DIR}/ConsumerTargets.cmake" )
diff --git a/Help/guide/tutorial/Consumer/consumer.cxx b/Help/guide/tutorial/Consumer/consumer.cxx
deleted file mode 100644
index ae7877b..0000000
--- a/Help/guide/tutorial/Consumer/consumer.cxx
+++ /dev/null
@@ -1,11 +0,0 @@
-// A simple function that computes the square root of a number
-#include <iostream>
-#include <sstream>
-#include <string>
-
-#include "MathFunctions.h"
-
-double string_square_root(std::string const& value)
-{
- return mathfunctions::sqrt(std::stod(value));
-}
diff --git a/Help/guide/tutorial/MultiPackage/MathFunctions/MakeTable.cxx b/Help/guide/tutorial/MultiPackage/MathFunctions/MakeTable.cxx
deleted file mode 100644
index ee58556..0000000
--- a/Help/guide/tutorial/MultiPackage/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/Step11/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt
index e6cb8ba..32f5e08 100644
--- a/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt
@@ -15,7 +15,7 @@ if(USE_MYMATH)
# first we add the executable that generates the table
add_executable(MakeTable MakeTable.cxx)
- target_link_libraries(MakeTable tutorial_compiler_flags)
+ target_link_libraries(MakeTable PRIVATE tutorial_compiler_flags)
# add the command to generate the source code
add_custom_command(
diff --git a/Help/guide/tutorial/MultiPackage/CMakeLists.txt b/Help/guide/tutorial/Step12/CMakeLists.txt
index 01d417a..eca79d9 100644
--- a/Help/guide/tutorial/MultiPackage/CMakeLists.txt
+++ b/Help/guide/tutorial/Step12/CMakeLists.txt
@@ -1,11 +1,19 @@
-cmake_minimum_required(VERSION 3.10)
+cmake_minimum_required(VERSION 3.15)
# set the project name and version
project(Tutorial VERSION 1.0)
-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>")
+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>>"
+)
# 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
diff --git a/Help/guide/tutorial/Step12/CTestConfig.cmake b/Help/guide/tutorial/Step12/CTestConfig.cmake
new file mode 100644
index 0000000..73efdb1
--- /dev/null
+++ b/Help/guide/tutorial/Step12/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/MultiPackage/Config.cmake.in b/Help/guide/tutorial/Step12/Config.cmake.in
index 17cbabd..17cbabd 100644
--- a/Help/guide/tutorial/MultiPackage/Config.cmake.in
+++ b/Help/guide/tutorial/Step12/Config.cmake.in
diff --git a/Help/guide/tutorial/MultiPackage/License.txt b/Help/guide/tutorial/Step12/License.txt
index c62d00b..c62d00b 100644
--- a/Help/guide/tutorial/MultiPackage/License.txt
+++ b/Help/guide/tutorial/Step12/License.txt
diff --git a/Help/guide/tutorial/MultiPackage/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step12/MathFunctions/CMakeLists.txt
index a2df2a7..720ee64 100644
--- a/Help/guide/tutorial/MultiPackage/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step12/MathFunctions/CMakeLists.txt
@@ -17,6 +17,7 @@ if(USE_MYMATH)
# first we add the executable that generates the table
add_executable(MakeTable MakeTable.cxx)
+ target_link_libraries(MakeTable PRIVATE tutorial_compiler_flags)
# add the command to generate the source code
add_custom_command(
@@ -41,19 +42,18 @@ if(USE_MYMATH)
POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}
)
+ target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
endif()
+target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
+
# define the symbol stating we are using the declspec(dllexport) when
# building on windows
target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH")
-# setup the version numbering
-set_property(TARGET MathFunctions PROPERTY VERSION "1.0.0")
-set_property(TARGET MathFunctions PROPERTY SOVERSION "1")
-
# install rules
-install(TARGETS MathFunctions
+install(TARGETS MathFunctions tutorial_compiler_flags
DESTINATION lib
EXPORT MathFunctionsTargets)
install(FILES MathFunctions.h DESTINATION include)
diff --git a/Help/guide/tutorial/Step5/MathFunctions/MakeTable.cxx b/Help/guide/tutorial/Step12/MathFunctions/MakeTable.cxx
index ee58556..ee58556 100644
--- a/Help/guide/tutorial/Step5/MathFunctions/MakeTable.cxx
+++ b/Help/guide/tutorial/Step12/MathFunctions/MakeTable.cxx
diff --git a/Help/guide/tutorial/MultiPackage/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step12/MathFunctions/MathFunctions.cxx
index 0145300..0145300 100644
--- a/Help/guide/tutorial/MultiPackage/MathFunctions/MathFunctions.cxx
+++ b/Help/guide/tutorial/Step12/MathFunctions/MathFunctions.cxx
diff --git a/Help/guide/tutorial/MultiPackage/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step12/MathFunctions/MathFunctions.h
index 3fb547b..3fb547b 100644
--- a/Help/guide/tutorial/MultiPackage/MathFunctions/MathFunctions.h
+++ b/Help/guide/tutorial/Step12/MathFunctions/MathFunctions.h
diff --git a/Help/guide/tutorial/MultiPackage/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step12/MathFunctions/mysqrt.cxx
index 5e622be..8153f18 100644
--- a/Help/guide/tutorial/MultiPackage/MathFunctions/mysqrt.cxx
+++ b/Help/guide/tutorial/Step12/MathFunctions/mysqrt.cxx
@@ -17,11 +17,10 @@ double mysqrt(double x)
// 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)];
}
- // if we have both log and exp then use them
-
// do ten iterations
for (int i = 0; i < 10; ++i) {
if (result <= 0) {
diff --git a/Help/guide/tutorial/MultiPackage/MathFunctions/mysqrt.h b/Help/guide/tutorial/Step12/MathFunctions/mysqrt.h
index e1c42ef..e1c42ef 100644
--- a/Help/guide/tutorial/MultiPackage/MathFunctions/mysqrt.h
+++ b/Help/guide/tutorial/Step12/MathFunctions/mysqrt.h
diff --git a/Help/guide/tutorial/MultiPackage/TutorialConfig.h.in b/Help/guide/tutorial/Step12/TutorialConfig.h.in
index 8cd2fc9..7e4d7fa 100644
--- a/Help/guide/tutorial/MultiPackage/TutorialConfig.h.in
+++ b/Help/guide/tutorial/Step12/TutorialConfig.h.in
@@ -1,3 +1,3 @@
-// the configured version number
+// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
diff --git a/Help/guide/tutorial/MultiPackage/tutorial.cxx b/Help/guide/tutorial/Step12/tutorial.cxx
index f97805b..a4f44d5 100644
--- a/Help/guide/tutorial/MultiPackage/tutorial.cxx
+++ b/Help/guide/tutorial/Step12/tutorial.cxx
@@ -8,6 +8,7 @@
int main(int argc, char* argv[])
{
if (argc < 2) {
+ // report version
std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
<< Tutorial_VERSION_MINOR << std::endl;
std::cout << "Usage: " << argv[0] << " number" << std::endl;
@@ -15,7 +16,7 @@ int main(int argc, char* argv[])
}
// convert input to double
- double inputValue = std::stod(argv[1]);
+ const double inputValue = std::stod(argv[1]);
const double outputValue = mathfunctions::sqrt(inputValue);
diff --git a/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt
index 4bf6024..f64c6ac 100644
--- a/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt
@@ -8,10 +8,20 @@ target_include_directories(MathFunctions
# does this system provide the log and exp functions?
include(CheckSymbolExists)
-set(CMAKE_REQUIRED_LIBRARIES "m")
check_symbol_exists(log "math.h" HAVE_LOG)
check_symbol_exists(exp "math.h" HAVE_EXP)
+if(NOT (HAVE_LOG AND HAVE_EXP))
+ unset(HAVE_LOG CACHE)
+ unset(HAVE_EXP CACHE)
+ set(CMAKE_REQUIRED_LIBRARIES "m")
+ check_symbol_exists(log "math.h" HAVE_LOG)
+ check_symbol_exists(exp "math.h" HAVE_EXP)
+ if(HAVE_LOG AND HAVE_EXP)
+ target_link_libraries(MathFunctions PRIVATE m)
+ endif()
+endif()
+# add compile definitions
if(HAVE_LOG AND HAVE_EXP)
target_compile_definitions(MathFunctions
PRIVATE "HAVE_LOG" "HAVE_EXP")
diff --git a/Help/guide/tutorial/index.rst b/Help/guide/tutorial/index.rst
index d74d160..6e26de9 100644
--- a/Help/guide/tutorial/index.rst
+++ b/Help/guide/tutorial/index.rst
@@ -45,7 +45,8 @@ 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.
-First, modify the ``CMakeLists.txt`` file to set the version number.
+First, modify the ``CMakeLists.txt`` file to use the :command:`project` command
+to set the project name and version number.
.. literalinclude:: Step2/CMakeLists.txt
:language: cmake
@@ -102,9 +103,10 @@ Next let's add some C++11 features to our project by replacing ``atof`` with
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 ``CMAKE_CXX_STANDARD`` variable. For this tutorial,
-set the ``CMAKE_CXX_STANDARD`` variable in the ``CMakeLists.txt`` file to 11
-and ``CMAKE_CXX_STANDARD_REQUIRED`` to True:
+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:
.. literalinclude:: Step2/CMakeLists.txt
:language: cmake
@@ -113,7 +115,8 @@ and ``CMAKE_CXX_STANDARD_REQUIRED`` to True:
Build and Test
--------------
-Run **cmake** or **cmake-gui** to configure the project and then build it
+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.
For example, from the command line we could navigate to the
@@ -156,11 +159,11 @@ directory:
.. literalinclude:: Step3/MathFunctions/CMakeLists.txt
:language: cmake
-To make use of the new library we will add an ``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 ``mqsqrt.h`` header file can be found. The last few lines
-of the top-level ``CMakeLists.txt`` file should now look like:
+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 ``mqsqrt.h`` header file can be found. The
+last few lines of the top-level ``CMakeLists.txt`` file should now look like:
.. code-block:: cmake
@@ -180,7 +183,7 @@ of the top-level ``CMakeLists.txt`` file should now look like:
)
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
+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.
@@ -189,10 +192,11 @@ occurrence. The first step is to add an option to the top-level
:start-after: # should we use our own math functions
:end-before: # add the MathFunctions library
-This option will be displayed in the CMake GUI and ccmake 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.
+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 change the end of the top-level ``CMakeLists.txt``
@@ -234,11 +238,13 @@ Since the source code now requires ``USE_MYMATH`` we can add it to
**Exercise**: 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 **cmake** or **cmake-gui** to configure the project and then build it
+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.
-Use ccmake or the CMake GUI to update the value of ``USE_MYMATH``. Rebuild and
-run the tutorial again. Which function gives better results, sqrt or mysqrt?
+Use the :manual:`ccmake <ccmake(1)>` executable or the :manual:`cmake-gui <cmake-gui(1)>`
+to update the value of ``USE_MYMATH``. Rebuild and run the tutorial again.
+Which function gives better results, sqrt or mysqrt?
Adding Usage Requirements for Library (Step 3)
==============================================
@@ -248,19 +254,20 @@ 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:
- - ``target_compile_definitions``
- - ``target_compile_options``
- - ``target_include_directories``
- - ``target_link_libraries``
+ - :command:`target_compile_definitions`
+ - :command:`target_compile_options`
+ - :command:`target_include_directories`
+ - :command:`target_link_libraries`
Let's refactor our code from `Adding a Library (Step 2)`_ 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
+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``:
+doesn't. Add the following lines to the end of
+``MathFunctions/CMakeLists.txt``:
.. literalinclude:: Step4/MathFunctions/CMakeLists.txt
:language: cmake
@@ -281,9 +288,10 @@ And here:
:language: cmake
:start-after: # so that we will find TutorialConfig.h
-Once this is done, run **cmake** or **cmake-gui** to configure the project
-and then build it with your chosen build tool or by using ``cmake --build .``
-from the build directory.
+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.
Installing and Testing (Step 4)
===============================
@@ -312,16 +320,17 @@ And to the end of the top-level ``CMakeLists.txt`` we add:
That is all that is needed to create a basic local install of the tutorial.
-Run **cmake** or **cmake-gui** to configure the project and then build it
-with your chosen build tool. Run the install step by typing
-``cmake --install .`` (introduced in 3.15, older versions of CMake must use
-``make install``) from the command line, or build the ``INSTALL`` target from
-an IDE. This will install the appropriate header files, libraries, and
-executables.
-
-The CMake variable ``CMAKE_INSTALL_PREFIX`` is used to determine the root of
-where the files will be installed. If using ``cmake --install`` a custom
-installation directory can be given via ``--prefix`` argument. For
+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. Run the install step by using the ``install``
+option of the :manual:`cmake <cmake(1)>` command (introduced in 3.15, older
+versions of CMake must use ``make install``) from the command line, or build
+the ``INSTALL`` target from an IDE. This will install the appropriate header
+files, libraries, and executables.
+
+The CMake variable :variable:`CMAKE_INSTALL_PREFIX` is used to determine the
+root of where the files will be installed. If using ``cmake --install`` a
+custom installation directory can be given via the ``--prefix`` argument. For
multi-configuration tools, use the ``--config`` argument to specify the
configuration.
@@ -339,25 +348,25 @@ the application is working correctly.
:start-after: # enable testing
The first test simply verifies that the application runs, does not segfault or
-otherwise crash, and has a zero return value. This is the basic form of a CTest
-test.
+otherwise crash, and has a zero return value. This is the basic form of a
+CTest test.
-The next test makes use of the ``PASS_REGULAR_EXPRESSION`` test property to
-verify that the output of the test contains certain strings. In this case,
-verifying that the usage message is printed when an incorrect number of
-arguments are provided.
+The next test makes use of the :prop_test:`PASS_REGULAR_EXPRESSION` test
+property to verify that the output of the test contains certain strings. In
+this case, verifying that the usage message is printed when an incorrect number
+of arguments are provided.
Lastly, we have a function called ``do_test`` that runs the application and
verifies that the computed square root is correct for given input. For each
invocation of ``do_test``, another test is added to the project with a name,
input, and expected results based on the passed arguments.
-Rebuild the application and then cd to the binary directory and run
-``ctest -N`` and ``ctest -VV``. For multi-config generators (e.g. Visual
-Studio), the configuration type must be specified. To run tests in Debug mode,
-for example, use ``ctest -C Debug -VV`` from the build directory (not the
-Debug subdirectory!). Alternatively, build the ``RUN_TESTS`` target from the
-IDE.
+Rebuild the application and then cd to the binary directory and run the
+:manual:`ctest <ctest(1)>` executable: ``ctest -N`` and ``ctest -VV``. For
+multi-config generators (e.g. Visual Studio), the configuration type must be
+specified. To run tests in Debug mode, for example, use ``ctest -C Debug -VV``
+from the build directory (not the Debug subdirectory!). Alternatively, build
+the ``RUN_TESTS`` target from the IDE.
Adding System Introspection (Step 5)
====================================
@@ -370,14 +379,18 @@ tutorial assume that they are not common.
If the platform has ``log`` and ``exp`` then we will use them to compute the
square root in the ``mysqrt`` function. We first test for the availability of
-these functions using the ``CheckSymbolExists`` module in the top-level
-``CMakeLists.txt``. We're going to use the new defines in
-``TutorialConfig.h.in``, so be sure to set them before that file is configured.
+these functions using the :module:`CheckSymbolExists` module in the top-level
+``CMakeLists.txt``. On some platforms, we will need to link to the m library.
+If ``log`` and ``exp`` are not initially found, require the m library and try
+again.
+
+We're going to use the new defines in ``TutorialConfig.h.in``, so be sure to
+set them before that file is configured.
.. literalinclude:: Step6/MathFunctions/CMakeLists.txt
:language: cmake
:start-after: # does this system provide the log and exp functions?
- :end-before: if(HAVE_LOG AND HAVE_EXP)
+ :end-before: # add compile definitions
Now let's add these defines to ``TutorialConfig.h.in`` so that we can use them
from ``mysqrt.cxx``:
@@ -388,22 +401,29 @@ from ``mysqrt.cxx``:
#cmakedefine HAVE_LOG
#cmakedefine HAVE_EXP
-Modify ``mysqrt.cxx`` to include cmath. Next, in that same file in the
-``mysqrt`` function we can provide an alternate implementation based on
-``log`` and ``exp`` if they are available on the system using the following
-code (don't forget the ``#endif`` before returning the result!):
+If ``log`` and ``exp`` are available on the system, then we will use them to
+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
:language: c++
:start-after: // if we have both log and exp then use them
:end-before: // do ten iterations
-Run **cmake** or **cmake-gui** to configure the project and then build it
+We will also need to modify ``mysqrt.cxx`` to include ``cmath``.
+
+.. literalinclude:: Step6/MathFunctions/mysqrt.cxx
+ :language: c++
+ :end-before: #include <iostream>
+
+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 and run the Tutorial executable.
You will notice that we're not using ``log`` and ``exp``, even if we think they
-should be available. We should realize quickly that we have forgotten to include
-``TutorialConfig.h`` in ``mysqrt.cxx``.
+should be available. We should realize quickly that we have forgotten to
+include ``TutorialConfig.h`` in ``mysqrt.cxx``.
We will also need to update ``MathFunctions/CMakeLists.txt`` so ``mysqrt.cxx``
knows where this file is located:
@@ -415,10 +435,10 @@ knows where this file is located:
PRIVATE ${CMAKE_BINARY_DIR}
)
-After making this update, go ahead and build the project again and run the built
-Tutorial executable. If ``log`` and ``exp`` are still not being used, open the
-generated ``TutorialConfig.h`` file from the build directory. Maybe they aren't
-available on the current system?
+After making this update, go ahead and build the project again and run the
+built Tutorial executable. If ``log`` and ``exp`` are still not being used,
+open the generated ``TutorialConfig.h`` file from the build directory. Maybe
+they aren't available on the current system?
Which function gives better results now, sqrt or mysqrt?
@@ -427,7 +447,7 @@ Specify Compile Definition
Is there a better place for us to save the ``HAVE_LOG`` and ``HAVE_EXP`` values
other than in ``TutorialConfig.h``? Let's try to use
-``target_compile_definitions``.
+:command:`target_compile_definitions`.
First, remove the defines from ``TutorialConfig.h.in``. We no longer need to
include ``TutorialConfig.h`` from ``mysqrt.cxx`` or the extra include in
@@ -460,8 +480,8 @@ First, let's remove the check for the ``log`` and ``exp`` functions in
``HAVE_EXP`` from ``mysqrt.cxx``. At the same time, we can remove
:code:`#include <cmath>`.
-In the ``MathFunctions`` subdirectory, a new source file named ``MakeTable.cxx``
-has been provided to generate the table.
+In the ``MathFunctions`` subdirectory, a new source file named
+``MakeTable.cxx`` has been provided to generate the table.
After reviewing the file, we can see that the table is produced as valid C++
code and that the output filename is passed in as an argument.
@@ -510,7 +530,8 @@ Now let's use the generated table. First, modify ``mysqrt.cxx`` to include
:language: c++
:start-after: // a hack square root calculation using simple operations
-Run **cmake** or **cmake-gui** to configure the project and then build it
+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.
When this project is built it will first build the ``MakeTable`` executable.
@@ -530,26 +551,28 @@ previously in `Installing and Testing (Step 4)`_ , where we were
installing the binaries that we had built from the source code. In this
example we will be building installation packages that support binary
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.
+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
:language: cmake
:start-after: # setup installer
That is all there is to it. We start by including
-``InstallRequiredSystemLibraries``. This module will include any runtime
-libraries that are needed by the project for the current platform. Next we
-set some CPack variables to where we have stored the license and version
+:module:`InstallRequiredSystemLibraries`. This module will include any runtime
+libraries that are needed by the project for the current platform. Next we set
+some CPack variables to where we have stored the license and version
information for this project. The version information was set earlier in this
tutorial and the ``license.txt`` has been included in the top-level source
directory for this step.
-Finally we include the CPack module which will use these variables and some
-other properties of the current system to setup an installer.
+Finally we include the :module:`CPack module <CPack>` which will use these
+variables and some other properties of the current system to setup an
+installer.
-The next step is to build the project in the usual manner and then run
-CPack on it. To build a binary distribution, from the binary directory run:
+The next step is to build the project in the usual manner and then run the
+:manual:`cpack <cpack(1)>` executable. To build a binary distribution, from the
+binary directory run:
.. code-block:: console
@@ -571,16 +594,17 @@ To create a source distribution you would type:
Alternatively, run ``make package`` or right click the ``Package`` target and
``Build Project`` from an IDE.
-Run the installer found in the binary directory. Then run the
-installed executable and verify that it works.
+Run the installer found in the binary directory. Then run the installed
+executable and verify that it works.
Adding Support for a Dashboard (Step 8)
=======================================
-Adding support for submitting our test results to a dashboard is very easy. We
+Adding support for submitting our test results to a dashboard is simple. We
already defined a number of tests for our project in `Testing Support`_. Now we
just have to run those tests and submit them to a dashboard. To include support
-for dashboards we include the CTest module in our top-level ``CMakeLists.txt``.
+for dashboards we include the :module:`CTest` module in our top-level
+``CMakeLists.txt``.
Replace:
@@ -596,8 +620,8 @@ With:
# enable dashboard scripting
include(CTest)
-The CTest module will automatically call ``enable_testing()``, so
-we can remove it from our CMake files.
+The :module:`CTest` module will automatically call ``enable_testing()``, so we
+can remove it from our CMake files.
We will also need to create a ``CTestConfig.cmake`` file in the top-level
directory where we can specify the name of the project and where to submit the
@@ -606,9 +630,11 @@ dashboard.
.. literalinclude:: Step9/CTestConfig.cmake
:language: cmake
-CTest will read in this file when it runs. To create a simple dashboard you can
-run **cmake** or **cmake-gui** to configure the project, but do not build it
-yet. Instead, change directory to the binary tree, and then run::
+The :manual:`ctest <ctest(1)>` executable will read in this file when it runs.
+To create a simple dashboard you can run the :manual:`cmake <cmake(1)>`
+executable or the :manual:`cmake-gui <cmake-gui(1)>` to configure the project,
+but do not build it yet. Instead, change directory to the binary tree, and then
+run:
ctest [-VV] -D Experimental
@@ -619,26 +645,26 @@ type must be specified::
Or, from an IDE, build the ``Experimental`` target.
-``ctest`` will build and test the project and submit the results to the Kitware
-public dashboard. The results of your dashboard will be uploaded to Kitware's
-public dashboard here: https://my.cdash.org/index.php?project=CMakeTutorial.
+The :manual:`ctest <ctest(1)>` executable will build and test the project and
+submit the results to Kitware's public dashboard:
+https://my.cdash.org/index.php?project=CMakeTutorial.
Mixing Static and Shared (Step 9)
=================================
-In this section we will show how by using the ``BUILD_SHARED_LIBS`` variable
-we can control the default behavior of ``add_library``, and allow control
-over how libraries without an explicit type (``STATIC``, ``SHARED``, ``MODULE``
-or ``OBJECT``) are built.
+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`,
+and allow control over how libraries without an explicit type (``STATIC``,
+``SHARED``, ``MODULE`` or ``OBJECT``) are built.
-To accomplish this we need to add ``BUILD_SHARED_LIBS`` to the top-level
-``CMakeLists.txt``. We use the ``option`` command as it allows users to
-optionally select if the value should be On or Off.
+To accomplish this we need to add :variable:`BUILD_SHARED_LIBS` to the
+top-level ``CMakeLists.txt``. We use the :command:`option` command as it allows
+users to optionally select if the value should be ON or OFF.
Next we are going to refactor MathFunctions to become a real library that
encapsulates using ``mysqrt`` or ``sqrt``, instead of requiring the calling
code to do this logic. This will also mean that ``USE_MYMATH`` will not control
-building MathFuctions, but instead will control the behavior of this library.
+building MathFunctions, but instead will control the behavior of this library.
The first step is to update the starting section of the top-level
``CMakeLists.txt`` to look like:
@@ -680,8 +706,8 @@ Finally, update ``MathFunctions/MathFunctions.h`` to use dll export defines:
At this point, if you build everything, you will notice that linking fails
as we are combining a static library without position independent code with a
library that has position independent code. The solution to this is to
-explicitly set the ``POSITION_INDEPENDENT_CODE`` target property of SqrtLibrary
-to be True no matter the build type.
+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
:language: cmake
@@ -694,35 +720,39 @@ Using CMake documentation can you find a helper module to simplify this?
Adding Generator Expressions (Step 10)
======================================
-Generator expressions are evaluated during build system generation to produce
-information specific to each build configuration.
+:manual:`Generator expressions <cmake-generator-expressions(7)>` are evaluated
+during build system generation to produce information specific to each build
+configuration.
-Generator expressions are allowed in the context of many target properties,
-such as ``LINK_LIBRARIES``, ``INCLUDE_DIRECTORIES``, ``COMPILE_DEFINITIONS``
-and others. They may also be used when using commands to populate those
-properties, such as ``target_link_libraries()``,
-``target_include_directories()``,
-``target_compile_definitions()`` and others.
+:manual:`Generator expressions <cmake-generator-expressions(7)>` are allowed in
+the context of many target properties, such as :prop_tgt:`LINK_LIBRARIES`,
+:prop_tgt:`INCLUDE_DIRECTORIES`, :prop_tgt:`COMPILE_DEFINITIONS` and others.
+They may also be used when using commands to populate those properties, such as
+:command:`target_link_libraries`, :command:`target_include_directories`,
+:command:`target_compile_definitions` and others.
-Generator expressions may be used to enable conditional linking, conditional
-definitions used when compiling, conditional include directories and more.
-The conditions may be based on the build configuration, target properties,
-platform information or any other queryable information.
+:manual:`Generator expressions <cmake-generator-expressions(7)>` may be used
+to enable conditional linking, conditional definitions used when compiling,
+conditional include directories and more. The conditions may be based on the
+build configuration, target properties, platform information or any other
+queryable information.
-There are different types of generator expressions including Logical,
-Informational, and Output expressions.
+There are different types of
+:manual:`generator expressions <cmake-generator-expressions(7)>` including
+Logical, Informational, and Output expressions.
Logical expressions are used to create conditional output. The basic
expressions are the 0 and 1 expressions. A ``$<0:...>`` results in the empty
string, and ``<1:...>`` results in the content of "...". They can also be
nested.
-A common usage of generator expressions is to conditionally add compiler
-flags, such as those for language levels or warnings. A nice pattern is
-to associate this information to an ``INTERFACE`` target allowing this
-information to propagate. Lets start by constructing an ``INTERFACE``
-target and specifying the required C++ standard level of ``11`` instead
-of using ``CMAKE_CXX_STANDARD``.
+A common usage of
+:manual:`generator expressions <cmake-generator-expressions(7)>` is to
+conditionally add compiler flags, such as those for language levels or
+warnings. A nice pattern is to associate this information to an ``INTERFACE``
+target allowing this information to propagate. Lets start by constructing an
+``INTERFACE`` target and specifying the required C++ standard level of ``11``
+instead of using :variable:`CMAKE_CXX_STANDARD`.
So the following code:
@@ -739,11 +769,10 @@ Would be replaced with:
:end-before: # add compiler warning flags just when building this project via
-Next we add the desired compiler warning flags that we want for our
-project. As 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:
+Next we add the desired compiler warning flags that we want for our project. As
+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
:language: cmake
@@ -755,8 +784,8 @@ Looking at this we see that the warning flags are encapsulated inside a
project will not inherit our warning flags.
-**Exercise**: Modify ``MathFunctions/CMakeLists.txt`` so that
-all targets have a ``target_link_libraries()`` call to ``tutorial_compiler_flags``.
+**Exercise**: Modify ``MathFunctions/CMakeLists.txt`` so that all targets have
+a :command:`target_link_libraries` call to ``tutorial_compiler_flags``.
Adding Export Configuration (Step 11)
@@ -771,12 +800,12 @@ The next step is to add the necessary information so that other CMake projects
can use our project, be it from a build directory, a local install or when
packaged.
-The first step is to update our ``install(TARGETS)`` commands to not only
-specify a ``DESTINATION`` but also an ``EXPORT``. The ``EXPORT`` keyword
+The first step is to update our :command:`install(TARGETS)` commands to not
+only specify a ``DESTINATION`` but also an ``EXPORT``. The ``EXPORT`` keyword
generates and installs a CMake file containing code to import all targets
-listed in the install command from the installation tree. So let's go ahead
-and explicitly ``EXPORT`` the MathFunctions library by updating the
-``install`` command in ``MathFunctions/CMakeLists.txt`` to look like:
+listed in the install command from the installation tree. So let's go ahead and
+explicitly ``EXPORT`` the MathFunctions library by updating the ``install``
+command in ``MathFunctions/CMakeLists.txt`` to look like:
.. literalinclude:: Complete/MathFunctions/CMakeLists.txt
:language: cmake
@@ -806,12 +835,12 @@ you will see that CMake will generate an error that looks like:
What CMake is trying to say is that during generating the export information
it will export a path that is intrinsically tied to the current machine and
will not be valid on other machines. The solution to this is to update the
-MathFunctions ``target_include_directories`` to understand that it needs
+MathFunctions :command:`target_include_directories` to understand that it needs
different ``INTERFACE`` locations when being used from within the build
directory and from an install / package. This means converting the
-``target_include_directories`` call for MathFunctions to look like:
+:command:`target_include_directories` call for MathFunctions to look like:
-.. literalinclude:: Complete/MathFunctions/CMakeLists.txt
+.. literalinclude:: Step12/MathFunctions/CMakeLists.txt
:language: cmake
:start-after: # to find MathFunctions.h, while we don't.
:end-before: # should we use our own math functions
@@ -821,16 +850,16 @@ warn anymore.
At this point, we have CMake properly packaging the target information that is
required but we will still need to generate a ``MathFunctionsConfig.cmake`` so
-that the CMake ``find_package`` command can find our project. So let's go
+that the CMake :command:`find_package` command can find our project. So let's go
ahead and add a new file to the top-level of the project called
``Config.cmake.in`` with the following contents:
-.. literalinclude:: Complete/Config.cmake.in
+.. literalinclude:: Step12/Config.cmake.in
Then, to properly configure and install that file, add the following to the
bottom of the top-level ``CMakeLists.txt``:
-.. literalinclude:: Complete/CMakeLists.txt
+.. literalinclude:: Step12/CMakeLists.txt
:language: cmake
:start-after: # install the configuration targets
:end-before: # generate the export
@@ -840,7 +869,7 @@ project that can be used after the project has been installed or packaged. If
we want our project to also be used from a build directory we only have to add
the following to the bottom of the top level ``CMakeLists.txt``:
-.. literalinclude:: Complete/CMakeLists.txt
+.. literalinclude:: Step12/CMakeLists.txt
:language: cmake
:start-after: # needs to be after the install(TARGETS ) command
@@ -848,55 +877,81 @@ With this export call we now generate a ``Targets.cmake``, allowing the
configured ``MathFunctionsConfig.cmake`` in the build directory to be used by
other projects, without needing it to be installed.
-Import a CMake Project (Consumer)
-=================================
+Packaging Debug and Release (Step 12)
+=====================================
+
+**Note:** This example is valid for single-configuration generators and will
+not work for multi-configuration generators (e.g. Visual Studio).
-This example shows how a project can find other CMake packages that
-generate ``Config.cmake`` files.
+By default, CMake's model is that a build directory only contains a single
+configuration, be it Debug, Release, MinSizeRel, or RelWithDebInfo. It is
+possible, however, to setup CPack to bundle multiple build directories and
+construct a package that contains multiple configurations of the same project.
-It also shows how to state a project's external dependencies when generating
-a ``Config.cmake``.
+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.
-Packaging Debug and Release (MultiPackage)
-==========================================
+Set :variable:`CMAKE_DEBUG_POSTFIX` near the beginning of the top-level
+``CMakeLists.txt`` file:
-By default CMake's model is that a build directory only contains a single
-configuration, be it Debug, Release, MinSizeRel, or RelWithDebInfo.
+.. literalinclude:: Complete/CMakeLists.txt
+ :language: cmake
+ :start-after: project(Tutorial VERSION 1.0)
+ :end-before: target_compile_features(tutorial_compiler_flags
-But it is possible to setup CPack to bundle multiple build directories at the
-same time to build a package that contains multiple configurations of the
-same project.
+And the :prop_tgt:`DEBUG_POSTFIX` property on the tutorial executable:
-First we need to construct a directory called ``multi_config``, which
-will contain all the builds that we want to package together.
+.. literalinclude:: Complete/CMakeLists.txt
+ :language: cmake
+ :start-after: # add the executable
+ :end-before: # add the binary tree to the search path for include files
-Second create a ``debug`` and ``release`` directory underneath
-``multi_config``. At the end you should have a layout that looks like:
+Let's also add version numbering to the MathFunctions library. In
+``MathFunctions/CMakeLists.txt``, set the :prop_tgt:`VERSION` and
+:prop_tgt:`SOVERSION` properties:
+
+.. literalinclude:: Complete/MathFunctions/CMakeLists.txt
+ :language: cmake
+ :start-after: # setup the version numbering
+ :end-before: # install rules
+
+From the ``Step12`` directory, create ``debug`` and ``release``
+subbdirectories. The layout will look like:
.. code-block:: none
- ─ multi_config
- ├── debug
- └── release
+ - Step12
+ - debug
+ - release
-Now we need to setup debug and release builds, which would roughly entail
-the following:
+Now we need to setup debug and release builds. We can use
+:variable:`CMAKE_BUILD_TYPE` to set the configuration type:
.. code-block:: console
cd debug
- cmake -DCMAKE_BUILD_TYPE=Debug ../../MultiPackage/
+ cmake -DCMAKE_BUILD_TYPE=Debug ..
cmake --build .
cd ../release
- cmake -DCMAKE_BUILD_TYPE=Release ../../MultiPackage/
+ cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build .
- cd ..
+Now that both the debug and release builds are complete, we can use a custom
+configuration file to package both builds into a single release. In the
+``Step12`` directory, create a file called ``MultiCPackConfig.cmake``. In this
+file, first include the default configuration file that was created by the
+:manual:`cmake <cmake(1)>` executable.
+
+Next, use the ``CPACK_INSTALL_CMAKE_PROJECTS`` variable to specify which
+projects to install. In this case, we want to install both debug and release.
+
+.. literalinclude:: Complete/MultiCPackConfig.cmake
+ :language: cmake
-Now that both the debug and release builds are complete, we can use
-a custom ``MultiCPackConfig.cmake`` file to package both builds into a single
-release.
+From the ``Step12`` directory, run :manual:`cpack <cpack(1)>` specifying our
+custom configuration file with the ``config`` option:
.. code-block:: console
- cpack --config ../../MultiPackage/MultiCPackConfig.cmake
+ cpack --config MultiCPackConfig.cmake
diff --git a/Help/guide/user-interaction/GUI-Add-Entry.png b/Help/guide/user-interaction/GUI-Add-Entry.png
new file mode 100644
index 0000000..1e9be7e
--- /dev/null
+++ b/Help/guide/user-interaction/GUI-Add-Entry.png
Binary files differ
diff --git a/Help/guide/user-interaction/GUI-Choose-Generator.png b/Help/guide/user-interaction/GUI-Choose-Generator.png
new file mode 100644
index 0000000..19ad2c0
--- /dev/null
+++ b/Help/guide/user-interaction/GUI-Choose-Generator.png
Binary files differ
diff --git a/Help/guide/user-interaction/GUI-Configure-Dialog.png b/Help/guide/user-interaction/GUI-Configure-Dialog.png
new file mode 100644
index 0000000..9839cac
--- /dev/null
+++ b/Help/guide/user-interaction/GUI-Configure-Dialog.png
Binary files differ
diff --git a/Help/guide/user-interaction/GUI-Source-Binary.png b/Help/guide/user-interaction/GUI-Source-Binary.png
new file mode 100644
index 0000000..e338354
--- /dev/null
+++ b/Help/guide/user-interaction/GUI-Source-Binary.png
Binary files differ
diff --git a/Help/guide/user-interaction/index.rst b/Help/guide/user-interaction/index.rst
new file mode 100644
index 0000000..c724b6f
--- /dev/null
+++ b/Help/guide/user-interaction/index.rst
@@ -0,0 +1,691 @@
+User Interaction Guide
+**********************
+
+.. only:: html
+
+ .. contents::
+
+Introduction
+============
+
+Where a software package supplies a CMake-based buildsystem
+with the source of their software, the consumer of the
+software is required to run a CMake user interaction tool
+in order to build it.
+
+Well-behaved CMake-based buildsystems do not create any
+output in the source directory, so typically, the user
+performs an out-of-source build and performs the build
+there. First, CMake must be instructed to generate a
+suitable buildsystem, then the user invokes a build tool
+to process that generated buildsystem. The generated
+buildsystem is specific to the machine used to generate
+it and is not redistributable. Each consumer of a provided
+source software package is required to use CMake to
+generate a buildsystem specific to their system.
+
+Generated buildsystems should generally be treated as
+read-only. The CMake files as a primary artifact should
+completely specify the buildsystem and there should be no
+reason to populate properties manually in an IDE for
+example after generating the buildsystem. CMake will
+periodically rewrite the generated buildsystem, so
+modifications by users will be overwritten.
+
+The features and user interfaces described in this manual
+are available for all CMake-based build systems by virtue
+of providing CMake files.
+
+The CMake tooling may report errors to the user when
+processing provided CMake files, such as reporting that
+the compiler is not supported, or the compiler does not
+support a required compile option, or a dependency can
+not be found. These errors must be resolved by the user
+by choosing a different compiler,
+:guide:`installing dependencies <Using Dependencies Guide>`,
+or instructing CMake where to find them, etc.
+
+Command Line cmake tool
+-----------------------
+
+A simple but typical use of :manual:`cmake(1)` with a fresh
+copy of software source code is to create a build directory
+and invoke cmake there:
+
+.. code-block:: console
+
+ $ cd some_software-1.4.2
+ $ mkdir build
+ $ cd build
+ $ cmake .. -DCMAKE_INSTALL_PREFIX=/opt/the/prefix
+ $ cmake --build .
+ $ cmake --build . --target install
+
+It is recommended to build in a separate directory to the
+source because that keeps the source directory pristine,
+allows for building a single source with multiple
+toolchains, and allows easy clearing of build artifacts by
+simply deleting the build directory.
+
+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)`.
+
+cmake-gui tool
+--------------
+
+Users more accustomed to GUI interfaces may use the
+:manual:`cmake-gui(1)` tool to invoke CMake and generate
+a buildsystem.
+
+The source and binary directories must first be
+populated. It is always advised to use different
+directories for the source and the build.
+
+.. image:: /guide/user-interaction/GUI-Source-Binary.png
+ :alt: Choosing source and binary directories
+
+Generating a Buildsystem
+========================
+
+There are several user interface tools which may be used
+to generate a buildsystem from CMake files. The
+:manual:`ccmake(1)` and :manual:`cmake-gui(1)` tools guide
+the user through setting the various necessary options.
+The :manual:`cmake(1)` tool can be invoked to specify
+options on the command line. This manual describes options
+which may be set using any of the user interface tools,
+though the mode of setting an option is different for each
+tool.
+
+Command line environment
+------------------------
+
+When invoking :manual:`cmake(1)` with a command line
+buildsystem such as ``Makefiles`` or ``Ninja``, it is
+necessary to use the correct build environment to
+ensure that build tools are available. CMake must be
+able to find the appropriate
+:variable:`build tool <CMAKE_MAKE_PROGRAM>`,
+compiler, linker and other tools as needed.
+
+On Linux systems, the appropriate tools are often
+provided in system-wide locations and may be readily
+installed through the system package manager. Other
+toolchains provided by the user or installed in
+non-default locations can also be used.
+
+When cross-compiling, some platforms may require
+environment variables to be set or may provide
+scripts to set the environment.
+
+Visual Studio ships multiple command prompts and
+``vcvarsall.bat`` scripts for setting up the
+correct environments for command line buildsystems. While
+not strictly necessary to use a corresponding
+command line environment when using a Visual Studio
+generator, doing so has no disadvantages.
+
+When using Xcode, there can be more than one Xcode
+version installed. Which one to use can be selected
+in a number of different ways, but the most common
+methods are:
+
+* Setting the default version in the preferences
+ of the Xcode IDE.
+* Setting the default version via the ``xcode-select``
+ command line tool.
+* Overriding the default version by setting the
+ ``DEVELOPER_DIR`` environment variable when running
+ CMake and the build tool.
+
+Command line ``-G`` option
+--------------------------
+
+CMake chooses a generator by default based on the
+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:
+
+.. code-block:: console
+
+ $ cmake .. -G Ninja
+
+The output of ``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.
+
+On Unix-like systems (including Mac OS X), the
+:generator:`Unix Makefiles` generator is used by
+default. A variant of that generator can also be used
+on Windows in various environments, such as the
+:generator:`NMake Makefiles` and
+:generator:`MinGW Makefiles` generator. These generators
+generate a ``Makefile`` variant which can be executed
+with ``make``, ``gmake``, ``nmake`` or similar tools.
+See the individual generator documentation for more
+information on targeted environments and tools.
+
+The :generator:`Ninja` generator is available on all
+major platforms. ``ninja`` is a build tool similar
+in use-cases to ``make``, but with a focus on
+performance and efficiency.
+
+On Windows, :manual:`cmake(1)` can be used to generate
+solutions for the Visual Studio IDE. Visual Studio
+versions may be specified by the product name of the
+IDE, which includes a four-digit year. Aliases are
+provided for other means by which Visual Studio
+versions are sometimes referred to, such as two
+digits which correspond to the product version of the
+VisualC++ compiler, or a combination of the two:
+
+.. code-block:: console
+
+ $ cmake .. -G "Visual Studio 2019"
+ $ cmake .. -G "Visual Studio 16"
+ $ cmake .. -G "Visual Studio 16 2019"
+
+Visual Studio generators can target different architectures.
+One can specify the target architecture using the `-A` option:
+
+.. code-block:: console
+
+ cmake .. -G "Visual Studio 2019" -A x64
+ cmake .. -G "Visual Studio 16" -A ARM
+ cmake .. -G "Visual Studio 16 2019" -A ARM64
+
+On Apple, the :generator:`Xcode` generator may be used to
+generate project files for the Xcode IDE.
+
+Some IDEs such as KDevelop4, QtCreator and CLion have
+native support for CMake-based buildsystems. Those IDEs
+provide user interface for selecting an underlying
+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
+deleted and the build must be started from scratch.
+
+When generating Visual Studio project and solutions
+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:
+
+.. code-block:: console
+
+ $ # Build with the clang-cl toolset
+ $ cmake.exe .. -G "Visual Studio 16 2019" -A x64 -T LLVM
+ $ # 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`
+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:
+
+.. code-block:: console
+
+ $ cmake .. -G "Visual Studio 16 2019" -A x64 -Thost=x64
+
+Choosing a generator in cmake-gui
+---------------------------------
+
+The "Configure" button triggers a new dialog to
+select the CMake generator to use.
+
+.. image:: /guide/user-interaction/GUI-Configure-Dialog.png
+ :alt: Configuring a generator
+
+All generators available on the command line are also
+available in :manual:`cmake-gui(1)`.
+
+.. image:: /guide/user-interaction/GUI-Choose-Generator.png
+ :alt: Choosing a generator
+
+When choosing a Visual Studio generator, further options
+are available to set an architecture to generate for.
+
+.. image:: /manual/VS-Choose-Arch.png
+ :alt: Choosing an architecture for Visual Studio generators
+
+.. _`Setting Build Variables`:
+
+Setting Build Variables
+=======================
+
+Software projects often require variables to be
+set on the command line when invoking CMake. Some of
+the most commonly used CMake variables are listed in
+the table below:
+
+========================================== ============================================================
+ Variable Meaning
+========================================== ============================================================
+ :variable:`CMAKE_PREFIX_PATH` Path to search for
+ :guide:`dependent packages <Using Dependencies Guide>`
+ :variable:`CMAKE_MODULE_PATH` Path to search for additional CMake modules
+ :variable:`CMAKE_BUILD_TYPE` Build configuration, such as
+ ``Debug`` or ``Release``, determining
+ debug/optimization flags. This is only
+ relevant for single-configuration buildsystems such
+ as ``Makefile`` and ``Ninja``. Multi-configuration
+ buildsystems such as those for Visual Studio and Xcode
+ ignore this setting.
+ :variable:`CMAKE_INSTALL_PREFIX` Location to install the
+ software to with the
+ ``install`` build target
+ :variable:`CMAKE_TOOLCHAIN_FILE` File containing cross-compiling
+ data such as
+ :manual:`toolchains and sysroots <cmake-toolchains(7)>`.
+ :variable:`BUILD_SHARED_LIBS` Whether to build shared
+ instead of static libraries
+ for :command:`add_library`
+ commands used without a type
+ :variable:`CMAKE_EXPORT_COMPILE_COMMANDS` Generate a ``compile_commands.json``
+ file for use with clang-based tools
+========================================== ============================================================
+
+Other project-specific variables may be available
+to control builds, such as enabling or disabling
+components of the project.
+
+There is no convention provided by CMake for how
+such variables are named between different
+provided buildsystems, except that variables with
+the prefix ``CMAKE_`` usually refer to options
+provided by CMake itself and should not be used
+in third-party options, which should use
+their own prefix instead. The
+:manual:`cmake-gui(1)` tool can display options
+in groups defined by their prefix, so it makes
+sense for third parties to ensure that they use a
+self-consistent prefix.
+
+Setting variables on the command line
+-------------------------------------
+
+CMake variables can be set on the command line either
+when creating the initial build:
+
+.. code-block:: console
+
+ $ mkdir build
+ $ cd build
+ $ cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Debug
+
+or later on a subsequent invocation of
+:manual:`cmake(1)`:
+
+.. code-block:: console
+
+ $ cd build
+ $ cmake . -DCMAKE_BUILD_TYPE=Debug
+
+The ``-U`` flag may be used to unset variables
+on the :manual:`cmake(1)` command line:
+
+.. code-block:: console
+
+ $ cd build
+ $ cmake . -UMyPackage_DIR
+
+A CMake buildsystem which was initially created
+on the command line can be modified using the
+:manual:`cmake-gui(1)` and vice-versa.
+
+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
+commands and scripts which repeatedly require the
+same cache entries.
+
+Setting variables with cmake-gui
+--------------------------------
+
+Variables may be set in the cmake-gui using the "Add Entry"
+button. This triggers a new dialog to set the value of
+the variable.
+
+.. image:: /guide/user-interaction/GUI-Add-Entry.png
+ :alt: Editing a cache entry
+
+The main view of the :manual:`cmake-gui(1)` user interface
+can be used to edit existing variables.
+
+The CMake Cache
+---------------
+
+When CMake is executed, it needs to find the locations of
+compilers, tools and dependencies. It also needs to be
+able to consistently re-generate a buildsystem to use the
+same compile/link flags and paths to dependencies. Such
+parameters are also required to be configurable by the
+user because they are paths and options specific to the
+users system.
+
+When it is first executed, CMake generates a
+``CMakeCache.txt`` file in the build directory containing
+key-value pairs for such artifacts. The cache file can be
+viewed or edited by the user by running the
+:manual:`cmake-gui(1)` or :manual:`ccmake(1)` tool. The
+tools provide an interactive interface for re-configuring
+the provided software and re-generating the buildsystem,
+as is needed after editing cached values. Each cache
+entry may have an associated short help text which is
+displayed in the user interface tools.
+
+The cache entries may also have a type to signify how it
+should be presented in the user interface. For example,
+a cache entry of type ``BOOL`` can be edited by a
+checkbox in a user interface, a ``STRING`` can be edited
+in a text field, and a ``FILEPATH`` while similar to a
+``STRING`` should also provide a way to locate filesystem
+paths using a file dialog. An entry of type ``STRING``
+may provide a restricted list of allowed values which are
+then provided in a drop-down menu in the
+:manual:`cmake-gui(1)` user interface (see the
+:prop_cache:`STRINGS` cache property).
+
+The CMake files shipped with a software package may also
+define boolean toggle options using the :command:`option`
+command. The command creates a cache entry which has a
+help text and a default value. Such cache entries are
+typically specific to the provided software and affect
+the configuration of the build, such as whether tests
+and examples are built, whether to build with exceptions
+enabled etc.
+
+Invoking the Buildsystem
+========================
+
+After generating the buildsystem, the software can be
+built by invoking the particular build tool. In the
+case of the IDE generators, this can involve loading
+the generated project file into the IDE to invoke the
+build.
+
+CMake is aware of the specific build tool needed to invoke
+a build so in general, to build a buildsystem or project
+from the command line after generating, the following
+command may be invoked in the build directory:
+
+.. code-block:: console
+
+ $ 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 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``:
+
+.. code-block:: console
+
+ $ cmake --build . --target myexe
+
+The ``--build`` mode also accepts a ``--config`` parameter
+in the case of multi-config generators to specify which
+particular configuration to build:
+
+.. code-block:: console
+
+ $ 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.
+
+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:
+
+.. 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
+build after a failed job, where CMake does not
+provide a high-level user interface.
+
+For all generators, it is possible to run the underlying
+build tool after invoking CMake. For example, ``make``
+may be executed after generating with the
+:generator:`Unix Makefiles` generator to invoke the build,
+or ``ninja`` after generating with the :generator:`Ninja`
+generator etc. The IDE buildsystems usually provide
+command line tooling for building a project which can
+also be invoked.
+
+Selecting a Target
+------------------
+
+Each executable and library described in the CMake files
+is a build target, and the buildsystem may describe
+custom targets, either for internal use, or for user
+consumption, for example to create documentation.
+
+CMake provides some built-in targets for all buildsystems
+providing CMake files.
+
+``all``
+ The default target used by ``Makefile`` and ``Ninja``
+ generators. Builds all targets in the buildsystem,
+ except those which are excluded by their
+ :prop_tgt:`EXCLUDE_FROM_ALL` target property or
+ :prop_dir:`EXCLUDE_FROM_ALL` directory property. The
+ name ``ALL_BUILD`` is used for this purpose for the
+ Xcode and Visual Studio generators.
+``help``
+ Lists the targets available for build. This target is
+ available when using the :generator:`Unix Makefiles` or
+ :generator:`Ninja` generator, and the exact output is
+ tool-specific.
+``clean``
+ Delete built object files and other output files. The
+ ``Makefile`` based generators create a ``clean`` target
+ per directory, so that an individual directory can be
+ cleaned. The ``Ninja`` tool provides its own granular
+ ``-t clean`` system.
+``test``
+ Runs tests. This target is only automatically available
+ if the CMake files provide CTest-based tests. See also
+ `Running Tests`_.
+``install``
+ Installs the software. This target is only automatically
+ available if the software defines install rules with the
+ :command:`install` command. See also
+ `Software Installation`_.
+``package``
+ Creates a binary package. This target is only
+ automatically available if the CMake files provide
+ CPack-based packages.
+``package_source``
+ Creates a source package. This target is only
+ automatically available if the CMake files provide
+ CPack-based packages.
+
+For ``Makefile`` based systems, ``/fast`` variants of binary
+build targets are provided. The ``/fast`` variants are used
+to build the specified target without regard for its
+dependencies. The dependencies are not checked and
+are not rebuilt if out of date. The :generator:`Ninja`
+generator is sufficiently fast at dependency checking that
+such targets are not provided for that generator.
+
+``Makefile`` based systems also provide build-targets to
+preprocess, assemble and compile individual files in a
+particular directory.
+
+.. code-block:: console
+
+ $ make foo.cpp.i
+ $ make foo.cpp.s
+ $ make foo.cpp.o
+
+The file extension is built into the name of the target
+because another file with the same name but a different
+extension may exist. However, build-targets without the
+file extension are also provided.
+
+.. code-block:: console
+
+ $ make foo.i
+ $ make foo.s
+ $ make foo.o
+
+In buildsystems which contain ``foo.c`` and ``foo.cpp``,
+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
+configured.
+
+===================== =========================== ===========================
+ Generator Default make program Alternatives
+===================== =========================== ===========================
+ XCode ``xcodebuild``
+ Unix Makefiles ``make``
+ NMake Makefiles ``nmake`` ``jom``
+ NMake Makefiles JOM ``jom`` ``nmake``
+ MinGW Makefiles ``mingw32-make``
+ MSYS Makefiles ``make``
+ Ninja ``ninja``
+ Visual Studio ``msbuild``
+ Watcom WMake ``wmake``
+===================== =========================== ===========================
+
+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``
+mode would also use ``jom`` if the
+:variable:`CMAKE_MAKE_PROGRAM` was set to ``jom`` while
+using the :generator:`NMake Makefiles` generator, and
+as a convenience, the :generator:`NMake Makefiles JOM`
+generator is provided to find ``jom`` in the normal way
+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.
+
+Software Installation
+=====================
+
+The :variable:`CMAKE_INSTALL_PREFIX` variable can be
+set in the CMake cache to specify where to install the
+provided software. If the provided software has install
+rules, specified using the :command:`install` command,
+they will install artifacts into that prefix. On Windows,
+the default installation location corresponds to the
+``ProgramFiles`` system directory which may be
+architecture specific. On Unix hosts, ``/usr/local`` is
+the default installation location.
+
+The :variable:`CMAKE_INSTALL_PREFIX` variable always
+refers to the installation prefix on the target
+filesystem.
+
+In cross-compiling or packaging scenarios where the
+sysroot is read-only or where the sysroot should otherwise
+remain pristine, the :variable:`CMAKE_STAGING_PREFIX`
+variable can be set to a location to actually install
+the files.
+
+The commands:
+
+.. code-block:: console
+
+ $ cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local \
+ -DCMAKE_SYSROOT=$HOME/root \
+ -DCMAKE_STAGING_PREFIX=/tmp/package
+ $ cmake --build .
+ $ cmake --build . --target install
+
+result in files being installed to paths such
+as ``/tmp/package/lib/libfoo.so`` on the host machine.
+The ``/usr/local`` location on the host machine is
+not affected.
+
+Some provided software may specify ``uninstall`` rules,
+but CMake does not generate such rules by default itself.
+
+Running Tests
+=============
+
+The :manual:`ctest(1)` tool is shipped with the CMake
+distribution to execute provided tests and report
+results. The ``test`` build-target is provided to run
+all available tests, but the :manual:`ctest(1)` tool
+allows granular control over which tests to run, how to
+run them, and how to report results. Executing
+:manual:`ctest(1)` in the build directory is equivalent
+to running the ``test`` target:
+
+.. code-block:: console
+
+ $ ctest
+
+A regular expression can be passed to run only tests
+which match the expression. To run only tests with
+``Qt`` in their name:
+
+.. code-block:: console
+
+ $ ctest -R Qt
+
+Tests can be excluded by regular expression too. To
+run only tests without ``Qt`` in their name:
+
+.. code-block:: console
+
+ $ ctest -E Qt
+
+Tests can be run in parallel by passing ``-j`` arguments
+to :manual:`ctest(1)`:
+
+.. code-block:: console
+
+ $ ctest -R Qt -j8
+
+The environment variable :envvar:`CTEST_PARALLEL_LEVEL`
+can alternatively be set to avoid the need to pass
+``-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
+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`
+can be set to ``1`` as an alternative to passing the
+``--output-on-failure`` option to :manual:`ctest(1)`.
diff --git a/Help/guide/using-dependencies/index.rst b/Help/guide/using-dependencies/index.rst
new file mode 100644
index 0000000..6fdcc55
--- /dev/null
+++ b/Help/guide/using-dependencies/index.rst
@@ -0,0 +1,200 @@
+Using Dependencies Guide
+************************
+
+.. only:: html
+
+ .. contents::
+
+Introduction
+============
+
+For developers wishing to use CMake to consume a third
+party binary package, there are multiple possibilities
+regarding how to optimally do so, depending on how
+CMake-aware the third-party library is.
+
+CMake files provided with a software package contain
+instructions for finding each build dependency. Some
+build dependencies are optional in that the build may
+succeed with a different feature set if the dependency
+is missing, and some dependencies are required. CMake
+searches well-known locations for each dependency, and
+the provided software may supply additional hints or
+locations to CMake to find each dependency.
+
+If a required dependency is not found by
+:manual:`cmake(1)`, the cache is populated with an entry
+which contains a ``NOTFOUND`` value. This value can be
+replaced by specifying it on the command line, or in
+the :manual:`ccmake(1)` or :manual:`cmake-gui(1)` tool.
+See the :guide:`User Interaction Guide` for
+more about setting cache entries.
+
+Libraries providing Config-file packages
+----------------------------------------
+
+The most convenient way for a third-party to provide library
+binaries for use with CMake is to provide
+:ref:`Config File Packages`. These packages are text files
+shipped with the library which instruct CMake how to use the
+library binaries and associated headers, helper tools and
+CMake macros provided by the library.
+
+The config files can usually be found in a directory whose
+name matches the pattern ``lib/cmake/<PackageName>``, though
+they may be in other locations instead. The
+``<PackageName>`` corresponds to use in CMake code with the
+:command:`find_package` command such as
+``find_package(PackageName REQUIRED)``.
+
+The ``lib/cmake/<PackageName>`` directory will contain a
+file which is either named ``<PackageName>Config.cmake``
+or ``<PackageName>-config.cmake``. This is the entry point
+to the package for CMake. A separate optional file named
+``<PackageName>ConfigVersion.cmake`` may also exist in the
+directory. This file is used by CMake to determine whether
+the version of the third party package satisfies uses of the
+:command:`find_package` command which specify version
+constraints. It is optional to specify a version when using
+:command:`find_package`, even if a ``ConfigVersion`` file is
+present.
+
+If the ``Config.cmake`` file is found and the
+optionally-specified version is satisfied, then the CMake
+:command:`find_package` command considers the package to be
+found and the entire library package is assumed to be
+complete as designed.
+
+There may be additional files providing CMake macros or
+:ref:`imported targets` for you to use. CMake does not
+enforce any naming convention for these
+files. They are related to the primary ``Config`` file by
+use of the CMake :command:`include` command.
+
+:guide:`Invoking CMake <User Interaction Guide>` with the
+intent of using a package of third party binaries requires
+that cmake :command:`find_package` commands succeed in finding
+the package. If the location of the package is in a directory
+known to CMake, the :command:`find_package` call should
+succeed. The directories known to cmake are platform-specific.
+For example, packages installed on Linux with a standard
+system package manager will be found in the ``/usr`` prefix
+automatically. Packages installed in ``Program Files`` on
+Windows will similarly be found automatically.
+
+Packages which are not found automatically are in locations
+not predictable to CMake such as ``/opt/mylib`` or
+``$HOME/dev/prefix``. This is a normal situation and CMake
+provides several ways for users to specify where to find
+such libraries.
+
+The :variable:`CMAKE_PREFIX_PATH` variable may be
+:ref:`set when invoking CMake <Setting Build Variables>`.
+It is treated as a list of paths to search for
+:ref:`Config File Packages`. A package installed in
+``/opt/somepackage`` will typically install config files
+such as
+``/opt/somepackage/lib/cmake/somePackage/SomePackageConfig.cmake``.
+In that case, ``/opt/somepackage`` should be added to
+:variable:`CMAKE_PREFIX_PATH`.
+
+The environment variable ``CMAKE_PREFIX_PATH`` may also be
+populated with prefixes to search for packages. Like the
+``PATH`` environment variable, this is a list and needs to use
+the platform-specific environment variable list item separator
+(``:`` on Unix and ``;`` on Windows).
+
+The :variable:`CMAKE_PREFIX_PATH` variable provides convenience
+in cases where multiple prefixes need to be specified, or when
+multiple different package binaries are available in the same
+prefix. Paths to packages may also be specified by setting
+variables matching ``<PackageName>_DIR``, such as
+``SomePackage_DIR``. Note that this is not a prefix but should
+be a full path to a directory containing a config-style package
+file, such as ``/opt/somepackage/lib/cmake/SomePackage/`` in
+the above example.
+
+Imported Targets from Packages
+------------------------------
+
+A third-party package which provides config-file packages may
+also provide :ref:`Imported targets`. These will be
+specified in files containing configuration-specific file
+paths relevant to the package, such as debug and release
+versions of libraries.
+
+Often the third-party package documentation will point out the
+names of imported targets available after a successful
+``find_package`` for a library. Those imported target names
+can be used with the :command:`target_link_libraries` command.
+
+A complete example which makes a simple use of a third party
+library might look like:
+
+.. code-block:: cmake
+
+ cmake_minimum_required(VERSION 3.10)
+ project(MyExeProject VERSION 1.0.0)
+
+ find_package(SomePackage REQUIRED)
+ add_executable(MyExe main.cpp)
+ target_link_libraries(MyExe PRIVATE SomePrefix::LibName)
+
+See :manual:`cmake-buildsystem(7)` for further information
+about developing a CMake buildsystem.
+
+Libraries not Providing Config-file Packages
+--------------------------------------------
+
+Third-party libraries which do not provide config-file packages
+can still be found with the :command:`find_package` command, if
+a ``FindSomePackage.cmake`` file is available.
+
+These module-file packages are different to config-file packages
+in that:
+
+#. They should not be provided by the third party, except
+ perhaps in the form of documentation
+#. The availability of a ``Find<PackageName>.cmake`` file does
+ not indicate the availability of the binaries themselves.
+#. CMake does not search the :variable:`CMAKE_PREFIX_PATH` for
+ ``Find<PackageName>.cmake`` files. Instead CMake searches
+ for such files in the :variable:`CMAKE_MODULE_PATH`
+ variable. It is common for users to set the
+ :variable:`CMAKE_MODULE_PATH` when running CMake, and it is
+ common for CMake projects to append to
+ :variable:`CMAKE_MODULE_PATH` to allow use of local
+ module-file packages.
+#. CMake ships ``Find<PackageName>.cmake`` files for some
+ :manual:`third party packages <cmake-modules(7)>`
+ for convenience in cases where the third party does
+ not provide config-file packages directly. These files are
+ a maintenance burden for CMake, so new Find modules are
+ generally not added to CMake anymore. Third-parties should
+ provide config file packages instead of relying on a Find
+ module to be provided by CMake.
+
+Module-file packages may also provide :ref:`Imported targets`.
+A complete example which finds such a package might look
+like:
+
+.. code-block:: cmake
+
+ cmake_minimum_required(VERSION 3.10)
+ project(MyExeProject VERSION 1.0.0)
+
+ find_package(PNG REQUIRED)
+
+ # Add path to a FindSomePackage.cmake file
+ list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
+ find_package(SomePackage REQUIRED)
+
+ add_executable(MyExe main.cpp)
+ target_link_libraries(MyExe PRIVATE
+ PNG::PNG
+ SomePrefix::LibName
+ )
+
+The :variable:`<PackageName>_ROOT` variable is also
+searched as a prefix for :command:`find_package` calls using
+module-file packages such as ``FindSomePackage``.
diff --git a/Help/index.rst b/Help/index.rst
index cc6cee6..4d9a9c8 100644
--- a/Help/index.rst
+++ b/Help/index.rst
@@ -1,5 +1,34 @@
.. title:: CMake Reference Documentation
+Introduction
+############
+
+CMake is a tool to manage building of source code. Originally, CMake was
+designed as a generator for various dialects of ``Makefile``, today
+CMake generates modern buildsystems such as ``Ninja`` as well as project
+files for IDEs such as Visual Studio and Xcode.
+
+CMake is widely used for the C and C++ languages, but it may be used to
+build source code of other languages too.
+
+People encountering CMake for the first time may have different initial
+goals. To learn how to build a source code package downloaded from the
+internet, start with the :guide:`User Interaction Guide`.
+This will detail the steps needed to run the :manual:`cmake(1)` or
+:manual:`cmake-gui(1)` executable and how to choose a generator, and
+how to complete the build.
+
+The :guide:`Using Dependencies Guide` is aimed at developers
+wishing to get started using a third-party library.
+
+For developers starting a project using CMake, the :guide:`CMake Tutorial`
+is a suitable starting point. The :manual:`cmake-buildsystem(7)`
+manual is aimed at developers expanding their knowledge of maintaining
+a buildsystem and becoming familiar with the build targets that
+can be represented in CMake. The :manual:`cmake-packages(7)` manual
+explains how to create packages which can easily be consumed by
+third-party CMake-based buildsystems.
+
Command-Line Tools
##################
@@ -53,6 +82,8 @@ Reference Manuals
:maxdepth: 1
/guide/tutorial/index
+ /guide/user-interaction/index
+ /guide/using-dependencies/index
.. only:: html or text
diff --git a/Help/manual/ID_RESERVE.txt b/Help/manual/ID_RESERVE.txt
new file mode 100644
index 0000000..be2b163
--- /dev/null
+++ b/Help/manual/ID_RESERVE.txt
@@ -0,0 +1,7 @@
+.. note::
+
+ CMake reserves identifiers that:
+
+ * begin with ``CMAKE_`` (upper-, lower-, or mixed-case), or
+ * begin with ``_CMAKE_`` (upper-, lower-, or mixed-case), or
+ * begin with ``_`` followed by the name of any :manual:`CMake Command <cmake-commands(7)>`.
diff --git a/Help/manual/VS-Choose-Arch.png b/Help/manual/VS-Choose-Arch.png
new file mode 100644
index 0000000..816b0f4
--- /dev/null
+++ b/Help/manual/VS-Choose-Arch.png
Binary files differ
diff --git a/Help/manual/cmake-commands.7.rst b/Help/manual/cmake-commands.7.rst
index 59ba897..87743b4 100644
--- a/Help/manual/cmake-commands.7.rst
+++ b/Help/manual/cmake-commands.7.rst
@@ -16,6 +16,7 @@ These commands are always available.
:maxdepth: 1
/command/break
+ /command/cmake_command
/command/cmake_host_system_information
/command/cmake_minimum_required
/command/cmake_parse_arguments
diff --git a/Help/manual/cmake-compile-features.7.rst b/Help/manual/cmake-compile-features.7.rst
index a14e322..05dc038 100644
--- a/Help/manual/cmake-compile-features.7.rst
+++ b/Help/manual/cmake-compile-features.7.rst
@@ -19,11 +19,11 @@ While features are typically specified in programming language standards,
CMake provides a primary user interface based on granular handling of
the features, not the language standard that introduced the feature.
-The :prop_gbl:`CMAKE_C_KNOWN_FEATURES` and
-:prop_gbl:`CMAKE_CXX_KNOWN_FEATURES` global properties contain all the
+The :prop_gbl:`CMAKE_C_KNOWN_FEATURES`, :prop_gbl:`CMAKE_CUDA_KNOWN_FEATURES`,
+and :prop_gbl:`CMAKE_CXX_KNOWN_FEATURES` global properties contain all the
features known to CMake, regardless of compiler support for the feature.
-The :variable:`CMAKE_C_COMPILE_FEATURES` and
-:variable:`CMAKE_CXX_COMPILE_FEATURES` variables contain all features
+The :variable:`CMAKE_C_COMPILE_FEATURES`, :variable:`CMAKE_CUDA_COMPILE_FEATURES`
+, and :variable:`CMAKE_CXX_COMPILE_FEATURES` variables contain all features
CMake knows are known to the compiler, regardless of language standard
or compile flags needed to use them.
@@ -368,8 +368,9 @@ versions specified for each:
* all compilers and versions listed above with only meta-features for C++.
* ``TI``: Texas Instruments compiler.
-CMake is currently aware of the :prop_tgt:`CUDA standards <CUDA_STANDARD>`
-from the following :variable:`compiler ids <CMAKE_<LANG>_COMPILER_ID>` as of the
+CMake is currently aware of the :prop_tgt:`CUDA standards <CUDA_STANDARD>` and
+their associated meta-features (e.g. ``cuda_std_11``) available from the
+following :variable:`compiler ids <CMAKE_<LANG>_COMPILER_ID>` as of the
versions specified for each:
* ``NVIDIA``: NVIDIA nvcc compiler 7.5+.
diff --git a/Help/manual/cmake-env-variables.7.rst b/Help/manual/cmake-env-variables.7.rst
index ec2c85d..ce1e360 100644
--- a/Help/manual/cmake-env-variables.7.rst
+++ b/Help/manual/cmake-env-variables.7.rst
@@ -14,6 +14,13 @@ For general information on environment variables, see the
:ref:`Environment Variables <CMake Language Environment Variables>`
section in the cmake-language manual.
+Environment Variables that Change Behavior
+==========================================
+
+.. toctree::
+ :maxdepth: 1
+
+ /envvar/CMAKE_PREFIX_PATH
Environment Variables that Control the Build
============================================
@@ -23,10 +30,12 @@ Environment Variables that Control the Build
/envvar/CMAKE_BUILD_PARALLEL_LEVEL
/envvar/CMAKE_CONFIG_TYPE
+ /envvar/CMAKE_EXPORT_COMPILE_COMMANDS
/envvar/CMAKE_GENERATOR
/envvar/CMAKE_GENERATOR_INSTANCE
/envvar/CMAKE_GENERATOR_PLATFORM
/envvar/CMAKE_GENERATOR_TOOLSET
+ /envvar/CMAKE_LANG_COMPILER_LAUNCHER
/envvar/CMAKE_MSVCIDE_RUN_PATH
/envvar/CMAKE_NO_VERBOSE
/envvar/CMAKE_OSX_ARCHITECTURES
@@ -73,3 +82,11 @@ Environment Variables for CTest
/envvar/CTEST_PROGRESS_OUTPUT
/envvar/CTEST_USE_LAUNCHERS_DEFAULT
/envvar/DASHBOARD_TEST_FROM_CTEST
+
+Environment Variables for the CMake curses interface
+====================================================
+
+.. toctree::
+ :maxdepth: 1
+
+ /envvar/CCMAKE_COLORS
diff --git a/Help/manual/cmake-file-api.7.rst b/Help/manual/cmake-file-api.7.rst
index 04b6ed2..12eecd9 100644
--- a/Help/manual/cmake-file-api.7.rst
+++ b/Help/manual/cmake-file-api.7.rst
@@ -199,6 +199,7 @@ The reply index file contains a JSON object:
"root": "/prefix/share/cmake-3.14"
},
"generator": {
+ "multiConfig": false,
"name": "Unix Makefiles"
}
},
@@ -267,6 +268,9 @@ The members are:
A JSON object describing the CMake generator used for the build.
It has members:
+ ``multiConfig``
+ A boolean specifying whether the generator supports multiple output
+ configurations.
``name``
A string specifying the name of the generator.
``platform``
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index 75f4bd4..9e411a4 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -259,6 +259,121 @@ Variable Queries
add_executable(myapp main.cpp)
target_link_libraries(myapp myapp_c myapp_cxx)
+.. _`Boolean LINK_LANGUAGE Generator Expression`:
+
+``$<LINK_LANG_AND_ID:language,compiler_ids>``
+ ``1`` when the language used for link step matches ``language`` and the
+ CMake's compiler id of the language linker matches any one of the entries
+ in ``compiler_ids``, otherwise ``0``. This expression is a short form for the
+ combination of ``$<LINK_LANGUAGE:language>`` and
+ ``$<LANG_COMPILER_ID:compiler_ids>``. This expression may be used to specify
+ link libraries, link options, link directories and link dependencies of a
+ particular language and linker combination in a target. For example:
+
+ .. code-block:: cmake
+
+ add_library(libC_Clang ...)
+ add_library(libCXX_Clang ...)
+ add_library(libC_Intel ...)
+ add_library(libCXX_Intel ...)
+
+ add_executable(myapp main.c)
+ if (CXX_CONFIG)
+ target_sources(myapp PRIVATE file.cxx)
+ endif()
+ target_link_libraries(myapp
+ PRIVATE $<$<LINK_LANG_AND_ID:CXX,Clang,AppleClang>:libCXX_Clang>
+ $<$<LINK_LANG_AND_ID:C,Clang,AppleClang>:libC_Clang>
+ $<$<LINK_LANG_AND_ID:CXX,Intel>:libCXX_Intel>
+ $<$<LINK_LANG_AND_ID:C,Intel>:libC_Intel>)
+
+ This specifies the use of different link libraries based on both the
+ compiler id and link language. This example will have target ``libCXX_Clang``
+ as link dependency when ``Clang`` or ``AppleClang`` is the ``CXX``
+ linker, and ``libCXX_Intel`` when ``Intel`` is the ``CXX`` linker.
+ Likewise when the ``C`` linker is ``Clang`` or ``AppleClang``, target
+ ``libC_Clang`` will be added as link dependency and ``libC_Intel`` when
+ ``Intel`` is the ``C`` linker.
+
+ See :ref:`the note related to
+ <Constraints LINK_LANGUAGE Generator Expression>`
+ ``$<LINK_LANGUAGE:language>`` for constraints about the usage of this
+ generator expression.
+
+``$<LINK_LANGUAGE:languages>``
+ ``1`` when the language used for link step matches any of the entries
+ in ``languages``, otherwise ``0``. This expression may be used to specify
+ link libraries, link options, link directories and link dependencies of a
+ particular language in a target. For example:
+
+ .. code-block:: cmake
+
+ add_library(api_C ...)
+ add_library(api_CXX ...)
+ add_library(api INTERFACE)
+ target_link_options(api INTERFACE $<$<LINK_LANGUAGE:C>:-opt_c>
+ $<$<LINK_LANGUAGE:CXX>:-opt_cxx>)
+ target_link_libraries(api INTERFACE $<$<LINK_LANGUAGE:C>:api_C>
+ $<$<LINK_LANGUAGE:CXX>:api_CXX>)
+
+ add_executable(myapp1 main.c)
+ target_link_options(myapp1 PRIVATE api)
+
+ add_executable(myapp2 main.cpp)
+ target_link_options(myapp2 PRIVATE api)
+
+ This specifies to use the ``api`` target for linking targets ``myapp1`` and
+ ``myapp2``. In practice, ``myapp1`` will link with target ``api_C`` and
+ option ``-opt_c`` because it will use ``C`` as link language. And ``myapp2``
+ will link with ``api_CXX`` and option ``-opt_cxx`` because ``CXX`` will be
+ the link language.
+
+ .. _`Constraints LINK_LANGUAGE Generator Expression`:
+
+ .. note::
+
+ To determine the link language of a target, it is required to collect,
+ transitively, all the targets which will be linked to it. So, for link
+ libraries properties, a double evaluation will be done. During the first
+ evaluation, ``$<LINK_LANGUAGE:..>`` expressions will always return ``0``.
+ The link language computed after this first pass will be used to do the
+ second pass. To avoid inconsistency, it is required that the second pass
+ do not change the link language. Moreover, to avoid unexpected
+ side-effects, it is required to specify complete entities as part of the
+ ``$<LINK_LANGUAGE:..>`` expression. For example:
+
+ .. code-block:: cmake
+
+ add_library(lib STATIC file.cxx)
+ add_library(libother STATIC file.c)
+
+ # bad usage
+ add_executable(myapp1 main.c)
+ target_link_libraries(myapp1 PRIVATE lib$<$<LINK_LANGUAGE:C>:other>)
+
+ # correct usage
+ add_executable(myapp2 main.c)
+ target_link_libraries(myapp2 PRIVATE $<$<LINK_LANGUAGE:C>:libother>)
+
+ In this example, for ``myapp1``, the first pass will, unexpectedly,
+ determine that the link language is ``CXX`` because the evaluation of the
+ generator expression will be an empty string so ``myapp1`` will depends on
+ target ``lib`` which is ``C++``. On the contrary, for ``myapp2``, the first
+ evaluation will give ``C`` as link language, so the second pass will
+ correctly add target ``libother`` as link dependency.
+
+``$<DEVICE_LINK:list>``
+ Returns the list if it is the device link step, an empty list otherwise.
+ The device link step is controlled by :prop_tgt:`CUDA_SEPARABLE_COMPILATION`
+ and :prop_tgt:`CUDA_RESOLVE_DEVICE_SYMBOLS` properties. This expression can
+ only be used to specify link options.
+
+``$<HOST_LINK:list>``
+ Returns the list if it is the normal link step, an empty list otherwise.
+ This expression is mainly useful when a device link step is also involved
+ (see ``$<DEVICE_LINK:list>`` generator expression). This expression can only
+ be used to specify link options.
+
String-Valued Generator Expressions
===================================
@@ -450,22 +565,41 @@ Variable Queries
<Boolean COMPILE_LANGUAGE Generator Expression>`
``$<COMPILE_LANGUAGE:language>``
for notes about the portability of this generator expression.
+``$<LINK_LANGUAGE>``
+ The link language of target when evaluating link options.
+ See :ref:`the related boolean expression
+ <Boolean LINK_LANGUAGE Generator Expression>` ``$<LINK_LANGUAGE:language>``
+ for notes about the portability of this generator expression.
+
+ .. note::
+
+ This generator expression is not supported by the link libraries
+ properties to avoid side-effects due to the double evaluation of
+ these properties.
Target-Dependent Queries
------------------------
+These queries refer to a target ``tgt``. This can be any runtime artifact,
+namely:
+
+* an executable target created by :command:`add_executable`
+* a shared library target (``.so``, ``.dll`` but not their ``.lib`` import library)
+ created by :command:`add_library`
+* a static library target created by :command:`add_library`
+
+In the following, "the ``tgt`` filename" means the name of the ``tgt``
+binary file. This has to be distinguished from "the target name",
+which is just the string ``tgt``.
+
``$<TARGET_NAME_IF_EXISTS:tgt>``
- Expands to the ``tgt`` if the given target exists, an empty string
- otherwise.
+ The target name ``tgt`` if the target exists, an empty string otherwise.
``$<TARGET_FILE:tgt>``
- Full path to main file (.exe, .so.1.2, .a) where ``tgt`` is the name of a
- target.
+ Full path to the ``tgt`` binary file.
``$<TARGET_FILE_BASE_NAME:tgt>``
- Base name of main file where ``tgt`` is the name of a target.
-
- The base name corresponds to the target file name (see
- ``$<TARGET_FILE_NAME:tgt>``) without prefix and suffix. For example, if
- target file name is ``libbase.so``, the base name is ``base``.
+ Base name of ``tgt``, i.e. ``$<TARGET_FILE_NAME:tgt>`` without prefix and
+ suffix.
+ For example, if the ``tgt`` filename is ``libbase.so``, the base name is ``base``.
See also the :prop_tgt:`OUTPUT_NAME`, :prop_tgt:`ARCHIVE_OUTPUT_NAME`,
:prop_tgt:`LIBRARY_OUTPUT_NAME` and :prop_tgt:`RUNTIME_OUTPUT_NAME`
@@ -480,32 +614,31 @@ Target-Dependent Queries
Note that ``tgt`` is not added as a dependency of the target this
expression is evaluated on.
``$<TARGET_FILE_PREFIX:tgt>``
- Prefix of main file where ``tgt`` is the name of a target.
+ Prefix of the ``tgt`` filename (such as ``lib``).
See also the :prop_tgt:`PREFIX` target property.
Note that ``tgt`` is not added as a dependency of the target this
expression is evaluated on.
``$<TARGET_FILE_SUFFIX:tgt>``
- Suffix of main file where ``tgt`` is the name of a target.
-
- The suffix corresponds to the file extension (such as ".so" or ".exe").
+ Suffix of the ``tgt`` filename (extension such as ``.so`` or ``.exe``).
See also the :prop_tgt:`SUFFIX` target property.
Note that ``tgt`` is not added as a dependency of the target this
expression is evaluated on.
``$<TARGET_FILE_NAME:tgt>``
- Name of main file (.exe, .so.1.2, .a).
+ The ``tgt`` filename.
``$<TARGET_FILE_DIR:tgt>``
- Directory of main file (.exe, .so.1.2, .a).
+ Directory of the ``tgt`` binary file.
``$<TARGET_LINKER_FILE:tgt>``
- File used to link (.a, .lib, .so) where ``tgt`` is the name of a target.
+ File used when linking to the ``tgt`` target. This will usually
+ be the library that ``tgt`` represents (``.a``, ``.lib``, ``.so``),
+ but for a shared library on DLL platforms, it would be the ``.lib``
+ import library associated with the DLL.
``$<TARGET_LINKER_FILE_BASE_NAME:tgt>``
- Base name of file used to link where ``tgt`` is the name of a target.
-
- The base name corresponds to the target linker file name (see
- ``$<TARGET_LINKER_FILE_NAME:tgt>``) without prefix and suffix. For example,
+ Base name of file used to link the target ``tgt``, i.e.
+ ``$<TARGET_LINKER_FILE_NAME:tgt>`` without prefix and suffix. For example,
if target file name is ``libbase.a``, the base name is ``base``.
See also the :prop_tgt:`OUTPUT_NAME`, :prop_tgt:`ARCHIVE_OUTPUT_NAME`,
@@ -520,7 +653,7 @@ Target-Dependent Queries
Note that ``tgt`` is not added as a dependency of the target this
expression is evaluated on.
``$<TARGET_LINKER_FILE_PREFIX:tgt>``
- Prefix of file used to link where ``tgt`` is the name of a target.
+ Prefix of file used to link target ``tgt``.
See also the :prop_tgt:`PREFIX` and :prop_tgt:`IMPORT_PREFIX` target
properties.
@@ -538,15 +671,15 @@ Target-Dependent Queries
Note that ``tgt`` is not added as a dependency of the target this
expression is evaluated on.
``$<TARGET_LINKER_FILE_NAME:tgt>``
- Name of file used to link (.a, .lib, .so).
+ Name of file used to link target ``tgt``.
``$<TARGET_LINKER_FILE_DIR:tgt>``
- Directory of file used to link (.a, .lib, .so).
+ Directory of file used to link target ``tgt``.
``$<TARGET_SONAME_FILE:tgt>``
- File with soname (.so.3) where ``tgt`` is the name of a target.
+ File with soname (``.so.3``) where ``tgt`` is the name of a target.
``$<TARGET_SONAME_FILE_NAME:tgt>``
- Name of file with soname (.so.3).
+ Name of file with soname (``.so.3``).
``$<TARGET_SONAME_FILE_DIR:tgt>``
- Directory of with soname (.so.3).
+ Directory of with soname (``.so.3``).
``$<TARGET_PDB_FILE:tgt>``
Full path to the linker generated program database file (.pdb)
where ``tgt`` is the name of a target.
@@ -589,14 +722,14 @@ Target-Dependent Queries
Note that ``tgt`` is not added as a dependency of the target this
expression is evaluated on.
``$<TARGET_PROPERTY:prop>``
- Value of the property ``prop`` on the target on which the generator
- expression is evaluated. Note that for generator expressions in
- :ref:`Target Usage Requirements` this is the value of the property
- on the consuming target rather than the target specifying the
- requirement.
+ Value of the property ``prop`` on the target for which the expression
+ is being evaluated. Note that for generator expressions in
+ :ref:`Target Usage Requirements` this is the consuming target rather
+ than the target specifying the requirement.
``$<INSTALL_PREFIX>``
Content of the install prefix when the target is exported via
- :command:`install(EXPORT)` and empty otherwise.
+ :command:`install(EXPORT)`, or when evaluated in
+ :prop_tgt:`INSTALL_NAME_DIR`, and empty otherwise.
Output-Related Expressions
--------------------------
diff --git a/Help/manual/cmake-generators.7.rst b/Help/manual/cmake-generators.7.rst
index 41f7652..6f88c0a 100644
--- a/Help/manual/cmake-generators.7.rst
+++ b/Help/manual/cmake-generators.7.rst
@@ -52,13 +52,14 @@ Makefile Generators
/generator/Unix Makefiles
/generator/Watcom WMake
-Ninja Generator
-^^^^^^^^^^^^^^^
+Ninja Generators
+^^^^^^^^^^^^^^^^
.. toctree::
:maxdepth: 1
/generator/Ninja
+ /generator/Ninja Multi-Config
.. _`IDE Build Tool Generators`:
diff --git a/Help/manual/cmake-language.7.rst b/Help/manual/cmake-language.7.rst
index 4ca8e3a..b7f0861 100644
--- a/Help/manual/cmake-language.7.rst
+++ b/Help/manual/cmake-language.7.rst
@@ -567,6 +567,8 @@ The :manual:`cmake-variables(7)` manual documents the many variables
that are provided by CMake or have meaning to CMake when set
by project code.
+.. include:: ID_RESERVE.txt
+
.. _`CMake Language Environment Variables`:
Environment Variables
diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst
index c60dc40..be64112 100644
--- a/Help/manual/cmake-modules.7.rst
+++ b/Help/manual/cmake-modules.7.rst
@@ -122,6 +122,7 @@ They are normally called through the :command:`find_package` command.
/module/FindCABLE
/module/FindCoin3D
/module/FindCups
+ /module/FindCUDAToolkit
/module/FindCURL
/module/FindCurses
/module/FindCVS
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index 44ea1a8..3f3b70d 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -51,6 +51,29 @@ The :variable:`CMAKE_MINIMUM_REQUIRED_VERSION` variable may also be used
to determine whether to report an error on use of deprecated macros or
functions.
+Policies Introduced by CMake 3.18
+=================================
+
+.. toctree::
+ :maxdepth: 1
+
+ CMP0106: The Documentation module is removed. </policy/CMP0106>
+ CMP0105: Device link step uses the link options. </policy/CMP0105>
+ CMP0104: CMAKE_CUDA_ARCHITECTURES now detected for NVCC, empty CUDA_ARCHITECTURES not allowed. </policy/CMP0104>
+ CMP0103: Multiple export() with same FILE without APPEND is not allowed. </policy/CMP0103>
+
+Policies Introduced by CMake 3.17
+=================================
+
+.. toctree::
+ :maxdepth: 1
+
+ CMP0102: mark_as_advanced() does nothing if a cache entry does not exist. </policy/CMP0102>
+ CMP0101: target_compile_options honors BEFORE keyword in all scopes. </policy/CMP0101>
+ CMP0100: Let AUTOMOC and AUTOUIC process .hh header files. </policy/CMP0100>
+ CMP0099: Link properties are transitive over private dependency on static libraries. </policy/CMP0099>
+ CMP0098: FindFLEX runs flex in CMAKE_CURRENT_BINARY_DIR when executing. </policy/CMP0098>
+
Policies Introduced by CMake 3.16
=================================
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index e704371..4103806 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -22,10 +22,13 @@ Properties of Global Scope
/prop_gbl/AUTOMOC_TARGETS_FOLDER
/prop_gbl/AUTORCC_SOURCE_GROUP
/prop_gbl/CMAKE_C_KNOWN_FEATURES
+ /prop_gbl/CMAKE_CUDA_KNOWN_FEATURES
/prop_gbl/CMAKE_CXX_KNOWN_FEATURES
/prop_gbl/CMAKE_ROLE
/prop_gbl/DEBUG_CONFIGURATIONS
/prop_gbl/DISABLED_FEATURES
+ /prop_gbl/ECLIPSE_EXTRA_CPROJECT_CONTENTS
+ /prop_gbl/ECLIPSE_EXTRA_NATURES
/prop_gbl/ENABLED_FEATURES
/prop_gbl/ENABLED_LANGUAGES
/prop_gbl/FIND_LIBRARY_USE_LIB32_PATHS
@@ -36,12 +39,10 @@ Properties of Global Scope
/prop_gbl/GLOBAL_DEPENDS_DEBUG_MODE
/prop_gbl/GLOBAL_DEPENDS_NO_CYCLES
/prop_gbl/IN_TRY_COMPILE
+ /prop_gbl/JOB_POOLS
/prop_gbl/PACKAGES_FOUND
/prop_gbl/PACKAGES_NOT_FOUND
- /prop_gbl/JOB_POOLS
/prop_gbl/PREDEFINED_TARGETS_FOLDER
- /prop_gbl/ECLIPSE_EXTRA_NATURES
- /prop_gbl/ECLIPSE_EXTRA_CPROJECT_CONTENTS
/prop_gbl/REPORT_UNDEFINED_PROPERTIES
/prop_gbl/RULE_LAUNCH_COMPILE
/prop_gbl/RULE_LAUNCH_CUSTOM
@@ -103,6 +104,7 @@ Properties on Targets
:maxdepth: 1
/prop_tgt/ADDITIONAL_CLEAN_FILES
+ /prop_tgt/AIX_EXPORT_ALL_SYMBOLS
/prop_tgt/ALIASED_TARGET
/prop_tgt/ANDROID_ANT_ADDITIONAL_OPTIONS
/prop_tgt/ANDROID_API
@@ -125,24 +127,25 @@ Properties on Targets
/prop_tgt/ARCHIVE_OUTPUT_DIRECTORY
/prop_tgt/ARCHIVE_OUTPUT_NAME_CONFIG
/prop_tgt/ARCHIVE_OUTPUT_NAME
+ /prop_tgt/PCH_WARN_INVALID
/prop_tgt/AUTOGEN_BUILD_DIR
/prop_tgt/AUTOGEN_ORIGIN_DEPENDS
/prop_tgt/AUTOGEN_PARALLEL
/prop_tgt/AUTOGEN_TARGET_DEPENDS
+ /prop_tgt/AUTOMOC
/prop_tgt/AUTOMOC_COMPILER_PREDEFINES
/prop_tgt/AUTOMOC_DEPEND_FILTERS
/prop_tgt/AUTOMOC_EXECUTABLE
/prop_tgt/AUTOMOC_MACRO_NAMES
/prop_tgt/AUTOMOC_MOC_OPTIONS
/prop_tgt/AUTOMOC_PATH_PREFIX
- /prop_tgt/AUTOMOC
+ /prop_tgt/AUTORCC
+ /prop_tgt/AUTORCC_EXECUTABLE
+ /prop_tgt/AUTORCC_OPTIONS
/prop_tgt/AUTOUIC
/prop_tgt/AUTOUIC_EXECUTABLE
/prop_tgt/AUTOUIC_OPTIONS
/prop_tgt/AUTOUIC_SEARCH_PATHS
- /prop_tgt/AUTORCC
- /prop_tgt/AUTORCC_EXECUTABLE
- /prop_tgt/AUTORCC_OPTIONS
/prop_tgt/BINARY_DIR
/prop_tgt/BUILD_RPATH
/prop_tgt/BUILD_RPATH_USE_ORIGIN
@@ -169,9 +172,11 @@ Properties on Targets
/prop_tgt/CONFIG_OUTPUT_NAME
/prop_tgt/CONFIG_POSTFIX
/prop_tgt/CROSSCOMPILING_EMULATOR
+ /prop_tgt/CUDA_ARCHITECTURES
/prop_tgt/CUDA_PTX_COMPILATION
/prop_tgt/CUDA_SEPARABLE_COMPILATION
/prop_tgt/CUDA_RESOLVE_DEVICE_SYMBOLS
+ /prop_tgt/CUDA_RUNTIME_LIBRARY
/prop_tgt/CUDA_EXTENSIONS
/prop_tgt/CUDA_STANDARD
/prop_tgt/CUDA_STANDARD_REQUIRED
@@ -182,7 +187,9 @@ Properties on Targets
/prop_tgt/DEFINE_SYMBOL
/prop_tgt/DEPLOYMENT_REMOTE_DIRECTORY
/prop_tgt/DEPLOYMENT_ADDITIONAL_FILES
+ /prop_tgt/DEPRECATION
/prop_tgt/DISABLE_PRECOMPILE_HEADERS
+ /prop_tgt/DOTNET_TARGET_FRAMEWORK
/prop_tgt/DOTNET_TARGET_FRAMEWORK_VERSION
/prop_tgt/EchoString
/prop_tgt/ENABLE_EXPORTS
@@ -195,6 +202,7 @@ Properties on Targets
/prop_tgt/Fortran_FORMAT
/prop_tgt/Fortran_MODULE_DIRECTORY
/prop_tgt/FRAMEWORK
+ /prop_tgt/FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG
/prop_tgt/FRAMEWORK_VERSION
/prop_tgt/GENERATOR_FILE_NAME
/prop_tgt/GHS_INTEGRITY_APP
@@ -251,6 +259,7 @@ Properties on Targets
/prop_tgt/IOS_INSTALL_COMBINED
/prop_tgt/JOB_POOL_COMPILE
/prop_tgt/JOB_POOL_LINK
+ /prop_tgt/JOB_POOL_PRECOMPILE_HEADER
/prop_tgt/LABELS
/prop_tgt/LANG_CLANG_TIDY
/prop_tgt/LANG_COMPILER_LAUNCHER
@@ -279,6 +288,8 @@ Properties on Targets
/prop_tgt/LINK_WHAT_YOU_USE
/prop_tgt/LOCATION_CONFIG
/prop_tgt/LOCATION
+ /prop_tgt/MACHO_COMPATIBILITY_VERSION
+ /prop_tgt/MACHO_CURRENT_VERSION
/prop_tgt/MACOSX_BUNDLE_INFO_PLIST
/prop_tgt/MACOSX_BUNDLE
/prop_tgt/MACOSX_FRAMEWORK_INFO_PLIST
@@ -335,6 +346,7 @@ Properties on Targets
/prop_tgt/UNITY_BUILD_BATCH_SIZE
/prop_tgt/UNITY_BUILD_CODE_AFTER_INCLUDE
/prop_tgt/UNITY_BUILD_CODE_BEFORE_INCLUDE
+ /prop_tgt/UNITY_BUILD_MODE
/prop_tgt/VERSION
/prop_tgt/VISIBILITY_INLINES_HIDDEN
/prop_tgt/VS_CONFIGURATION_TYPE
@@ -348,6 +360,7 @@ Properties on Targets
/prop_tgt/VS_DOTNET_REFERENCES
/prop_tgt/VS_DOTNET_REFERENCES_COPY_LOCAL
/prop_tgt/VS_DOTNET_TARGET_FRAMEWORK_VERSION
+ /prop_tgt/VS_DOTNET_DOCUMENTATION_FILE
/prop_tgt/VS_DPI_AWARE
/prop_tgt/VS_GLOBAL_KEYWORD
/prop_tgt/VS_GLOBAL_PROJECT_TYPES
@@ -360,12 +373,15 @@ Properties on Targets
/prop_tgt/VS_MOBILE_EXTENSIONS_VERSION
/prop_tgt/VS_NO_SOLUTION_DEPLOY
/prop_tgt/VS_PACKAGE_REFERENCES
+ /prop_tgt/VS_PLATFORM_TOOLSET
/prop_tgt/VS_PROJECT_IMPORT
/prop_tgt/VS_SCC_AUXPATH
/prop_tgt/VS_SCC_LOCALPATH
/prop_tgt/VS_SCC_PROJECTNAME
/prop_tgt/VS_SCC_PROVIDER
/prop_tgt/VS_SDK_REFERENCES
+ /prop_tgt/VS_SOLUTION_DEPLOY
+ /prop_tgt/VS_SOURCE_SETTINGS_tool
/prop_tgt/VS_USER_PROPS
/prop_tgt/VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION
/prop_tgt/VS_WINRT_COMPONENT
@@ -396,6 +412,7 @@ 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_WORKING_DIRECTORY
/prop_tgt/XCODE_SCHEME_ZOMBIE_OBJECTS
/prop_tgt/XCTEST
@@ -442,8 +459,8 @@ Properties on Source Files
:maxdepth: 1
/prop_sf/ABSTRACT
- /prop_sf/AUTOUIC_OPTIONS
/prop_sf/AUTORCC_OPTIONS
+ /prop_sf/AUTOUIC_OPTIONS
/prop_sf/COMPILE_DEFINITIONS
/prop_sf/COMPILE_FLAGS
/prop_sf/COMPILE_OPTIONS
@@ -468,12 +485,14 @@ Properties on Source Files
/prop_sf/Swift_DEPENDENCIES_FILE
/prop_sf/Swift_DIAGNOSTICS_FILE
/prop_sf/SYMBOLIC
+ /prop_sf/UNITY_GROUP
/prop_sf/VS_COPY_TO_OUT_DIR
/prop_sf/VS_CSHARP_tagname
/prop_sf/VS_DEPLOYMENT_CONTENT
/prop_sf/VS_DEPLOYMENT_LOCATION
/prop_sf/VS_INCLUDE_IN_VSIX
/prop_sf/VS_RESOURCE_GENERATOR
+ /prop_sf/VS_SETTINGS
/prop_sf/VS_SHADER_DISABLE_OPTIMIZATIONS
/prop_sf/VS_SHADER_ENABLE_DEBUG
/prop_sf/VS_SHADER_ENTRYPOINT
diff --git a/Help/manual/cmake-toolchains.7.rst b/Help/manual/cmake-toolchains.7.rst
index f233d08..e8badd4 100644
--- a/Help/manual/cmake-toolchains.7.rst
+++ b/Help/manual/cmake-toolchains.7.rst
@@ -233,6 +233,9 @@ value to those supported compilers when compiling:
set(CMAKE_CXX_COMPILER QCC)
set(CMAKE_CXX_COMPILER_TARGET ${arch})
+ set(CMAKE_SYSROOT $ENV{QNX_TARGET})
+
+
Cross Compiling for Windows CE
------------------------------
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 53b7f8d..7d802e1 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -14,6 +14,7 @@ For general information on variables, see the
:ref:`Variables <CMake Language Variables>`
section in the cmake-language manual.
+.. include:: ID_RESERVE.txt
Variables that Provide Information
==================================
@@ -37,17 +38,24 @@ Variables that Provide Information
/variable/CMAKE_CROSSCOMPILING_EMULATOR
/variable/CMAKE_CTEST_COMMAND
/variable/CMAKE_CURRENT_BINARY_DIR
+ /variable/CMAKE_CURRENT_FUNCTION
+ /variable/CMAKE_CURRENT_FUNCTION_LIST_DIR
+ /variable/CMAKE_CURRENT_FUNCTION_LIST_FILE
+ /variable/CMAKE_CURRENT_FUNCTION_LIST_LINE
/variable/CMAKE_CURRENT_LIST_DIR
/variable/CMAKE_CURRENT_LIST_FILE
/variable/CMAKE_CURRENT_LIST_LINE
/variable/CMAKE_CURRENT_SOURCE_DIR
+ /variable/CMAKE_DEBUG_TARGET_PROPERTIES
/variable/CMAKE_DIRECTORY_LABELS
/variable/CMAKE_DL_LIBS
+ /variable/CMAKE_DOTNET_TARGET_FRAMEWORK
/variable/CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION
/variable/CMAKE_EDIT_COMMAND
/variable/CMAKE_EXECUTABLE_SUFFIX
/variable/CMAKE_EXTRA_GENERATOR
/variable/CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES
+ /variable/CMAKE_FIND_DEBUG_MODE
/variable/CMAKE_FIND_PACKAGE_NAME
/variable/CMAKE_FIND_PACKAGE_SORT_DIRECTION
/variable/CMAKE_FIND_PACKAGE_SORT_ORDER
@@ -59,6 +67,7 @@ Variables that Provide Information
/variable/CMAKE_IMPORT_LIBRARY_SUFFIX
/variable/CMAKE_JOB_POOL_COMPILE
/variable/CMAKE_JOB_POOL_LINK
+ /variable/CMAKE_JOB_POOL_PRECOMPILE_HEADER
/variable/CMAKE_JOB_POOLS
/variable/CMAKE_LANG_COMPILER_AR
/variable/CMAKE_LANG_COMPILER_RANLIB
@@ -70,7 +79,6 @@ Variables that Provide Information
/variable/CMAKE_MAKE_PROGRAM
/variable/CMAKE_MATCH_COUNT
/variable/CMAKE_MATCH_n
- /variable/CMAKE_MESSAGE_INDENT
/variable/CMAKE_MINIMUM_REQUIRED_VERSION
/variable/CMAKE_MINOR_VERSION
/variable/CMAKE_NETRC
@@ -155,7 +163,6 @@ Variables that Change Behavior
/variable/CMAKE_CODELITE_USE_TARGETS
/variable/CMAKE_COLOR_MAKEFILE
/variable/CMAKE_CONFIGURATION_TYPES
- /variable/CMAKE_DEBUG_TARGET_PROPERTIES
/variable/CMAKE_DEPENDS_IN_PROJECT_ONLY
/variable/CMAKE_DISABLE_FIND_PACKAGE_PackageName
/variable/CMAKE_ECLIPSE_GENERATE_LINKED_RESOURCES
@@ -206,6 +213,10 @@ Variables that Change Behavior
/variable/CMAKE_LINK_DIRECTORIES_BEFORE
/variable/CMAKE_MFC_FLAG
/variable/CMAKE_MAXIMUM_RECURSION_DEPTH
+ /variable/CMAKE_MESSAGE_CONTEXT
+ /variable/CMAKE_MESSAGE_CONTEXT_SHOW
+ /variable/CMAKE_MESSAGE_INDENT
+ /variable/CMAKE_MESSAGE_LOG_LEVEL
/variable/CMAKE_MODULE_PATH
/variable/CMAKE_POLICY_DEFAULT_CMPNNNN
/variable/CMAKE_POLICY_WARNING_CMPNNNN
@@ -214,6 +225,7 @@ Variables that Change Behavior
/variable/CMAKE_PROJECT_INCLUDE
/variable/CMAKE_PROJECT_INCLUDE_BEFORE
/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE
+ /variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE_BEFORE
/variable/CMAKE_SKIP_INSTALL_ALL_DEPENDENCY
/variable/CMAKE_STAGING_PREFIX
/variable/CMAKE_SUBLIME_TEXT_2_ENV_SETTINGS
@@ -239,6 +251,7 @@ Variables that Change Behavior
/variable/CMAKE_XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER
/variable/CMAKE_XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS
/variable/CMAKE_XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE
+ /variable/CMAKE_XCODE_SCHEME_ENVIRONMENT
/variable/CMAKE_XCODE_SCHEME_GUARD_MALLOC
/variable/CMAKE_XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP
/variable/CMAKE_XCODE_SCHEME_MALLOC_GUARD_EDGES
@@ -248,6 +261,7 @@ 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_WORKING_DIRECTORY
/variable/CMAKE_XCODE_SCHEME_ZOMBIE_OBJECTS
/variable/PackageName_ROOT
@@ -309,6 +323,7 @@ Variables that Control the Build
.. toctree::
:maxdepth: 1
+ /variable/CMAKE_AIX_EXPORT_ALL_SYMBOLS
/variable/CMAKE_ANDROID_ANT_ADDITIONAL_OPTIONS
/variable/CMAKE_ANDROID_API
/variable/CMAKE_ANDROID_API_MIN
@@ -357,9 +372,14 @@ Variables that Control the Build
/variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY
/variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG
/variable/CMAKE_CONFIG_POSTFIX
+ /variable/CMAKE_CROSS_CONFIGS
+ /variable/CMAKE_CTEST_ARGUMENTS
/variable/CMAKE_CUDA_SEPARABLE_COMPILATION
/variable/CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS
+ /variable/CMAKE_CUDA_RUNTIME_LIBRARY
/variable/CMAKE_DEBUG_POSTFIX
+ /variable/CMAKE_DEFAULT_BUILD_TYPE
+ /variable/CMAKE_DEFAULT_CONFIGS
/variable/CMAKE_DISABLE_PRECOMPILE_HEADERS
/variable/CMAKE_ENABLE_EXPORTS
/variable/CMAKE_EXE_LINKER_FLAGS
@@ -368,6 +388,7 @@ Variables that Control the Build
/variable/CMAKE_EXE_LINKER_FLAGS_INIT
/variable/CMAKE_FOLDER
/variable/CMAKE_FRAMEWORK
+ /variable/CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG
/variable/CMAKE_Fortran_FORMAT
/variable/CMAKE_Fortran_MODULE_DIRECTORY
/variable/CMAKE_GHS_NO_SOURCE_GROUP_FILE
@@ -417,6 +438,7 @@ Variables that Control the Build
/variable/CMAKE_OSX_ARCHITECTURES
/variable/CMAKE_OSX_DEPLOYMENT_TARGET
/variable/CMAKE_OSX_SYSROOT
+ /variable/CMAKE_PCH_WARN_INVALID
/variable/CMAKE_PDB_OUTPUT_DIRECTORY
/variable/CMAKE_PDB_OUTPUT_DIRECTORY_CONFIG
/variable/CMAKE_POSITION_INDEPENDENT_CODE
@@ -466,6 +488,8 @@ Variables for Languages
/variable/CMAKE_COMPILER_IS_GNUCC
/variable/CMAKE_COMPILER_IS_GNUCXX
/variable/CMAKE_COMPILER_IS_GNUG77
+ /variable/CMAKE_CUDA_ARCHITECTURES
+ /variable/CMAKE_CUDA_COMPILE_FEATURES
/variable/CMAKE_CUDA_HOST_COMPILER
/variable/CMAKE_CUDA_EXTENSIONS
/variable/CMAKE_CUDA_STANDARD
@@ -600,6 +624,7 @@ Variables for CTest
/variable/CTEST_P4_COMMAND
/variable/CTEST_P4_OPTIONS
/variable/CTEST_P4_UPDATE_OPTIONS
+ /variable/CTEST_RESOURCE_SPEC_FILE
/variable/CTEST_RUN_CURRENT_SCRIPT
/variable/CTEST_SCP_COMMAND
/variable/CTEST_SITE
diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst
index 4ab55a0..9becfc6 100644
--- a/Help/manual/cmake.1.rst
+++ b/Help/manual/cmake.1.rst
@@ -206,9 +206,24 @@ Options
The :command:`message` command will only output messages of the specified
log level or higher. The default log level is ``STATUS``.
+ To make a log level persist between CMake runs, set
+ :variable:`CMAKE_MESSAGE_LOG_LEVEL` as a cache variable instead.
+ If both the command line option and the variable are given, the command line
+ option takes precedence.
+
For backward compatibility reasons, ``--loglevel`` is also accepted as a
synonym for this option.
+``--log-context``
+ Enable the :command:`message` command outputting context attached to each
+ message.
+
+ This option turns on showing context for the current CMake run only.
+ To make showing the context persistent for all subsequent CMake runs, set
+ :variable:`CMAKE_MESSAGE_CONTEXT_SHOW` as a cache variable instead.
+ When this command line option is given, :variable:`CMAKE_MESSAGE_CONTEXT_SHOW`
+ is ignored.
+
``--debug-trycompile``
Do not delete the :command:`try_compile` build tree.
Only useful on one :command:`try_compile` at a time.
@@ -226,6 +241,14 @@ Options
Print extra information during the cmake run like stack traces with
:command:`message(SEND_ERROR)` calls.
+``--debug-find``
+ Put cmake find commands in a debug mode.
+
+ Print extra find call information during the cmake run to standard
+ error. Output is designed for human consumption and not for parsing.
+ See also the :variable:`CMAKE_FIND_DEBUG_MODE` variable for debugging
+ a more local part of the project.
+
``--trace``
Put cmake in trace mode.
@@ -236,6 +259,74 @@ Options
Like ``--trace``, but with variables expanded.
+``--trace-format=<format>``
+ Put cmake in trace mode and sets the trace output format.
+
+ ``<format>`` can be one of the following values.
+
+ ``human``
+ Prints each trace line in a human-readable format. This is the
+ default format.
+
+ ``json-v1``
+ Prints each line as a separate JSON document. Each document is
+ separated by a newline ( ``\n`` ). It is guaranteed that no
+ newline characters will be present inside a JSON document.
+
+ JSON trace format:
+
+ .. code-block:: json
+
+ {
+ "file": "/full/path/to/the/CMake/file.txt",
+ "line": 0,
+ "cmd": "add_executable",
+ "args": ["foo", "bar"],
+ "time": 1579512535.9687231,
+ "frame": 2
+ }
+
+ The members are:
+
+ ``file``
+ The full path to the CMake source file where the function
+ was called.
+
+ ``line``
+ The line in ``file`` of the function call.
+
+ ``cmd``
+ The name of the function that was called.
+
+ ``args``
+ A string list of all function parameters.
+
+ ``time``
+ Timestamp (seconds since epoch) of the function call.
+
+ ``frame``
+ Stack frame depth of the function that was called.
+
+ Additionally, the first JSON document outputted contains the
+ ``version`` key for the current major and minor version of the
+
+ JSON trace format:
+
+ .. code-block:: json
+
+ {
+ "version": {
+ "major": 1,
+ "minor": 0
+ }
+ }
+
+ The members are:
+
+ ``version``
+ Indicates the version of the JSON format. The version has a
+ major and minor components following semantic version conventions.
+
``--trace-source=<file>``
Put cmake in trace mode, but output only lines of a specified file.
@@ -267,6 +358,20 @@ Options
in :variable:`CMAKE_SOURCE_DIR` and :variable:`CMAKE_BINARY_DIR`.
This flag tells CMake to warn about other files as well.
+``--profiling-output=<path>``
+ Used in conjuction with ``--profiling-format`` to output to a given path.
+
+``--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
+ applications should be used to process the output into human readable format.
+
+ Currently supported values are:
+ ``google-trace`` Outputs in Google Trace Format, which can be parsed by the
+ about:tracing tab of Google Chrome or using a plugin for a tool like Trace
+ Compass.
+
.. _`Build Tool Mode`:
Build a Project
@@ -376,13 +481,17 @@ Run a Script
.. code-block:: shell
- cmake [{-D <var>=<value>}...] -P <cmake-script-file>
+ cmake [{-D <var>=<value>}...] -P <cmake-script-file> [-- <unparsed-options>...]
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
+script (including the ``--`` itself).
+
Run a Command-Line Tool
=======================
@@ -449,6 +558,9 @@ Available commands are:
``serverMode``
``true`` if cmake supports server-mode and ``false`` otherwise.
+``cat <files>...``
+ Concatenate files and print on the standard output.
+
``chdir <dir> <cmd> [<arg>...]``
Change the current working directory and run a command.
@@ -539,22 +651,38 @@ Available commands are:
7a0b54896fe5e70cca6dd643ad6f672614b189bf26f8153061c4d219474b05dad08c4e729af9f4b009f1a1a280cb625454bf587c690f4617c27e3aebdf3b7a2d file2.txt
``remove [-f] <file>...``
- Remove the file(s). If any of the listed files already do not
- exist, the command returns a non-zero exit code, but no message
- is logged. The ``-f`` option changes the behavior to return a
+ .. deprecated:: 3.17
+
+ Remove the file(s). The planned behaviour was that if any of the
+ listed files already do not exist, the command returns a non-zero exit code,
+ but no message is logged. The ``-f`` option changes the behavior to return a
zero exit code (i.e. success) in such situations instead.
``remove`` does not follow symlinks. That means it remove only symlinks
and not files it point to.
+ The implementation was buggy and always returned 0. It cannot be fixed without
+ breaking backwards compatibility. Use ``rm`` instead.
+
``remove_directory <dir>...``
- Remove ``<dir>`` directories and their contents. If a directory does
+ .. deprecated:: 3.17
+
+ Remove ``<dir>`` directories and their contents. If a directory does
not exist it will be silently ignored. If ``<dir>`` is a symlink to
a directory, just the symlink will be removed.
+ Use ``rm`` instead.
``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>...``
+ Remove the files ``<file>`` or directories ``dir``.
+ Use ``-r`` or ``-R`` to remove directories and their contents recursively.
+ If any of the listed files/directories do not exist, the command returns a
+ non-zero exit code, but no message is logged. The ``-f`` option changes
+ the behavior to return a zero exit code (i.e. success) in such
+ situations instead.
+
``server``
Launch :manual:`cmake-server(7)` mode.
diff --git a/Help/manual/ctest.1.rst b/Help/manual/ctest.1.rst
index e29ebca..5f953b3 100644
--- a/Help/manual/ctest.1.rst
+++ b/Help/manual/ctest.1.rst
@@ -72,6 +72,9 @@ Options
This option can also be enabled by setting the
:envvar:`CTEST_OUTPUT_ON_FAILURE` environment variable
+``--stop-on-failure``
+ Stop running the tests when the first failure happens.
+
``-F``
Enable failover.
@@ -261,10 +264,27 @@ Options
fail, subsequent calls to CTest with the ``--rerun-failed`` option will run
the set of tests that most recently failed (if any).
-``--repeat-until-fail <n>``
- Require each test to run ``<n>`` times without failing in order to pass.
+``--repeat <mode>:<n>``
+ Run tests repeatedly based on the given ``<mode>`` up to ``<n>`` times.
+ The modes are:
+
+ ``until-fail``
+ Require each test to run ``<n>`` times without failing in order to pass.
+ This is useful in finding sporadic failures in test cases.
- This is useful in finding sporadic failures in test cases.
+ ``until-pass``
+ Allow each test to run up to ``<n>`` times in order to pass.
+ Repeats tests if they fail for any reason.
+ This is useful in tolerating sporadic failures in test cases.
+
+ ``after-timeout``
+ Allow each test to run up to ``<n>`` times in order to pass.
+ Repeats tests only if they timeout.
+ This is useful in tolerating sporadic timeouts in test cases
+ on busy machines.
+
+``--repeat-until-fail <n>``
+ Equivalent to ``--repeat until-fail:<n>``.
``--max-width <width>``
Set the max width for a test name to output.
@@ -353,6 +373,14 @@ See `Build and Test Mode`_.
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.
+
+ 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.
+
.. include:: OPTIONS_HELP.txt
.. _`Label and Subproject Summary`:
@@ -969,8 +997,12 @@ Configuration settings include:
``ResourceSpecFile``
Specify a
- :ref:`resource specification file <ctest-resource-specification-file>`. See
- :ref:`ctest-resource-allocation` for more information.
+ :ref:`resource specification file <ctest-resource-specification-file>`.
+
+ * `CTest Script`_ variable: :variable:`CTEST_RESOURCE_SPEC_FILE`
+ * :module:`CTest` module variable: ``CTEST_RESOURCE_SPEC_FILE``
+
+ See :ref:`ctest-resource-allocation` for more information.
``LabelsForSubprojects``
Specify a semicolon-separated list of labels that will be treated as
@@ -1096,6 +1128,20 @@ Additional configuration settings include:
* `CTest Script`_ variable: none
* :module:`CTest` module variable: ``VALGRIND_COMMAND_OPTIONS``
+``DrMemoryCommand``
+ Specify a ``MemoryCheckCommand`` that is known to be a command-line
+ compatible with DrMemory.
+
+ * `CTest Script`_ variable: none
+ * :module:`CTest` module variable: ``DRMEMORY_COMMAND``
+
+``DrMemoryCommandOptions``
+ Specify command-line options to the ``DrMemoryCommand`` tool.
+ They will be placed prior to the test command line.
+
+ * `CTest Script`_ variable: none
+ * :module:`CTest` module variable: ``DRMEMORY_COMMAND_OPTIONS``
+
.. _`CTest Submit Step`:
CTest Submit Step
@@ -1292,6 +1338,15 @@ the running machine. This allows CTest to internally keep track of which
resources are in use and which are free, scheduling tests in a way that
prevents them from trying to claim resources that are not available.
+When the resource allocation feature is used, CTest will not oversubscribe
+resources. For example, if a resource has 8 slots, CTest will not run tests
+that collectively use more than 8 slots at a time. This has the effect of
+limiting how many tests can run at any given time, even if a high ``-j``
+argument is used, if those tests all use some slots from the same resource.
+In addition, it means that a single test that uses more of a resource than is
+available on a machine will not run at all (and will be reported as
+``Not Run``).
+
A common use case for this feature is for tests that require the use of a GPU.
Multiple tests can simultaneously allocate memory from a GPU, but if too many
tests try to do this at once, some of them will fail to allocate, resulting in
diff --git a/Help/module/FindCUDAToolkit.rst b/Help/module/FindCUDAToolkit.rst
new file mode 100644
index 0000000..5f01d68
--- /dev/null
+++ b/Help/module/FindCUDAToolkit.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindCUDAToolkit.cmake
diff --git a/Help/policy/CMP0098.rst b/Help/policy/CMP0098.rst
new file mode 100644
index 0000000..6d1443b
--- /dev/null
+++ b/Help/policy/CMP0098.rst
@@ -0,0 +1,30 @@
+CMP0098
+-------
+
+:module:`FindFLEX` runs ``flex`` in directory
+:variable:`CMAKE_CURRENT_BINARY_DIR` when executing.
+
+The module provides a ``FLEX_TARGET`` macro which generates FLEX output.
+In CMake 3.16 and below the macro would generate a custom command that runs
+``flex`` in the current source directory. CMake 3.17 and later prefer to
+run it in the build directory and use :variable:`CMAKE_CURRENT_BINARY_DIR`
+as the ``WORKING_DIRECTORY`` of its :command:`add_custom_command` invocation.
+This ensures that any implicitly generated file is written relative to the
+build tree rather than the source tree, unless the generated file is
+provided as absolute path.
+
+This policy provides compatibility for projects that have not been updated
+to expect the new behavior.
+
+The ``OLD`` behavior for this policy is for ``FLEX_TARGET`` to use
+the current source directory for the ``WORKING_DIRECTORY`` and where
+to generate implicit files. The ``NEW`` behavior of this policy is to
+use the current binary directory for the ``WORKING_DIRECTORY`` relative to
+which implicit files are generated unless provided as absolute path.
+
+This policy was introduced in CMake version 3.17. Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+Unlike many policies, CMake version |release| does *not* warn
+when this policy is not set and simply uses ``OLD`` behavior.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0099.rst b/Help/policy/CMP0099.rst
new file mode 100644
index 0000000..c897e7b
--- /dev/null
+++ b/Help/policy/CMP0099.rst
@@ -0,0 +1,24 @@
+CMP0099
+-------
+
+Target link properties :prop_tgt:`INTERFACE_LINK_OPTIONS`,
+:prop_tgt:`INTERFACE_LINK_DIRECTORIES` and :prop_tgt:`INTERFACE_LINK_DEPENDS`
+are now transitive over private dependencies of static libraries.
+
+In CMake 3.16 and below the interface link properties attached to libraries
+are not propagated for private dependencies of static libraries.
+Only the libraries themselves are propagated to link the dependent binary.
+CMake 3.17 and later prefer to propagate all interface link properties.
+This policy provides compatibility for projects that have not been updated
+to expect the new behavior.
+
+The ``OLD`` behavior for this policy is to not propagate interface link
+properties. The ``NEW`` behavior of this policy is to propagate interface link
+properties.
+
+This policy was introduced in CMake version 3.17. Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+Unlike many policies, CMake version |release| does *not* warn
+when this policy is not set and simply uses ``OLD`` behavior.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0100.rst b/Help/policy/CMP0100.rst
new file mode 100644
index 0000000..b24d013
--- /dev/null
+++ b/Help/policy/CMP0100.rst
@@ -0,0 +1,40 @@
+CMP0100
+-------
+
+Let :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC` process
+header files that end with a ``.hh`` extension.
+
+Since version 3.17, CMake processes header files that end with a
+``.hh`` extension in :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC`.
+In earlier CMake versions, these header files were ignored by
+:prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC`.
+
+This policy affects how header files that end with a ``.hh`` extension
+get treated in :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC`.
+
+The ``OLD`` behavior for this policy is to ignore ``.hh`` header files
+in :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC`.
+
+The ``NEW`` behavior for this policy is to process ``.hh`` header files
+in :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC` just like other header files.
+
+.. note::
+
+ To silence the ``CMP0100`` warning source files can be excluded from
+ :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC` processing by setting the
+ source file properties :prop_sf:`SKIP_AUTOMOC`, :prop_sf:`SKIP_AUTOUIC` or
+ :prop_sf:`SKIP_AUTOGEN`.
+
+ .. code-block:: cmake
+
+ # Source skip example:
+ set_property(SOURCE /path/to/file1.hh PROPERTY SKIP_AUTOMOC ON)
+ set_property(SOURCE /path/to/file2.hh PROPERTY SKIP_AUTOUIC ON)
+ set_property(SOURCE /path/to/file3.hh PROPERTY SKIP_AUTOGEN ON)
+
+This policy was introduced in CMake version 3.17.0. 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/policy/CMP0101.rst b/Help/policy/CMP0101.rst
new file mode 100644
index 0000000..9941acf
--- /dev/null
+++ b/Help/policy/CMP0101.rst
@@ -0,0 +1,20 @@
+CMP0101
+-------
+
+:command:`target_compile_options` now honors ``BEFORE`` keyword in all scopes.
+
+In CMake 3.16 and below the :command:`target_compile_options` ignores the
+``BEFORE`` keyword in private scope. CMake 3.17 and later honors
+``BEFORE`` keyword in all scopes. This policy provides compatibility for
+projects that have not been updated to expect the new behavior.
+
+The ``OLD`` behavior for this policy is to not honor ``BEFORE`` keyword in
+private scope. The ``NEW`` behavior of this policy is to honor
+``BEFORE`` keyword in all scopes.
+
+This policy was introduced in CMake version 3.17. Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+Unlike many policies, CMake version |release| does *not* warn
+when this policy is not set and simply uses ``OLD`` behavior.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0102.rst b/Help/policy/CMP0102.rst
new file mode 100644
index 0000000..9859006
--- /dev/null
+++ b/Help/policy/CMP0102.rst
@@ -0,0 +1,25 @@
+CMP0102
+-------
+
+The :command:`mark_as_advanced` command no longer creates a cache entry if one
+does not already exist.
+
+In CMake 3.16 and below, if a variable was not defined at all or just defined
+locally, the :command:`mark_as_advanced` command would create a new cache
+entry with an ``UNINITIALIZED`` type and no value. When a :command:`find_path`
+(or other similar ``find_`` command) would next run, it would find this
+undefined cache entry and set it up with an empty string value. This process
+would end up deleting the local variable in the process (due to the way the
+cache works), effectively clearing any stored ``find_`` results that were only
+available in the local scope.
+
+The ``OLD`` behavior for this policy is to create the empty cache definition.
+The ``NEW`` behavior of this policy is to ignore variables which do not
+already exist in the cache.
+
+This policy was introduced in CMake version 3.17. Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+Unlike many policies, CMake version |release| does *not* warn
+when this policy is not set and simply uses ``OLD`` behavior.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0103.rst b/Help/policy/CMP0103.rst
new file mode 100644
index 0000000..223e0cb
--- /dev/null
+++ b/Help/policy/CMP0103.rst
@@ -0,0 +1,22 @@
+CMP0103
+-------
+
+Multiple calls to :command:`export` command with same ``FILE`` without
+``APPEND`` is no longer allowed.
+
+In CMake 3.17 and below, multiple calls to :command:`export` command with the
+same ``FILE`` without ``APPEND`` are accepted silently but only the last
+occurrence is taken into account during the generation.
+
+The ``OLD`` behavior for this policy is to ignore the multiple occurrences of
+ :command:`export` command except the last one.
+
+The ``NEW`` behavior of this policy is to raise an error on second call to
+:command:`export` command with same ``FILE`` without ``APPEND``.
+
+This policy was introduced in CMake version 3.18. 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/policy/CMP0104.rst b/Help/policy/CMP0104.rst
new file mode 100644
index 0000000..ca2c571
--- /dev/null
+++ b/Help/policy/CMP0104.rst
@@ -0,0 +1,31 @@
+CMP0104
+-------
+
+Initialize :variable:`CMAKE_CUDA_ARCHITECTURES` when
+:variable:`CMAKE_CUDA_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` is ``NVIDIA``.
+Raise an error if :prop_tgt:`CUDA_ARCHITECTURES` is empty.
+
+:variable:`CMAKE_CUDA_ARCHITECTURES` introduced in CMake 3.18 is used to
+initialize :prop_tgt:`CUDA_ARCHITECTURES`, which passes correct code generation
+flags to the CUDA compiler.
+
+Previous to this users had to manually specify the code generation flags. This
+policy is for backwards compatibility with manually specifying code generation
+flags.
+
+The ``OLD`` behavior for this policy is to not initialize
+:variable:`CMAKE_CUDA_ARCHITECTURES` when
+:variable:`CMAKE_CUDA_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` is ``NVIDIA``.
+Empty :prop_tgt:`CUDA_ARCHITECTURES` is allowed.
+
+The ``NEW`` behavior of this policy is to initialize
+:variable:`CMAKE_CUDA_ARCHITECTURES` when
+:variable:`CMAKE_CUDA_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` is ``NVIDIA``
+and raise an error if :prop_tgt:`CUDA_ARCHITECTURES` is empty during generation.
+
+This policy was introduced in CMake version 3.18. 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/policy/CMP0105.rst b/Help/policy/CMP0105.rst
new file mode 100644
index 0000000..19a1edb
--- /dev/null
+++ b/Help/policy/CMP0105.rst
@@ -0,0 +1,19 @@
+CMP0105
+-------
+
+:prop_tgt:`LINK_OPTIONS` and :prop_tgt:`INTERFACE_LINK_OPTIONS` target
+properties are now used for the device link step.
+
+In CMake 3.17 and below, link options are not used by the device link step.
+
+The ``OLD`` behavior for this policy is to ignore the link options.
+
+The ``NEW`` behavior of this policy is to use the link options during the
+device link step.
+
+This policy was introduced in CMake version 3.17. Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+Unlike many policies, CMake version |release| does *not* warn
+when this policy is not set and simply uses ``OLD`` behavior.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0106.rst b/Help/policy/CMP0106.rst
new file mode 100644
index 0000000..e34d15a
--- /dev/null
+++ b/Help/policy/CMP0106.rst
@@ -0,0 +1,19 @@
+CMP0106
+-------
+
+The :module:`Documentation` module is removed.
+
+The :module:`Documentation` was added as a support mechanism for the VTK
+project and was tuned for that project. Instead of CMake providing this module
+with (now old) VTK patterns for cache variables and required packages, the
+module is now deprecated by CMake itself.
+
+The ``OLD`` behavior of this policy is for :module:`Documentation` to add
+cache variables and find VTK documentation dependent packages. The ``NEW``
+behavior is to act as an empty module.
+
+This policy was introduced in CMake version 3.18. 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_dir/LINK_OPTIONS.rst b/Help/prop_dir/LINK_OPTIONS.rst
index 54ac6dd..f229ba6 100644
--- a/Help/prop_dir/LINK_OPTIONS.rst
+++ b/Help/prop_dir/LINK_OPTIONS.rst
@@ -2,7 +2,7 @@ LINK_OPTIONS
------------
List of options to use for the link step of shared library, module
-and executable targets.
+and executable targets as well as the device link step.
This property holds a :ref:`semicolon-separated list <CMake Language Lists>` of options
given so far to the :command:`add_link_options` command.
diff --git a/Help/prop_gbl/CMAKE_CUDA_KNOWN_FEATURES.rst b/Help/prop_gbl/CMAKE_CUDA_KNOWN_FEATURES.rst
new file mode 100644
index 0000000..44e37fe
--- /dev/null
+++ b/Help/prop_gbl/CMAKE_CUDA_KNOWN_FEATURES.rst
@@ -0,0 +1,30 @@
+CMAKE_CUDA_KNOWN_FEATURES
+-------------------------
+
+List of CUDA features known to this version of CMake.
+
+The features listed in this global property may be known to be available to the
+CUDA compiler. If the feature is available with the C++ compiler, it will
+be listed in the :variable:`CMAKE_CUDA_COMPILE_FEATURES` variable.
+
+The features listed here may be used with the :command:`target_compile_features`
+command. See the :manual:`cmake-compile-features(7)` manual for information on
+compile features and a list of supported compilers.
+
+
+The features known to this version of CMake are:
+
+``cuda_std_03``
+ Compiler mode is at least CUDA/C++ 03.
+
+``cuda_std_11``
+ Compiler mode is at least CUDA/C++ 11.
+
+``cuda_std_14``
+ Compiler mode is at least CUDA/C++ 14.
+
+``cuda_std_17``
+ Compiler mode is at least CUDA/C++ 17.
+
+``cuda_std_20``
+ Compiler mode is at least CUDA/C++ 20.
diff --git a/Help/prop_sf/GENERATED.rst b/Help/prop_sf/GENERATED.rst
index d430ee2..48ff70c 100644
--- a/Help/prop_sf/GENERATED.rst
+++ b/Help/prop_sf/GENERATED.rst
@@ -4,16 +4,29 @@ GENERATED
Is this source file generated as part of the build or CMake process.
Tells the internal CMake engine that a source file is generated by an outside
-process such as another build step, or the execution of CMake itself. This
-information is then used to exempt the file from any existence or validity
-checks. Generated files are created by the execution of commands such as
-:command:`add_custom_command` and :command:`file(GENERATE)`.
-
-When a generated file created by an :command:`add_custom_command` command
-is explicitly listed as a source file for any target in the same
-directory scope (which usually means the same ``CMakeLists.txt`` file),
-CMake will automatically create a dependency to make sure the file is
-generated before building that target.
+process such as another build step, or the execution of CMake itself.
+This information is then used to exempt the file from any existence or
+validity checks.
+
+Any file that is
+
+- created by the execution of commands such as
+ :command:`add_custom_command` and :command:`file(GENERATE)`
+- listed as one of the ``BYPRODUCTS`` of an :command:`add_custom_command`
+ or :command:`add_custom_target` command, or
+- created by a CMake ``AUTOGEN`` operation such as :prop_tgt:`AUTOMOC`,
+ :prop_tgt:`AUTORCC`, or :prop_tgt:`AUTOUIC`
+
+will be marked with the ``GENERATED`` property.
+
+When a generated file created as the ``OUTPUT`` of an
+:command:`add_custom_command` command is explicitly listed as a source file
+for any target in the same directory scope (which usually means the same
+``CMakeLists.txt`` file), CMake will automatically create a dependency to
+make sure the file is generated before building that target.
+
+The :ref:`Makefile Generators` will remove ``GENERATED`` files during
+``make clean``.
Generated sources may be hidden in some IDE tools, while in others they might
be shown. For the special case of sources generated by CMake's :prop_tgt:`AUTOMOC`
diff --git a/Help/prop_sf/SKIP_PRECOMPILE_HEADERS.rst b/Help/prop_sf/SKIP_PRECOMPILE_HEADERS.rst
index 5f39f30..0031da3 100644
--- a/Help/prop_sf/SKIP_PRECOMPILE_HEADERS.rst
+++ b/Help/prop_sf/SKIP_PRECOMPILE_HEADERS.rst
@@ -6,8 +6,8 @@ Is this source file skipped by :prop_tgt:`PRECOMPILE_HEADERS` feature.
This property helps with build problems that one would run into
when using the :prop_tgt:`PRECOMPILE_HEADERS` feature.
-One example would be the usage of Objective-C (*.m) files, and
-Objective-C++ (*.mm) files, which lead to compilation failure
+One example would be the usage of Objective-C (``*.m``) files, and
+Objective-C++ (``*.mm``) files, which lead to compilation failure
because they are treated (in case of Ninja / Makefile generator)
as C, and CXX respectively. The precompile headers are not
compatible between languages.
diff --git a/Help/prop_sf/UNITY_GROUP.rst b/Help/prop_sf/UNITY_GROUP.rst
new file mode 100644
index 0000000..ec6b0f6
--- /dev/null
+++ b/Help/prop_sf/UNITY_GROUP.rst
@@ -0,0 +1,5 @@
+UNITY_GROUP
+-----------
+
+This property controls which *bucket* the source will be part of when
+the :prop_tgt:`UNITY_BUILD_MODE` is set to ``GROUP``.
diff --git a/Help/prop_sf/VS_SETTINGS.rst b/Help/prop_sf/VS_SETTINGS.rst
new file mode 100644
index 0000000..0719406
--- /dev/null
+++ b/Help/prop_sf/VS_SETTINGS.rst
@@ -0,0 +1,18 @@
+VS_SETTINGS
+-----------
+
+Set any item metadata on a non-built file.
+
+Takes a list of ``Key=Value`` pairs. Tells the Visual Studio generator to set
+``Key`` to ``Value`` as item metadata on the file.
+
+For example:
+
+.. code-block:: cmake
+
+ set_property(SOURCE file.hlsl PROPERTY VS_SETTINGS "Key=Value" "Key2=Value2")
+
+will set ``Key`` to ``Value`` and ``Key2`` to ``Value2`` on the
+``file.hlsl`` item as metadata.
+
+Generator expressions are supported.
diff --git a/Help/prop_tgt/AIX_EXPORT_ALL_SYMBOLS.rst b/Help/prop_tgt/AIX_EXPORT_ALL_SYMBOLS.rst
new file mode 100644
index 0000000..15ddc0b
--- /dev/null
+++ b/Help/prop_tgt/AIX_EXPORT_ALL_SYMBOLS.rst
@@ -0,0 +1,12 @@
+AIX_EXPORT_ALL_SYMBOLS
+----------------------
+
+On AIX, CMake automatically exports all symbols from shared libraries, and
+from executables with the :prop_tgt:`ENABLE_EXPORTS` target property set.
+Explicitly disable this boolean property to suppress the behavior and
+export no symbols by default. In this case it is expected that the project
+will use other means to export some symbols.
+
+This property is initialized by the value of
+the :variable:`CMAKE_AIX_EXPORT_ALL_SYMBOLS` variable if it is set
+when a target is created.
diff --git a/Help/prop_tgt/AUTOGEN_PARALLEL.rst b/Help/prop_tgt/AUTOGEN_PARALLEL.rst
index 07fbc5a..968b619 100644
--- a/Help/prop_tgt/AUTOGEN_PARALLEL.rst
+++ b/Help/prop_tgt/AUTOGEN_PARALLEL.rst
@@ -4,9 +4,9 @@ AUTOGEN_PARALLEL
Number of parallel ``moc`` or ``uic`` processes to start when using
:prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC`.
-The custom `<origin>_autogen` target starts a number of threads of which
+The custom ``<origin>_autogen`` target starts a number of threads of which
each one parses a source file and on demand starts a ``moc`` or ``uic``
-process. :prop_tgt:`AUTOGEN_PARALLEL` controls how many parallel threads
+process. ``AUTOGEN_PARALLEL`` controls how many parallel threads
(and therefore ``moc`` or ``uic`` processes) are started.
- An empty (or unset) value or the string ``AUTO`` sets the number of
@@ -14,7 +14,7 @@ process. :prop_tgt:`AUTOGEN_PARALLEL` controls how many parallel threads
- A positive non zero integer value sets the exact thread/process count.
- Otherwise a single thread/process is started.
-By default :prop_tgt:`AUTOGEN_PARALLEL` is initialized from
+By default ``AUTOGEN_PARALLEL`` is initialized from
:variable:`CMAKE_AUTOGEN_PARALLEL`.
See the :manual:`cmake-qt(7)` manual for more information on using CMake
diff --git a/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst b/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst
index d5c5e14..92b52a3 100644
--- a/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst
+++ b/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst
@@ -33,4 +33,4 @@ If :prop_tgt:`AUTOMOC` or :prop_tgt:`AUTOUIC` depends on a file that is either
:prop_sf:`SKIP_AUTOUIC`, :prop_sf:`SKIP_AUTOGEN` or :policy:`CMP0071` or
- a file that isn't in the origin target's sources
-it must added to :prop_tgt:`AUTOGEN_TARGET_DEPENDS`.
+it must be added to :prop_tgt:`AUTOGEN_TARGET_DEPENDS`.
diff --git a/Help/prop_tgt/AUTOMOC.rst b/Help/prop_tgt/AUTOMOC.rst
index f6dfabd..c18859b 100644
--- a/Help/prop_tgt/AUTOMOC.rst
+++ b/Help/prop_tgt/AUTOMOC.rst
@@ -172,7 +172,7 @@ variables. If the call is in a different context than the
then the version variables might not be available to the :prop_tgt:`AUTOMOC`
enabled target.
In that case the version variables can be forwarded from the
-`find_package(Qt[45]...)` calling context to the :command:`add_executable`
+``find_package(Qt[45]...)`` calling context to the :command:`add_executable`
or :command:`add_library` calling context as directory properties.
The following Qt5 example demonstrates the procedure.
diff --git a/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst b/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst
index 69957bf..6eda26c 100644
--- a/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst
+++ b/Help/prop_tgt/AUTOMOC_DEPEND_FILTERS.rst
@@ -26,6 +26,9 @@ See :prop_tgt:`AUTOGEN_TARGET_DEPENDS` for reference.
By default :prop_tgt:`AUTOMOC_DEPEND_FILTERS` is initialized from
:variable:`CMAKE_AUTOMOC_DEPEND_FILTERS`, which is empty by default.
+From Qt 5.15.0 on this variable is ignored as moc is able to output the correct
+dependencies.
+
See the :manual:`cmake-qt(7)` manual for more information on using CMake
with Qt.
diff --git a/Help/prop_tgt/AUTOMOC_MOC_OPTIONS.rst b/Help/prop_tgt/AUTOMOC_MOC_OPTIONS.rst
index ebd5c49..330849b 100644
--- a/Help/prop_tgt/AUTOMOC_MOC_OPTIONS.rst
+++ b/Help/prop_tgt/AUTOMOC_MOC_OPTIONS.rst
@@ -1,7 +1,7 @@
AUTOMOC_MOC_OPTIONS
-------------------
-Additional options for moc when using :prop_tgt:`AUTOMOC`
+Additional options for ``moc`` when using :prop_tgt:`AUTOMOC`
This property is only used if the :prop_tgt:`AUTOMOC` property is ``ON``
for this target. In this case, it holds additional command line
@@ -9,7 +9,9 @@ options which will be used when ``moc`` is executed during the build, i.e.
it is equivalent to the optional ``OPTIONS`` argument of the
:module:`qt4_wrap_cpp() <FindQt4>` macro.
-By default it is empty.
+This property is initialized by the value of the
+:variable:`CMAKE_AUTOMOC_MOC_OPTIONS` variable if it is set when a target
+is created, or an empty string otherwise.
See the :manual:`cmake-qt(7)` manual for more information on using CMake
with Qt.
diff --git a/Help/prop_tgt/AUTOMOC_PATH_PREFIX.rst b/Help/prop_tgt/AUTOMOC_PATH_PREFIX.rst
index e2ebb3f..3e3059d 100644
--- a/Help/prop_tgt/AUTOMOC_PATH_PREFIX.rst
+++ b/Help/prop_tgt/AUTOMOC_PATH_PREFIX.rst
@@ -21,11 +21,11 @@ with Qt.
Reproducible builds
^^^^^^^^^^^^^^^^^^^
-For reproducible builds is is recommended to keep headers that are ``moc``
+For reproducible builds it is recommended to keep headers that are ``moc``
compiled in one of the target
:command:`include directories <target_include_directories>` and set
:prop_tgt:`AUTOMOC_PATH_PREFIX` to ``ON`` (which is the default). This ensures
-that
+that:
- ``moc`` output files are identical on different build setups,
- ``moc`` output files will compile correctly when the source and/or
diff --git a/Help/prop_tgt/AUTORCC.rst b/Help/prop_tgt/AUTORCC.rst
index cca3e58..9a98f44 100644
--- a/Help/prop_tgt/AUTORCC.rst
+++ b/Help/prop_tgt/AUTORCC.rst
@@ -31,9 +31,10 @@ Modifiers
The ``rcc`` executable will be detected automatically, but can be forced to
a certain binary by setting this target property.
-:prop_sf:`AUTORCC_OPTIONS`:
-Additional command line options for ``rcc`` can be set via this ``.qrc``
-source file property.
+:prop_tgt:`AUTORCC_OPTIONS`:
+Additional command line options for ``rcc`` can be set via this target
+property. The corresponding :prop_sf:`AUTORCC_OPTIONS` source file property
+can be used to specify options to be applied only to a specific ``.qrc`` file.
:prop_sf:`SKIP_AUTORCC`:
``.qrc`` files can be excluded from :prop_tgt:`AUTORCC` processing by
diff --git a/Help/prop_tgt/AUTORCC_OPTIONS.rst b/Help/prop_tgt/AUTORCC_OPTIONS.rst
index d6ade5a..5261aff 100644
--- a/Help/prop_tgt/AUTORCC_OPTIONS.rst
+++ b/Help/prop_tgt/AUTORCC_OPTIONS.rst
@@ -8,11 +8,9 @@ when ``rcc`` is executed during the build via :prop_tgt:`AUTORCC`,
i.e. it is equivalent to the optional ``OPTIONS`` argument of the
:module:`qt4_add_resources() <FindQt4>` macro.
-By default it is empty.
-
This property is initialized by the value of the
:variable:`CMAKE_AUTORCC_OPTIONS` variable if it is set when a target is
-created.
+created, or an empty string otherwise.
The options set on the target may be overridden by :prop_sf:`AUTORCC_OPTIONS`
set on the ``.qrc`` source file.
diff --git a/Help/prop_tgt/AUTOUIC.rst b/Help/prop_tgt/AUTOUIC.rst
index 5cf8755..cd24f5e 100644
--- a/Help/prop_tgt/AUTOUIC.rst
+++ b/Help/prop_tgt/AUTOUIC.rst
@@ -52,8 +52,11 @@ Modifiers
The ``uic`` executable will be detected automatically, but can be forced to
a certain binary using this target property.
-:prop_sf:`AUTOUIC_OPTIONS`: Additional command line options for ``uic`` can
-be set via this source file property on a ``<base_name>.ui`` file.
+:prop_tgt:`AUTOUIC_OPTIONS`:
+Additional command line options for ``uic`` can be set via this target
+property. The corresponding :prop_sf:`AUTOUIC_OPTIONS` source file property
+can be used to specify options to be applied only to a specific
+``<base_name>.ui`` file.
:prop_sf:`SKIP_AUTOUIC`:
Source files can be excluded from :prop_tgt:`AUTOUIC` processing by setting
diff --git a/Help/prop_tgt/AUTOUIC_OPTIONS.rst b/Help/prop_tgt/AUTOUIC_OPTIONS.rst
index 3f613b9..425ea1c 100644
--- a/Help/prop_tgt/AUTOUIC_OPTIONS.rst
+++ b/Help/prop_tgt/AUTOUIC_OPTIONS.rst
@@ -8,11 +8,9 @@ This property holds additional command line options which will be used when
equivalent to the optional ``OPTIONS`` argument of the
:module:`qt4_wrap_ui() <FindQt4>` macro.
-By default it is empty.
-
This property is initialized by the value of the
:variable:`CMAKE_AUTOUIC_OPTIONS` variable if it is set when a target is
-created.
+created, or an empty string otherwise.
The options set on the target may be overridden by :prop_sf:`AUTOUIC_OPTIONS`
set on the ``.ui`` source file.
diff --git a/Help/prop_tgt/COMPILE_FEATURES.rst b/Help/prop_tgt/COMPILE_FEATURES.rst
index 195215e..46aec4f 100644
--- a/Help/prop_tgt/COMPILE_FEATURES.rst
+++ b/Help/prop_tgt/COMPILE_FEATURES.rst
@@ -4,7 +4,8 @@ COMPILE_FEATURES
Compiler features enabled for this target.
The list of features in this property are a subset of the features listed
-in the :variable:`CMAKE_CXX_COMPILE_FEATURES` variable.
+in the :variable:`CMAKE_C_COMPILE_FEATURES`, :variable:`CMAKE_CUDA_COMPILE_FEATURES`, and
+:variable:`CMAKE_CXX_COMPILE_FEATURES` variables.
Contents of ``COMPILE_FEATURES`` may use "generator expressions" with the
syntax ``$<...>``. See the :manual:`cmake-generator-expressions(7)` manual for
diff --git a/Help/prop_tgt/CONFIG_POSTFIX.rst b/Help/prop_tgt/CONFIG_POSTFIX.rst
index 11b50b9..5c2fbd7 100644
--- a/Help/prop_tgt/CONFIG_POSTFIX.rst
+++ b/Help/prop_tgt/CONFIG_POSTFIX.rst
@@ -8,3 +8,6 @@ is appended to the target file name built on disk. For non-executable
targets, this property is initialized by the value of the variable
CMAKE_<CONFIG>_POSTFIX if it is set when a target is created. This
property is ignored on the Mac for Frameworks and App Bundles.
+
+For macOS see also the :prop_tgt:`FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>`
+target property.
diff --git a/Help/prop_tgt/CUDA_ARCHITECTURES.rst b/Help/prop_tgt/CUDA_ARCHITECTURES.rst
new file mode 100644
index 0000000..328f40b
--- /dev/null
+++ b/Help/prop_tgt/CUDA_ARCHITECTURES.rst
@@ -0,0 +1,30 @@
+CUDA_ARCHITECTURES
+------------------
+
+List of architectures to generate device code for.
+
+An architecture can be suffixed by either ``-real`` or ``-virtual`` to specify
+the kind of architecture to generate code for.
+If no suffix is given then code is generated for both real and virtual
+architectures.
+
+This property is initialized by the value of the :variable:`CMAKE_CUDA_ARCHITECTURES`
+variable if it is set when a target is created.
+
+The ``CUDA_ARCHITECTURES`` target property must be set to a non-empty value on targets
+that compile CUDA sources, or it is an error. See policy :policy:`CMP0104`.
+
+Examples
+^^^^^^^^
+
+.. code-block:: cmake
+
+ set_property(TARGET tgt PROPERTY CUDA_ARCHITECTURES 35 50 72)
+
+Generates code for real and virtual architectures ``30``, ``50`` and ``72``.
+
+.. code-block:: cmake
+
+ set_property(TARGET tgt PROPERTY CUDA_ARCHITECTURES 70-real 72-virtual)
+
+Generates code for real architecture ``70`` and virtual architecture ``72``.
diff --git a/Help/prop_tgt/CUDA_RUNTIME_LIBRARY-VALUES.txt b/Help/prop_tgt/CUDA_RUNTIME_LIBRARY-VALUES.txt
new file mode 100644
index 0000000..a6d7050
--- /dev/null
+++ b/Help/prop_tgt/CUDA_RUNTIME_LIBRARY-VALUES.txt
@@ -0,0 +1,9 @@
+``None``
+ Link with ``-cudart=none`` or equivalent flag(s) to use no CUDA
+ runtime library.
+``Shared``
+ Link with ``-cudart=shared`` or equivalent flag(s) to use a
+ dynamically-linked CUDA runtime library.
+``Static``
+ Link with ``-cudart=static`` or equivalent flag(s) to use a
+ statically-linked CUDA runtime library.
diff --git a/Help/prop_tgt/CUDA_RUNTIME_LIBRARY.rst b/Help/prop_tgt/CUDA_RUNTIME_LIBRARY.rst
new file mode 100644
index 0000000..0782765
--- /dev/null
+++ b/Help/prop_tgt/CUDA_RUNTIME_LIBRARY.rst
@@ -0,0 +1,21 @@
+CUDA_RUNTIME_LIBRARY
+--------------------
+
+Select the CUDA runtime library for use by compilers targeting the CUDA language.
+
+The allowed case insensitive values are:
+
+.. include:: CUDA_RUNTIME_LIBRARY-VALUES.txt
+
+Contents of ``CUDA_RUNTIME_LIBRARY`` may use
+:manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+If this property is not set then CMake uses the default value
+``Static`` to select the CUDA runtime library.
+
+.. note::
+
+ This property has effect only when the ``CUDA`` language is enabled. To
+ control the CUDA runtime linking when only using the CUDA SDK with the
+ ``C`` or ``C++`` language we recommend using the :module:`FindCUDAToolkit`
+ module.
diff --git a/Help/prop_tgt/DEPRECATION.rst b/Help/prop_tgt/DEPRECATION.rst
new file mode 100644
index 0000000..fef2e2e
--- /dev/null
+++ b/Help/prop_tgt/DEPRECATION.rst
@@ -0,0 +1,7 @@
+DEPRECATION
+-----------
+
+Deprecation message from imported target's developer.
+
+``DEPRECATION`` is the message regarding a deprecation status to be displayed
+to downstream users of a target.
diff --git a/Help/prop_tgt/DOTNET_TARGET_FRAMEWORK.rst b/Help/prop_tgt/DOTNET_TARGET_FRAMEWORK.rst
new file mode 100644
index 0000000..8698eb6
--- /dev/null
+++ b/Help/prop_tgt/DOTNET_TARGET_FRAMEWORK.rst
@@ -0,0 +1,13 @@
+DOTNET_TARGET_FRAMEWORK
+-----------------------
+
+Specify the .NET target framework.
+
+Used to specify the .NET target framework for C++/CLI and C#. For
+example: ``netcoreapp2.1``.
+
+This property is only evaluated for :ref:`Visual Studio Generators`
+VS 2010 and above.
+
+Can be initialized for all targets using the variable
+:variable:`CMAKE_DOTNET_TARGET_FRAMEWORK`.
diff --git a/Help/prop_tgt/DOTNET_TARGET_FRAMEWORK_VERSION.rst b/Help/prop_tgt/DOTNET_TARGET_FRAMEWORK_VERSION.rst
index c100326..b33f4fb 100644
--- a/Help/prop_tgt/DOTNET_TARGET_FRAMEWORK_VERSION.rst
+++ b/Help/prop_tgt/DOTNET_TARGET_FRAMEWORK_VERSION.rst
@@ -3,11 +3,13 @@ DOTNET_TARGET_FRAMEWORK_VERSION
Specify the .NET target framework version.
-Used to specify the .NET target framework version for C++/CLI. For
-example: ``v4.5``.
+Used to specify the .NET target framework version for C++/CLI and C#.
+For example: ``v4.5``.
This property is only evaluated for :ref:`Visual Studio Generators`
VS 2010 and above.
-Can be initialized for all targets using the variable
-:variable:`CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION`.
+To initialize this variable for all targets set
+:variable:`CMAKE_DOTNET_TARGET_FRAMEWORK` or
+:variable:`CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION`. If both are set,
+the latter is ignored.
diff --git a/Help/prop_tgt/FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG.rst b/Help/prop_tgt/FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG.rst
new file mode 100644
index 0000000..2b20bf9
--- /dev/null
+++ b/Help/prop_tgt/FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG.rst
@@ -0,0 +1,25 @@
+FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>
+---------------------------------------
+
+Postfix to append to the framework file name for configuration <CONFIG>,
+when using a multi-config generator (like Xcode and Ninja Multi-Config).
+
+When building with configuration <CONFIG> the value of this property
+is appended to the framework file name built on disk.
+
+For example given a framework called ``my_fw``, a value of ``_debug``
+for the :prop_tgt:`FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>` property, and
+``Debug;Release`` in `CMAKE_CONFIGURATION_TYPES`, the following relevant
+files would be created for the ``Debug`` and ``Release`` configurations:
+
+- Release/my_fw.framework/my_fw
+- Release/my_fw.framework/Versions/A/my_fw
+- Debug/my_fw.framework/my_fw_debug
+- Debug/my_fw.framework/Versions/A/my_fw_debug
+
+For framework targets, this property is initialized by the value of the
+variable :variable:`CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>` if it
+is set when a target is created.
+
+This property is ignored for non-framework targets, and when using single
+config generators.
diff --git a/Help/prop_tgt/INSTALL_NAME_DIR.rst b/Help/prop_tgt/INSTALL_NAME_DIR.rst
index 2216072..747615a 100644
--- a/Help/prop_tgt/INSTALL_NAME_DIR.rst
+++ b/Help/prop_tgt/INSTALL_NAME_DIR.rst
@@ -10,3 +10,7 @@ installed targets.
This property is initialized by the value of the variable
:variable:`CMAKE_INSTALL_NAME_DIR` if it is set when a target is
created.
+
+This property supports :manual:`generator expressions <cmake-generator-expressions(7)>`.
+In particular, the ``$<INSTALL_PREFIX>`` generator expression can be used to set the
+directory relative to the install-time prefix.
diff --git a/Help/prop_tgt/INSTALL_RPATH.rst b/Help/prop_tgt/INSTALL_RPATH.rst
index 93b4488..4549b92 100644
--- a/Help/prop_tgt/INSTALL_RPATH.rst
+++ b/Help/prop_tgt/INSTALL_RPATH.rst
@@ -8,5 +8,9 @@ targets (for platforms that support it). This property is initialized
by the value of the variable :variable:`CMAKE_INSTALL_RPATH` if it is set when
a target is created.
+Because the rpath may contain ``${ORIGIN}``, which coincides with CMake syntax,
+the contents of ``INSTALL_RPATH`` are properly escaped in the
+``cmake_install.cmake`` script (see policy :policy:`CMP0095`.)
+
This property supports
:manual:`generator expressions <cmake-generator-expressions(7)>`.
diff --git a/Help/prop_tgt/INSTALL_RPATH_USE_LINK_PATH.rst b/Help/prop_tgt/INSTALL_RPATH_USE_LINK_PATH.rst
index d8be954..d16a7a1 100644
--- a/Help/prop_tgt/INSTALL_RPATH_USE_LINK_PATH.rst
+++ b/Help/prop_tgt/INSTALL_RPATH_USE_LINK_PATH.rst
@@ -3,8 +3,12 @@ INSTALL_RPATH_USE_LINK_PATH
Add paths to linker search and installed rpath.
-``INSTALL_RPATH_USE_LINK_PATH`` is a boolean that if set to ``True`` will
-append directories in the linker search path and outside the project
-to the :prop_tgt:`INSTALL_RPATH`. This property is initialized by the value of
-the variable ``CMAKE_INSTALL_RPATH_USE_LINK_PATH`` if it is set when a
-target is created.
+``INSTALL_RPATH_USE_LINK_PATH`` is a boolean that if set to ``True``
+will append to the runtime search path (rpath) of installed binaries
+any directories outside the project that are in the linker search path or
+contain linked library files. The directories are appended after the
+value of the :prop_tgt:`INSTALL_RPATH` target property.
+
+This property is initialized by the value of the variable
+:variable:`CMAKE_INSTALL_RPATH_USE_LINK_PATH` if it is set when a target is
+created.
diff --git a/Help/prop_tgt/JOB_POOL_PRECOMPILE_HEADER.rst b/Help/prop_tgt/JOB_POOL_PRECOMPILE_HEADER.rst
new file mode 100644
index 0000000..ece28a4
--- /dev/null
+++ b/Help/prop_tgt/JOB_POOL_PRECOMPILE_HEADER.rst
@@ -0,0 +1,21 @@
+JOB_POOL_PRECOMPILE_HEADER
+--------------------------
+
+Ninja only: Pool used for generating pre-compiled headers.
+
+The number of parallel compile processes could be limited by defining
+pools with the global :prop_gbl:`JOB_POOLS`
+property and then specifying here the pool name.
+
+For instance:
+
+.. code-block:: cmake
+
+ set_property(TARGET myexe PROPERTY JOB_POOL_PRECOMPILE_HEADER two_jobs)
+
+This property is initialized by the value of
+:variable:`CMAKE_JOB_POOL_PRECOMPILE_HEADER`.
+
+If neither :prop_tgt:`JOB_POOL_PRECOMPILE_HEADER` nor
+:variable:`CMAKE_JOB_POOL_PRECOMPILE_HEADER` are set then
+:prop_tgt:`JOB_POOL_COMPILE` will be used for this task.
diff --git a/Help/prop_tgt/LINK_LIBRARIES_INDIRECTION.txt b/Help/prop_tgt/LINK_LIBRARIES_INDIRECTION.txt
index 1fdb6ad..476e4a6 100644
--- a/Help/prop_tgt/LINK_LIBRARIES_INDIRECTION.txt
+++ b/Help/prop_tgt/LINK_LIBRARIES_INDIRECTION.txt
@@ -1,9 +1,9 @@
.. note::
A call to :command:`target_link_libraries(<target> ...)` may update this
property on ``<target>``. If ``<target>`` was not created in the same
- directory as the call then :command:`target_link_libraries` will add a
- suffix of the form ``::@<directory-id>`` to each entry, where the
- ``::@`` is a separator and the ``<directory-id>`` is unspecified.
+ directory as the call then :command:`target_link_libraries` will wrap each
+ entry with the form ``::@(directory-id);...;::@``, where the ``::@`` is
+ literal and the ``(directory-id)`` is unspecified.
This tells the generators that the named libraries must be looked up in
the scope of the caller rather than in the scope in which the
``<target>`` was created. Valid directory ids are stripped on export
diff --git a/Help/prop_tgt/LINK_OPTIONS.rst b/Help/prop_tgt/LINK_OPTIONS.rst
index 2a05ea7..ff3ee87 100644
--- a/Help/prop_tgt/LINK_OPTIONS.rst
+++ b/Help/prop_tgt/LINK_OPTIONS.rst
@@ -2,12 +2,16 @@ LINK_OPTIONS
------------
List of options to use for the link step of shared library, module
-and executable targets. Targets that are static libraries need to use
-the :prop_tgt:`STATIC_LIBRARY_OPTIONS` target property.
+and executable targets as well as the device link step. Targets that are static
+libraries need to use the :prop_tgt:`STATIC_LIBRARY_OPTIONS` target property.
+These options are used for both normal linking and device linking
+(see policy :policy:`CMP0105`). To control link options for normal and device
+link steps, ``$<HOST_LINK>`` and ``$<DEVICE_LINK>``
+:manual:`generator expressions <cmake-generator-expressions(7)>` can be used.
-This property holds a :ref:`semicolon-separated list <CMake Language Lists>` of options
-specified so far for its target. Use the :command:`target_link_options`
+This property holds a :ref:`semicolon-separated list <CMake Language Lists>` of
+options specified so far for its target. Use the :command:`target_link_options`
command to append more options.
This property is initialized by the :prop_dir:`LINK_OPTIONS` directory
diff --git a/Help/prop_tgt/MACHO_COMPATIBILITY_VERSION.rst b/Help/prop_tgt/MACHO_COMPATIBILITY_VERSION.rst
new file mode 100644
index 0000000..26d5cc8
--- /dev/null
+++ b/Help/prop_tgt/MACHO_COMPATIBILITY_VERSION.rst
@@ -0,0 +1,25 @@
+MACHO_COMPATIBILITY_VERSION
+---------------------------
+
+What compatibility version number is this target for Mach-O binaries.
+
+For shared libraries on Mach-O systems (e.g. macOS, iOS)
+the ``MACHO_COMPATIBILITY_VERSION`` property corresponds to the
+*compatibility version* and :prop_tgt:`MACHO_CURRENT_VERSION` corresponds to
+the *current version*. These are both embedded in the shared library binary
+and can be checked with the ``otool -L <binary>`` command.
+
+It should be noted that the :prop_tgt:`MACHO_CURRENT_VERSION` and
+``MACHO_COMPATIBILITY_VERSION`` properties do not affect the file
+names or version-related symlinks that CMake generates for the library.
+The :prop_tgt:`VERSION` and :prop_tgt:`SOVERSION` target properties still
+control the file and symlink names. The ``install_name`` is also still
+controlled by :prop_tgt:`SOVERSION`.
+
+When :prop_tgt:`MACHO_CURRENT_VERSION` and ``MACHO_COMPATIBILITY_VERSION``
+are not given, :prop_tgt:`VERSION` and :prop_tgt:`SOVERSION` are used for
+the version details to be embedded in the binaries respectively.
+The :prop_tgt:`MACHO_CURRENT_VERSION` and ``MACHO_COMPATIBILITY_VERSION``
+properties only need to be given if the project needs to decouple the file
+and symlink naming from the version details embedded in the binaries
+(e.g. to match libtool conventions).
diff --git a/Help/prop_tgt/MACHO_CURRENT_VERSION.rst b/Help/prop_tgt/MACHO_CURRENT_VERSION.rst
new file mode 100644
index 0000000..9afb356
--- /dev/null
+++ b/Help/prop_tgt/MACHO_CURRENT_VERSION.rst
@@ -0,0 +1,25 @@
+MACHO_CURRENT_VERSION
+---------------------
+
+What current version number is this target for Mach-O binaries.
+
+For shared libraries on Mach-O systems (e.g. macOS, iOS)
+the :prop_tgt:`MACHO_COMPATIBILITY_VERSION` property corresponds to the
+*compatibility version* and ``MACHO_CURRENT_VERSION`` corresponds to the
+*current version*. These are both embedded in the shared library binary
+and can be checked with the ``otool -L <binary>`` command.
+
+It should be noted that the ``MACHO_CURRENT_VERSION`` and
+:prop_tgt:`MACHO_COMPATIBILITY_VERSION` properties do not affect the file
+names or version-related symlinks that CMake generates for the library.
+The :prop_tgt:`VERSION` and :prop_tgt:`SOVERSION` target properties still
+control the file and symlink names. The ``install_name`` is also still
+controlled by :prop_tgt:`SOVERSION`.
+
+When ``MACHO_CURRENT_VERSION`` and :prop_tgt:`MACHO_COMPATIBILITY_VERSION`
+are not given, :prop_tgt:`VERSION` and :prop_tgt:`SOVERSION` are used for
+the version details to be embedded in the binaries respectively.
+The ``MACHO_CURRENT_VERSION`` and :prop_tgt:`MACHO_COMPATIBILITY_VERSION`
+properties only need to be given if the project needs to decouple the file
+and symlink naming from the version details embedded in the binaries
+(e.g. to match libtool conventions).
diff --git a/Help/prop_tgt/PCH_WARN_INVALID.rst b/Help/prop_tgt/PCH_WARN_INVALID.rst
new file mode 100644
index 0000000..36ec348
--- /dev/null
+++ b/Help/prop_tgt/PCH_WARN_INVALID.rst
@@ -0,0 +1,8 @@
+PCH_WARN_INVALID
+----------------
+
+When this property is set to true, the precompile header compiler options
+will contain a compiler flag wich should warn about invalid precompiled
+headers e.g. ``-Winvalid-pch`` for GNU compiler.
+
+The defalut value is ``ON``.
diff --git a/Help/prop_tgt/SOVERSION.rst b/Help/prop_tgt/SOVERSION.rst
index b07c17c..b377f22 100644
--- a/Help/prop_tgt/SOVERSION.rst
+++ b/Help/prop_tgt/SOVERSION.rst
@@ -21,7 +21,17 @@ Mach-O Versions
^^^^^^^^^^^^^^^
For shared libraries and executables on Mach-O systems (e.g. macOS, iOS),
-the ``SOVERSION`` property corresponds to *compatibility version* and
-:prop_tgt:`VERSION` to *current version*. See the :prop_tgt:`FRAMEWORK` target
-property for an example. Versions of Mach-O binaries may be checked with the
-``otool -L <binary>`` command.
+the ``SOVERSION`` property corresponds to the *compatibility version* and
+:prop_tgt:`VERSION` corresponds to the *current version* (unless Mach-O
+specific overrides are provided, as discussed below).
+See the :prop_tgt:`FRAMEWORK` target property for an example.
+
+For shared libraries, the :prop_tgt:`MACHO_COMPATIBILITY_VERSION` and
+:prop_tgt:`MACHO_CURRENT_VERSION` properties can be used to
+override the *compatibility version* and *current version* respectively.
+Note that ``SOVERSION`` will still be used to form the ``install_name``
+and both ``SOVERSION`` and :prop_tgt:`VERSION` may also affect the file
+and symlink names.
+
+Versions of Mach-O binaries may be checked with the ``otool -L <binary>``
+command.
diff --git a/Help/prop_tgt/UNITY_BUILD.rst b/Help/prop_tgt/UNITY_BUILD.rst
index 479802e..e140952 100644
--- a/Help/prop_tgt/UNITY_BUILD.rst
+++ b/Help/prop_tgt/UNITY_BUILD.rst
@@ -5,8 +5,28 @@ When this property is set to true, the target source files will be combined
into batches for faster compilation. This is done by creating a (set of)
unity sources which ``#include`` the original sources, then compiling these
unity sources instead of the originals. This is known as a *Unity* or *Jumbo*
-build. The :prop_tgt:`UNITY_BUILD_BATCH_SIZE` property controls the upper
-limit on how many sources can be combined per unity source file.
+build.
+
+CMake provides different algorithms for selecting which sources are grouped
+together into a *bucket*. Algorithm selection is decided by the
+:prop_tgt:`UNITY_BUILD_MODE` target property, which has the following acceptable
+values:
+
+* ``BATCH``
+ When in this mode CMake determines which files are grouped together.
+ The :prop_tgt:`UNITY_BUILD_BATCH_SIZE` property controls the upper limit on
+ how many sources can be combined per unity source file.
+
+* ``GROUP``
+ When in this mode each target explicitly specifies how to group
+ source files. Each source file that has the same
+ :prop_sf:`UNITY_GROUP` value will be grouped together. Any sources
+ that don't have this property will be compiled individually. The
+ :prop_tgt:`UNITY_BUILD_BATCH_SIZE` property is ignored when using
+ this mode.
+
+If no explicit :prop_tgt:`UNITY_BUILD_MODE` has been specified, CMake will
+default to ``BATCH``.
Unity builds are not currently supported for all languages. CMake version
|release| supports combining ``C`` and ``CXX`` source files. For targets that
diff --git a/Help/prop_tgt/UNITY_BUILD_MODE.rst b/Help/prop_tgt/UNITY_BUILD_MODE.rst
new file mode 100644
index 0000000..1ebab23
--- /dev/null
+++ b/Help/prop_tgt/UNITY_BUILD_MODE.rst
@@ -0,0 +1,58 @@
+UNITY_BUILD_MODE
+----------------
+
+CMake provides different algorithms for selecting which sources are grouped
+together into a *bucket*. Selection is decided by this property,
+which has the following acceptable values:
+
+``BATCH``
+ When in this mode CMake determines which files are grouped together.
+ The :prop_tgt:`UNITY_BUILD_BATCH_SIZE` property controls the upper limit on
+ how many sources can be combined per unity source file.
+
+ Example usage:
+
+ .. code-block:: cmake
+
+ add_library(example_library
+ source1.cxx
+ source2.cxx
+ source3.cxx
+ source4.cxx)
+
+ set_target_properties(example_library PROPERTIES
+ UNITY_BUILD_MODE BATCH
+ UNITY_BUILD_BATCH_SIZE 2
+ )
+
+``GROUP``
+ When in this mode each target explicitly specifies how to group
+ source files. Each source file that has the same
+ :prop_sf:`UNITY_GROUP` value will be grouped together. Any sources
+ that don't have this property will be compiled individually. The
+ :prop_tgt:`UNITY_BUILD_BATCH_SIZE` property is ignored when using
+ this mode.
+
+ Example usage:
+
+ .. code-block:: cmake
+
+ add_library(example_library
+ source1.cxx
+ source2.cxx
+ source3.cxx
+ source4.cxx)
+
+ set_target_properties(example_library PROPERTIES
+ UNITY_BUILD_MODE GROUP
+ )
+
+ set_source_files_properties(source1.cxx source2.cxx source3.cxx
+ PROPERTIES UNITY_GROUP "bucket1"
+ )
+ set_source_files_properties(source4.cxx
+ PROPERTIES UNITY_GROUP "bucket2"
+ )
+
+If no explicit :prop_tgt:`UNITY_BUILD_MODE` has been specified, CMake will
+default to ``BATCH``.
diff --git a/Help/prop_tgt/VERSION.rst b/Help/prop_tgt/VERSION.rst
index ff3b303..95db483 100644
--- a/Help/prop_tgt/VERSION.rst
+++ b/Help/prop_tgt/VERSION.rst
@@ -23,7 +23,17 @@ Mach-O Versions
^^^^^^^^^^^^^^^
For shared libraries and executables on Mach-O systems (e.g. macOS, iOS),
-the :prop_tgt:`SOVERSION` property correspond to *compatibility version* and
-``VERSION`` to *current version*. See the :prop_tgt:`FRAMEWORK` target
-property for an example. Versions of Mach-O binaries may be checked with the
-``otool -L <binary>`` command.
+the :prop_tgt:`SOVERSION` property corresponds to the *compatibility version*
+and ``VERSION`` corresponds to the *current version* (unless Mach-O specific
+overrides are provided, as discussed below).
+See the :prop_tgt:`FRAMEWORK` target property for an example.
+
+For shared libraries, the :prop_tgt:`MACHO_COMPATIBILITY_VERSION` and
+:prop_tgt:`MACHO_CURRENT_VERSION` properties can be used to
+override the *compatibility version* and *current version* respectively.
+Note that :prop_tgt:`SOVERSION` will still be used to form the
+``install_name`` and both :prop_tgt:`SOVERSION` and ``VERSION`` may also
+affect the file and symlink names.
+
+Versions of Mach-O binaries may be checked with the ``otool -L <binary>``
+command.
diff --git a/Help/prop_tgt/VS_DOTNET_DOCUMENTATION_FILE.rst b/Help/prop_tgt/VS_DOTNET_DOCUMENTATION_FILE.rst
new file mode 100644
index 0000000..1bc361c
--- /dev/null
+++ b/Help/prop_tgt/VS_DOTNET_DOCUMENTATION_FILE.rst
@@ -0,0 +1,6 @@
+VS_DOTNET_DOCUMENTATION_FILE
+----------------------------
+
+Visual Studio managed project .NET documentation output
+
+Sets the target XML documentation file output.
diff --git a/Help/prop_tgt/VS_DOTNET_TARGET_FRAMEWORK_VERSION.rst b/Help/prop_tgt/VS_DOTNET_TARGET_FRAMEWORK_VERSION.rst
index 9f5a313..6cb8f86 100644
--- a/Help/prop_tgt/VS_DOTNET_TARGET_FRAMEWORK_VERSION.rst
+++ b/Help/prop_tgt/VS_DOTNET_TARGET_FRAMEWORK_VERSION.rst
@@ -3,8 +3,9 @@ VS_DOTNET_TARGET_FRAMEWORK_VERSION
Specify the .NET target framework version.
-Used to specify the .NET target framework version for C++/CLI. For
+Used to specify the .NET target framework version for C++/CLI. For
example, "v4.5".
This property is deprecated and should not be used anymore. Use
+:prop_tgt:`DOTNET_TARGET_FRAMEWORK` or
:prop_tgt:`DOTNET_TARGET_FRAMEWORK_VERSION` instead.
diff --git a/Help/prop_tgt/VS_PLATFORM_TOOLSET.rst b/Help/prop_tgt/VS_PLATFORM_TOOLSET.rst
new file mode 100644
index 0000000..f8f2e8e
--- /dev/null
+++ b/Help/prop_tgt/VS_PLATFORM_TOOLSET.rst
@@ -0,0 +1,10 @@
+VS_PLATFORM_TOOLSET
+-------------------
+
+Overrides the platform toolset used to build a target.
+
+Only supported when the compiler used by the given toolset is the
+same as the compiler used to build the whole source tree.
+
+This is especially useful to create driver projects with the toolsets
+"WindowsUserModeDriver10.0" or "WindowsKernelModeDriver10.0".
diff --git a/Help/prop_tgt/VS_SOLUTION_DEPLOY.rst b/Help/prop_tgt/VS_SOLUTION_DEPLOY.rst
new file mode 100644
index 0000000..7906d75
--- /dev/null
+++ b/Help/prop_tgt/VS_SOLUTION_DEPLOY.rst
@@ -0,0 +1,29 @@
+VS_SOLUTION_DEPLOY
+------------------
+
+Specify that the target should be marked for deployment when not targeting
+Windows CE, Windows Phone or a Windows Store application.
+
+If the target platform doesn't support deployment, this property won't have any effect.
+
+Generator expressions are supported.
+
+Example 1
+^^^^^^^^^
+
+This shows setting the variable for the target foo.
+
+.. code-block:: cmake
+
+ add_executable(foo SHARED foo.cpp)
+ set_property(TARGET foo PROPERTY VS_SOLUTION_DEPLOY ON)
+
+Example 2
+^^^^^^^^^
+
+This shows setting the variable for the Release configuration only.
+
+.. code-block:: cmake
+
+ add_executable(foo SHARED foo.cpp)
+ set_property(TARGET foo PROPERTY VS_SOLUTION_DEPLOY "$<NOT:$<CONFIG:Release>>")
diff --git a/Help/prop_tgt/VS_SOURCE_SETTINGS_tool.rst b/Help/prop_tgt/VS_SOURCE_SETTINGS_tool.rst
new file mode 100644
index 0000000..f706888
--- /dev/null
+++ b/Help/prop_tgt/VS_SOURCE_SETTINGS_tool.rst
@@ -0,0 +1,19 @@
+VS_SOURCE_SETTINGS_<tool>
+-------------------------
+
+Set any item metadata on all non-built files that use <tool>.
+
+Takes a list of ``Key=Value`` pairs. Tells the Visual Studio generator
+to set ``Key`` to ``Value`` as item metadata on all non-built files
+that use ``<tool>``.
+
+For example:
+
+.. code-block:: cmake
+
+ set_property(TARGET main PROPERTY VS_SOURCE_SETTINGS_FXCompile "Key=Value" "Key2=Value2")
+
+will set ``Key`` to ``Value`` and ``Key2`` to ``Value2`` for all
+non-built files that use ``FXCompile``.
+
+Generator expressions are supported.
diff --git a/Help/prop_tgt/XCODE_GENERATE_SCHEME.rst b/Help/prop_tgt/XCODE_GENERATE_SCHEME.rst
index 0e182cf..c32b4de 100644
--- a/Help/prop_tgt/XCODE_GENERATE_SCHEME.rst
+++ b/Help/prop_tgt/XCODE_GENERATE_SCHEME.rst
@@ -38,3 +38,4 @@ The following target properties will be applied on the
- :prop_tgt:`XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING`
- :prop_tgt:`XCODE_SCHEME_ENVIRONMENT`
- :prop_tgt:`XCODE_SCHEME_EXECUTABLE`
+- :prop_tgt:`XCODE_SCHEME_WORKING_DIRECTORY`
diff --git a/Help/prop_tgt/XCODE_SCHEME_WORKING_DIRECTORY.rst b/Help/prop_tgt/XCODE_SCHEME_WORKING_DIRECTORY.rst
new file mode 100644
index 0000000..f538f1d
--- /dev/null
+++ b/Help/prop_tgt/XCODE_SCHEME_WORKING_DIRECTORY.rst
@@ -0,0 +1,13 @@
+XCODE_SCHEME_WORKING_DIRECTORY
+------------------------------
+
+Specify the ``Working Directory`` of the *Run* and *Profile*
+actions in the generated Xcode scheme. In case the value contains
+generator expressions those are evaluated.
+
+This property is initialized by the value of the variable
+:variable:`CMAKE_XCODE_SCHEME_WORKING_DIRECTORY` 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/3.17.rst b/Help/release/3.17.rst
new file mode 100644
index 0000000..b7c66d8
--- /dev/null
+++ b/Help/release/3.17.rst
@@ -0,0 +1,348 @@
+CMake 3.17 Release Notes
+************************
+
+.. only:: html
+
+ .. contents::
+
+Changes made since CMake 3.16 include the following.
+
+New Features
+============
+
+Generators
+----------
+
+* :manual:`cmake(1)` gained a :generator:`Ninja Multi-Config` generator,
+ which is similar to the :generator:`Ninja` generator but can be used to build
+ multiple configurations at once.
+
+* :ref:`Visual Studio Generators` learned to support per-config sources.
+ Previously only :ref:`Command-Line Build Tool Generators` supported them.
+
+* :ref:`Visual Studio Generators` for VS 2010 and above now support
+ specifying the ``VCTargetsPath`` value for project files in
+ :variable:`CMAKE_GENERATOR_TOOLSET` setting.
+
+* :ref:`Visual Studio Generators` for VS 2010 and above learned to
+ support .NET Standard and .NET Core. See the
+ :prop_tgt:`DOTNET_TARGET_FRAMEWORK` target property and
+ associated :variable:`CMAKE_DOTNET_TARGET_FRAMEWORK` variable.
+
+Languages
+---------
+
+* The :manual:`Compile Features <cmake-compile-features(7)>` functionality
+ now offers meta-features for the CUDA language standard levels
+ (e.g. ``cuda_std_03``, ``cuda_std_14``). See
+ :prop_gbl:`CMAKE_CUDA_KNOWN_FEATURES`.
+
+Compilers
+---------
+
+* The IBM XL Fortran compiler is now supported by the :generator:`Ninja`
+ generator.
+
+Command-Line
+------------
+
+* :manual:`cmake(1)` gained a ``--debug-find`` command-line option to
+ enable additional human-readable output on where ``find_*`` commands search.
+
+* :manual:`cmake(1)` gained a ``--trace-format`` command-line option that
+ can be used to set the ``--trace`` output format. Currently, the old
+ human readable and the new JSON format are supported. The new JSON format
+ is easier to parse automatically than the existing format.
+
+* :manual:`cmake(1)` gained a ``-E rm`` command-line tool that can be
+ used to remove directories and files. This supersedes the existing
+ ``-E remove`` and ``-E remove_directory`` tools and has better semantics.
+
+Commands
+--------
+
+* The :command:`add_custom_command` command learned to interpret paths in
+ ``DEPENDS`` arguments that are specified relative to the current
+ binary directory.
+
+* The :command:`foreach` command learned a new ``ZIP_LISTS`` option to iterate
+ over multiple lists simultaneously.
+
+* The :command:`load_cache(READ_WITH_PREFIX)` command mode is now allowed
+ when using ``cmake -P`` to :ref:`Run a Script <Script Processing Mode>`.
+
+* The :command:`message` command learned to output context provided in
+ the :variable:`CMAKE_MESSAGE_CONTEXT` variable for log levels
+ ``NOTICE`` and below. Enable this output with the new ``--log-context``
+ command-line option or :variable:`CMAKE_MESSAGE_CONTEXT_SHOW` variable.
+
+* The :command:`message` command gained new keywords ``CHECK_START``,
+ ``CHECK_PASS`` and ``CHECK_FAIL``.
+
+* The :command:`target_compile_options` command now honors the ``BEFORE``
+ keyword more consistently. See policy :policy:`CMP0101`.
+
+Variables
+---------
+
+* A :variable:`CMAKE_CTEST_ARGUMENTS` variable was added to specify a list
+ of command-line arguments passed to CTest when running through the
+ ``test`` (or ``RUN_TESTS``) target of the generated build system.
+
+* The following variables are now defined inside a :command:`function`:
+
+ - :variable:`CMAKE_CURRENT_FUNCTION`
+ - :variable:`CMAKE_CURRENT_FUNCTION_LIST_DIR`
+ - :variable:`CMAKE_CURRENT_FUNCTION_LIST_FILE`
+ - :variable:`CMAKE_CURRENT_FUNCTION_LIST_LINE`
+
+* The :variable:`CMAKE_CUDA_RUNTIME_LIBRARY` variable and
+ :prop_tgt:`CUDA_RUNTIME_LIBRARY` target property were introduced to
+ select the CUDA runtime library used when linking targets that
+ use CUDA.
+
+* The :variable:`CMAKE_FIND_DEBUG_MODE` variable was introduced to
+ print extra ``find_*`` call information during the cmake run to standard
+ error. Output is designed for human consumption and not for parsing.
+
+* The :variable:`CMAKE_EXPORT_COMPILE_COMMANDS` variable now takes its
+ initial value from the :envvar:`CMAKE_EXPORT_COMPILE_COMMANDS` environment
+ variable if no explicit configuration is given.
+
+* The :variable:`CMAKE_<LANG>_COMPILER_LAUNCHER` variable, if not set
+ explicitly, now takes its initial value from the
+ :envvar:`CMAKE_<LANG>_COMPILER_LAUNCHER` environment variable.
+
+* The :variable:`CMAKE_MESSAGE_LOG_LEVEL` variable can now be used
+ to persist a log level between CMake runs, unlike the ``--log-level``
+ command line option which only applies to that particular run.
+
+* The :variable:`CMAKE_XCODE_SCHEME_ENVIRONMENT` variable was added
+ to initialize the :prop_tgt:`XCODE_SCHEME_ENVIRONMENT` target property.
+
+* The :variable:`CMAKE_XCODE_SCHEME_WORKING_DIRECTORY` variable and
+ associated :prop_tgt:`XCODE_SCHEME_WORKING_DIRECTORY` target property
+ were added to tell the :generator:`Xcode` generator to set the value of
+ the ``Custom Working Directory`` schema option.
+
+Properties
+----------
+
+* The :prop_tgt:`AIX_EXPORT_ALL_SYMBOLS` target property and associated
+ :variable:`CMAKE_AIX_EXPORT_ALL_SYMBOLS` variable were created to
+ optionally explicitly disable automatic export of symbols from shared
+ libraries on AIX.
+
+* The :prop_tgt:`DEPRECATION` target property was added to mark
+ a target as deprecated. If a linked target is marked as
+ deprecated, a warning with the deprecation message is issued
+ at generate time.
+
+* The :prop_tgt:`INSTALL_NAME_DIR` target property now supports
+ :manual:`generator expressions <cmake-generator-expressions(7)>`.
+ In particular, the ``$<INSTALL_PREFIX>`` generator expression can
+ be used to set the directory relative to the install-time prefix.
+
+* Target properties :prop_tgt:`MACHO_COMPATIBILITY_VERSION` and
+ :prop_tgt:`MACHO_CURRENT_VERSION` were added to set the
+ ``compatibility_version`` and ``curent_version``, respectively,
+ for Mach-O binaries. For backwards compatibility, if these properties
+ are not set, :prop_tgt:`SOVERSION` and :prop_tgt:`VERSION`
+ are used respectively as fallbacks.
+
+* The :prop_tgt:`VS_DOTNET_DOCUMENTATION_FILE` target property was added
+ to tell :ref:`Visual Studio Generators` to generate a ``DocumentationFile``
+ reference in ``.csproj`` files.
+
+Modules
+-------
+
+* The :module:`ExternalProject` module :command:`ExternalProject_Add`
+ command gained a ``GIT_SUBMODULES_RECURSE`` option to specify whether
+ Git submodules should be updated recursively. The default is on to
+ preserve existing behavior.
+
+* The :module:`FindCUDAToolkit` module was added to find the
+ CUDA Toolkit without enabling CUDA as a language.
+
+* The :module:`FindCURL` module learned to find CURL using
+ the ``CURLConfig.cmake`` package configuration file generated by
+ CURL's cmake buildsystem. It also gained a new ``CURL_NO_CURL_CMAKE``
+ option to disable this behavior.
+
+* The :module:`FindFLEX` module's ``FLEX_TARGET`` command now runs ``flex``
+ with :variable:`CMAKE_CURRENT_BINARY_DIR` as the working directory.
+ See policy :policy:`CMP0098`.
+
+* The :module:`FindLibArchive` module now provides an imported target
+ for libarchive.
+
+* The :module:`FindPython` module has learned to find Python components
+ in active virtual environments managed by ``conda``.
+
+* The :module:`FindPython3` and :module:`FindPython` modules gained,
+ respectively, variable ``Python3_SOABI`` and ``Python_SOABI`` giving
+ the standard extension suffix for modules. Moreover, commands
+ ``Python3_add_library()`` and ``Python_add_library()`` gained the option
+ ``WITH_SOABI`` to prefix the library suffix with the value of ``SOABI``.
+
+* The :module:`FindLibXml2` module now provides an imported target for the
+ ``xmllint`` executable.
+
+Autogen
+-------
+
+* :prop_tgt:`AUTOMOC` and :prop_tgt:`AUTOUIC` learned to process headers
+ with a ``.hh`` extension. See policy :policy:`CMP0100`.
+
+CTest
+-----
+
+* The :variable:`CTEST_CONFIGURATION_TYPE` variable is now set from the
+ command line when :manual:`ctest(1)` is invoked with ``-C <cfg>``.
+
+* The :manual:`ctest(1)` tool gained support for Dr. Memory to run
+ memcheck runs.
+
+* The :manual:`ctest(1)` tool gained a ``--no-tests=<[error|ignore]>`` option
+ to explicitly set and unify the behavior between direct invocation and
+ script mode if no tests were found.
+
+* The :manual:`ctest(1)` tool gained a ``--repeat <mode>:<n>`` option
+ to specify conditions in which to repeat tests. This generalizes
+ the existing ``--repeat-until-fail <n>`` option to add modes for
+ ``until-pass`` and ``after-timeout``.
+
+* The :command:`ctest_test` command gained a ``REPEAT <mode>:<n>`` option
+ to specify conditions in which to repeat tests.
+
+CPack
+-----
+
+* The :cpack_gen:`CPack DragNDrop Generator` learned to use
+ the :variable:`CPACK_DMG_<component>_FILE_NAME` variable
+ to set a custom filename when packaging components into
+ their own DMGs.
+
+* The :cpack_gen:`CPack DragNDrop Generator` learned to handle
+ RTF formatted license files. When :variable:`CPACK_DMG_SLA_DIR`
+ variable is set, ``<language>.license.rtf`` is considered, but
+ only as a fallback when the plaintext (``.txt``) file is not found
+ in order to maintain backwards compatibility.
+
+* The :cpack_gen:`CPack NSIS Generator` gained a new variable
+ :variable:`CPACK_NSIS_MUI_HEADERIMAGE` to set the header image.
+ To not break existing setups, it still defaults to
+ :variable:`CPACK_PACKAGE_ICON` if the new variable is not set.
+
+* The :cpack_gen:`CPack NSIS Generator` now supports
+ :variable:`CPACK_NSIS_UNINSTALL_NAME`.
+ This can be used to specify the name of the Uninstall program.
+
+* The :cpack_gen:`CPack NSIS Generator` now supports
+ :variable:`CPACK_NSIS_WELCOME_TITLE` and
+ :variable:`CPACK_NSIS_WELCOME_TITLE_3LINES`.
+ These can be used to specify the welcome page title and display it in 3 lines.
+
+* The :cpack_gen:`CPack NSIS Generator` now supports
+ :variable:`CPACK_NSIS_FINISH_TITLE` and
+ :variable:`CPACK_NSIS_FINISH_TITLE_3LINES`.
+ These can be used to specify the finish page title and display it in 3 lines.
+
+* The :cpack_gen:`CPack productbuild Generator` gained support for a
+ :variable:`CPACK_PRODUCTBUILD_BACKGROUND` variable to specify a background
+ image for the macOS installer.
+
+Other
+-----
+
+* :manual:`ccmake(1)` now displays cache values using colors
+ based on the entry type if the terminal supports color.
+
+* :manual:`ccmake(1)` now displays messages and a progress bar during
+ configure and generate. It will keep the output displayed if any
+ errors or warnings occurred.
+
+Deprecated and Removed Features
+===============================
+
+* An explicit deprecation diagnostic was added for policy ``CMP0068``
+ and policy ``CMP0069`` (``CMP0067`` and below were already deprecated).
+ The :manual:`cmake-policies(7)` manual explains that the OLD behaviors
+ of all policies are deprecated and that projects should port to the
+ NEW behaviors.
+
+* The :cpack_gen:`CPack PackageMaker Generator` generator has been
+ deprecated because Xcode no longer distributes the PackageMaker tools.
+ The undocumented ``OSXX11`` generator has also been deprecated.
+
+* The :manual:`cmake(1)` command-line ``-E remove`` and ``-E remove_directory``
+ tools are deprecated in favor of the new ``-E rm`` tool. The older tools
+ always returned 0 if a named path did not exist even without the force
+ option and cannot be fixed without breaking compatibility, and so have
+ been superseded.
+
+* The :cpack_gen:`CPack NSIS Generator` now requires NSIS 3.0 or later.
+
+Other Changes
+=============
+
+* The :manual:`file API <cmake-file-api(7)>` index file now emits a
+ ``multiConfig`` flag specifying whether or not the generator supports
+ multiple output configurations.
+
+* Target link properties :prop_tgt:`INTERFACE_LINK_OPTIONS`,
+ :prop_tgt:`INTERFACE_LINK_DIRECTORIES` and
+ :prop_tgt:`INTERFACE_LINK_DEPENDS` are now transitive over private
+ dependencies on static libraries.
+ See policy :policy:`CMP0099`.
+
+* When using MinGW tools, the :command:`find_library` command no longer
+ finds ``.dll`` files by default. Instead, it expects ``.dll.a`` import
+ libraries to be available.
+
+* The :generator:`MinGW Makefiles` generator no longer issues an error if
+ ``sh.exe`` is present in the environment's ``PATH``.
+
+* The :generator:`Ninja` generator now prefers the first ninja build
+ tool to appear in the ``PATH`` no matter whether it is called
+ ``ninja-build``, ``ninja``, or ``samu``. Previously the first
+ of those names to appear anywhere in the ``PATH`` would be preferred.
+
+* With SDCC the ``sdar`` tool is now preferred over ``sdcclib`` as librarian.
+ The latter was deprecated by SDCC 3.2.0 and removed in SDCC 3.8.6.
+
+* With SDCC the default flags no longer include any target-specific flags.
+ Previously the default flags were hard-coded for 8051.
+
+* The :variable:`CMAKE_VS_GLOBALS` variable value now applies during
+ compiler identification and in targets created by the
+ :command:`add_custom_target` command.
+
+* The :generator:`Xcode` generator no longer hard-codes ``-Wmost``,
+ ``-Wno-four-char-constants``, and ``-Wno-unknown-pragmas`` warning flags.
+
+Updates
+=======
+
+Changes made since CMake 3.17.0 include the following.
+
+3.17.1
+------
+
+* CMake 3.17.0 updated the :cpack_gen:`CPack NSIS Generator` with changes
+ that require NSIS 3.0 or later. CMake 3.17.1 now enforces the use
+ of a sufficiently new version.
+
+3.17.3
+------
+
+* Selection of the Objective C or C++ compiler now considers the
+ :envvar:`CC` or :envvar:`CXX` environment variable if the
+ :envvar:`OBJC` or :envvar:`OBJCXX` environment variable is not set.
+
+* The :module:`FindPkgConfig` module now extracts include directories
+ prefixed with ``-isystem`` into the ``*_INCLUDE_DIRS`` variables and
+ :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` target properties.
+ Previously they would be places in ``*_CFLAGS_OTHER`` variables and
+ :prop_tgt:`INTERFACE_COMPILE_OPTIONS` target 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/CPackRPM-trans-scripts.rst b/Help/release/dev/CPackRPM-trans-scripts.rst
new file mode 100644
index 0000000..57fc099
--- /dev/null
+++ b/Help/release/dev/CPackRPM-trans-scripts.rst
@@ -0,0 +1,7 @@
+CPackRPM-trans-scripts
+----------------------
+
+* The :cpack_gen:`CPack RPM Generator` gained
+ :variable:`CPACK_RPM_PRE_TRANS_SCRIPT_FILE`
+ :variable:`CPACK_RPM_POST_TRANS_SCRIPT_FILE`
+ variables to specify pre- and post-trans scripts.
diff --git a/Help/release/dev/CTestCoverageCollectGCOV-compress-opts.rst b/Help/release/dev/CTestCoverageCollectGCOV-compress-opts.rst
new file mode 100644
index 0000000..eb8532d
--- /dev/null
+++ b/Help/release/dev/CTestCoverageCollectGCOV-compress-opts.rst
@@ -0,0 +1,7 @@
+CTestCoverageCollectGCOV-compress-opts
+--------------------------------------
+
+* The :module:`CTestCoverageCollectGCOV` module
+ :command:`ctest_coverage_collect_gcov` function gained a
+ ``TARBALL_COMPRESSION`` option to control compression of the
+ tarball of collected results.
diff --git a/Help/release/dev/FPHSA-handle_components.rst b/Help/release/dev/FPHSA-handle_components.rst
new file mode 100644
index 0000000..39907c4
--- /dev/null
+++ b/Help/release/dev/FPHSA-handle_components.rst
@@ -0,0 +1,5 @@
+FPHSA-handle_components
+-----------------------
+
+* The :module:`FindPackageHandleStandardArgs` module option ``REQUIRED_VARS``
+ is now optional if ``HANDLE_COMPONENTS`` is specified.
diff --git a/Help/release/dev/FindBLAS-import-target.rst b/Help/release/dev/FindBLAS-import-target.rst
new file mode 100644
index 0000000..29d6f0c
--- /dev/null
+++ b/Help/release/dev/FindBLAS-import-target.rst
@@ -0,0 +1,4 @@
+FindBLAS-import-target
+----------------------
+
+* The :module:`FindBLAS` module now provides an imported target.
diff --git a/Help/release/dev/FindLAPACK-import-target.rst b/Help/release/dev/FindLAPACK-import-target.rst
new file mode 100644
index 0000000..912d642
--- /dev/null
+++ b/Help/release/dev/FindLAPACK-import-target.rst
@@ -0,0 +1,4 @@
+FindLAPACK-import-target
+------------------------
+
+* The :module:`FindLAPACK` module now provides an imported target.
diff --git a/Help/release/dev/FindPython-IronPython-support.rst b/Help/release/dev/FindPython-IronPython-support.rst
new file mode 100644
index 0000000..0ed11e9
--- /dev/null
+++ b/Help/release/dev/FindPython-IronPython-support.rst
@@ -0,0 +1,5 @@
+FindPython-IronPython-support
+-----------------------------
+
+* The :module:`FindPython3`, :module:`FindPython2` and :module:`FindPython`
+ modules support now the ``IronPython`` implementation on all platforms.
diff --git a/Help/release/dev/FindPython-artifacts-interactive.rst b/Help/release/dev/FindPython-artifacts-interactive.rst
new file mode 100644
index 0000000..1aa4b3e
--- /dev/null
+++ b/Help/release/dev/FindPython-artifacts-interactive.rst
@@ -0,0 +1,6 @@
+FindPython-artifacts-interactive
+--------------------------------
+
+* The :module:`FindPython3`, :module:`FindPython2` and :module:`FindPython`
+ modules gained the possibility to create artifacts cache variables for
+ interactive edition.
diff --git a/Help/release/dev/FindPython-dev-subcomponents.rst b/Help/release/dev/FindPython-dev-subcomponents.rst
new file mode 100644
index 0000000..fe76ee8
--- /dev/null
+++ b/Help/release/dev/FindPython-dev-subcomponents.rst
@@ -0,0 +1,6 @@
+FindPython-dev-subcomponents
+----------------------------
+
+* The :module:`FindPython3`, :module:`FindPython2` and :module:`FindPython`
+ modules gained sub-components ``Development.Module`` and
+ ``Development.Embed`` for ``Development`` component.
diff --git a/Help/release/dev/FindPython-find-implementations.rst b/Help/release/dev/FindPython-find-implementations.rst
new file mode 100644
index 0000000..d4f548b
--- /dev/null
+++ b/Help/release/dev/FindPython-find-implementations.rst
@@ -0,0 +1,5 @@
+FindPython-find-implementations
+-------------------------------
+
+* The :module:`FindPython3`, :module:`FindPython2` and :module:`FindPython`
+ modules gained the capability to specify which implementations to search for.
diff --git a/Help/release/dev/FindPython-pypy.rst b/Help/release/dev/FindPython-pypy.rst
new file mode 100644
index 0000000..84f0db1
--- /dev/null
+++ b/Help/release/dev/FindPython-pypy.rst
@@ -0,0 +1,5 @@
+FindPython-pypy
+---------------
+
+* The :module:`FindPython3`, :module:`FindPython2` and :module:`FindPython`
+ modules gained the capability to handle ``PyPy`` product.
diff --git a/Help/release/dev/FindRuby-variable-case.rst b/Help/release/dev/FindRuby-variable-case.rst
new file mode 100644
index 0000000..bd4a2f1
--- /dev/null
+++ b/Help/release/dev/FindRuby-variable-case.rst
@@ -0,0 +1,7 @@
+FindRuby-variable-case
+----------------------
+
+* The :module:`FindRuby` module input and output variables were all renamed
+ from ``RUBY_`` to ``Ruby_`` for consistency with other find modules.
+ Input variables of the old case will be honored if provided, and output
+ variables of the old case are always provided.
diff --git a/Help/release/dev/GoogleTest-DISCOVERY_MODE.rst b/Help/release/dev/GoogleTest-DISCOVERY_MODE.rst
new file mode 100644
index 0000000..7bc2f14
--- /dev/null
+++ b/Help/release/dev/GoogleTest-DISCOVERY_MODE.rst
@@ -0,0 +1,7 @@
+GoogleTest-DISCOVERY_MODE
+-------------------------
+
+* The :module:`GoogleTest` module :command:`gtest_discover_tests` command
+ gained a new ``DISCOVERY_MODE`` option to control when the test
+ discovery step is run. It offers a new ``PRE_TEST`` setting to
+ run the discovery at test time instead of build time.
diff --git a/Help/release/dev/GoogleTest-XML_OUTPUT_DIR.rst b/Help/release/dev/GoogleTest-XML_OUTPUT_DIR.rst
new file mode 100644
index 0000000..e8aba01
--- /dev/null
+++ b/Help/release/dev/GoogleTest-XML_OUTPUT_DIR.rst
@@ -0,0 +1,6 @@
+GoogleTest-XML_OUTPUT_DIR
+-------------------------
+
+* The :module:`GoogleTest` module :command:`gtest_discover_tests` command
+ gained a new optional parameter ``XML_OUTPUT_DIR``. When set the JUnit XML
+ test results are stored in that directory.
diff --git a/Help/release/dev/ccmake-custom-colors.rst b/Help/release/dev/ccmake-custom-colors.rst
new file mode 100644
index 0000000..fcabe56
--- /dev/null
+++ b/Help/release/dev/ccmake-custom-colors.rst
@@ -0,0 +1,5 @@
+ccmake-custom-colors
+--------------------
+
+* :manual:`ccmake(1)` learned to read a :envvar:`CCMAKE_COLORS`
+ environment variable to customize colors.
diff --git a/Help/release/dev/cmake-gui-env-platform-defaults.rst b/Help/release/dev/cmake-gui-env-platform-defaults.rst
new file mode 100644
index 0000000..0960ef1
--- /dev/null
+++ b/Help/release/dev/cmake-gui-env-platform-defaults.rst
@@ -0,0 +1,8 @@
+cmake-gui-env-platform-defaults
+-------------------------------
+
+* :manual:`cmake-gui(1)` now populates its generator selection
+ widget default value from the :envvar:`CMAKE_GENERATOR` environment
+ variable. Additionally, environment variables
+ :envvar:`CMAKE_GENERATOR_PLATFORM` and :envvar:`CMAKE_GENERATOR_TOOLSET`
+ are used to populate their respective widget defaults.
diff --git a/Help/release/dev/cmake_command-command.rst b/Help/release/dev/cmake_command-command.rst
new file mode 100644
index 0000000..6200ae2
--- /dev/null
+++ b/Help/release/dev/cmake_command-command.rst
@@ -0,0 +1,6 @@
+cmake_command
+-------------
+
+* The :command:`cmake_command()` command was added for meta-operations on
+ scripted or built-in commands, starting with a mode to ``INVOKE`` other
+ commands, and ``EVAL CODE`` to inplace evaluate a CMake script.
diff --git a/Help/release/dev/command-line-cat.rst b/Help/release/dev/command-line-cat.rst
new file mode 100644
index 0000000..acde835
--- /dev/null
+++ b/Help/release/dev/command-line-cat.rst
@@ -0,0 +1,5 @@
+Command-Line
+------------
+* :manual:`cmake(1)` gained a ``cat`` command line
+ option that can be used to concatenate files and print them
+ on standard output.
diff --git a/Help/release/dev/ctest_resource_spec_file-variable.rst b/Help/release/dev/ctest_resource_spec_file-variable.rst
new file mode 100644
index 0000000..2ddf854
--- /dev/null
+++ b/Help/release/dev/ctest_resource_spec_file-variable.rst
@@ -0,0 +1,6 @@
+ctest_resource_spec_file-variable
+---------------------------------
+
+* :manual:`ctest(1)` gained a new :variable:`CTEST_RESOURCE_SPEC_FILE`
+ variable, which can be used to specify a
+ :ref:`resource specification file <ctest-resource-specification-file>`.
diff --git a/Help/release/dev/ctest_stop_on_failure.rst b/Help/release/dev/ctest_stop_on_failure.rst
new file mode 100644
index 0000000..f10c37c
--- /dev/null
+++ b/Help/release/dev/ctest_stop_on_failure.rst
@@ -0,0 +1,8 @@
+ctest_stop_on_failure
+---------------------
+
+* :manual:`ctest(1)` gained a ``--stop-on-failure`` option,
+ which can be used to stop running the tests once one has failed.
+
+* The :command:`ctest_test` command gained a ``STOP_ON_FAILURE`` option
+ which can be used to stop running the tests once one has failed.
diff --git a/Help/release/dev/cuda-architectures-empty.rst b/Help/release/dev/cuda-architectures-empty.rst
new file mode 100644
index 0000000..b0fc327
--- /dev/null
+++ b/Help/release/dev/cuda-architectures-empty.rst
@@ -0,0 +1,7 @@
+cuda-architectures-empty
+------------------------
+
+* :variable:`CMAKE_CUDA_ARCHITECTURES` is now initialized when
+ :variable:`CMAKE_CUDA_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>` is ``NVIDIA``.
+ Empty :prop_tgt:`CUDA_ARCHITECTURES` raises an error. See policy
+ :policy:`CMP0104`.
diff --git a/Help/release/dev/cuda-architectures.rst b/Help/release/dev/cuda-architectures.rst
new file mode 100644
index 0000000..dc6c55b
--- /dev/null
+++ b/Help/release/dev/cuda-architectures.rst
@@ -0,0 +1,6 @@
+cuda-architectures
+------------------
+
+* Added :prop_tgt:`CUDA_ARCHITECTURES` target property for specifying CUDA
+ output architectures. Users are encouraged to use this instead of specifying
+ options manually, as this approach is compiler-agnostic.
diff --git a/Help/release/dev/curl-http2.rst b/Help/release/dev/curl-http2.rst
new file mode 100644
index 0000000..8390a42
--- /dev/null
+++ b/Help/release/dev/curl-http2.rst
@@ -0,0 +1,8 @@
+curl-http2
+----------
+
+* When building CMake itself from source and not using a system-provided
+ libcurl, HTTP/2 support is now enabled for commands supporting
+ network communication via ``http(s)``, such as :command:`file(DOWNLOAD)`,
+ :command:`file(UPLOAD)`, and :command:`ctest_submit`.
+ The precompiled binaries provided on ``cmake.org`` now support HTTP/2.
diff --git a/Help/release/dev/deprecate-documentation-module.rst b/Help/release/dev/deprecate-documentation-module.rst
new file mode 100644
index 0000000..5c3157b
--- /dev/null
+++ b/Help/release/dev/deprecate-documentation-module.rst
@@ -0,0 +1,6 @@
+deprecate-documentation-module
+------------------------------
+
+* The :module:`Documentation` module has been deprecated via
+ :policy:`CMP0106`. This module was essentially VTK code that CMake should
+ not be shipping anymore.
diff --git a/Help/release/dev/deprecate-policy-old.rst b/Help/release/dev/deprecate-policy-old.rst
new file mode 100644
index 0000000..cffd206
--- /dev/null
+++ b/Help/release/dev/deprecate-policy-old.rst
@@ -0,0 +1,8 @@
+deprecate-policy-old
+--------------------
+
+* An explicit deprecation diagnostic was added for policy ``CMP0070``
+ and policy ``CMP0071`` (``CMP0069`` and below were already deprecated).
+ The :manual:`cmake-policies(7)` manual explains that the OLD behaviors
+ of all policies are deprecated and that projects should port to the
+ NEW behaviors.
diff --git a/Help/release/dev/device-link-options.rst b/Help/release/dev/device-link-options.rst
new file mode 100644
index 0000000..f58026b
--- /dev/null
+++ b/Help/release/dev/device-link-options.rst
@@ -0,0 +1,5 @@
+device-link-options
+-------------------
+
+* the :prop_tgt:`LINK_OPTIONS` and :prop_tgt:`INTERFACE_LINK_OPTIONS` target
+ properties are now used for the device link step. See policy :policy:`CMP0105`.
diff --git a/Help/release/dev/execute_process.rst b/Help/release/dev/execute_process.rst
new file mode 100644
index 0000000..02e813b
--- /dev/null
+++ b/Help/release/dev/execute_process.rst
@@ -0,0 +1,5 @@
+execute_process
+---------------
+
+* The :command:`execute_process` command gained the ``ECHO_OUTPUT_VARIABLE``
+ and ``ECHO_ERROR_VARIABLE`` options.
diff --git a/Help/release/dev/export-multiple-calls.rst b/Help/release/dev/export-multiple-calls.rst
new file mode 100644
index 0000000..00372ce
--- /dev/null
+++ b/Help/release/dev/export-multiple-calls.rst
@@ -0,0 +1,5 @@
+export-multiple-calls
+---------------------
+
+* The :command:`export` command now raise an error if used multiple times with
+ same ``FILE`` without ``APPEND``. See policy :policy:`CMP0103`.
diff --git a/Help/release/dev/file-upload-tls.rst b/Help/release/dev/file-upload-tls.rst
new file mode 100644
index 0000000..e19be24
--- /dev/null
+++ b/Help/release/dev/file-upload-tls.rst
@@ -0,0 +1,5 @@
+file-upload-tls
+---------------
+
+* The :command:`file(UPLOAD)` command gained ``TLS_VERIFY`` and ``TLS_CAINFO``
+ options to control server certificate verification.
diff --git a/Help/release/dev/file_archive.rst b/Help/release/dev/file_archive.rst
new file mode 100644
index 0000000..e79529c
--- /dev/null
+++ b/Help/release/dev/file_archive.rst
@@ -0,0 +1,7 @@
+file_archive
+------------
+
+* The :command:`file` command gained the ``ARCHIVE_{CREATE|EXTRACT}`` subcommands.
+
+ These subcommands will replicate the :manual:`cmake(1)` ``-E tar`` functionality in
+ CMake scripting code.
diff --git a/Help/release/dev/file_configure.rst b/Help/release/dev/file_configure.rst
new file mode 100644
index 0000000..35e99c4
--- /dev/null
+++ b/Help/release/dev/file_configure.rst
@@ -0,0 +1,6 @@
+file_configure
+--------------
+
+* The :command:`file(CONFIGURE)` subcommand was created in order replicate the
+ :command:`configure_file` functionality without resorting to a pre-existing
+ file on disk as input. The content is instead passed as a string.
diff --git a/Help/release/dev/findswig-components.rst b/Help/release/dev/findswig-components.rst
new file mode 100644
index 0000000..ce569be
--- /dev/null
+++ b/Help/release/dev/findswig-components.rst
@@ -0,0 +1,5 @@
+findswig-components
+-------------------
+
+* The :module:`FindSWIG` module now accepts target languages as ``COMPONENTS``
+ and ``OPTIONAL_COMPONENTS`` arguments to ``find_package``.
diff --git a/Help/release/dev/framework-multi-config-postfix.rst b/Help/release/dev/framework-multi-config-postfix.rst
new file mode 100644
index 0000000..50cf9ce
--- /dev/null
+++ b/Help/release/dev/framework-multi-config-postfix.rst
@@ -0,0 +1,7 @@
+framework-multi-config-postfix
+------------------------------
+
+* The :prop_tgt:`FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>` target property
+ and associated :variable:`CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>`
+ variable were created to allow adding a postfix to the name of a
+ framework file name when using a multi-config generator.
diff --git a/Help/release/dev/genex-DEVICE_LINK-HOST_LINK.rst b/Help/release/dev/genex-DEVICE_LINK-HOST_LINK.rst
new file mode 100644
index 0000000..ef275e7
--- /dev/null
+++ b/Help/release/dev/genex-DEVICE_LINK-HOST_LINK.rst
@@ -0,0 +1,6 @@
+genex-DEVICE_LINK-HOST_LINK
+---------------------------
+
+* To manage device and host link steps, the ``$<DEVICE_LINK:...>`` and
+ ``$<HOST_LINK:...>``
+ :manual:`generator expressions <cmake-generator-expressions(7)>` were added.
diff --git a/Help/release/dev/genex-LINK_LANGUAGE.rst b/Help/release/dev/genex-LINK_LANGUAGE.rst
new file mode 100644
index 0000000..05894d6
--- /dev/null
+++ b/Help/release/dev/genex-LINK_LANGUAGE.rst
@@ -0,0 +1,5 @@
+genex-LINK_LANGUAGE
+===================
+
+* The ``$<LINK_LANGUAGE:...>`` and ``$<LINK_LANG_AND_ID:...>``
+ :manual:`generator expressions <cmake-generator-expressions(7)>` were added.
diff --git a/Help/release/dev/grouped-unity-build-mode.rst b/Help/release/dev/grouped-unity-build-mode.rst
new file mode 100644
index 0000000..802de4a
--- /dev/null
+++ b/Help/release/dev/grouped-unity-build-mode.rst
@@ -0,0 +1,6 @@
+grouped-unity-build-mode
+------------------------
+
+* The :prop_tgt:`UNITY_BUILD_MODE` target property was added to tell
+ generators which algorithm to use for grouping included source
+ files.
diff --git a/Help/release/dev/libxslt.rst b/Help/release/dev/libxslt.rst
new file mode 100644
index 0000000..ce3527e
--- /dev/null
+++ b/Help/release/dev/libxslt.rst
@@ -0,0 +1,4 @@
+libxslt-target
+--------------
+
+* The :module:`FindLibXslt` module now provides imported targets.
diff --git a/Help/release/dev/list_natural_sort.rst b/Help/release/dev/list_natural_sort.rst
new file mode 100644
index 0000000..ff74e5a
--- /dev/null
+++ b/Help/release/dev/list_natural_sort.rst
@@ -0,0 +1,5 @@
+list_natural_sort
+-----------------
+
+* The :command:`list` operation ``SORT`` gained the ``NATURAL`` sort
+ option to sort using natural order (see ``strverscmp(3)`` manual).
diff --git a/Help/release/dev/ninja-compiler-PATH-windows.rst b/Help/release/dev/ninja-compiler-PATH-windows.rst
new file mode 100644
index 0000000..cb33493
--- /dev/null
+++ b/Help/release/dev/ninja-compiler-PATH-windows.rst
@@ -0,0 +1,7 @@
+ninja-compiler-PATH-windows
+---------------------------
+
+* On Windows, the :generator:`Ninja` and :generator:`Ninja Multi-Config`
+ generators, when a compiler is not explicitly specified, now select
+ the first compiler (of any name) found in directories listed by the
+ ``PATH`` environment variable.
diff --git a/Help/release/dev/nsis-dpi-aware.rst b/Help/release/dev/nsis-dpi-aware.rst
new file mode 100644
index 0000000..8b5032e
--- /dev/null
+++ b/Help/release/dev/nsis-dpi-aware.rst
@@ -0,0 +1,6 @@
+nsis-dpi-aware
+--------------
+
+* The :cpack_gen:`CPack NSIS Generator` gained a new variable
+ :variable:`CPACK_NSIS_MANIFEST_DPI_AWARE` to declare that the
+ installer is DPI-aware.
diff --git a/Help/release/dev/parallel-lzma-compression.rst b/Help/release/dev/parallel-lzma-compression.rst
new file mode 100644
index 0000000..12b7102
--- /dev/null
+++ b/Help/release/dev/parallel-lzma-compression.rst
@@ -0,0 +1,6 @@
+parallel-lzma-compression
+-------------------------
+
+* The :cpack_gen:`CPack Archive Generator`'s ``TXZ`` format learned the
+ :variable:`CPACK_ARCHIVE_THREADS` variable to enable parallel compression.
+ Requires support in the ``liblzma`` used by CMake.
diff --git a/Help/release/dev/pch-warn-invalid.rst b/Help/release/dev/pch-warn-invalid.rst
new file mode 100644
index 0000000..5fa3de7
--- /dev/null
+++ b/Help/release/dev/pch-warn-invalid.rst
@@ -0,0 +1,6 @@
+pch-warn-invalid
+----------------
+
+* The :variable:`CMAKE_PCH_WARN_INVALID` variable was added to initialize the
+ :prop_tgt:`PCH_WARN_INVALID` target property to allow the removal of the
+ precompiled header invalid warning.
diff --git a/Help/release/dev/profiling.rst b/Help/release/dev/profiling.rst
new file mode 100644
index 0000000..ab180f0
--- /dev/null
+++ b/Help/release/dev/profiling.rst
@@ -0,0 +1,9 @@
+cmake-profiling
+---------------
+
+* Add support for profiling of CMake scripts through the parameters
+ ``--profiling-output`` and ``--profiling-format``. These options can
+ be used by users to gain insight into the performance of their scripts.
+
+ The first supported output format is ``google-trace`` which is a format
+ supported by Google Chrome's ``about:tracing`` tab.
diff --git a/Help/release/dev/required_find_commands.rst b/Help/release/dev/required_find_commands.rst
new file mode 100644
index 0000000..cc2bf02
--- /dev/null
+++ b/Help/release/dev/required_find_commands.rst
@@ -0,0 +1,6 @@
+required_find_commands
+----------------------
+
+* The :command:`find_program`, :command:`find_library`, :command:`find_path`
+ and :command:`find_file` commands gained a new ``REQUIRED`` option that will
+ stop processing with an error message if nothing is found.
diff --git a/Help/release/dev/sf-property-scopes.rst b/Help/release/dev/sf-property-scopes.rst
new file mode 100644
index 0000000..0b61625
--- /dev/null
+++ b/Help/release/dev/sf-property-scopes.rst
@@ -0,0 +1,15 @@
+sf-property-scopes
+------------------
+
+* The :command:`set_property` with the ``SOURCE`` scope gained the
+ ``DIRECTORY`` and ``TARGET_DIRECTORY`` options to set properties
+ in the provided directory scopes.
+* The :command:`set_source_files_properties` gained the ``DIRECTORY``
+ and ``TARGET_DIRECTORY`` options to set properties in the provided
+ directory scopes.
+* The :command:`get_property` with ``SOURCE`` scope gained the
+ ``DIRECTORY`` and ``TARGET_DIRECTORY`` options to get a property
+ from the provided directory scope.
+* The :command:`get_source_file_property` gained the ``DIRECTORY``
+ and ``TARGET_DIRECTORY`` options to get a property from the
+ provided directory scope.
diff --git a/Help/release/dev/source_group_forward_slashes.rst b/Help/release/dev/source_group_forward_slashes.rst
new file mode 100644
index 0000000..fa0dfa9
--- /dev/null
+++ b/Help/release/dev/source_group_forward_slashes.rst
@@ -0,0 +1,5 @@
+source_group_forward_slashes
+----------------------------
+
+* The :command:`source_group` command now also recognizes forward slashes
+ as subgroup delimiters, not just backslashes.
diff --git a/Help/release/dev/string-hex.rst b/Help/release/dev/string-hex.rst
new file mode 100644
index 0000000..f220aca
--- /dev/null
+++ b/Help/release/dev/string-hex.rst
@@ -0,0 +1,5 @@
+string-hex
+----------
+
+* The :command:`string` command learned a new ``HEX`` sub-command, which
+ converts strings into their hexadecimal representation.
diff --git a/Help/release/dev/useswig-fortran.rst b/Help/release/dev/useswig-fortran.rst
new file mode 100644
index 0000000..17baf96
--- /dev/null
+++ b/Help/release/dev/useswig-fortran.rst
@@ -0,0 +1,7 @@
+useswig-fortran
+---------------
+
+* The :module:`UseSWIG` module now supports Fortran as a target language if
+ the ``SWIG_EXECUTABLE`` is SWIG-Fortran_.
+
+.. _`SWIG-Fortran`: https://github.com/swig-fortran/swig
diff --git a/Help/release/dev/vs-non-built-file-item-metadata.rst b/Help/release/dev/vs-non-built-file-item-metadata.rst
new file mode 100644
index 0000000..26cbad0
--- /dev/null
+++ b/Help/release/dev/vs-non-built-file-item-metadata.rst
@@ -0,0 +1,10 @@
+vs-non-built-file-item-metadata
+-------------------------------
+
+* The :prop_tgt:`VS_SOURCE_SETTINGS_<tool>` target property was added
+ to tell :ref:`Visual Studio Generators` for VS 2010 and above to add
+ metadata to non-built source files using ``<tool>``.
+
+* The :prop_sf:`VS_SETTINGS` source file property was added to tell
+ :ref:`Visual Studio Generators` for VS 2010 and above to add
+ metadata to a non-built source file.
diff --git a/Help/release/dev/vs-platform-toolset.rst b/Help/release/dev/vs-platform-toolset.rst
new file mode 100644
index 0000000..c5062c7
--- /dev/null
+++ b/Help/release/dev/vs-platform-toolset.rst
@@ -0,0 +1,6 @@
+vs-platform-toolset
+-------------------
+
+* The :prop_tgt:`VS_PLATFORM_TOOLSET` target property was added to tell
+ :ref:`Visual Studio Generators` for VS 2010 and above to override
+ the platform toolset.
diff --git a/Help/release/dev/vs-sln-deploy.rst b/Help/release/dev/vs-sln-deploy.rst
new file mode 100644
index 0000000..2e83e52
--- /dev/null
+++ b/Help/release/dev/vs-sln-deploy.rst
@@ -0,0 +1,6 @@
+vs-sln-deploy
+-------------
+
+* The :prop_tgt:`VS_SOLUTION_DEPLOY` target property was added to tell
+ :ref:`Visual Studio Generators` for VS 2010 and above to mark a
+ target for deployment even when not building for Windows Phone/Store/CE.
diff --git a/Help/release/index.rst b/Help/release/index.rst
index 0cc3f97..22b1a09 100644
--- a/Help/release/index.rst
+++ b/Help/release/index.rst
@@ -7,12 +7,15 @@ CMake Release Notes
This file should include the adjacent "dev.txt" file
in development versions but not in release versions.
+.. include:: dev.txt
+
Releases
========
.. toctree::
:maxdepth: 1
+ 3.17 <3.17>
3.16 <3.16>
3.15 <3.15>
3.14 <3.14>
diff --git a/Help/variable/CMAKE_AIX_EXPORT_ALL_SYMBOLS.rst b/Help/variable/CMAKE_AIX_EXPORT_ALL_SYMBOLS.rst
new file mode 100644
index 0000000..c64dd48
--- /dev/null
+++ b/Help/variable/CMAKE_AIX_EXPORT_ALL_SYMBOLS.rst
@@ -0,0 +1,6 @@
+CMAKE_AIX_EXPORT_ALL_SYMBOLS
+----------------------------
+
+Default value for :prop_tgt:`AIX_EXPORT_ALL_SYMBOLS` target property.
+This variable is used to initialize the property on each target as it is
+created.
diff --git a/Help/variable/CMAKE_CFG_INTDIR.rst b/Help/variable/CMAKE_CFG_INTDIR.rst
index af82f75..842654e 100644
--- a/Help/variable/CMAKE_CFG_INTDIR.rst
+++ b/Help/variable/CMAKE_CFG_INTDIR.rst
@@ -16,6 +16,13 @@ Example values:
$(Configuration) = Visual Studio 10
$(CONFIGURATION) = Xcode
. = Make-based tools
+ . = Ninja
+ ${CONFIGURATION} = Ninja Multi-Config
+
+Note that this variable only has limited support on
+:generator:`Ninja Multi-Config`. It is recommended that you use the
+``$<CONFIG>`` :manual:`generator expression <cmake-generator-expressions(7)>`
+instead.
Since these values are evaluated by the native build system, this
variable is suitable only for use in command lines that will be
diff --git a/Help/variable/CMAKE_CROSS_CONFIGS.rst b/Help/variable/CMAKE_CROSS_CONFIGS.rst
new file mode 100644
index 0000000..94157f3
--- /dev/null
+++ b/Help/variable/CMAKE_CROSS_CONFIGS.rst
@@ -0,0 +1,15 @@
+CMAKE_CROSS_CONFIGS
+-------------------
+
+Specifies a :ref:`semicolon-separated list <CMake Language Lists>` of
+configurations available from all ``build-<Config>.ninja`` files in the
+:generator:`Ninja Multi-Config` generator. This variable activates
+cross-config mode. Targets from each config specified in this variable can be
+built from any ``build-<Config>.ninja`` file. Custom commands will use the
+configuration native to ``build-<Config>.ninja``. If it is set to ``all``, all
+configurations from :variable:`CMAKE_CONFIGURATION_TYPES` are cross-configs. If
+it is not specified, or empty, each ``build-<Config>.ninja`` file will only
+contain build rules for its own configuration.
+
+The value of this variable must be a subset of
+:variable:`CMAKE_CONFIGURATION_TYPES`.
diff --git a/Help/variable/CMAKE_CTEST_ARGUMENTS.rst b/Help/variable/CMAKE_CTEST_ARGUMENTS.rst
new file mode 100644
index 0000000..0940b46
--- /dev/null
+++ b/Help/variable/CMAKE_CTEST_ARGUMENTS.rst
@@ -0,0 +1,6 @@
+CMAKE_CTEST_ARGUMENTS
+---------------------
+
+Set this to a :ref:`semicolon-separated list <CMake Language Lists>` of
+command-line arguments to pass to :manual:`ctest(1)` when running tests
+through the ``test`` (or ``RUN_TESTS``) target of the generated build system.
diff --git a/Help/variable/CMAKE_CUDA_ARCHITECTURES.rst b/Help/variable/CMAKE_CUDA_ARCHITECTURES.rst
new file mode 100644
index 0000000..149bffa
--- /dev/null
+++ b/Help/variable/CMAKE_CUDA_ARCHITECTURES.rst
@@ -0,0 +1,17 @@
+CMAKE_CUDA_ARCHITECTURES
+------------------------
+
+Default value for :prop_tgt:`CUDA_ARCHITECTURES` property of targets.
+
+This is initialized as follows depending on :variable:`CMAKE_CUDA_COMPILER_ID <CMAKE_<LANG>_COMPILER_ID>`:
+
+- For ``Clang``: the oldest architecture that works.
+
+- For ``NVIDIA``: the default architecture chosen by the compiler.
+ See policy :policy:`CMP0104`.
+
+Users are encouraged to override this, as the default varies across compilers
+and compiler versions.
+
+This variable is used to initialize the :prop_tgt:`CUDA_ARCHITECTURES` property
+on all targets. See the target property for additional information.
diff --git a/Help/variable/CMAKE_CUDA_COMPILE_FEATURES.rst b/Help/variable/CMAKE_CUDA_COMPILE_FEATURES.rst
new file mode 100644
index 0000000..2cd2650
--- /dev/null
+++ b/Help/variable/CMAKE_CUDA_COMPILE_FEATURES.rst
@@ -0,0 +1,11 @@
+CMAKE_CUDA_COMPILE_FEATURES
+---------------------------
+
+List of features known to the CUDA compiler
+
+These features are known to be available for use with the CUDA compiler. This
+list is a subset of the features listed in the
+:prop_gbl:`CMAKE_CUDA_KNOWN_FEATURES` global property.
+
+See the :manual:`cmake-compile-features(7)` manual for information on
+compile features and a list of supported compilers.
diff --git a/Help/variable/CMAKE_CUDA_RUNTIME_LIBRARY.rst b/Help/variable/CMAKE_CUDA_RUNTIME_LIBRARY.rst
new file mode 100644
index 0000000..ea1c1b8
--- /dev/null
+++ b/Help/variable/CMAKE_CUDA_RUNTIME_LIBRARY.rst
@@ -0,0 +1,24 @@
+CMAKE_CUDA_RUNTIME_LIBRARY
+--------------------------
+
+Select the CUDA runtime library for use by compilers targeting the MSVC ABI.
+This variable is used to initialize the :prop_tgt:`CUDA_RUNTIME_LIBRARY`
+property on all targets as they are created.
+
+The allowed case insensitive values are:
+
+.. include:: ../prop_tgt/CUDA_RUNTIME_LIBRARY-VALUES.txt
+
+Contents of ``CMAKE_CUDA_RUNTIME_LIBRARY`` may use
+:manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+If this variable is not set then the :prop_tgt:`CUDA_RUNTIME_LIBRARY` target
+property will not be set automatically. If that property is not set then
+CMake uses the default value ``Static`` to select the CUDA runtime library.
+
+.. note::
+
+ This property has effect only when the ``CUDA`` language is enabled. To
+ control the CUDA runtime linking when only using the CUDA SDK with the
+ ``C`` or ``C++`` language we recommend using the :module:`FindCUDAToolkit`
+ module.
diff --git a/Help/variable/CMAKE_CURRENT_FUNCTION.rst b/Help/variable/CMAKE_CURRENT_FUNCTION.rst
new file mode 100644
index 0000000..fb7f610
--- /dev/null
+++ b/Help/variable/CMAKE_CURRENT_FUNCTION.rst
@@ -0,0 +1,10 @@
+CMAKE_CURRENT_FUNCTION
+----------------------
+
+When executing code inside a :command:`function`, this variable
+contains the name of the current function. It can be useful for
+diagnostic or debug messages.
+
+See also :variable:`CMAKE_CURRENT_FUNCTION_LIST_DIR`,
+:variable:`CMAKE_CURRENT_FUNCTION_LIST_FILE` and
+:variable:`CMAKE_CURRENT_FUNCTION_LIST_LINE`.
diff --git a/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_DIR.rst b/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_DIR.rst
new file mode 100644
index 0000000..44ae1e5
--- /dev/null
+++ b/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_DIR.rst
@@ -0,0 +1,41 @@
+CMAKE_CURRENT_FUNCTION_LIST_DIR
+-------------------------------
+
+When executing code inside a :command:`function`, this variable
+contains the full directory of the listfile that defined the current function.
+
+It is quite common practice in CMake for modules to use some additional files,
+such as templates to be copied in after substituting CMake variables.
+In such cases, a function needs to know where to locate those files in a way
+that doesn't depend on where the function is called. Without
+``CMAKE_CURRENT_FUNCTION_LIST_DIR``, the code to do that would typically use
+the following pattern:
+
+.. code-block:: cmake
+
+ set(_THIS_MODULE_BASE_DIR "${CMAKE_CURRENT_LIST_DIR}")
+
+ function(foo)
+ configure_file(
+ "${_THIS_MODULE_BASE_DIR}/some.template.in"
+ some.output
+ )
+ endfunction()
+
+Using ``CMAKE_CURRENT_FUNCTION_LIST_DIR`` inside the function instead
+eliminates the need for the extra variable which would otherwise be visible
+outside the function's scope.
+The above example can be written in the more concise and more robust form:
+
+.. code-block:: cmake
+
+ function(foo)
+ configure_file(
+ "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/some.template.in"
+ some.output
+ )
+ endfunction()
+
+See also :variable:`CMAKE_CURRENT_FUNCTION`,
+:variable:`CMAKE_CURRENT_FUNCTION_LIST_FILE` and
+:variable:`CMAKE_CURRENT_FUNCTION_LIST_LINE`.
diff --git a/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_FILE.rst b/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_FILE.rst
new file mode 100644
index 0000000..c737af9
--- /dev/null
+++ b/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_FILE.rst
@@ -0,0 +1,9 @@
+CMAKE_CURRENT_FUNCTION_LIST_FILE
+--------------------------------
+
+When executing code inside a :command:`function`, this variable
+contains the full path to the listfile that defined the current function.
+
+See also :variable:`CMAKE_CURRENT_FUNCTION`,
+:variable:`CMAKE_CURRENT_FUNCTION_LIST_DIR` and
+:variable:`CMAKE_CURRENT_FUNCTION_LIST_LINE`.
diff --git a/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_LINE.rst b/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_LINE.rst
new file mode 100644
index 0000000..ad6282e
--- /dev/null
+++ b/Help/variable/CMAKE_CURRENT_FUNCTION_LIST_LINE.rst
@@ -0,0 +1,10 @@
+CMAKE_CURRENT_FUNCTION_LIST_LINE
+--------------------------------
+
+When executing code inside a :command:`function`, this variable
+contains the line number in the listfile where the current function
+was defined.
+
+See also :variable:`CMAKE_CURRENT_FUNCTION`,
+:variable:`CMAKE_CURRENT_FUNCTION_LIST_DIR` and
+:variable:`CMAKE_CURRENT_FUNCTION_LIST_FILE`.
diff --git a/Help/variable/CMAKE_DEFAULT_BUILD_TYPE.rst b/Help/variable/CMAKE_DEFAULT_BUILD_TYPE.rst
new file mode 100644
index 0000000..aa4f82d
--- /dev/null
+++ b/Help/variable/CMAKE_DEFAULT_BUILD_TYPE.rst
@@ -0,0 +1,12 @@
+CMAKE_DEFAULT_BUILD_TYPE
+------------------------
+
+Specifies the configuration to use by default in a ``build.ninja`` file in the
+:generator:`Ninja Multi-Config` generator. If this variable is specified,
+``build.ninja`` uses build rules from ``build-<Config>.ninja`` by default. All
+custom commands are executed with this configuration. If the variable is not
+specified, the first item from :variable:`CMAKE_CONFIGURATION_TYPES` is used
+instead.
+
+The value of this variable must be one of the items from
+:variable:`CMAKE_CONFIGURATION_TYPES`.
diff --git a/Help/variable/CMAKE_DEFAULT_CONFIGS.rst b/Help/variable/CMAKE_DEFAULT_CONFIGS.rst
new file mode 100644
index 0000000..84c642a
--- /dev/null
+++ b/Help/variable/CMAKE_DEFAULT_CONFIGS.rst
@@ -0,0 +1,19 @@
+CMAKE_DEFAULT_CONFIGS
+---------------------
+
+Specifies a :ref:`semicolon-separated list <CMake Language Lists>` of configurations
+to build for a target in ``build.ninja`` if no ``:<Config>`` suffix is specified in
+the :generator:`Ninja Multi-Config` generator. If it is set to ``all``, all
+configurations from :variable:`CMAKE_CROSS_CONFIGS` are used. If it is not
+specified, it defaults to :variable:`CMAKE_DEFAULT_BUILD_TYPE`.
+
+For example, if you set :variable:`CMAKE_DEFAULT_BUILD_TYPE` to ``Release``,
+but set :variable:`CMAKE_DEFAULT_CONFIGS` to ``Debug`` or ``all``, all
+``<target>`` aliases in ``build.ninja`` will resolve to ``<target>:Debug`` or
+``<target>:all``, but custom commands will still use the ``Release``
+configuration.
+
+The value of this variable must be a subset of :variable:`CMAKE_CROSS_CONFIGS`
+or be the same as :variable:`CMAKE_DEFAULT_BUILD_TYPE`. It must not be
+specified if :variable:`CMAKE_DEFAULT_BUILD_TYPE` or
+:variable:`CMAKE_CROSS_CONFIGS` is not used.
diff --git a/Help/variable/CMAKE_DOTNET_TARGET_FRAMEWORK.rst b/Help/variable/CMAKE_DOTNET_TARGET_FRAMEWORK.rst
new file mode 100644
index 0000000..8edcd1e
--- /dev/null
+++ b/Help/variable/CMAKE_DOTNET_TARGET_FRAMEWORK.rst
@@ -0,0 +1,16 @@
+CMAKE_DOTNET_TARGET_FRAMEWORK
+-----------------------------
+
+Default value for :prop_tgt:`DOTNET_TARGET_FRAMEWORK` property of
+targets.
+
+This variable is used to initialize the
+:prop_tgt:`DOTNET_TARGET_FRAMEWORK` property on all targets. See that
+target property for additional information.
+
+Setting ``CMAKE_DOTNET_TARGET_FRAMEWORK`` may be necessary
+when working with ``C#`` and newer .NET framework versions to
+avoid referencing errors with the ``ALL_BUILD`` CMake target.
+
+This variable is only evaluated for :ref:`Visual Studio Generators`
+VS 2010 and above.
diff --git a/Help/variable/CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION.rst b/Help/variable/CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION.rst
index 124fefe..c2eef9e 100644
--- a/Help/variable/CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION.rst
+++ b/Help/variable/CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION.rst
@@ -6,7 +6,11 @@ property of targets.
This variable is used to initialize the
:prop_tgt:`DOTNET_TARGET_FRAMEWORK_VERSION` property on all
-targets. See that target property for additional information.
+targets. See that target property for additional information. When set,
+:variable:`CMAKE_DOTNET_TARGET_FRAMEWORK` takes precednece over this
+variable. See that variable or the associated target property
+:prop_tgt:`DOTNET_TARGET_FRAMEWORK` for additional information.
+
Setting ``CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION`` may be necessary
when working with ``C#`` and newer .NET framework versions to
diff --git a/Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst b/Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst
index 4548abc..6d2450b 100644
--- a/Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst
+++ b/Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst
@@ -25,6 +25,9 @@ form. The format of the JSON file looks like:
}
]
+This is initialized by the :envvar:`CMAKE_EXPORT_COMPILE_COMMANDS` environment
+variable.
+
.. note::
This option is implemented only by :ref:`Makefile Generators`
and the :generator:`Ninja`. It is ignored on other generators.
diff --git a/Help/variable/CMAKE_FIND_DEBUG_MODE.rst b/Help/variable/CMAKE_FIND_DEBUG_MODE.rst
new file mode 100644
index 0000000..f5fd8ce
--- /dev/null
+++ b/Help/variable/CMAKE_FIND_DEBUG_MODE.rst
@@ -0,0 +1,23 @@
+CMAKE_FIND_DEBUG_MODE
+---------------------
+
+Print extra find call information for the following commands to standard
+error:
+
+* :command:`find_program`
+* :command:`find_library`
+* :command:`find_file`
+* :command:`find_path`
+* :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``
+with the added ability to enable debugging for a subset of find calls.
+
+.. code-block:: cmake
+
+ set(CMAKE_FIND_DEBUG_MODE TRUE)
+ find_program(...)
+ set(CMAKE_FIND_DEBUG_MODE FALSE)
+
+Default is unset.
diff --git a/Help/variable/CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG.rst b/Help/variable/CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG.rst
new file mode 100644
index 0000000..5c7cd23
--- /dev/null
+++ b/Help/variable/CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_CONFIG.rst
@@ -0,0 +1,8 @@
+CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>
+---------------------------------------------
+
+Default framework filename postfix under configuration ``<CONFIG>`` when
+using a multi-config generator.
+
+When a framework target is created its :prop_tgt:`FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>`
+target property is initialized with the value of this variable if it is set.
diff --git a/Help/variable/CMAKE_GENERATOR_TOOLSET.rst b/Help/variable/CMAKE_GENERATOR_TOOLSET.rst
index 222824f..53ad2f3 100644
--- a/Help/variable/CMAKE_GENERATOR_TOOLSET.rst
+++ b/Help/variable/CMAKE_GENERATOR_TOOLSET.rst
@@ -58,3 +58,8 @@ Supported pairs are:
Specify the toolset version to use. Supported by VS 2017
and above with the specified toolset installed.
See the :variable:`CMAKE_VS_PLATFORM_TOOLSET_VERSION` variable.
+
+``VCTargetsPath=<path>``
+ Specify an alternative ``VCTargetsPath`` value for Visual Studio
+ project files. This allows use of VS platform extension configuration
+ files (``.props`` and ``.targets``) that are not installed with VS.
diff --git a/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst b/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst
index e82867d..8587742 100644
--- a/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst
+++ b/Help/variable/CMAKE_GLOBAL_AUTOGEN_TARGET.rst
@@ -3,7 +3,7 @@ CMAKE_GLOBAL_AUTOGEN_TARGET
Switch to enable generation of a global ``autogen`` target.
-When :variable:`CMAKE_GLOBAL_AUTORCC_TARGET` is enabled, a custom target
+When :variable:`CMAKE_GLOBAL_AUTOGEN_TARGET` is enabled, a custom target
``autogen`` is generated. This target depends on all :prop_tgt:`AUTOMOC` and
:prop_tgt:`AUTOUIC` generated ``<ORIGIN>_autogen`` targets in the project.
By building the global ``autogen`` target, all :prop_tgt:`AUTOMOC` and
diff --git a/Help/variable/CMAKE_HOST_SYSTEM_PROCESSOR.rst b/Help/variable/CMAKE_HOST_SYSTEM_PROCESSOR.rst
index ba8a850..5f08728 100644
--- a/Help/variable/CMAKE_HOST_SYSTEM_PROCESSOR.rst
+++ b/Help/variable/CMAKE_HOST_SYSTEM_PROCESSOR.rst
@@ -3,6 +3,13 @@ CMAKE_HOST_SYSTEM_PROCESSOR
The name of the CPU CMake is running on.
-On systems that support ``uname``, this variable is set to the output of
-``uname -p``. On Windows it is set to the value of the environment variable
-``PROCESSOR_ARCHITECTURE``.
+On Windows, this variable is set to the value of the environment variable
+``PROCESSOR_ARCHITECTURE``. On systems that support ``uname``, this variable is
+set to the output of:
+
+- ``uname -m`` on GNU, Linux, Cygwin, Darwin, Android, or
+- ``arch`` on OpenBSD, or
+- on other systems,
+
+ * ``uname -p`` if its exit code is nonzero, or
+ * ``uname -m`` otherwise.
diff --git a/Help/variable/CMAKE_INSTALL_RPATH_USE_LINK_PATH.rst b/Help/variable/CMAKE_INSTALL_RPATH_USE_LINK_PATH.rst
index 78148d5..34524d1 100644
--- a/Help/variable/CMAKE_INSTALL_RPATH_USE_LINK_PATH.rst
+++ b/Help/variable/CMAKE_INSTALL_RPATH_USE_LINK_PATH.rst
@@ -3,7 +3,11 @@ CMAKE_INSTALL_RPATH_USE_LINK_PATH
Add paths to linker search and installed rpath.
-``CMAKE_INSTALL_RPATH_USE_LINK_PATH`` is a boolean that if set to ``true``
-will append directories in the linker search path and outside the
-project to the :prop_tgt:`INSTALL_RPATH`. This is used to initialize the
-target property :prop_tgt:`INSTALL_RPATH_USE_LINK_PATH` for all targets.
+``CMAKE_INSTALL_RPATH_USE_LINK_PATH`` is a boolean that if set to ``True``
+will append to the runtime search path (rpath) of installed binaries
+any directories outside the project that are in the linker search path or
+contain linked library files. The directories are appended after the
+value of the :prop_tgt:`INSTALL_RPATH` target property.
+
+This variable is used to initialize the target property
+:prop_tgt:`INSTALL_RPATH_USE_LINK_PATH` for all targets.
diff --git a/Help/variable/CMAKE_JOB_POOL_PRECOMPILE_HEADER.rst b/Help/variable/CMAKE_JOB_POOL_PRECOMPILE_HEADER.rst
new file mode 100644
index 0000000..f9467b3
--- /dev/null
+++ b/Help/variable/CMAKE_JOB_POOL_PRECOMPILE_HEADER.rst
@@ -0,0 +1,6 @@
+CMAKE_JOB_POOL_PRECOMPILE_HEADER
+--------------------------------
+
+This variable is used to initialize the :prop_tgt:`JOB_POOL_PRECOMPILE_HEADER`
+property on all the targets. See :prop_tgt:`JOB_POOL_PRECOMPILE_HEADER`
+for additional information.
diff --git a/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst b/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst
index 6b7e35a..c76e2d0 100644
--- a/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst
+++ b/Help/variable/CMAKE_LANG_COMPILER_LAUNCHER.rst
@@ -5,3 +5,6 @@ Default value for :prop_tgt:`<LANG>_COMPILER_LAUNCHER` target property.
This variable is used to initialize the property on each target as it is
created. This is done only when ``<LANG>`` is ``C``, ``CXX``, ``Fortran``,
``OBJC``, ``OBJCXX``, or ``CUDA``.
+
+This variable is initialized to the :envvar:`CMAKE_<LANG>_COMPILER_LAUNCHER`
+environment variable if it is set.
diff --git a/Help/variable/CMAKE_MESSAGE_CONTEXT.rst b/Help/variable/CMAKE_MESSAGE_CONTEXT.rst
new file mode 100644
index 0000000..6b4ca40
--- /dev/null
+++ b/Help/variable/CMAKE_MESSAGE_CONTEXT.rst
@@ -0,0 +1,62 @@
+CMAKE_MESSAGE_CONTEXT
+---------------------
+
+When enabled by the :manual:`cmake <cmake(1)>` ``--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
+for messages of log levels ``NOTICE`` and below.
+
+For logging contexts to work effectively, projects should generally
+``APPEND`` and ``POP_BACK`` an item to the current value of
+``CMAKE_MESSAGE_CONTEXT`` rather than replace it.
+Projects should not assume the message context at the top of the source tree
+is empty, as there are scenarios where the context might have already been set
+(e.g. hierarchical projects).
+
+.. warning::
+
+ Valid context names are restricted to anything that could be used
+ as a CMake variable name. All names that begin with an underscore
+ or the string ``cmake_`` are also reserved for use by CMake and
+ should not be used by projects.
+
+Example:
+
+.. code-block:: cmake
+
+ function(bar)
+ list(APPEND CMAKE_MESSAGE_CONTEXT "bar")
+ message(VERBOSE "bar VERBOSE message")
+ endfunction()
+
+ function(baz)
+ list(APPEND CMAKE_MESSAGE_CONTEXT "baz")
+ message(DEBUG "baz DEBUG message")
+ endfunction()
+
+ function(foo)
+ list(APPEND CMAKE_MESSAGE_CONTEXT "foo")
+ bar()
+ message(TRACE "foo TRACE message")
+ baz()
+ endfunction()
+
+ list(APPEND CMAKE_MESSAGE_CONTEXT "top")
+
+ message(VERBOSE "Before `foo`")
+ foo()
+ message(VERBOSE "After `foo`")
+
+ list(POP_BACK CMAKE_MESSAGE_CONTEXT)
+
+
+Which results in the following output:
+
+.. code-block:: none
+
+ -- [top] Before `foo`
+ -- [top.foo.bar] bar VERBOSE message
+ -- [top.foo] foo TRACE message
+ -- [top.foo.baz] baz DEBUG message
+ -- [top] After `foo`
diff --git a/Help/variable/CMAKE_MESSAGE_CONTEXT_SHOW.rst b/Help/variable/CMAKE_MESSAGE_CONTEXT_SHOW.rst
new file mode 100644
index 0000000..7ec218e
--- /dev/null
+++ b/Help/variable/CMAKE_MESSAGE_CONTEXT_SHOW.rst
@@ -0,0 +1,15 @@
+CMAKE_MESSAGE_CONTEXT_SHOW
+--------------------------
+
+Setting this variable to true enables showing a context with each line
+logged by the :command:`message` command (see :variable:`CMAKE_MESSAGE_CONTEXT`
+for how the context itself is specified).
+
+This variable is an alternative to providing the ``--log-context`` option
+on the :manual:`cmake <cmake(1)>` command line. Whereas the command line
+option will apply only to that one CMake run, setting
+``CMAKE_MESSAGE_CONTEXT_SHOW`` to true as a cache variable will ensure that
+subsequent CMake runs will continue to show the message context.
+
+Projects should not set ``CMAKE_MESSAGE_CONTEXT_SHOW``. It is intended for
+users so that they may control whether or not to include context with messages.
diff --git a/Help/variable/CMAKE_MESSAGE_LOG_LEVEL.rst b/Help/variable/CMAKE_MESSAGE_LOG_LEVEL.rst
new file mode 100644
index 0000000..1d4cfe6
--- /dev/null
+++ b/Help/variable/CMAKE_MESSAGE_LOG_LEVEL.rst
@@ -0,0 +1,15 @@
+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
+given, the command line option takes precedence.
+
+The main advantage to using this variable is to make a log level persist
+between CMake runs. Setting it as a cache variable will ensure that
+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.
diff --git a/Help/variable/CMAKE_PCH_WARN_INVALID.rst b/Help/variable/CMAKE_PCH_WARN_INVALID.rst
new file mode 100644
index 0000000..e152abd
--- /dev/null
+++ b/Help/variable/CMAKE_PCH_WARN_INVALID.rst
@@ -0,0 +1,5 @@
+CMAKE_PCH_WARN_INVALID
+----------------------
+
+This variable is used to initialize the :prop_tgt:`PCH_WARN_INVALID`
+property of targets when they are created.
diff --git a/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst b/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst
index fc52e7b..de71d0e 100644
--- a/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst
+++ b/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst
@@ -23,6 +23,8 @@ warn by default:
policy :policy:`CMP0082`.
* ``CMAKE_POLICY_WARNING_CMP0089`` controls the warning for
policy :policy:`CMP0089`.
+* ``CMAKE_POLICY_WARNING_CMP0102`` controls the warning for
+ policy :policy:`CMP0102`.
This variable should not be set by a project in CMake code. Project
developers running CMake may set this variable in their cache to
diff --git a/Help/variable/CMAKE_PROJECT_INCLUDE.rst b/Help/variable/CMAKE_PROJECT_INCLUDE.rst
index 965c94e..5835264 100644
--- a/Help/variable/CMAKE_PROJECT_INCLUDE.rst
+++ b/Help/variable/CMAKE_PROJECT_INCLUDE.rst
@@ -5,5 +5,6 @@ A CMake language file or module to be included as the last step of all
:command:`project` command calls. This is intended for injecting custom code
into project builds without modifying their source.
-See also the :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE` and
+See also the :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE`,
+:variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE` and
:variable:`CMAKE_PROJECT_INCLUDE_BEFORE` variables.
diff --git a/Help/variable/CMAKE_PROJECT_INCLUDE_BEFORE.rst b/Help/variable/CMAKE_PROJECT_INCLUDE_BEFORE.rst
index 70b15e6..280c14a 100644
--- a/Help/variable/CMAKE_PROJECT_INCLUDE_BEFORE.rst
+++ b/Help/variable/CMAKE_PROJECT_INCLUDE_BEFORE.rst
@@ -5,5 +5,6 @@ A CMake language file or module to be included as the first step of all
:command:`project` command calls. This is intended for injecting custom code
into project builds without modifying their source.
-See also the :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE` and
+See also the :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE`,
+:variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE` and
:variable:`CMAKE_PROJECT_INCLUDE` variables.
diff --git a/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE.rst b/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE.rst
index 3485c38..74247f1 100644
--- a/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE.rst
+++ b/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE.rst
@@ -6,5 +6,6 @@ A CMake language file or module to be included as the last step of any
name. This is intended for injecting custom code into project builds without
modifying their source.
-See also the :variable:`CMAKE_PROJECT_INCLUDE` and
+See also the :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE`,
+:variable:`CMAKE_PROJECT_INCLUDE` and
:variable:`CMAKE_PROJECT_INCLUDE_BEFORE` variables.
diff --git a/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE_BEFORE.rst b/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE_BEFORE.rst
new file mode 100644
index 0000000..db1432d
--- /dev/null
+++ b/Help/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE_BEFORE.rst
@@ -0,0 +1,11 @@
+CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE_BEFORE
+-------------------------------------------
+
+A CMake language file or module to be included as the first step of any
+:command:`project` command calls that specify ``<PROJECT-NAME>`` as the project
+name. This is intended for injecting custom code into project builds without
+modifying their source.
+
+See also the :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE`,
+:variable:`CMAKE_PROJECT_INCLUDE` and
+:variable:`CMAKE_PROJECT_INCLUDE_BEFORE` variables.
diff --git a/Help/variable/CMAKE_VS_WINRT_BY_DEFAULT.rst b/Help/variable/CMAKE_VS_WINRT_BY_DEFAULT.rst
index 2ba8fe2..2eea424 100644
--- a/Help/variable/CMAKE_VS_WINRT_BY_DEFAULT.rst
+++ b/Help/variable/CMAKE_VS_WINRT_BY_DEFAULT.rst
@@ -1,8 +1,18 @@
CMAKE_VS_WINRT_BY_DEFAULT
-------------------------
-Tell :ref:`Visual Studio Generators` for VS 2010 and above that the
-target platform compiles as WinRT by default (compiles with ``/ZW``).
+Inform :ref:`Visual Studio Generators` for VS 2010 and above that the
+target platform enables WinRT compilation by default and it needs to
+be explicitly disabled if ``/ZW`` or :prop_tgt:`VS_WINRT_COMPONENT` is
+omitted (as opposed to enabling it when either of those options is
+present)
+
+This makes cmake configuration consistent in terms of WinRT among
+platforms - if you did not enable the WinRT compilation explicitly, it
+will be disabled (by either not enabling it or explicitly disabling it)
+
+Note: WinRT compilation is always explicitly disabled for C language
+source files, even if it is expliclty enabled for a project
This variable is meant to be set by a
:variable:`toolchain file <CMAKE_TOOLCHAIN_FILE>` for such platforms.
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_ENVIRONMENT.rst b/Help/variable/CMAKE_XCODE_SCHEME_ENVIRONMENT.rst
new file mode 100644
index 0000000..4832659
--- /dev/null
+++ b/Help/variable/CMAKE_XCODE_SCHEME_ENVIRONMENT.rst
@@ -0,0 +1,15 @@
+CMAKE_XCODE_SCHEME_ENVIRONMENT
+------------------------------
+
+Specify environment variables that should be added to the Arguments
+section of the generated Xcode scheme.
+
+If set to a list of environment variables and values of the form
+``MYVAR=value`` those environment variables will be added to the
+scheme.
+
+This variable initializes the :prop_tgt:`XCODE_SCHEME_ENVIRONMENT`
+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_WORKING_DIRECTORY.rst b/Help/variable/CMAKE_XCODE_SCHEME_WORKING_DIRECTORY.rst
new file mode 100644
index 0000000..5bb7907
--- /dev/null
+++ b/Help/variable/CMAKE_XCODE_SCHEME_WORKING_DIRECTORY.rst
@@ -0,0 +1,12 @@
+CMAKE_XCODE_SCHEME_WORKING_DIRECTORY
+------------------------------------
+
+Specify the ``Working Directory`` of the *Run* and *Profile*
+actions in the generated Xcode scheme.
+
+This variable initializes the
+:prop_tgt:`XCODE_SCHEME_WORKING_DIRECTORY`
+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/CTEST_CONFIGURATION_TYPE.rst b/Help/variable/CTEST_CONFIGURATION_TYPE.rst
index c905480..9e277fa 100644
--- a/Help/variable/CTEST_CONFIGURATION_TYPE.rst
+++ b/Help/variable/CTEST_CONFIGURATION_TYPE.rst
@@ -3,3 +3,6 @@ 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
+then this variable is populated accordingly.
diff --git a/Help/variable/CTEST_MEMORYCHECK_TYPE.rst b/Help/variable/CTEST_MEMORYCHECK_TYPE.rst
index b8b4c30..4e7d5c0 100644
--- a/Help/variable/CTEST_MEMORYCHECK_TYPE.rst
+++ b/Help/variable/CTEST_MEMORYCHECK_TYPE.rst
@@ -3,6 +3,6 @@ CTEST_MEMORYCHECK_TYPE
Specify the CTest ``MemoryCheckType`` setting
in a :manual:`ctest(1)` dashboard client script.
-Valid values are ``Valgrind``, ``Purify``, ``BoundsChecker``, and
+Valid values are ``Valgrind``, ``Purify``, ``BoundsChecker``, ``DrMemory`` and
``ThreadSanitizer``, ``AddressSanitizer``, ``LeakSanitizer``, ``MemorySanitizer``, and
``UndefinedBehaviorSanitizer``.
diff --git a/Help/variable/CTEST_NIGHTLY_START_TIME.rst b/Help/variable/CTEST_NIGHTLY_START_TIME.rst
index bc80276..90841f9 100644
--- a/Help/variable/CTEST_NIGHTLY_START_TIME.rst
+++ b/Help/variable/CTEST_NIGHTLY_START_TIME.rst
@@ -1,5 +1,9 @@
CTEST_NIGHTLY_START_TIME
------------------------
-Specify the CTest ``NightlyStartTime`` setting
-in a :manual:`ctest(1)` dashboard client script.
+Specify the CTest ``NightlyStartTime`` setting in a :manual:`ctest(1)`
+dashboard client script.
+
+Note that this variable must always be set for a nightly build in a
+dashboard script. It is needed so that nightly builds can be properly grouped
+together in CDash.
diff --git a/Help/variable/CTEST_RESOURCE_SPEC_FILE.rst b/Help/variable/CTEST_RESOURCE_SPEC_FILE.rst
new file mode 100644
index 0000000..59f365f
--- /dev/null
+++ b/Help/variable/CTEST_RESOURCE_SPEC_FILE.rst
@@ -0,0 +1,5 @@
+CTEST_RESOURCE_SPEC_FILE
+------------------------
+
+Specify the CTest ``ResourceSpecFile`` setting in a :manual:`ctest(1)`
+dashboard client script.
diff --git a/Help/variable/PROJECT_SOURCE_DIR.rst b/Help/variable/PROJECT_SOURCE_DIR.rst
index 27f2838..b4601c2 100644
--- a/Help/variable/PROJECT_SOURCE_DIR.rst
+++ b/Help/variable/PROJECT_SOURCE_DIR.rst
@@ -1,6 +1,8 @@
PROJECT_SOURCE_DIR
------------------
-Top level source directory for the current project.
-
-This is the source directory of the most recent :command:`project` command.
+This is the source directory of the last call to the
+:command:`project` command made in the current directory scope or one
+of its parents. Note, it is not affected by calls to
+:command:`project` made within a child directory scope (i.e. from
+within a call to :command:`add_subdirectory` from the current scope).
diff --git a/Modules/AndroidTestUtilities.cmake b/Modules/AndroidTestUtilities.cmake
index e333cdb..95e2ef7 100644
--- a/Modules/AndroidTestUtilities.cmake
+++ b/Modules/AndroidTestUtilities.cmake
@@ -76,8 +76,6 @@ Module Functions
include(${CMAKE_CURRENT_LIST_DIR}/ExternalData.cmake)
-set(_AndroidTestUtilities_SELF_DIR "${CMAKE_CURRENT_LIST_DIR}")
-
# The parameters to this function should be set to the list of directories,
# files, and libraries that need to be installed prior to testing.
function(android_add_test_data test_name)
@@ -159,6 +157,6 @@ function(android_add_test_data test_name)
"-Darg_files=${processed_FILES}"
"-Darg_libs=${AST_LIBS}"
"-Darg_src_dir=${CMAKE_CURRENT_SOURCE_DIR}"
- -P ${_AndroidTestUtilities_SELF_DIR}/AndroidTestUtilities/PushToAndroidDevice.cmake)
+ -P ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/AndroidTestUtilities/PushToAndroidDevice.cmake)
endif()
endfunction()
diff --git a/Modules/CMakeASMCompiler.cmake.in b/Modules/CMakeASMCompiler.cmake.in
index b8e09fe..3953b30 100644
--- a/Modules/CMakeASMCompiler.cmake.in
+++ b/Modules/CMakeASMCompiler.cmake.in
@@ -10,7 +10,9 @@ set(CMAKE_ASM@ASM_DIALECT@_COMPILER_LOADED 1)
set(CMAKE_ASM@ASM_DIALECT@_COMPILER_ID "@_CMAKE_ASM_COMPILER_ID@")
set(CMAKE_ASM@ASM_DIALECT@_COMPILER_VERSION "@_CMAKE_ASM_COMPILER_VERSION@")
set(CMAKE_ASM@ASM_DIALECT@_COMPILER_ENV_VAR "@_CMAKE_ASM_COMPILER_ENV_VAR@")
+@_SET_CMAKE_ASM_COMPILER_ID_VENDOR_MATCH@
@_SET_CMAKE_ASM_COMPILER_ARCHITECTURE_ID@
+@_SET_CMAKE_ASM_COMPILER_SYSROOT@
set(CMAKE_ASM@ASM_DIALECT@_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC)
set(CMAKE_ASM@ASM_DIALECT@_LINKER_PREFERENCE 0)
diff --git a/Modules/CMakeASMInformation.cmake b/Modules/CMakeASMInformation.cmake
index 6b73730..03195cc 100644
--- a/Modules/CMakeASMInformation.cmake
+++ b/Modules/CMakeASMInformation.cmake
@@ -76,12 +76,12 @@ endif()
if(NOT CMAKE_ASM${ASM_DIALECT}_CREATE_STATIC_LIBRARY)
set(CMAKE_ASM${ASM_DIALECT}_CREATE_STATIC_LIBRARY
"<CMAKE_AR> cr <TARGET> <LINK_FLAGS> <OBJECTS> "
- "<CMAKE_RANLIB> <TARGET> ")
+ "<CMAKE_RANLIB> <TARGET>")
endif()
if(NOT CMAKE_ASM${ASM_DIALECT}_LINK_EXECUTABLE)
set(CMAKE_ASM${ASM_DIALECT}_LINK_EXECUTABLE
- "<CMAKE_ASM${ASM_DIALECT}_COMPILER> <FLAGS> <CMAKE_ASM${ASM_DIALECT}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
+ "<CMAKE_ASM${ASM_DIALECT}_COMPILER> <FLAGS> <CMAKE_ASM${ASM_DIALECT}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
endif()
if(NOT CMAKE_EXECUTABLE_RUNTIME_ASM${ASM_DIALECT}_FLAG)
diff --git a/Modules/CMakeASM_MASMInformation.cmake b/Modules/CMakeASM_MASMInformation.cmake
index 9f7e934..6d1e174 100644
--- a/Modules/CMakeASM_MASMInformation.cmake
+++ b/Modules/CMakeASM_MASMInformation.cmake
@@ -8,7 +8,7 @@ set(ASM_DIALECT "_MASM")
set(CMAKE_ASM${ASM_DIALECT}_SOURCE_FILE_EXTENSIONS asm)
-set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT "<CMAKE_ASM${ASM_DIALECT}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> /c /Fo <OBJECT> <SOURCE>")
+set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT "<CMAKE_ASM${ASM_DIALECT}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> /c /Fo <OBJECT> <SOURCE>")
# The ASM_MASM compiler id for this compiler is "MSVC", so fill out the runtime library table.
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded "")
diff --git a/Modules/CMakeASM_NASMInformation.cmake b/Modules/CMakeASM_NASMInformation.cmake
index cb793e7..97cb488 100644
--- a/Modules/CMakeASM_NASMInformation.cmake
+++ b/Modules/CMakeASM_NASMInformation.cmake
@@ -8,19 +8,25 @@ set(CMAKE_ASM_NASM_SOURCE_FILE_EXTENSIONS nasm asm)
if(NOT CMAKE_ASM_NASM_OBJECT_FORMAT)
if(WIN32)
- if(CMAKE_C_SIZEOF_DATA_PTR EQUAL 8)
+ if(DEFINED CMAKE_C_SIZEOF_DATA_PTR AND CMAKE_C_SIZEOF_DATA_PTR EQUAL 8)
+ set(CMAKE_ASM_NASM_OBJECT_FORMAT win64)
+ elseif(DEFINED CMAKE_CXX_SIZEOF_DATA_PTR AND CMAKE_CXX_SIZEOF_DATA_PTR EQUAL 8)
set(CMAKE_ASM_NASM_OBJECT_FORMAT win64)
else()
set(CMAKE_ASM_NASM_OBJECT_FORMAT win32)
endif()
elseif(APPLE)
- if(CMAKE_C_SIZEOF_DATA_PTR EQUAL 8)
+ if(DEFINED CMAKE_C_SIZEOF_DATA_PTR AND CMAKE_C_SIZEOF_DATA_PTR EQUAL 8)
+ set(CMAKE_ASM_NASM_OBJECT_FORMAT macho64)
+ elseif(DEFINED CMAKE_CXX_SIZEOF_DATA_PTR AND CMAKE_CXX_SIZEOF_DATA_PTR EQUAL 8)
set(CMAKE_ASM_NASM_OBJECT_FORMAT macho64)
else()
set(CMAKE_ASM_NASM_OBJECT_FORMAT macho)
endif()
else()
- if(CMAKE_C_SIZEOF_DATA_PTR EQUAL 8)
+ if(DEFINED CMAKE_C_SIZEOF_DATA_PTR AND CMAKE_C_SIZEOF_DATA_PTR EQUAL 8)
+ set(CMAKE_ASM_NASM_OBJECT_FORMAT elf64)
+ elseif(DEFINED CMAKE_CXX_SIZEOF_DATA_PTR AND CMAKE_CXX_SIZEOF_DATA_PTR EQUAL 8)
set(CMAKE_ASM_NASM_OBJECT_FORMAT elf64)
else()
set(CMAKE_ASM_NASM_OBJECT_FORMAT elf)
diff --git a/Modules/CMakeAddFortranSubdirectory.cmake b/Modules/CMakeAddFortranSubdirectory.cmake
index 2613569..69a8417 100644
--- a/Modules/CMakeAddFortranSubdirectory.cmake
+++ b/Modules/CMakeAddFortranSubdirectory.cmake
@@ -43,7 +43,6 @@ future version that supports installation of the external project
binaries during ``make install``.
#]=======================================================================]
-set(_MS_MINGW_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR})
include(CheckLanguage)
include(ExternalProject)
@@ -87,11 +86,11 @@ function(_setup_mingw_config_and_build source_dir build_dir)
file(TO_NATIVE_PATH "${MINGW_PATH}" MINGW_PATH)
string(REPLACE "\\" "\\\\" MINGW_PATH "${MINGW_PATH}")
configure_file(
- ${_MS_MINGW_SOURCE_DIR}/CMakeAddFortranSubdirectory/config_mingw.cmake.in
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/CMakeAddFortranSubdirectory/config_mingw.cmake.in
${build_dir}/config_mingw.cmake
@ONLY)
configure_file(
- ${_MS_MINGW_SOURCE_DIR}/CMakeAddFortranSubdirectory/build_mingw.cmake.in
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/CMakeAddFortranSubdirectory/build_mingw.cmake.in
${build_dir}/build_mingw.cmake
@ONLY)
endfunction()
@@ -150,17 +149,9 @@ function(cmake_add_fortran_subdirectory subdir)
-P ${build_dir}/config_mingw.cmake
BUILD_COMMAND ${CMAKE_COMMAND}
-P ${build_dir}/build_mingw.cmake
+ BUILD_ALWAYS 1
INSTALL_COMMAND ""
)
- # make the external project always run make with each build
- externalproject_add_step(${project_name}_build forcebuild
- COMMAND ${CMAKE_COMMAND}
- -E remove
- ${CMAKE_CURRENT_BUILD_DIR}/${project_name}-prefix/src/${project_name}-stamp/${project_name}-build
- DEPENDEES configure
- DEPENDERS build
- ALWAYS 1
- )
# create imported targets for all libraries
foreach(lib ${libraries})
add_library(${lib} SHARED IMPORTED GLOBAL)
diff --git a/Modules/CMakeCCompiler.cmake.in b/Modules/CMakeCCompiler.cmake.in
index 9b8d423..eea3f5d 100644
--- a/Modules/CMakeCCompiler.cmake.in
+++ b/Modules/CMakeCCompiler.cmake.in
@@ -15,6 +15,7 @@ set(CMAKE_C_SIMULATE_ID "@CMAKE_C_SIMULATE_ID@")
set(CMAKE_C_COMPILER_FRONTEND_VARIANT "@CMAKE_C_COMPILER_FRONTEND_VARIANT@")
set(CMAKE_C_SIMULATE_VERSION "@CMAKE_C_SIMULATE_VERSION@")
@_SET_CMAKE_C_COMPILER_ARCHITECTURE_ID@
+@_SET_CMAKE_C_COMPILER_SYSROOT@
@SET_MSVC_C_ARCHITECTURE_ID@
@SET_CMAKE_XCODE_ARCHS@
set(CMAKE_AR "@CMAKE_AR@")
diff --git a/Modules/CMakeCInformation.cmake b/Modules/CMakeCInformation.cmake
index df43559..f6d620f 100644
--- a/Modules/CMakeCInformation.cmake
+++ b/Modules/CMakeCInformation.cmake
@@ -110,6 +110,11 @@ if(CMAKE_C_STANDARD_LIBRARIES_INIT)
mark_as_advanced(CMAKE_C_STANDARD_LIBRARIES)
endif()
+if(NOT CMAKE_C_COMPILER_LAUNCHER AND DEFINED ENV{CMAKE_C_COMPILER_LAUNCHER})
+ set(CMAKE_C_COMPILER_LAUNCHER "$ENV{CMAKE_C_COMPILER_LAUNCHER}"
+ CACHE STRING "Compiler launcher for C.")
+endif()
+
include(CMakeCommonLanguageInclude)
# now define the following rule variables
@@ -156,7 +161,7 @@ if(NOT DEFINED CMAKE_C_ARCHIVE_CREATE)
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>")
endif()
if(NOT DEFINED CMAKE_C_ARCHIVE_APPEND)
- set(CMAKE_C_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
+ set(CMAKE_C_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
endif()
if(NOT DEFINED CMAKE_C_ARCHIVE_FINISH)
set(CMAKE_C_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")
@@ -165,12 +170,12 @@ endif()
# compile a C file into an object file
if(NOT CMAKE_C_COMPILE_OBJECT)
set(CMAKE_C_COMPILE_OBJECT
- "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
+ "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
endif()
if(NOT CMAKE_C_LINK_EXECUTABLE)
set(CMAKE_C_LINK_EXECUTABLE
- "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
+ "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
endif()
if(NOT CMAKE_EXECUTABLE_RUNTIME_C_FLAG)
diff --git a/Modules/CMakeCSharpInformation.cmake b/Modules/CMakeCSharpInformation.cmake
index 48e1a1e..41cd449 100644
--- a/Modules/CMakeCSharpInformation.cmake
+++ b/Modules/CMakeCSharpInformation.cmake
@@ -10,7 +10,7 @@ get_filename_component(CMAKE_BASE_NAME "${CMAKE_CSharp_COMPILER}" NAME_WE)
set(CMAKE_BUILD_TYPE_INIT Debug)
-set(CMAKE_CSharp_FLAGS_INIT "/define:TRACE /langversion:3")
+set(CMAKE_CSharp_FLAGS_INIT "/define:TRACE")
set(CMAKE_CSharp_FLAGS_DEBUG_INIT "/debug:full /optimize- /warn:3 /errorreport:prompt /define:DEBUG")
set(CMAKE_CSharp_FLAGS_RELEASE_INIT "/debug:none /optimize /warn:1 /errorreport:queue")
set(CMAKE_CSharp_FLAGS_RELWITHDEBINFO_INIT "/debug:full /optimize-")
diff --git a/Modules/CMakeCUDACompiler.cmake.in b/Modules/CMakeCUDACompiler.cmake.in
index 711129a..289e96e 100644
--- a/Modules/CMakeCUDACompiler.cmake.in
+++ b/Modules/CMakeCUDACompiler.cmake.in
@@ -4,9 +4,19 @@ set(CMAKE_CUDA_HOST_LINK_LAUNCHER "@CMAKE_CUDA_HOST_LINK_LAUNCHER@")
set(CMAKE_CUDA_COMPILER_ID "@CMAKE_CUDA_COMPILER_ID@")
set(CMAKE_CUDA_COMPILER_VERSION "@CMAKE_CUDA_COMPILER_VERSION@")
set(CMAKE_CUDA_STANDARD_COMPUTED_DEFAULT "@CMAKE_CUDA_STANDARD_COMPUTED_DEFAULT@")
+set(CMAKE_CUDA_COMPILE_FEATURES "@CMAKE_CUDA_COMPILE_FEATURES@")
+set(CMAKE_CUDA03_COMPILE_FEATURES "@CMAKE_CUDA03_COMPILE_FEATURES@")
+set(CMAKE_CUDA11_COMPILE_FEATURES "@CMAKE_CUDA11_COMPILE_FEATURES@")
+set(CMAKE_CUDA14_COMPILE_FEATURES "@CMAKE_CUDA14_COMPILE_FEATURES@")
+set(CMAKE_CUDA17_COMPILE_FEATURES "@CMAKE_CUDA17_COMPILE_FEATURES@")
+set(CMAKE_CUDA20_COMPILE_FEATURES "@CMAKE_CUDA20_COMPILE_FEATURES@")
+
+set(CMAKE_CUDA_PLATFORM_ID "@CMAKE_CUDA_PLATFORM_ID@")
set(CMAKE_CUDA_SIMULATE_ID "@CMAKE_CUDA_SIMULATE_ID@")
+set(CMAKE_CUDA_COMPILER_FRONTEND_VARIANT "@CMAKE_CUDA_COMPILER_FRONTEND_VARIANT@")
set(CMAKE_CUDA_SIMULATE_VERSION "@CMAKE_CUDA_SIMULATE_VERSION@")
@SET_MSVC_CUDA_ARCHITECTURE_ID@
+@_SET_CMAKE_CUDA_COMPILER_SYSROOT@
set(CMAKE_CUDA_COMPILER_ENV_VAR "CUDACXX")
set(CMAKE_CUDA_HOST_COMPILER_ENV_VAR "CUDAHOSTCXX")
@@ -17,6 +27,22 @@ set(CMAKE_CUDA_SOURCE_FILE_EXTENSIONS cu)
set(CMAKE_CUDA_LINKER_PREFERENCE 15)
set(CMAKE_CUDA_LINKER_PREFERENCE_PROPAGATES 1)
+set(CMAKE_CUDA_SIZEOF_DATA_PTR "@CMAKE_CUDA_SIZEOF_DATA_PTR@")
+set(CMAKE_CUDA_COMPILER_ABI "@CMAKE_CUDA_COMPILER_ABI@")
+set(CMAKE_CUDA_LIBRARY_ARCHITECTURE "@CMAKE_CUDA_LIBRARY_ARCHITECTURE@")
+
+if(CMAKE_CUDA_SIZEOF_DATA_PTR)
+ set(CMAKE_SIZEOF_VOID_P "${CMAKE_CUDA_SIZEOF_DATA_PTR}")
+endif()
+
+if(CMAKE_CUDA_COMPILER_ABI)
+ set(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_CUDA_COMPILER_ABI}")
+endif()
+
+if(CMAKE_CUDA_LIBRARY_ARCHITECTURE)
+ set(CMAKE_LIBRARY_ARCHITECTURE "@CMAKE_CUDA_LIBRARY_ARCHITECTURE@")
+endif()
+
set(CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES "@CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES@")
set(CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES "@CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES@")
@@ -29,4 +55,5 @@ set(CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES "@CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES@
set(CMAKE_CUDA_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "@CMAKE_CUDA_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES@")
set(CMAKE_LINKER "@CMAKE_LINKER@")
+set(CMAKE_AR "@CMAKE_AR@")
set(CMAKE_MT "@CMAKE_MT@")
diff --git a/Modules/CMakeCUDACompilerId.cu.in b/Modules/CMakeCUDACompilerId.cu.in
index 6eda924..2055de2 100644
--- a/Modules/CMakeCUDACompilerId.cu.in
+++ b/Modules/CMakeCUDACompilerId.cu.in
@@ -26,7 +26,7 @@ const char* info_language_dialect_default = "INFO" ":" "dialect_default["
#elif __cplusplus >= 201103L
"11"
#else
- "98"
+ "03"
#endif
"]";
diff --git a/Modules/CMakeCUDAInformation.cmake b/Modules/CMakeCUDAInformation.cmake
index b0d80d1..e8b60b6 100644
--- a/Modules/CMakeCUDAInformation.cmake
+++ b/Modules/CMakeCUDAInformation.cmake
@@ -82,6 +82,11 @@ if(CMAKE_CUDA_STANDARD_LIBRARIES_INIT)
mark_as_advanced(CMAKE_CUDA_STANDARD_LIBRARIES)
endif()
+if(NOT CMAKE_CUDA_COMPILER_LAUNCHER AND DEFINED ENV{CMAKE_CUDA_COMPILER_LAUNCHER})
+ set(CMAKE_CUDA_COMPILER_LAUNCHER "$ENV{CMAKE_CUDA_COMPILER_LAUNCHER}"
+ CACHE STRING "Compiler launcher for CUDA.")
+endif()
+
include(CMakeCommonLanguageInclude)
# now define the following rules:
@@ -93,9 +98,7 @@ include(CMakeCommonLanguageInclude)
# CMAKE_CUDA_LINK_EXECUTABLE
if(CMAKE_CUDA_HOST_COMPILER)
- set(CMAKE_CUDA_HOST_FLAGS "-ccbin=<CMAKE_CUDA_HOST_COMPILER>")
-else()
- set(CMAKE_CUDA_HOST_FLAGS "")
+ string(APPEND _CMAKE_CUDA_EXTRA_FLAGS " -ccbin=<CMAKE_CUDA_HOST_COMPILER>")
endif()
set(__IMPLICT_LINKS )
@@ -126,7 +129,7 @@ if(NOT DEFINED CMAKE_CUDA_ARCHIVE_CREATE)
set(CMAKE_CUDA_ARCHIVE_CREATE "<CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>")
endif()
if(NOT DEFINED CMAKE_CUDA_ARCHIVE_APPEND)
- set(CMAKE_CUDA_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
+ set(CMAKE_CUDA_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
endif()
if(NOT DEFINED CMAKE_CUDA_ARCHIVE_FINISH)
set(CMAKE_CUDA_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")
@@ -135,26 +138,26 @@ endif()
#Specify how to compile when ptx has been requested
if(NOT CMAKE_CUDA_COMPILE_PTX_COMPILATION)
set(CMAKE_CUDA_COMPILE_PTX_COMPILATION
- "<CMAKE_CUDA_COMPILER> ${CMAKE_CUDA_HOST_FLAGS} <DEFINES> <INCLUDES> <FLAGS> -x cu -ptx <SOURCE> -o <OBJECT>")
+ "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <DEFINES> <INCLUDES> <FLAGS> ${_CMAKE_COMPILE_AS_CUDA_FLAG} ${_CMAKE_CUDA_PTX_FLAG} <SOURCE> -o <OBJECT>")
endif()
#Specify how to compile when separable compilation has been requested
if(NOT CMAKE_CUDA_COMPILE_SEPARABLE_COMPILATION)
set(CMAKE_CUDA_COMPILE_SEPARABLE_COMPILATION
- "<CMAKE_CUDA_COMPILER> ${CMAKE_CUDA_HOST_FLAGS} <DEFINES> <INCLUDES> <FLAGS> -x cu -dc <SOURCE> -o <OBJECT>")
+ "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <DEFINES> <INCLUDES> <FLAGS> ${_CMAKE_COMPILE_AS_CUDA_FLAG} -dc <SOURCE> -o <OBJECT>")
endif()
#Specify how to compile when whole compilation has been requested
if(NOT CMAKE_CUDA_COMPILE_WHOLE_COMPILATION)
set(CMAKE_CUDA_COMPILE_WHOLE_COMPILATION
- "<CMAKE_CUDA_COMPILER> ${CMAKE_CUDA_HOST_FLAGS} <DEFINES> <INCLUDES> <FLAGS> -x cu -c <SOURCE> -o <OBJECT>")
+ "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <DEFINES> <INCLUDES> <FLAGS> ${_CMAKE_COMPILE_AS_CUDA_FLAG} -c <SOURCE> -o <OBJECT>")
endif()
-if(CMAKE_GENERATOR STREQUAL "Ninja")
+if(CMAKE_GENERATOR STREQUAL "Ninja" AND NOT CMAKE_DEPFILE_FLAGS_CUDA)
set(CMAKE_CUDA_COMPILE_DEPENDENCY_DETECTION
- "<CMAKE_CUDA_COMPILER> ${CMAKE_CUDA_HOST_FLAGS} <DEFINES> <INCLUDES> <FLAGS> -x cu -M <SOURCE> -MT <OBJECT> -o $DEP_FILE")
+ "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <DEFINES> <INCLUDES> <FLAGS> ${_CMAKE_COMPILE_AS_CUDA_FLAG} -M <SOURCE> -MT <OBJECT> -o $DEP_FILE")
#The Ninja generator uses the make file dependency files to determine what
- #files need to be recompiled. Unfortunately, nvcc doesn't support building
+ #files need to be recompiled. Unfortunately, nvcc < 10.2 doesn't support building
#a source file and generating the dependencies of said file in a single
#invocation. Instead we have to state that you need to chain two commands.
#
@@ -171,13 +174,6 @@ if(NOT CMAKE_CUDA_LINK_EXECUTABLE)
"<CMAKE_CUDA_HOST_LINK_LAUNCHER> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICT_LINKS}")
endif()
-if( CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA" AND
- CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "8.0.0")
- set(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS "-Wno-deprecated-gpu-targets")
-else()
- set(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS "")
-endif()
-
# Add implicit host link directories that contain device libraries
# to the device link line.
set(__IMPLICT_DLINK_DIRS ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES})
@@ -192,17 +188,17 @@ foreach(dir ${__IMPLICT_DLINK_DIRS})
endforeach()
unset(__IMPLICT_DLINK_DIRS)
+
#These are used when linking relocatable (dc) cuda code
if(NOT CMAKE_CUDA_DEVICE_LINK_LIBRARY)
set(CMAKE_CUDA_DEVICE_LINK_LIBRARY
- "<CMAKE_CUDA_COMPILER> ${CMAKE_CUDA_HOST_FLAGS} <LANGUAGE_COMPILE_FLAGS> ${CMAKE_CUDA_COMPILE_OPTIONS_PIC} ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICT_DLINK_FLAGS}")
+ "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> ${CMAKE_CUDA_COMPILE_OPTIONS_PIC} ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICT_DLINK_FLAGS}")
endif()
if(NOT CMAKE_CUDA_DEVICE_LINK_EXECUTABLE)
set(CMAKE_CUDA_DEVICE_LINK_EXECUTABLE
- "<CMAKE_CUDA_COMPILER> ${CMAKE_CUDA_HOST_FLAGS} <FLAGS> ${CMAKE_CUDA_COMPILE_OPTIONS_PIC} ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICT_DLINK_FLAGS}")
+ "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> ${CMAKE_CUDA_COMPILE_OPTIONS_PIC} ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES>${__IMPLICT_DLINK_FLAGS}")
endif()
-unset(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS)
unset(__IMPLICT_DLINK_FLAGS)
set(CMAKE_CUDA_INFORMATION_LOADED 1)
diff --git a/Modules/CMakeCXXCompiler.cmake.in b/Modules/CMakeCXXCompiler.cmake.in
index efb8abf..09bdc23 100644
--- a/Modules/CMakeCXXCompiler.cmake.in
+++ b/Modules/CMakeCXXCompiler.cmake.in
@@ -17,6 +17,7 @@ set(CMAKE_CXX_SIMULATE_ID "@CMAKE_CXX_SIMULATE_ID@")
set(CMAKE_CXX_COMPILER_FRONTEND_VARIANT "@CMAKE_CXX_COMPILER_FRONTEND_VARIANT@")
set(CMAKE_CXX_SIMULATE_VERSION "@CMAKE_CXX_SIMULATE_VERSION@")
@_SET_CMAKE_CXX_COMPILER_ARCHITECTURE_ID@
+@_SET_CMAKE_CXX_COMPILER_SYSROOT@
@SET_MSVC_CXX_ARCHITECTURE_ID@
@SET_CMAKE_XCODE_ARCHS@
set(CMAKE_AR "@CMAKE_AR@")
diff --git a/Modules/CMakeCXXInformation.cmake b/Modules/CMakeCXXInformation.cmake
index a896b99..dbb4366 100644
--- a/Modules/CMakeCXXInformation.cmake
+++ b/Modules/CMakeCXXInformation.cmake
@@ -207,6 +207,11 @@ if(CMAKE_CXX_STANDARD_LIBRARIES_INIT)
mark_as_advanced(CMAKE_CXX_STANDARD_LIBRARIES)
endif()
+if(NOT CMAKE_CXX_COMPILER_LAUNCHER AND DEFINED ENV{CMAKE_CXX_COMPILER_LAUNCHER})
+ set(CMAKE_CXX_COMPILER_LAUNCHER "$ENV{CMAKE_CXX_COMPILER_LAUNCHER}"
+ CACHE STRING "Compiler launcher for CXX.")
+endif()
+
include(CMakeCommonLanguageInclude)
# now define the following rules:
@@ -253,7 +258,7 @@ if(NOT DEFINED CMAKE_CXX_ARCHIVE_CREATE)
set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>")
endif()
if(NOT DEFINED CMAKE_CXX_ARCHIVE_APPEND)
- set(CMAKE_CXX_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
+ set(CMAKE_CXX_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
endif()
if(NOT DEFINED CMAKE_CXX_ARCHIVE_FINISH)
set(CMAKE_CXX_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")
@@ -262,12 +267,12 @@ endif()
# compile a C++ file into an object file
if(NOT CMAKE_CXX_COMPILE_OBJECT)
set(CMAKE_CXX_COMPILE_OBJECT
- "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
+ "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
endif()
if(NOT CMAKE_CXX_LINK_EXECUTABLE)
set(CMAKE_CXX_LINK_EXECUTABLE
- "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
+ "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
endif()
mark_as_advanced(
diff --git a/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake b/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake
index e1ce617..2dc75d6 100644
--- a/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake
+++ b/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake
@@ -9,6 +9,7 @@
macro (CHECK_COMPILER_FLAG_COMMON_PATTERNS _VAR)
set(${_VAR}
FAIL_REGEX "[Uu]nrecogni[sz]ed .*option" # GNU, NAG
+ FAIL_REGEX "switch .* is no longer supported" # GNU
FAIL_REGEX "unknown .*option" # Clang
FAIL_REGEX "optimization flag .* not supported" # Clang
FAIL_REGEX "unknown argument ignored" # Clang (cl)
diff --git a/Modules/CMakeDetermineASMCompiler.cmake b/Modules/CMakeDetermineASMCompiler.cmake
index e47f3a4..bc8b86b 100644
--- a/Modules/CMakeDetermineASMCompiler.cmake
+++ b/Modules/CMakeDetermineASMCompiler.cmake
@@ -134,6 +134,9 @@ if(NOT CMAKE_ASM${ASM_DIALECT}_COMPILER_ID)
list(GET _all_compileid_matches "-1" CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID)
endif()
endif()
+
+ _cmake_find_compiler_sysroot(ASM${ASM_DIALECT})
+
unset(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_OUTPUT)
unset(_all_compileid_matches)
unset(_compileid)
@@ -211,6 +214,21 @@ foreach(_var
set(_CMAKE_ASM_${_var} "${CMAKE_ASM${ASM_DIALECT}_${_var}}")
endforeach()
+if(CMAKE_ASM${ASM_DIALECT}_COMPILER_SYSROOT)
+ string(CONCAT _SET_CMAKE_ASM_COMPILER_SYSROOT
+ "set(CMAKE_ASM${ASM_DIALECT}_COMPILER_SYSROOT \"${CMAKE_ASM${ASM_DIALECT}_COMPILER_SYSROOT}\")\n"
+ "set(CMAKE_COMPILER_SYSROOT \"${CMAKE_ASM${ASM_DIALECT}_COMPILER_SYSROOT}\")")
+else()
+ set(_SET_CMAKE_ASM_COMPILER_SYSROOT "")
+endif()
+
+if(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_MATCH)
+ set(_SET_CMAKE_ASM_COMPILER_ID_VENDOR_MATCH
+ "set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_MATCH [==[${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_MATCH}]==])")
+else()
+ set(_SET_CMAKE_ASM_COMPILER_ID_VENDOR_MATCH "")
+endif()
+
if(CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID)
set(_SET_CMAKE_ASM_COMPILER_ARCHITECTURE_ID
"set(CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID ${CMAKE_ASM${ASM_DIALECT}_COMPILER_ARCHITECTURE_ID})")
diff --git a/Modules/CMakeDetermineCCompiler.cmake b/Modules/CMakeDetermineCCompiler.cmake
index 037c33b..f870956 100644
--- a/Modules/CMakeDetermineCCompiler.cmake
+++ b/Modules/CMakeDetermineCCompiler.cmake
@@ -115,6 +115,8 @@ if(NOT CMAKE_C_COMPILER_ID_RUN)
include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
CMAKE_DETERMINE_COMPILER_ID(C CFLAGS CMakeCCompilerId.c)
+ _cmake_find_compiler_sysroot(C)
+
# Set old compiler and platform id variables.
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
set(CMAKE_COMPILER_IS_GNUCC 1)
@@ -153,7 +155,7 @@ endif ()
# NAME_WE cannot be used since then this test will fail for names like
# "arm-unknown-nto-qnx6.3.0-gcc.exe", where BASENAME would be
# "arm-unknown-nto-qnx6" instead of the correct "arm-unknown-nto-qnx6.3.0-"
-if (CMAKE_CROSSCOMPILING AND NOT _CMAKE_TOOLCHAIN_PREFIX)
+if (NOT _CMAKE_TOOLCHAIN_PREFIX)
if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang|QCC")
get_filename_component(COMPILER_BASENAME "${CMAKE_C_COMPILER}" NAME)
@@ -191,6 +193,14 @@ include(CMakeFindBinUtils)
include(Compiler/${CMAKE_C_COMPILER_ID}-FindBinUtils OPTIONAL)
unset(_CMAKE_PROCESSING_LANGUAGE)
+if(CMAKE_C_COMPILER_SYSROOT)
+ string(CONCAT _SET_CMAKE_C_COMPILER_SYSROOT
+ "set(CMAKE_C_COMPILER_SYSROOT \"${CMAKE_C_COMPILER_SYSROOT}\")\n"
+ "set(CMAKE_COMPILER_SYSROOT \"${CMAKE_C_COMPILER_SYSROOT}\")")
+else()
+ set(_SET_CMAKE_C_COMPILER_SYSROOT "")
+endif()
+
if(CMAKE_C_COMPILER_ARCHITECTURE_ID)
set(_SET_CMAKE_C_COMPILER_ARCHITECTURE_ID
"set(CMAKE_C_COMPILER_ARCHITECTURE_ID ${CMAKE_C_COMPILER_ARCHITECTURE_ID})")
diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake
index 490d659..ead4125 100644
--- a/Modules/CMakeDetermineCUDACompiler.cmake
+++ b/Modules/CMakeDetermineCUDACompiler.cmake
@@ -70,10 +70,13 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN)
include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
CMAKE_DETERMINE_COMPILER_ID(CUDA CUDAFLAGS CMakeCUDACompilerId.cu)
+
+ _cmake_find_compiler_sysroot(CUDA)
endif()
set(_CMAKE_PROCESSING_LANGUAGE "CUDA")
include(CMakeFindBinUtils)
+include(Compiler/${CMAKE_CUDA_COMPILER_ID}-FindBinUtils OPTIONAL)
unset(_CMAKE_PROCESSING_LANGUAGE)
if(MSVC_CUDA_ARCHITECTURE_ID)
@@ -86,7 +89,7 @@ if(${CMAKE_GENERATOR} MATCHES "Visual Studio")
set(CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES "")
set(CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES "")
set(CMAKE_CUDA_HOST_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "")
-elseif(CMAKE_CUDA_COMPILER_ID STREQUAL NVIDIA)
+elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
set(_nvcc_log "")
string(REPLACE "\r" "" _nvcc_output_orig "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}")
if(_nvcc_output_orig MATCHES "#\\\$ +PATH= *([^\n]*)\n")
@@ -186,8 +189,20 @@ elseif(CMAKE_CUDA_COMPILER_ID STREQUAL NVIDIA)
"Failed to parsed CUDA nvcc implicit link information:\n${_nvcc_log}\n\n")
message(FATAL_ERROR "Failed to extract nvcc implicit link line.")
endif()
+endif()
+
+if(CMAKE_CUDA_COMPILER_SYSROOT)
+ string(CONCAT _SET_CMAKE_CUDA_COMPILER_SYSROOT
+ "set(CMAKE_CUDA_COMPILER_SYSROOT \"${CMAKE_CUDA_COMPILER_SYSROOT}\")\n"
+ "set(CMAKE_COMPILER_SYSROOT \"${CMAKE_CUDA_COMPILER_SYSROOT}\")")
+else()
+ set(_SET_CMAKE_CUDA_COMPILER_SYSROOT "")
+endif()
- set(CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES )
+# Determine CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES
+if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
+ set(CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES)
+ string(REPLACE "\r" "" _nvcc_output_orig "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}")
if(_nvcc_output_orig MATCHES "#\\\$ +INCLUDES= *([^\n]*)\n")
set(_nvcc_includes "${CMAKE_MATCH_1}")
string(APPEND _nvcc_log " found 'INCLUDES=' string: [${_nvcc_includes}]\n")
@@ -198,7 +213,7 @@ elseif(CMAKE_CUDA_COMPILER_ID STREQUAL NVIDIA)
endif()
if(_nvcc_includes)
# across all operating system each include directory is prefixed with -I
- separate_arguments(_nvcc_output UNIX_COMMAND "${_nvcc_includes}")
+ separate_arguments(_nvcc_output NATIVE_COMMAND "${_nvcc_includes}")
foreach(line IN LISTS _nvcc_output)
string(REGEX REPLACE "^-I" "" line "${line}")
get_filename_component(line "${line}" ABSOLUTE)
@@ -212,7 +227,16 @@ elseif(CMAKE_CUDA_COMPILER_ID STREQUAL NVIDIA)
"Failed to detect CUDA nvcc include information:\n${_nvcc_log}\n\n")
endif()
+ # Parse default CUDA architecture.
+ cmake_policy(GET CMP0104 _CUDA_CMP0104)
+ if(NOT CMAKE_CUDA_ARCHITECTURES AND _CUDA_CMP0104 STREQUAL "NEW")
+ string(REGEX MATCH "arch[ =]compute_([0-9]+)" dont_care "${CMAKE_CUDA_COMPILER_PRODUCED_OUTPUT}")
+ set(CMAKE_CUDA_ARCHITECTURES "${CMAKE_MATCH_1}" CACHE STRING "CUDA architectures")
+ if(NOT CMAKE_CUDA_ARCHITECTURES)
+ message(FATAL_ERROR "Failed to find default CUDA architecture.")
+ endif()
+ endif()
endif()
# configure all variables set in this file
diff --git a/Modules/CMakeDetermineCXXCompiler.cmake b/Modules/CMakeDetermineCXXCompiler.cmake
index 7274eec..e6b46b8 100644
--- a/Modules/CMakeDetermineCXXCompiler.cmake
+++ b/Modules/CMakeDetermineCXXCompiler.cmake
@@ -110,6 +110,8 @@ if(NOT CMAKE_CXX_COMPILER_ID_RUN)
include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
CMAKE_DETERMINE_COMPILER_ID(CXX CXXFLAGS CMakeCXXCompilerId.cpp)
+ _cmake_find_compiler_sysroot(CXX)
+
# Set old compiler and platform id variables.
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(CMAKE_COMPILER_IS_GNUCXX 1)
@@ -150,7 +152,7 @@ endif ()
# "arm-unknown-nto-qnx6" instead of the correct "arm-unknown-nto-qnx6.3.0-"
-if (CMAKE_CROSSCOMPILING AND NOT _CMAKE_TOOLCHAIN_PREFIX)
+if (NOT _CMAKE_TOOLCHAIN_PREFIX)
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU|Clang|QCC")
get_filename_component(COMPILER_BASENAME "${CMAKE_CXX_COMPILER}" NAME)
@@ -189,6 +191,14 @@ include(CMakeFindBinUtils)
include(Compiler/${CMAKE_CXX_COMPILER_ID}-FindBinUtils OPTIONAL)
unset(_CMAKE_PROCESSING_LANGUAGE)
+if(CMAKE_CXX_COMPILER_SYSROOT)
+ string(CONCAT _SET_CMAKE_CXX_COMPILER_SYSROOT
+ "set(CMAKE_CXX_COMPILER_SYSROOT \"${CMAKE_CXX_COMPILER_SYSROOT}\")\n"
+ "set(CMAKE_COMPILER_SYSROOT \"${CMAKE_CXX_COMPILER_SYSROOT}\")")
+else()
+ set(_SET_CMAKE_CXX_COMPILER_SYSROOT "")
+endif()
+
if(CMAKE_CXX_COMPILER_ARCHITECTURE_ID)
set(_SET_CMAKE_CXX_COMPILER_ARCHITECTURE_ID
"set(CMAKE_CXX_COMPILER_ARCHITECTURE_ID ${CMAKE_CXX_COMPILER_ARCHITECTURE_ID})")
diff --git a/Modules/CMakeDetermineCompileFeatures.cmake b/Modules/CMakeDetermineCompileFeatures.cmake
index 01a81a1..b50e5f1 100644
--- a/Modules/CMakeDetermineCompileFeatures.cmake
+++ b/Modules/CMakeDetermineCompileFeatures.cmake
@@ -5,7 +5,7 @@
function(cmake_determine_compile_features lang)
if(lang STREQUAL C AND COMMAND cmake_record_c_compile_features)
- message(STATUS "Detecting ${lang} compile features")
+ message(CHECK_START "Detecting ${lang} compile features")
set(CMAKE_C90_COMPILE_FEATURES)
set(CMAKE_C99_COMPILE_FEATURES)
@@ -16,7 +16,7 @@ function(cmake_determine_compile_features lang)
cmake_record_c_compile_features()
if(NOT _result EQUAL 0)
- message(STATUS "Detecting ${lang} compile features - failed")
+ message(CHECK_FAIL "failed")
return()
endif()
@@ -40,10 +40,10 @@ function(cmake_determine_compile_features lang)
set(CMAKE_C99_COMPILE_FEATURES ${CMAKE_C99_COMPILE_FEATURES} PARENT_SCOPE)
set(CMAKE_C11_COMPILE_FEATURES ${CMAKE_C11_COMPILE_FEATURES} PARENT_SCOPE)
- message(STATUS "Detecting ${lang} compile features - done")
+ message(CHECK_PASS "done")
elseif(lang STREQUAL CXX AND COMMAND cmake_record_cxx_compile_features)
- message(STATUS "Detecting ${lang} compile features")
+ message(CHECK_START "Detecting ${lang} compile features")
set(CMAKE_CXX98_COMPILE_FEATURES)
set(CMAKE_CXX11_COMPILE_FEATURES)
@@ -56,7 +56,7 @@ function(cmake_determine_compile_features lang)
cmake_record_cxx_compile_features()
if(NOT _result EQUAL 0)
- message(STATUS "Detecting ${lang} compile features - failed")
+ message(CHECK_FAIL "failed")
return()
endif()
@@ -90,7 +90,58 @@ 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)
- message(STATUS "Detecting ${lang} compile features - done")
+ message(CHECK_PASS "done")
+
+ elseif(lang STREQUAL CUDA AND COMMAND cmake_record_cuda_compile_features)
+ message(CHECK_START "Detecting ${lang} compile features")
+
+ set(CMAKE_CUDA03_COMPILE_FEATURES)
+ set(CMAKE_CUDA11_COMPILE_FEATURES)
+ set(CMAKE_CUDA14_COMPILE_FEATURES)
+ set(CMAKE_CUDA17_COMPILE_FEATURES)
+ set(CMAKE_CUDA20_COMPILE_FEATURES)
+
+ include("${CMAKE_ROOT}/Modules/Internal/FeatureTesting.cmake")
+
+ cmake_record_cuda_compile_features()
+
+ if(NOT _result EQUAL 0)
+ message(CHECK_FAIL "failed")
+ return()
+ endif()
+
+ if (CMAKE_CUDA17_COMPILE_FEATURES AND CMAKE_CUDA20_COMPILE_FEATURES)
+ list(REMOVE_ITEM CMAKE_CUDA20_COMPILE_FEATURES ${CMAKE_CUDA17_COMPILE_FEATURES})
+ endif()
+ if (CMAKE_CUDA14_COMPILE_FEATURES AND CMAKE_CUDA17_COMPILE_FEATURES)
+ list(REMOVE_ITEM CMAKE_CUDA17_COMPILE_FEATURES ${CMAKE_CUDA14_COMPILE_FEATURES})
+ endif()
+ if (CMAKE_CUDA11_COMPILE_FEATURES AND CMAKE_CUDA14_COMPILE_FEATURES)
+ list(REMOVE_ITEM CMAKE_CUDA14_COMPILE_FEATURES ${CMAKE_CUDA11_COMPILE_FEATURES})
+ endif()
+ if (CMAKE_CUDA03_COMPILE_FEATURES AND CMAKE_CUDA11_COMPILE_FEATURES)
+ list(REMOVE_ITEM CMAKE_CUDA11_COMPILE_FEATURES ${CMAKE_CUDA03_COMPILE_FEATURES})
+ endif()
+
+ if(NOT CMAKE_CUDA_COMPILE_FEATURES)
+ set(CMAKE_CUDA_COMPILE_FEATURES
+ ${CMAKE_CUDA03_COMPILE_FEATURES}
+ ${CMAKE_CUDA11_COMPILE_FEATURES}
+ ${CMAKE_CUDA14_COMPILE_FEATURES}
+ ${CMAKE_CUDA17_COMPILE_FEATURES}
+ ${CMAKE_CUDA20_COMPILE_FEATURES}
+ )
+ endif()
+
+ set(CMAKE_CUDA_COMPILE_FEATURES ${CMAKE_CUDA_COMPILE_FEATURES} PARENT_SCOPE)
+ set(CMAKE_CUDA03_COMPILE_FEATURES ${CMAKE_CUDA03_COMPILE_FEATURES} PARENT_SCOPE)
+ set(CMAKE_CUDA11_COMPILE_FEATURES ${CMAKE_CUDA11_COMPILE_FEATURES} PARENT_SCOPE)
+ set(CMAKE_CUDA14_COMPILE_FEATURES ${CMAKE_CUDA14_COMPILE_FEATURES} PARENT_SCOPE)
+ set(CMAKE_CUDA17_COMPILE_FEATURES ${CMAKE_CUDA17_COMPILE_FEATURES} PARENT_SCOPE)
+ set(CMAKE_CUDA20_COMPILE_FEATURES ${CMAKE_CUDA20_COMPILE_FEATURES} PARENT_SCOPE)
+
+ message(CHECK_PASS "done")
+
endif()
endfunction()
diff --git a/Modules/CMakeDetermineCompiler.cmake b/Modules/CMakeDetermineCompiler.cmake
index c37adae..7cd7c47 100644
--- a/Modules/CMakeDetermineCompiler.cmake
+++ b/Modules/CMakeDetermineCompiler.cmake
@@ -53,6 +53,20 @@ macro(_cmake_find_compiler lang)
NO_DEFAULT_PATH
DOC "${lang} compiler")
endif()
+ if(CMAKE_HOST_WIN32 AND CMAKE_GENERATOR MATCHES "Ninja")
+ # On Windows command-line builds, the Makefile generators each imply
+ # a preferred compiler tool. The Ninja generator does not imply a
+ # compiler tool, so use the compiler that occurs first in PATH.
+ find_program(CMAKE_${lang}_COMPILER
+ NAMES ${CMAKE_${lang}_COMPILER_LIST}
+ NAMES_PER_DIR
+ DOC "${lang} compiler"
+ NO_PACKAGE_ROOT_PATH
+ NO_CMAKE_PATH
+ NO_CMAKE_ENVIRONMENT_PATH
+ NO_CMAKE_SYSTEM_PATH
+ )
+ endif()
find_program(CMAKE_${lang}_COMPILER NAMES ${CMAKE_${lang}_COMPILER_LIST} DOC "${lang} compiler")
if(CMAKE_${lang}_COMPILER_INIT AND NOT CMAKE_${lang}_COMPILER)
set_property(CACHE CMAKE_${lang}_COMPILER PROPERTY VALUE "${CMAKE_${lang}_COMPILER_INIT}")
@@ -118,3 +132,19 @@ macro(_cmake_find_compiler_path lang)
endif()
endif()
endmacro()
+
+function(_cmake_find_compiler_sysroot lang)
+ if(CMAKE_${lang}_COMPILER_ID STREQUAL "GNU")
+ execute_process(COMMAND "${CMAKE_${lang}_COMPILER}" -print-sysroot
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ OUTPUT_VARIABLE _cmake_sysroot_run_out
+ ERROR_VARIABLE _cmake_sysroot_run_err)
+
+ if(_cmake_sysroot_run_out AND NOT _cmake_sysroot_run_err AND IS_DIRECTORY "${_cmake_sysroot_run_out}/usr")
+ file(TO_CMAKE_PATH "${_cmake_sysroot_run_out}/usr" _cmake_sysroot_run_out_usr)
+ set(CMAKE_${lang}_COMPILER_SYSROOT "${_cmake_sysroot_run_out_usr}" PARENT_SCOPE)
+ else()
+ set(CMAKE_${lang}_COMPILER_SYSROOT "" PARENT_SCOPE)
+ endif()
+ endif()
+endfunction()
diff --git a/Modules/CMakeDetermineCompilerABI.cmake b/Modules/CMakeDetermineCompilerABI.cmake
index 06f3ba2..e1b3c52 100644
--- a/Modules/CMakeDetermineCompilerABI.cmake
+++ b/Modules/CMakeDetermineCompilerABI.cmake
@@ -12,7 +12,7 @@ include(CMakeTestCompilerCommon)
function(CMAKE_DETERMINE_COMPILER_ABI lang src)
if(NOT DEFINED CMAKE_${lang}_ABI_COMPILED)
- message(STATUS "Detecting ${lang} compiler ABI info")
+ message(CHECK_START "Detecting ${lang} compiler ABI info")
# Compile the ABI identification source.
set(BIN "${CMAKE_PLATFORM_INFO_DIR}/CMakeDetermineCompilerABI_${lang}.bin")
@@ -32,6 +32,9 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src)
endif()
__TestCompiler_setTryCompileTargetType()
+ # Avoid failing ABI detection on warnings.
+ string(REGEX REPLACE "(^| )-Werror(=[^ ]*)?( |$)" " " CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS}")
+
# Save the current LC_ALL, LC_MESSAGES, and LANG environment variables
# and set them to "C" that way GCC's "search starts here" text is in
# English and we can grok it.
@@ -66,7 +69,7 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src)
# Load the resulting information strings.
if(CMAKE_${lang}_ABI_COMPILED AND NOT _copy_error)
- message(STATUS "Detecting ${lang} compiler ABI info - done")
+ message(CHECK_PASS "done")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Detecting ${lang} compiler ABI info compiled with the following output:\n${OUTPUT}\n\n")
file(STRINGS "${BIN}" ABI_STRINGS LIMIT_COUNT 2 REGEX "INFO:[A-Za-z0-9_]+\\[[^]]*\\]")
@@ -124,8 +127,7 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src)
# a try-compile
if("${lang}" MATCHES "Fortran"
AND "${CMAKE_GENERATOR}" MATCHES "Visual Studio")
- set(_desc "Determine Intel Fortran Compiler Implicit Link Path")
- message(STATUS "${_desc}")
+ message(CHECK_START "Determine Intel Fortran Compiler Implicit Link Path")
# Build a sample project which reports symbols.
try_compile(IFORT_LIB_PATH_COMPILED
${CMAKE_BINARY_DIR}/CMakeFiles/IntelVSImplicitPath
@@ -138,8 +140,7 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src)
"${CMAKE_BINARY_DIR}/CMakeFiles/IntelVSImplicitPath/output.txt"
"${_output}")
include(${CMAKE_BINARY_DIR}/CMakeFiles/IntelVSImplicitPath/output.cmake OPTIONAL)
- set(_desc "Determine Intel Fortran Compiler Implicit Link Path -- done")
- message(STATUS "${_desc}")
+ message(CHECK_PASS "done")
endif()
# Implicit link libraries cannot be used explicitly for multiple
@@ -163,10 +164,22 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src)
break()
endif()
endforeach()
+ elseif(CMAKE_CXX_COMPILER_ID STREQUAL QCC)
+ foreach(dir ${implicit_dirs})
+ if (dir MATCHES "/lib$")
+ get_filename_component(assumedArchDir "${dir}" DIRECTORY)
+ get_filename_component(archParentDir "${assumedArchDir}" DIRECTORY)
+ if (archParentDir STREQUAL CMAKE_SYSROOT)
+ get_filename_component(archDirName "${assumedArchDir}" NAME)
+ set(CMAKE_${lang}_LIBRARY_ARCHITECTURE "${archDirName}" PARENT_SCOPE)
+ break()
+ endif()
+ endif()
+ endforeach()
endif()
else()
- message(STATUS "Detecting ${lang} compiler ABI info - failed")
+ message(CHECK_FAIL "failed")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Detecting ${lang} compiler ABI info failed to compile with the following output:\n${OUTPUT}\n${_copy_error}\n\n")
endif()
diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake
index 7b571c3..9ebaa6c 100644
--- a/Modules/CMakeDetermineCompilerId.cmake
+++ b/Modules/CMakeDetermineCompilerId.cmake
@@ -128,7 +128,7 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src)
set(CMAKE_EXECUTABLE_FORMAT "Unknown" CACHE INTERNAL "Executable file format")
endif()
- if(CMAKE_GENERATOR STREQUAL "Ninja" AND MSVC_${lang}_ARCHITECTURE_ID)
+ if(CMAKE_GENERATOR MATCHES "^Ninja" AND MSVC_${lang}_ARCHITECTURE_ID)
foreach(userflags "${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}" "")
CMAKE_DETERMINE_MSVC_SHOWINCLUDES_PREFIX(${lang} "${userflags}")
endforeach()
@@ -182,6 +182,10 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src)
message(STATUS "The ${lang} compiler identification is unknown")
endif()
+ if(lang STREQUAL "Fortran" AND CMAKE_${lang}_COMPILER_ID STREQUAL "XL")
+ set(CMAKE_${lang}_XL_CPP "${CMAKE_${lang}_COMPILER_ID_CPP}" PARENT_SCOPE)
+ endif()
+
set(CMAKE_${lang}_COMPILER_ID "${CMAKE_${lang}_COMPILER_ID}" PARENT_SCOPE)
set(CMAKE_${lang}_PLATFORM_ID "${CMAKE_${lang}_PLATFORM_ID}" PARENT_SCOPE)
set(CMAKE_${lang}_COMPILER_ARCHITECTURE_ID "${CMAKE_${lang}_COMPILER_ARCHITECTURE_ID}" PARENT_SCOPE)
@@ -244,6 +248,8 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS}
set(id_PostBuildEvent_Command "")
if(CMAKE_VS_PLATFORM_TOOLSET MATCHES "^[Ll][Ll][Vv][Mm](_v[0-9]+(_xp)?)?$")
set(id_cl_var "ClangClExecutable")
+ elseif(CMAKE_VS_PLATFORM_TOOLSET MATCHES "^[Cc][Ll][Aa][Nn][Gg][Cc][Ll]$")
+ set(id_cl "$(CLToolExe)")
elseif(CMAKE_VS_PLATFORM_TOOLSET MATCHES "v[0-9]+_clang_.*")
set(id_cl clang.exe)
else()
@@ -318,6 +324,15 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS}
if(CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION)
set(id_WindowsTargetPlatformVersion "<WindowsTargetPlatformVersion>${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}</WindowsTargetPlatformVersion>")
endif()
+ if(CMAKE_VS_PLATFORM_TOOLSET_VCTARGETS_CUSTOM_DIR)
+ set(id_ToolsetVCTargetsDir "<VCTargetsPath>${CMAKE_VS_PLATFORM_TOOLSET_VCTARGETS_CUSTOM_DIR}</VCTargetsPath>")
+ endif()
+ set(id_CustomGlobals "")
+ foreach(pair IN LISTS CMAKE_VS_GLOBALS)
+ if("${pair}" MATCHES "([^=]+)=(.*)$")
+ string(APPEND id_CustomGlobals "<${CMAKE_MATCH_1}>${CMAKE_MATCH_2}</${CMAKE_MATCH_1}>\n ")
+ endif()
+ endforeach()
if(id_platform STREQUAL ARM64)
set(id_WindowsSDKDesktopARMSupport "<WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>")
elseif(id_platform STREQUAL ARM)
@@ -353,6 +368,7 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS}
endif()
set(cuda_tools "CUDA ${CMAKE_VS_PLATFORM_TOOLSET_CUDA}")
set(id_compile "CudaCompile")
+ set(id_ItemDefinitionGroup_entry "<CudaCompile><AdditionalOptions>%(AdditionalOptions)-v</AdditionalOptions></CudaCompile>")
set(id_PostBuildEvent_Command [[echo CMAKE_CUDA_COMPILER=$(CudaToolkitBinDir)\nvcc.exe]])
if(CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR)
set(id_CudaToolkitCustomDir "<CudaToolkitCustomDir>${CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR}nvcc</CudaToolkitCustomDir>")
@@ -363,7 +379,7 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS}
string(CONCAT id_Import_targets [[<Import Project="$(VCTargetsPath)\BuildCustomizations\]] "${cuda_tools}" [[.targets" />]])
endif()
if(CMAKE_VS_PLATFORM_NAME STREQUAL x64)
- set(id_ItemDefinitionGroup_entry "<CudaCompile><TargetMachinePlatform>64</TargetMachinePlatform></CudaCompile>")
+ set(id_ItemDefinitionGroup_entry "<CudaCompile><TargetMachinePlatform>64</TargetMachinePlatform><AdditionalOptions>%(AdditionalOptions)-v</AdditionalOptions></CudaCompile>")
endif()
set(id_Link_AdditionalDependencies "<AdditionalDependencies>cudart.lib</AdditionalDependencies>")
endif()
@@ -534,6 +550,12 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS}
ERROR_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
RESULT_VARIABLE CMAKE_${lang}_COMPILER_ID_RESULT
)
+ if("${CMAKE_${lang}_COMPILER_ID_OUTPUT}" MATCHES "exec: [^\n]*\\((/[^,\n]*/cpp),CMakeFortranCompilerId.F")
+ set(_cpp "${CMAKE_MATCH_1}")
+ if(EXISTS "${_cpp}")
+ set(CMAKE_${lang}_COMPILER_ID_CPP "${_cpp}" PARENT_SCOPE)
+ endif()
+ endif()
endif()
# Check the result of compilation.
@@ -848,6 +870,14 @@ function(CMAKE_DETERMINE_COMPILER_ID_VENDOR lang userflags)
file(MAKE_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR})
endif()
+ # Save the current LC_ALL, LC_MESSAGES, and LANG environment variables
+ # and set them to "C" so we get the expected output to match.
+ set(_orig_lc_all $ENV{LC_ALL})
+ set(_orig_lc_messages $ENV{LC_MESSAGES})
+ set(_orig_lang $ENV{LANG})
+ set(ENV{LC_ALL} C)
+ set(ENV{LC_MESSAGES} C)
+ set(ENV{LANG} C)
foreach(vendor ${CMAKE_${lang}_COMPILER_ID_VENDORS})
set(flags ${CMAKE_${lang}_COMPILER_ID_VENDOR_FLAGS_${vendor}})
@@ -869,6 +899,7 @@ function(CMAKE_DETERMINE_COMPILER_ID_VENDOR lang userflags)
"matched \"${regex}\":\n${output}")
set(CMAKE_${lang}_COMPILER_ID "${vendor}" PARENT_SCOPE)
set(CMAKE_${lang}_COMPILER_ID_OUTPUT "${output}" PARENT_SCOPE)
+ set(CMAKE_${lang}_COMPILER_ID_VENDOR_MATCH "${CMAKE_MATCH_1}" PARENT_SCOPE)
break()
else()
if("${result}" MATCHES "timeout")
@@ -882,6 +913,11 @@ function(CMAKE_DETERMINE_COMPILER_ID_VENDOR lang userflags)
endif()
endif()
endforeach()
+
+ # Restore original LC_ALL, LC_MESSAGES, and LANG
+ set(ENV{LC_ALL} ${_orig_lc_all})
+ set(ENV{LC_MESSAGES} ${_orig_lc_messages})
+ set(ENV{LANG} ${_orig_lang})
endfunction()
function(CMAKE_DETERMINE_MSVC_SHOWINCLUDES_PREFIX lang userflags)
diff --git a/Modules/CMakeDetermineFortranCompiler.cmake b/Modules/CMakeDetermineFortranCompiler.cmake
index 5ddd64f..5f5a70a 100644
--- a/Modules/CMakeDetermineFortranCompiler.cmake
+++ b/Modules/CMakeDetermineFortranCompiler.cmake
@@ -186,6 +186,8 @@ if(NOT CMAKE_Fortran_COMPILER_ID_RUN)
include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
CMAKE_DETERMINE_COMPILER_ID(Fortran FFLAGS CMakeFortranCompilerId.F)
+ _cmake_find_compiler_sysroot(Fortran)
+
# Fall back to old is-GNU test.
if(NOT CMAKE_Fortran_COMPILER_ID)
execute_process(COMMAND ${CMAKE_Fortran_COMPILER} ${CMAKE_Fortran_COMPILER_ID_FLAGS_LIST} -E "${CMAKE_ROOT}/Modules/CMakeTestGNU.c"
@@ -249,7 +251,7 @@ endif ()
# NAME_WE cannot be used since then this test will fail for names like
# "arm-unknown-nto-qnx6.3.0-gcc.exe", where BASENAME would be
# "arm-unknown-nto-qnx6" instead of the correct "arm-unknown-nto-qnx6.3.0-"
-if (CMAKE_CROSSCOMPILING AND NOT _CMAKE_TOOLCHAIN_PREFIX)
+if (NOT _CMAKE_TOOLCHAIN_PREFIX)
if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU")
get_filename_component(COMPILER_BASENAME "${CMAKE_Fortran_COMPILER}" NAME)
@@ -271,6 +273,19 @@ include(CMakeFindBinUtils)
include(Compiler/${CMAKE_Fortran_COMPILER_ID}-FindBinUtils OPTIONAL)
unset(_CMAKE_PROCESSING_LANGUAGE)
+if(CMAKE_Fortran_XL_CPP)
+ set(_SET_CMAKE_Fortran_XL_CPP
+ "set(CMAKE_Fortran_XL_CPP \"${CMAKE_Fortran_XL_CPP}\")")
+endif()
+
+if(CMAKE_Fortran_COMPILER_SYSROOT)
+ string(CONCAT _SET_CMAKE_Fortran_COMPILER_SYSROOT
+ "set(CMAKE_Fortran_COMPILER_SYSROOT \"${CMAKE_Fortran_COMPILER_SYSROOT}\")\n"
+ "set(CMAKE_COMPILER_SYSROOT \"${CMAKE_Fortran_COMPILER_SYSROOT}\")")
+else()
+ set(_SET_CMAKE_Fortran_COMPILER_SYSROOT "")
+endif()
+
if(CMAKE_Fortran_COMPILER_ARCHITECTURE_ID)
set(_SET_CMAKE_Fortran_COMPILER_ARCHITECTURE_ID
"set(CMAKE_Fortran_COMPILER_ARCHITECTURE_ID ${CMAKE_Fortran_COMPILER_ARCHITECTURE_ID})")
diff --git a/Modules/CMakeDetermineOBJCXXCompiler.cmake b/Modules/CMakeDetermineOBJCXXCompiler.cmake
index db874d1..99ad6c3 100644
--- a/Modules/CMakeDetermineOBJCXXCompiler.cmake
+++ b/Modules/CMakeDetermineOBJCXXCompiler.cmake
@@ -148,7 +148,7 @@ endif ()
# "arm-unknown-nto-qnx6" instead of the correct "arm-unknown-nto-qnx6.3.0-"
-if (CMAKE_CROSSCOMPILING AND NOT _CMAKE_TOOLCHAIN_PREFIX)
+if (NOT _CMAKE_TOOLCHAIN_PREFIX)
if("${CMAKE_OBJCXX_COMPILER_ID}" MATCHES "GNU|Clang|QCC")
get_filename_component(COMPILER_BASENAME "${CMAKE_OBJCXX_COMPILER}" NAME)
diff --git a/Modules/CMakeDetermineSwiftCompiler.cmake b/Modules/CMakeDetermineSwiftCompiler.cmake
index 9aafe48..688133f 100644
--- a/Modules/CMakeDetermineSwiftCompiler.cmake
+++ b/Modules/CMakeDetermineSwiftCompiler.cmake
@@ -16,7 +16,7 @@ if("${CMAKE_GENERATOR}" STREQUAL "Xcode")
endif()
set(CMAKE_Swift_COMPILER_XCODE_TYPE sourcecode.swift)
_cmake_find_compiler_path(Swift)
-elseif("${CMAKE_GENERATOR}" STREQUAL "Ninja")
+elseif("${CMAKE_GENERATOR}" MATCHES "^Ninja")
if(CMAKE_Swift_COMPILER)
_cmake_find_compiler_path(Swift)
else()
diff --git a/Modules/CMakeDetermineSystem.cmake b/Modules/CMakeDetermineSystem.cmake
index dc208c6..f3ec4da 100644
--- a/Modules/CMakeDetermineSystem.cmake
+++ b/Modules/CMakeDetermineSystem.cmake
@@ -43,7 +43,7 @@ if(CMAKE_HOST_UNIX)
else()
exec_program(${CMAKE_UNAME} ARGS -r OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_VERSION)
endif()
- if(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|CYGWIN.*|Darwin|^GNU$")
+ if(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|CYGWIN.*|Darwin|^GNU$|Android")
exec_program(${CMAKE_UNAME} ARGS -m OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_PROCESSOR
RETURN_VALUE val)
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin" AND
diff --git a/Modules/CMakeFindBinUtils.cmake b/Modules/CMakeFindBinUtils.cmake
index c23e447..de9ef9a 100644
--- a/Modules/CMakeFindBinUtils.cmake
+++ b/Modules/CMakeFindBinUtils.cmake
@@ -75,6 +75,7 @@ if(("x${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_SIMULATE_ID}" STREQUAL "xMSVC" AND
endif()
find_program(CMAKE_LINKER NAMES ${_CMAKE_ADDITIONAL_LINKER_NAMES} link HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
+ find_program(CMAKE_AR NAMES lib HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
find_program(CMAKE_MT NAMES mt HINTS ${_CMAKE_TOOLCHAIN_LOCATION})
list(APPEND _CMAKE_TOOL_VARS LINKER MT)
diff --git a/Modules/CMakeFindFrameworks.cmake b/Modules/CMakeFindFrameworks.cmake
index 06c05fb..8906f48 100644
--- a/Modules/CMakeFindFrameworks.cmake
+++ b/Modules/CMakeFindFrameworks.cmake
@@ -17,13 +17,25 @@ if(NOT CMAKE_FIND_FRAMEWORKS_INCLUDED)
macro(CMAKE_FIND_FRAMEWORKS fwk)
set(${fwk}_FRAMEWORKS)
if(APPLE)
- foreach(dir
- ~/Library/Frameworks/${fwk}.framework
- /usr/local/Frameworks/${fwk}.framework
- /Library/Frameworks/${fwk}.framework
- /System/Library/Frameworks/${fwk}.framework
- /Network/Library/Frameworks/${fwk}.framework
- ${CMAKE_FIND_FRAMEWORK_EXTRA_LOCATIONS})
+ 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
+ /Library/Frameworks
+ /System/Library/Frameworks
+ /Network/Library/Frameworks
+ ${CMAKE_SYSTEM_FRAMEWORK_PATH})
+
+ # For backwards compatibility reasons,
+ # CMAKE_FIND_FRAMEWORK_EXTRA_LOCATIONS includes ${fwk}.framework
+ list(TRANSFORM _cmff_search_paths APPEND /${fwk}.framework)
+ list(APPEND _cmff_search_paths ${CMAKE_FIND_FRAMEWORK_EXTRA_LOCATIONS})
+
+ list(REMOVE_DUPLICATES _cmff_search_paths)
+
+ foreach(dir IN LISTS _cmff_search_paths)
if(EXISTS ${dir})
set(${fwk}_FRAMEWORKS ${${fwk}_FRAMEWORKS} ${dir})
endif()
diff --git a/Modules/CMakeFortranCompiler.cmake.in b/Modules/CMakeFortranCompiler.cmake.in
index ae7b73a..06ee528 100644
--- a/Modules/CMakeFortranCompiler.cmake.in
+++ b/Modules/CMakeFortranCompiler.cmake.in
@@ -6,7 +6,9 @@ set(CMAKE_Fortran_COMPILER_WRAPPER "@CMAKE_Fortran_COMPILER_WRAPPER@")
set(CMAKE_Fortran_PLATFORM_ID "@CMAKE_Fortran_PLATFORM_ID@")
set(CMAKE_Fortran_SIMULATE_ID "@CMAKE_Fortran_SIMULATE_ID@")
set(CMAKE_Fortran_SIMULATE_VERSION "@CMAKE_Fortran_SIMULATE_VERSION@")
+@_SET_CMAKE_Fortran_XL_CPP@
@_SET_CMAKE_Fortran_COMPILER_ARCHITECTURE_ID@
+@_SET_CMAKE_Fortran_COMPILER_SYSROOT@
@SET_MSVC_Fortran_ARCHITECTURE_ID@
set(CMAKE_AR "@CMAKE_AR@")
set(CMAKE_Fortran_COMPILER_AR "@CMAKE_Fortran_COMPILER_AR@")
diff --git a/Modules/CMakeFortranInformation.cmake b/Modules/CMakeFortranInformation.cmake
index ffa6a24..9a4ce63 100644
--- a/Modules/CMakeFortranInformation.cmake
+++ b/Modules/CMakeFortranInformation.cmake
@@ -163,6 +163,11 @@ set(CMAKE_Fortran_FLAGS_INIT "$ENV{FFLAGS} ${CMAKE_Fortran_FLAGS_INIT}")
cmake_initialize_per_config_variable(CMAKE_Fortran_FLAGS "Flags used by the Fortran compiler")
+if(NOT CMAKE_Fortran_COMPILER_LAUNCHER AND DEFINED ENV{CMAKE_Fortran_COMPILER_LAUNCHER})
+ set(CMAKE_Fortran_COMPILER_LAUNCHER "$ENV{CMAKE_Fortran_COMPILER_LAUNCHER}"
+ CACHE STRING "Compiler launcher for Fortran.")
+endif()
+
include(CMakeCommonLanguageInclude)
# now define the following rule variables
@@ -188,7 +193,7 @@ if(NOT DEFINED CMAKE_Fortran_ARCHIVE_CREATE)
set(CMAKE_Fortran_ARCHIVE_CREATE "<CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>")
endif()
if(NOT DEFINED CMAKE_Fortran_ARCHIVE_APPEND)
- set(CMAKE_Fortran_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
+ set(CMAKE_Fortran_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
endif()
if(NOT DEFINED CMAKE_Fortran_ARCHIVE_FINISH)
set(CMAKE_Fortran_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")
@@ -204,7 +209,7 @@ endif()
# link a fortran program
if(NOT CMAKE_Fortran_LINK_EXECUTABLE)
set(CMAKE_Fortran_LINK_EXECUTABLE
- "<CMAKE_Fortran_COMPILER> <CMAKE_Fortran_LINK_FLAGS> <LINK_FLAGS> <FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
+ "<CMAKE_Fortran_COMPILER> <CMAKE_Fortran_LINK_FLAGS> <LINK_FLAGS> <FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
endif()
if(CMAKE_Fortran_STANDARD_LIBRARIES_INIT)
diff --git a/Modules/CMakeGenericSystem.cmake b/Modules/CMakeGenericSystem.cmake
index 77d8cfd..000fba1 100644
--- a/Modules/CMakeGenericSystem.cmake
+++ b/Modules/CMakeGenericSystem.cmake
@@ -27,7 +27,7 @@ set(CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".a")
set(CMAKE_AUTOGEN_ORIGIN_DEPENDS ON)
set(CMAKE_AUTOMOC_COMPILER_PREDEFINES ON)
set(CMAKE_AUTOMOC_PATH_PREFIX ON)
-set(CMAKE_AUTOMOC_MACRO_NAMES "Q_OBJECT" "Q_GADGET" "Q_NAMESPACE")
+set(CMAKE_AUTOMOC_MACRO_NAMES "Q_OBJECT" "Q_GADGET" "Q_NAMESPACE" "Q_NAMESPACE_EXPORT")
# basically all general purpose OSs support shared libs
set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE)
@@ -50,17 +50,11 @@ if(CMAKE_GENERATOR MATCHES "Make")
if(DEFINED CMAKE_TARGET_MESSAGES)
set_property(GLOBAL PROPERTY TARGET_MESSAGES ${CMAKE_TARGET_MESSAGES})
endif()
- if(CMAKE_GENERATOR MATCHES "Unix Makefiles")
- set(CMAKE_EXPORT_COMPILE_COMMANDS OFF CACHE BOOL
- "Enable/Disable output of compile commands during generation."
- )
- mark_as_advanced(CMAKE_EXPORT_COMPILE_COMMANDS)
- endif()
endif()
-if(CMAKE_GENERATOR MATCHES "Ninja")
- set(CMAKE_EXPORT_COMPILE_COMMANDS OFF CACHE BOOL
- "Enable/Disable output of compile commands during generation."
+if(NOT DEFINED CMAKE_EXPORT_COMPILE_COMMANDS AND CMAKE_GENERATOR MATCHES "Ninja|Unix Makefiles")
+ set(CMAKE_EXPORT_COMPILE_COMMANDS "$ENV{CMAKE_EXPORT_COMPILE_COMMANDS}"
+ CACHE BOOL "Enable/Disable output of compile commands during generation."
)
mark_as_advanced(CMAKE_EXPORT_COMPILE_COMMANDS)
endif()
diff --git a/Modules/CMakeGraphVizOptions.cmake b/Modules/CMakeGraphVizOptions.cmake
index 1911e73..be4a3be 100644
--- a/Modules/CMakeGraphVizOptions.cmake
+++ b/Modules/CMakeGraphVizOptions.cmake
@@ -5,119 +5,145 @@
CMakeGraphVizOptions
--------------------
-The builtin graphviz support of CMake.
+The builtin Graphviz support of CMake.
-Variables specific to the graphviz support
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Generating Graphviz files
+^^^^^^^^^^^^^^^^^^^^^^^^^
-CMake
-can generate `graphviz <http://www.graphviz.org/>`_ files, showing the dependencies between the
-targets in a project and also external libraries which are linked
-against. When CMake is run with the ``--graphviz=foo.dot`` option, it will
-produce:
+CMake can generate `Graphviz <https://www.graphviz.org/>`_ files showing the
+dependencies between the targets in a project, as well as external libraries
+which are linked against.
-* a ``foo.dot`` file showing all dependencies in the project
-* a ``foo.dot.<target>`` file for each target, file showing on which other targets the respective target depends
-* a ``foo.dot.<target>.dependers`` file, showing which other targets depend on the respective target
+When running CMake with the ``--graphviz=foo.dot`` option, it produces:
-The different dependency types ``PUBLIC``, ``PRIVATE`` and ``INTERFACE``
-are represented as solid, dashed and dotted edges.
+* a ``foo.dot`` file, showing all dependencies in the project
+* a ``foo.dot.<target>`` file for each target, showing on which other targets
+ it depends
+* a ``foo.dot.<target>.dependers`` file for each target, showing which other
+ targets depend on it
-This can result in huge graphs. Using the file
-``CMakeGraphVizOptions.cmake`` the look and content of the generated
-graphs can be influenced. This file is searched first in
-:variable:`CMAKE_BINARY_DIR` and then in :variable:`CMAKE_SOURCE_DIR`. If found, it is
-read and the variables set in it are used to adjust options for the
-generated graphviz files.
+Those .dot files can be converted to images using the *dot* command from the
+Graphviz package:
-.. variable:: GRAPHVIZ_GRAPH_TYPE
+.. code-block:: shell
- The graph type.
+ dot -Tpng -o foo.png foo.dot
- * Mandatory : NO
- * Default : "digraph"
+The different dependency types ``PUBLIC``, ``INTERFACE`` and ``PRIVATE``
+are represented as solid, dashed and dotted edges.
- Valid graph types are:
+Variables specific to the Graphviz support
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- * "graph" : Nodes are joined with lines
- * "digraph" : Nodes are joined with arrows showing direction
- * "strict graph" : Like "graph" but max one line between each node
- * "strict digraph" : Like "graph" but max one line between each node in each direction
+The resulting graphs can be huge. The look and content of the generated graphs
+can be controlled using the file ``CMakeGraphVizOptions.cmake``. This file is
+first searched in :variable:`CMAKE_BINARY_DIR`, and then in
+:variable:`CMAKE_SOURCE_DIR`. If found, the variables set in it are used to
+adjust options for the generated Graphviz files.
.. variable:: GRAPHVIZ_GRAPH_NAME
The graph name.
- * Mandatory : NO
- * Default : "GG"
+ * Mandatory: NO
+ * Default: value of :variable:`CMAKE_PROJECT_NAME`
.. variable:: GRAPHVIZ_GRAPH_HEADER
- The header written at the top of the graphviz file.
+ The header written at the top of the Graphviz files.
- * Mandatory : NO
- * Default : "node [n fontsize = "12"];"
+ * Mandatory: NO
+ * Default: "node [ fontsize = "12" ];"
.. variable:: GRAPHVIZ_NODE_PREFIX
- The prefix for each node in the graphviz file.
+ The prefix for each node in the Graphviz files.
- * Mandatory : NO
- * Default : "node"
+ * Mandatory: NO
+ * Default: "node"
.. variable:: GRAPHVIZ_EXECUTABLES
- Set this to FALSE to exclude executables from the generated graphs.
+ Set to FALSE to exclude executables from the generated graphs.
- * Mandatory : NO
- * Default : TRUE
+ * Mandatory: NO
+ * Default: TRUE
.. variable:: GRAPHVIZ_STATIC_LIBS
- Set this to FALSE to exclude static libraries from the generated graphs.
+ Set to FALSE to exclude static libraries from the generated graphs.
- * Mandatory : NO
- * Default : TRUE
+ * Mandatory: NO
+ * Default: TRUE
.. variable:: GRAPHVIZ_SHARED_LIBS
- Set this to FALSE to exclude shared libraries from the generated graphs.
+ Set to FALSE to exclude shared libraries from the generated graphs.
- * Mandatory : NO
- * Default : TRUE
+ * Mandatory: NO
+ * Default: TRUE
.. variable:: GRAPHVIZ_MODULE_LIBS
- Set this to FALSE to exclude module libraries from the generated graphs.
+ Set to FALSE to exclude module libraries from the generated graphs.
+
+ * Mandatory: NO
+ * Default: TRUE
+
+.. variable:: GRAPHVIZ_INTERFACE_LIBS
+
+ Set to FALSE to exclude interface libraries from the generated graphs.
+
+ * Mandatory: NO
+ * Default: TRUE
- * Mandatory : NO
- * Default : TRUE
+.. variable:: GRAPHVIZ_OBJECT_LIBS
+
+ Set to FALSE to exclude object libraries from the generated graphs.
+
+ * Mandatory: NO
+ * Default: TRUE
+
+.. variable:: GRAPHVIZ_UNKNOWN_LIBS
+
+ Set to FALSE to exclude unknown libraries from the generated graphs.
+
+ * Mandatory: NO
+ * Default: TRUE
.. variable:: GRAPHVIZ_EXTERNAL_LIBS
- Set this to FALSE to exclude external libraries from the generated graphs.
+ Set to FALSE to exclude external libraries from the generated graphs.
+
+ * Mandatory: NO
+ * Default: TRUE
+
+.. variable:: GRAPHVIZ_CUSTOM_TARGETS
+
+ Set to TRUE to include custom targets in the generated graphs.
- * Mandatory : NO
- * Default : TRUE
+ * Mandatory: NO
+ * Default: FALSE
.. variable:: GRAPHVIZ_IGNORE_TARGETS
- A list of regular expressions for ignoring targets.
+ A list of regular expressions for names of targets to exclude from the
+ generated graphs.
- * Mandatory : NO
- * Default : empty
+ * Mandatory: NO
+ * Default: empty
.. variable:: GRAPHVIZ_GENERATE_PER_TARGET
- Set this to FALSE to exclude per target graphs ``foo.dot.<target>``.
+ Set to FALSE to not generate per-target graphs ``foo.dot.<target>``.
- * Mandatory : NO
- * Default : TRUE
+ * Mandatory: NO
+ * Default: TRUE
.. variable:: GRAPHVIZ_GENERATE_DEPENDERS
- Set this to FALSE to exclude depender graphs ``foo.dot.<target>.dependers``.
+ Set to FALSE to not generate depender graphs ``foo.dot.<target>.dependers``.
- * Mandatory : NO
- * Default : TRUE
+ * Mandatory: NO
+ * Default: TRUE
#]=======================================================================]
diff --git a/Modules/CMakeMinGWFindMake.cmake b/Modules/CMakeMinGWFindMake.cmake
index 523f00c..f026e9a 100644
--- a/Modules/CMakeMinGWFindMake.cmake
+++ b/Modules/CMakeMinGWFindMake.cmake
@@ -7,10 +7,5 @@ find_program(CMAKE_MAKE_PROGRAM mingw32-make.exe PATHS
c:/MinGW/bin /MinGW/bin
"[HKEY_CURRENT_USER\\Software\\CodeBlocks;Path]/MinGW/bin"
)
-find_program(CMAKE_SH sh.exe )
-if(CMAKE_SH)
- message(FATAL_ERROR "sh.exe was found in your PATH, here:\n${CMAKE_SH}\nFor MinGW make to work correctly sh.exe must NOT be in your path.\nRun cmake from a shell that does not have sh.exe in your PATH.\nIf you want to use a UNIX shell, then use MSYS Makefiles.\n")
- set(CMAKE_MAKE_PROGRAM NOTFOUND)
-endif()
-mark_as_advanced(CMAKE_MAKE_PROGRAM CMAKE_SH)
+mark_as_advanced(CMAKE_MAKE_PROGRAM)
diff --git a/Modules/CMakeNinjaFindMake.cmake b/Modules/CMakeNinjaFindMake.cmake
index 702af13..32f78da 100644
--- a/Modules/CMakeNinjaFindMake.cmake
+++ b/Modules/CMakeNinjaFindMake.cmake
@@ -4,5 +4,6 @@
find_program(CMAKE_MAKE_PROGRAM
NAMES ninja-build ninja samu
+ NAMES_PER_DIR
DOC "Program used to build from build.ninja files.")
mark_as_advanced(CMAKE_MAKE_PROGRAM)
diff --git a/Modules/CMakeOBJCInformation.cmake b/Modules/CMakeOBJCInformation.cmake
index cb61cb8..b3da82d 100644
--- a/Modules/CMakeOBJCInformation.cmake
+++ b/Modules/CMakeOBJCInformation.cmake
@@ -110,6 +110,11 @@ if(CMAKE_OBJC_STANDARD_LIBRARIES_INIT)
mark_as_advanced(CMAKE_OBJC_STANDARD_LIBRARIES)
endif()
+if(NOT CMAKE_OBJC_COMPILER_LAUNCHER AND DEFINED ENV{CMAKE_OBJC_COMPILER_LAUNCHER})
+ set(CMAKE_OBJC_COMPILER_LAUNCHER "$ENV{CMAKE_OBJC_COMPILER_LAUNCHER}"
+ CACHE STRING "Compiler launcher for OBJC.")
+endif()
+
include(CMakeCommonLanguageInclude)
# now define the following rule variables
@@ -156,7 +161,7 @@ if(NOT DEFINED CMAKE_OBJC_ARCHIVE_CREATE)
set(CMAKE_OBJC_ARCHIVE_CREATE "<CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>")
endif()
if(NOT DEFINED CMAKE_OBJC_ARCHIVE_APPEND)
- set(CMAKE_OBJC_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
+ set(CMAKE_OBJC_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
endif()
if(NOT DEFINED CMAKE_OBJC_ARCHIVE_FINISH)
set(CMAKE_OBJC_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")
@@ -165,12 +170,12 @@ endif()
# compile an Objective-C file into an object file
if(NOT CMAKE_OBJC_COMPILE_OBJECT)
set(CMAKE_OBJC_COMPILE_OBJECT
- "<CMAKE_OBJC_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -x objective-c -o <OBJECT> -c <SOURCE>")
+ "<CMAKE_OBJC_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -x objective-c -o <OBJECT> -c <SOURCE>")
endif()
if(NOT CMAKE_OBJC_LINK_EXECUTABLE)
set(CMAKE_OBJC_LINK_EXECUTABLE
- "<CMAKE_OBJC_COMPILER> <FLAGS> <CMAKE_OBJC_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
+ "<CMAKE_OBJC_COMPILER> <FLAGS> <CMAKE_OBJC_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
endif()
if(NOT CMAKE_EXECUTABLE_RUNTIME_OBJC_FLAG)
diff --git a/Modules/CMakeOBJCXXInformation.cmake b/Modules/CMakeOBJCXXInformation.cmake
index 71ac26a..71beb7f 100644
--- a/Modules/CMakeOBJCXXInformation.cmake
+++ b/Modules/CMakeOBJCXXInformation.cmake
@@ -203,6 +203,11 @@ if(CMAKE_OBJCXX_STANDARD_LIBRARIES_INIT)
mark_as_advanced(CMAKE_OBJCXX_STANDARD_LIBRARIES)
endif()
+if(NOT CMAKE_OBJCXX_COMPILER_LAUNCHER AND DEFINED ENV{CMAKE_OBJCXX_COMPILER_LAUNCHER})
+ set(CMAKE_OBJCXX_COMPILER_LAUNCHER "$ENV{CMAKE_OBJCXX_COMPILER_LAUNCHER}"
+ CACHE STRING "Compiler launcher for OBJCXX.")
+endif()
+
include(CMakeCommonLanguageInclude)
# now define the following rules:
@@ -249,7 +254,7 @@ if(NOT DEFINED CMAKE_OBJCXX_ARCHIVE_CREATE)
set(CMAKE_OBJCXX_ARCHIVE_CREATE "<CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>")
endif()
if(NOT DEFINED CMAKE_OBJCXX_ARCHIVE_APPEND)
- set(CMAKE_OBJCXX_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
+ set(CMAKE_OBJCXX_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
endif()
if(NOT DEFINED CMAKE_OBJCXX_ARCHIVE_FINISH)
set(CMAKE_OBJCXX_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")
@@ -258,12 +263,12 @@ endif()
# compile an Objective-C++ file into an object file
if(NOT CMAKE_OBJCXX_COMPILE_OBJECT)
set(CMAKE_OBJCXX_COMPILE_OBJECT
- "<CMAKE_OBJCXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -x objective-c++ -o <OBJECT> -c <SOURCE>")
+ "<CMAKE_OBJCXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -x objective-c++ -o <OBJECT> -c <SOURCE>")
endif()
if(NOT CMAKE_OBJCXX_LINK_EXECUTABLE)
set(CMAKE_OBJCXX_LINK_EXECUTABLE
- "<CMAKE_OBJCXX_COMPILER> <FLAGS> <CMAKE_OBJCXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
+ "<CMAKE_OBJCXX_COMPILER> <FLAGS> <CMAKE_OBJCXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
endif()
mark_as_advanced(
diff --git a/Modules/CMakePrintSystemInformation.cmake b/Modules/CMakePrintSystemInformation.cmake
index f873a4d..d44e933 100644
--- a/Modules/CMakePrintSystemInformation.cmake
+++ b/Modules/CMakePrintSystemInformation.cmake
@@ -5,13 +5,13 @@
CMakePrintSystemInformation
---------------------------
-print system information
+Print system information.
-This file can be used for diagnostic purposes just include it in a
+This module serves diagnostic purposes. Just include it in a
project to see various internal CMake variables.
#]=======================================================================]
-message("CMAKE_SYSTEM is ${CMAKE_SYSTEM} ${CMAKE_SYSTEM_NAME} ${CMAKE_SYSTEM_VERSION}")
+message("CMAKE_SYSTEM is ${CMAKE_SYSTEM} ${CMAKE_SYSTEM_NAME} ${CMAKE_SYSTEM_VERSION} ${CMAKE_SYSTEM_PROCESSOR}")
message("CMAKE_SYSTEM file is ${CMAKE_SYSTEM_INFO_FILE}")
message("CMAKE_C_COMPILER is ${CMAKE_C_COMPILER}")
message("CMAKE_CXX_COMPILER is ${CMAKE_CXX_COMPILER}")
diff --git a/Modules/CMakeRCInformation.cmake b/Modules/CMakeRCInformation.cmake
index 7c3a5ab..b634796 100644
--- a/Modules/CMakeRCInformation.cmake
+++ b/Modules/CMakeRCInformation.cmake
@@ -39,7 +39,7 @@ set(CMAKE_RC_FLAG_REGEX "^[-/](D|I)")
# now define the following rule variables
# CMAKE_RC_COMPILE_OBJECT
-set(CMAKE_INCLUDE_FLAG_RC "-I")
+set(CMAKE_INCLUDE_FLAG_RC "-I ")
# compile a Resource file into an object file
if(NOT CMAKE_RC_COMPILE_OBJECT)
set(CMAKE_RC_COMPILE_OBJECT
diff --git a/Modules/CMakeSwiftCompiler.cmake.in b/Modules/CMakeSwiftCompiler.cmake.in
index 7c8d1c1..47ada38 100644
--- a/Modules/CMakeSwiftCompiler.cmake.in
+++ b/Modules/CMakeSwiftCompiler.cmake.in
@@ -12,3 +12,5 @@ set(CMAKE_Swift_COMPILER_ENV_VAR "SWIFTC")
set(CMAKE_Swift_COMPILER_ID_RUN 1)
set(CMAKE_Swift_SOURCE_FILE_EXTENSIONS swift)
+
+set(CMAKE_Swift_IMPLICIT_INCLUDE_DIRECTORIES "@CMAKE_Swift_IMPLICIT_INCLUDE_DIRECTORIES@")
diff --git a/Modules/CMakeSwiftInformation.cmake b/Modules/CMakeSwiftInformation.cmake
index 2c54da0..8f0909c 100644
--- a/Modules/CMakeSwiftInformation.cmake
+++ b/Modules/CMakeSwiftInformation.cmake
@@ -17,6 +17,8 @@ if(CMAKE_Swift_COMPILER_ID)
include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_Swift_COMPILER_ID}-Swift OPTIONAL)
endif()
+set(CMAKE_EXE_EXPORTS_Swift_FLAG "-emit-module -emit-module-path <SWIFT_MODULE> ${CMAKE_Swift_IMPLIB_LINKER_FLAGS}")
+
set(CMAKE_INCLUDE_FLAG_Swift "-I ")
if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
set(CMAKE_SHARED_LIBRARY_SONAME_Swift_FLAG "-Xlinker -install_name -Xlinker ")
@@ -25,8 +27,15 @@ elseif(NOT CMAKE_SYSTEM_NAME STREQUAL Windows)
endif()
if(NOT CMAKE_SYSTEM_NAME STREQUAL Windows)
+ set(CMAKE_EXECUTABLE_RUNTIME_Swift_FLAG "-Xlinker -rpath -Xlinker ")
set(CMAKE_SHARED_LIBRARY_RUNTIME_Swift_FLAG "-Xlinker -rpath -Xlinker ")
- set(CMAKE_SHARED_LIBRARY_RUNTIME_Swift_FLAG_SEP ":")
+ if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+ set(CMAKE_EXECUTABLE_RUNTIME_Swift_FLAG_SEP "")
+ set(CMAKE_SHARED_LIBRARY_RUNTIME_Swift_FLAG_SEP "")
+ else()
+ set(CMAKE_EXECUTABLE_RUNTIME_Swift_FLAG_SEP ":")
+ set(CMAKE_SHARED_LIBRARY_RUNTIME_Swift_FLAG_SEP ":")
+ endif()
endif()
set(CMAKE_Swift_COMPILE_OPTIONS_TARGET "-target ")
@@ -72,10 +81,6 @@ if(NOT CMAKE_Swift_NUM_THREADS MATCHES "^[0-9]+$")
cmake_host_system_information(RESULT CMAKE_Swift_NUM_THREADS QUERY NUMBER_OF_LOGICAL_CORES)
endif()
-if(CMAKE_SYSTEM_NAME STREQUAL Windows)
- set(CMAKE_Swift_IMPLIB_LINKER_FLAGS "-Xlinker -implib:<TARGET_IMPLIB>")
-endif()
-
if(NOT CMAKE_Swift_CREATE_SHARED_LIBRARY)
set(CMAKE_Swift_CREATE_SHARED_LIBRARY "<CMAKE_Swift_COMPILER> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -j ${CMAKE_Swift_NUM_THREADS} -emit-library -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <SONAME_FLAG> <TARGET_INSTALLNAME_DIR><TARGET_SONAME> ${CMAKE_Swift_IMPLIB_LINKER_FLAGS} <LINK_LIBRARIES>")
endif()
@@ -85,7 +90,7 @@ if(NOT CMAKE_Swift_CREATE_SHARED_MODULE)
endif()
if(NOT CMAKE_Swift_LINK_EXECUTABLE)
- set(CMAKE_Swift_LINK_EXECUTABLE "<CMAKE_Swift_COMPILER> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -j ${CMAKE_Swift_NUM_THREADS} -emit-executable -o <TARGET> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> ${CMAKE_Swift_IMPLIB_LINKER_FLAGS} <LINK_LIBRARIES>")
+ set(CMAKE_Swift_LINK_EXECUTABLE "<CMAKE_Swift_COMPILER> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -j ${CMAKE_Swift_NUM_THREADS} -emit-executable -o <TARGET> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>")
endif()
if(NOT CMAKE_Swift_CREATE_STATIC_LIBRARY)
diff --git a/Modules/CMakeTestCCompiler.cmake b/Modules/CMakeTestCCompiler.cmake
index 7bf6fde..eadea89 100644
--- a/Modules/CMakeTestCCompiler.cmake
+++ b/Modules/CMakeTestCCompiler.cmake
@@ -27,7 +27,7 @@ unset(CMAKE_C_COMPILER_WORKS CACHE)
# is set and cmake stops processing commands and will not generate
# any makefiles or projects.
if(NOT CMAKE_C_COMPILER_WORKS)
- PrintTestCompilerStatus("C" "")
+ PrintTestCompilerStatus("C")
__TestCompiler_setTryCompileTargetType()
file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testCCompiler.c
"#ifdef __cplusplus\n"
@@ -52,7 +52,7 @@ if(NOT CMAKE_C_COMPILER_WORKS)
endif()
if(NOT CMAKE_C_COMPILER_WORKS)
- PrintTestCompilerStatus("C" " -- broken")
+ PrintTestCompilerResult(CHECK_FAIL "broken")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the C compiler works failed with "
"the following output:\n${__CMAKE_C_COMPILER_OUTPUT}\n\n")
@@ -63,7 +63,7 @@ if(NOT CMAKE_C_COMPILER_WORKS)
"CMake will not be able to correctly generate this project.")
else()
if(C_TEST_WAS_RUN)
- PrintTestCompilerStatus("C" " -- works")
+ PrintTestCompilerResult(CHECK_PASS "works")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the C compiler works passed with "
"the following output:\n${__CMAKE_C_COMPILER_OUTPUT}\n\n")
diff --git a/Modules/CMakeTestCSharpCompiler.cmake b/Modules/CMakeTestCSharpCompiler.cmake
index 6715c30..1119a45 100644
--- a/Modules/CMakeTestCSharpCompiler.cmake
+++ b/Modules/CMakeTestCSharpCompiler.cmake
@@ -20,7 +20,9 @@ set(test_compile_file "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/test
# is set and cmake stops processing commands and will not generate
# any makefiles or projects.
if(NOT CMAKE_CSharp_COMPILER_WORKS)
- PrintTestCompilerStatus("C#" "${CMAKE_CSharp_COMPILER}")
+ # Don't call PrintTestCompilerStatus() because the "C#" we want to pass
+ # as the LANG doesn't match with the variable name "CMAKE_CSharp_COMPILER"
+ message(CHECK_START "Check for working C# compiler: ${CMAKE_CSharp_COMPILER}")
file(WRITE "${test_compile_file}"
"namespace Test {"
" public class CSharp {"
@@ -38,7 +40,7 @@ if(NOT CMAKE_CSharp_COMPILER_WORKS)
endif()
if(NOT CMAKE_CSharp_COMPILER_WORKS)
- PrintTestCompilerStatus("C#" "${CMAKE_CSharp_COMPILER} -- broken")
+ PrintTestCompilerResult(CHECK_FAIL "broken")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the C# compiler works failed with "
"the following output:\n${__CMAKE_CSharp_COMPILER_OUTPUT}\n\n")
@@ -49,7 +51,7 @@ if(NOT CMAKE_CSharp_COMPILER_WORKS)
"CMake will not be able to correctly generate this project.")
else()
if(CSharp_TEST_WAS_RUN)
- PrintTestCompilerStatus("C#" "${CMAKE_CSharp_COMPILER} -- works")
+ PrintTestCompilerResult(CHECK_PASS "works")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the C# compiler works passed with "
"the following output:\n${__CMAKE_CSharp_COMPILER_OUTPUT}\n\n")
diff --git a/Modules/CMakeTestCUDACompiler.cmake b/Modules/CMakeTestCUDACompiler.cmake
index f0454da..05811a8 100644
--- a/Modules/CMakeTestCUDACompiler.cmake
+++ b/Modules/CMakeTestCUDACompiler.cmake
@@ -20,7 +20,7 @@ unset(CMAKE_CUDA_COMPILER_WORKS CACHE)
# is set and cmake stops processing commands and will not generate
# any makefiles or projects.
if(NOT CMAKE_CUDA_COMPILER_WORKS)
- PrintTestCompilerStatus("CUDA" "")
+ PrintTestCompilerStatus("CUDA")
file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/main.cu
"#ifndef __CUDACC__\n"
"# error \"The CMAKE_CUDA_COMPILER is set to an invalid CUDA compiler\"\n"
@@ -38,7 +38,7 @@ if(NOT CMAKE_CUDA_COMPILER_WORKS)
endif()
if(NOT CMAKE_CUDA_COMPILER_WORKS)
- PrintTestCompilerStatus("CUDA" " -- broken")
+ PrintTestCompilerResult(CHECK_FAIL "broken")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the CUDA compiler works failed with "
"the following output:\n${__CMAKE_CUDA_COMPILER_OUTPUT}\n\n")
@@ -49,7 +49,7 @@ if(NOT CMAKE_CUDA_COMPILER_WORKS)
"CMake will not be able to correctly generate this project.")
else()
if(CUDA_TEST_WAS_RUN)
- PrintTestCompilerStatus("CUDA" " -- works")
+ PrintTestCompilerResult(CHECK_PASS "works")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the CUDA compiler works passed with "
"the following output:\n${__CMAKE_CUDA_COMPILER_OUTPUT}\n\n")
@@ -58,12 +58,38 @@ else()
# Try to identify the ABI and configure it into CMakeCUDACompiler.cmake
include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerABI.cmake)
CMAKE_DETERMINE_COMPILER_ABI(CUDA ${CMAKE_ROOT}/Modules/CMakeCUDACompilerABI.cu)
+ # Try to identify the compiler features
+ include(${CMAKE_ROOT}/Modules/CMakeDetermineCompileFeatures.cmake)
+ CMAKE_DETERMINE_COMPILE_FEATURES(CUDA)
if("x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC")
set(CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES "${CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES}")
set(CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES "${CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES}")
endif()
+ # Remove the following libraries from CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES and
+ # CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES
+ #
+ # - cudart
+ # - cudart_static
+ # - cudadevrt
+ #
+ # These are controlled by CMAKE_CUDA_RUNTIME_LIBRARY
+ list(REMOVE_ITEM CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES cudart cudart_static cudadevrt)
+ list(REMOVE_ITEM CMAKE_CUDA_HOST_IMPLICIT_LINK_LIBRARIES cudart cudart_static cudadevrt)
+
+ # 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
+ if(CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES)
+ list(REMOVE_ITEM CMAKE_CUDA_IMPLICIT_INCLUDE_DIRECTORIES
+ ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}
+ )
+ endif()
+
# Re-configure to save learned information.
configure_file(
${CMAKE_ROOT}/Modules/CMakeCUDACompiler.cmake.in
diff --git a/Modules/CMakeTestCXXCompiler.cmake b/Modules/CMakeTestCXXCompiler.cmake
index 7e595b7..bd42153 100644
--- a/Modules/CMakeTestCXXCompiler.cmake
+++ b/Modules/CMakeTestCXXCompiler.cmake
@@ -27,7 +27,7 @@ unset(CMAKE_CXX_COMPILER_WORKS CACHE)
# is set and cmake stops processing commands and will not generate
# any makefiles or projects.
if(NOT CMAKE_CXX_COMPILER_WORKS)
- PrintTestCompilerStatus("CXX" "")
+ PrintTestCompilerStatus("CXX")
__TestCompiler_setTryCompileTargetType()
file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testCXXCompiler.cxx
"#ifndef __cplusplus\n"
@@ -45,7 +45,7 @@ if(NOT CMAKE_CXX_COMPILER_WORKS)
endif()
if(NOT CMAKE_CXX_COMPILER_WORKS)
- PrintTestCompilerStatus("CXX" " -- broken")
+ PrintTestCompilerResult(CHECK_FAIL "broken")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the CXX compiler works failed with "
"the following output:\n${__CMAKE_CXX_COMPILER_OUTPUT}\n\n")
@@ -56,7 +56,7 @@ if(NOT CMAKE_CXX_COMPILER_WORKS)
"CMake will not be able to correctly generate this project.")
else()
if(CXX_TEST_WAS_RUN)
- PrintTestCompilerStatus("CXX" " -- works")
+ PrintTestCompilerResult(CHECK_PASS "works")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the CXX compiler works passed with "
"the following output:\n${__CMAKE_CXX_COMPILER_OUTPUT}\n\n")
diff --git a/Modules/CMakeTestCompilerCommon.cmake b/Modules/CMakeTestCompilerCommon.cmake
index 6ee5175..da7c007 100644
--- a/Modules/CMakeTestCompilerCommon.cmake
+++ b/Modules/CMakeTestCompilerCommon.cmake
@@ -2,8 +2,15 @@
# file Copyright.txt or https://cmake.org/licensing for details.
-function(PrintTestCompilerStatus LANG MSG)
- message(STATUS "Check for working ${LANG} compiler: ${CMAKE_${LANG}_COMPILER}${MSG}")
+function(PrintTestCompilerStatus LANG)
+ # ARGN shouldn't be needed now, but it is there to preserve backward
+ # compatibility in case this function is called from project code or
+ # custom toolchains (they shouldn't, but we can easily support it)
+ message(CHECK_START "Check for working ${LANG} compiler: ${CMAKE_${LANG}_COMPILER}${ARGN}")
+endfunction()
+
+function(PrintTestCompilerResult TYPE MSG)
+ message(${TYPE} "${MSG}")
endfunction()
# if required set the target type if not already explicitly set
diff --git a/Modules/CMakeTestFortranCompiler.cmake b/Modules/CMakeTestFortranCompiler.cmake
index e9860e9..7461f9c 100644
--- a/Modules/CMakeTestFortranCompiler.cmake
+++ b/Modules/CMakeTestFortranCompiler.cmake
@@ -21,7 +21,7 @@ unset(CMAKE_Fortran_COMPILER_WORKS CACHE)
# is set and cmake stops processing commands and will not generate
# any makefiles or projects.
if(NOT CMAKE_Fortran_COMPILER_WORKS)
- PrintTestCompilerStatus("Fortran" "")
+ PrintTestCompilerStatus("Fortran")
file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompiler.f "
PROGRAM TESTFortran
PRINT *, 'Hello'
@@ -37,7 +37,7 @@ if(NOT CMAKE_Fortran_COMPILER_WORKS)
endif()
if(NOT CMAKE_Fortran_COMPILER_WORKS)
- PrintTestCompilerStatus("Fortran" " -- broken")
+ PrintTestCompilerResult(CHECK_FAIL "broken")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the Fortran compiler works failed with "
"the following output:\n${OUTPUT}\n\n")
@@ -48,7 +48,7 @@ if(NOT CMAKE_Fortran_COMPILER_WORKS)
"CMake will not be able to correctly generate this project.")
else()
if(FORTRAN_TEST_WAS_RUN)
- PrintTestCompilerStatus("Fortran" " -- works")
+ PrintTestCompilerResult(CHECK_PASS "works")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the Fortran compiler works passed with "
"the following output:\n${OUTPUT}\n\n")
@@ -60,7 +60,7 @@ else()
# Test for Fortran 90 support by using an f90-specific construct.
if(NOT DEFINED CMAKE_Fortran_COMPILER_SUPPORTS_F90)
- message(STATUS "Checking whether ${CMAKE_Fortran_COMPILER} supports Fortran 90")
+ message(CHECK_START "Checking whether ${CMAKE_Fortran_COMPILER} supports Fortran 90")
file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompilerF90.f90 "
PROGRAM TESTFortran90
integer stop ; stop = 1 ; do while ( stop .eq. 0 ) ; end do
@@ -70,13 +70,13 @@ else()
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompilerF90.f90
OUTPUT_VARIABLE OUTPUT)
if(CMAKE_Fortran_COMPILER_SUPPORTS_F90)
- message(STATUS "Checking whether ${CMAKE_Fortran_COMPILER} supports Fortran 90 -- yes")
+ message(CHECK_PASS "yes")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the Fortran compiler supports Fortran 90 passed with "
"the following output:\n${OUTPUT}\n\n")
set(CMAKE_Fortran_COMPILER_SUPPORTS_F90 1)
else()
- message(STATUS "Checking whether ${CMAKE_Fortran_COMPILER} supports Fortran 90 -- no")
+ message(CHECK_FAIL "no")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the Fortran compiler supports Fortran 90 failed with "
"the following output:\n${OUTPUT}\n\n")
diff --git a/Modules/CMakeTestOBJCCompiler.cmake b/Modules/CMakeTestOBJCCompiler.cmake
index 0030683..bcc6fae 100644
--- a/Modules/CMakeTestOBJCCompiler.cmake
+++ b/Modules/CMakeTestOBJCCompiler.cmake
@@ -27,7 +27,7 @@ unset(CMAKE_OBJC_COMPILER_WORKS CACHE)
# is set and cmake stops processing commands and will not generate
# any makefiles or projects.
if(NOT CMAKE_OBJC_COMPILER_WORKS)
- PrintTestCompilerStatus("OBJC" "")
+ PrintTestCompilerStatus("OBJC")
__TestCompiler_setTryCompileTargetType()
file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testOBJCCompiler.m
"#ifdef __cplusplus\n"
@@ -49,7 +49,7 @@ if(NOT CMAKE_OBJC_COMPILER_WORKS)
endif()
if(NOT CMAKE_OBJC_COMPILER_WORKS)
- PrintTestCompilerStatus("OBJC" " -- broken")
+ PrintTestCompilerResult(CHECK_FAIL "broken")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the Objective-C compiler works failed with "
"the following output:\n${__CMAKE_OBJC_COMPILER_OUTPUT}\n\n")
@@ -60,7 +60,7 @@ if(NOT CMAKE_OBJC_COMPILER_WORKS)
"CMake will not be able to correctly generate this project.")
else()
if(OBJC_TEST_WAS_RUN)
- PrintTestCompilerStatus("OBJC" " -- works")
+ PrintTestCompilerResult(CHECK_PASS "works")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the Objective-C compiler works passed with "
"the following output:\n${__CMAKE_OBJC_COMPILER_OUTPUT}\n\n")
diff --git a/Modules/CMakeTestOBJCXXCompiler.cmake b/Modules/CMakeTestOBJCXXCompiler.cmake
index bcce2f1..83227d5 100644
--- a/Modules/CMakeTestOBJCXXCompiler.cmake
+++ b/Modules/CMakeTestOBJCXXCompiler.cmake
@@ -27,7 +27,7 @@ unset(CMAKE_OBJCXX_COMPILER_WORKS CACHE)
# is set and cmake stops processing commands and will not generate
# any makefiles or projects.
if(NOT CMAKE_OBJCXX_COMPILER_WORKS)
- PrintTestCompilerStatus("OBJCXX" "")
+ PrintTestCompilerStatus("OBJCXX")
__TestCompiler_setTryCompileTargetType()
file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testOBJCXXCompiler.mm
"#ifndef __cplusplus\n"
@@ -48,7 +48,7 @@ if(NOT CMAKE_OBJCXX_COMPILER_WORKS)
endif()
if(NOT CMAKE_OBJCXX_COMPILER_WORKS)
- PrintTestCompilerStatus("OBJCXX" " -- broken")
+ PrintTestCompilerResult(CHECK_FAIL "broken")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the Objective-C++ compiler works failed with "
"the following output:\n${__CMAKE_OBJCXX_COMPILER_OUTPUT}\n\n")
@@ -59,7 +59,7 @@ if(NOT CMAKE_OBJCXX_COMPILER_WORKS)
"CMake will not be able to correctly generate this project.")
else()
if(OBJCXX_TEST_WAS_RUN)
- PrintTestCompilerStatus("OBJCXX" " -- works")
+ PrintTestCompilerResult(CHECK_PASS "works")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the Objective-C++ compiler works passed with "
"the following output:\n${__CMAKE_OBJCXX_COMPILER_OUTPUT}\n\n")
diff --git a/Modules/CMakeTestSwiftCompiler.cmake b/Modules/CMakeTestSwiftCompiler.cmake
index 841aee6..d98dc9d 100644
--- a/Modules/CMakeTestSwiftCompiler.cmake
+++ b/Modules/CMakeTestSwiftCompiler.cmake
@@ -20,7 +20,7 @@ unset(CMAKE_Swift_COMPILER_WORKS CACHE)
# is set and cmake stops processing commands and will not generate
# any makefiles or projects.
if(NOT CMAKE_Swift_COMPILER_WORKS)
- PrintTestCompilerStatus("Swift" "")
+ PrintTestCompilerStatus("Swift")
file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/main.swift
"print(\"CMake\")\n")
try_compile(CMAKE_Swift_COMPILER_WORKS ${CMAKE_BINARY_DIR}
@@ -33,7 +33,7 @@ if(NOT CMAKE_Swift_COMPILER_WORKS)
endif()
if(NOT CMAKE_Swift_COMPILER_WORKS)
- PrintTestCompilerStatus("Swift" " -- broken")
+ PrintTestCompilerResult(CHECK_FAIL "broken")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the Swift compiler works failed with "
"the following output:\n${__CMAKE_Swift_COMPILER_OUTPUT}\n\n")
@@ -44,12 +44,17 @@ if(NOT CMAKE_Swift_COMPILER_WORKS)
"CMake will not be able to correctly generate this project.")
else()
if(Swift_TEST_WAS_RUN)
- PrintTestCompilerStatus("Swift" " -- works")
+ PrintTestCompilerResult(CHECK_PASS "works")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the Swift compiler works passed with "
"the following output:\n${__CMAKE_Swift_COMPILER_OUTPUT}\n\n")
endif()
+ # Unlike C and CXX we do not yet detect any information about the Swift ABI.
+ # However, one of the steps done for C and CXX as part of that detection is
+ # to initialize the implicit include directories. That is relevant here.
+ set(CMAKE_Swift_IMPLICIT_INCLUDE_DIRECTORIES "${_CMAKE_Swift_IMPLICIT_INCLUDE_DIRECTORIES_INIT}")
+
# Re-configure to save learned information.
configure_file(${CMAKE_ROOT}/Modules/CMakeSwiftCompiler.cmake.in
${CMAKE_PLATFORM_INFO_DIR}/CMakeSwiftCompiler.cmake @ONLY)
diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake
index c2ed3de..6234b9d 100644
--- a/Modules/CPack.cmake
+++ b/Modules/CPack.cmake
@@ -5,26 +5,31 @@
CPack
-----
-Build binary and source package installers.
+Configure generators for binary installers and source packages.
Introduction
^^^^^^^^^^^^
-The CPack module generates a file ``CPackConfig.cmake`` intended for
-use in a subsequent run of the :manual:`cpack <cpack(1)>` program
-where it steers the generation of installers or/and source packages.
+The CPack module generates the configuration files ``CPackConfig.cmake``
+and ``CPackSourceConfig.cmake``. They are intended for use in a subsequent
+run of the :manual:`cpack <cpack(1)>` program where they steer the generation
+of installers or/and source packages.
-Inclusion of the CPack module adds two new build targets, ``package``
-and ``package_source``, which build the binary and source installers
-respectively. The generated binary installers contain everything
-installed via CMake's :command:`install` command (and the deprecated
-commands :command:`install_files`, :command:`install_programs`, and
-:command:`install_targets`).
+Depending on the CMake generator, the CPack module may also add two new build
+targets, ``package`` and ``package_source``. See the `packaging targets`_
+section below for details.
-For certain kinds of binary installers (including the graphical
-installers on macOS and Windows), CPack generates installers that
-allow users to select individual application components to install.
-See :module:`CPackComponent` module for further details.
+The generated binary installers will contain all files that have been installed
+via CMake's :command:`install` command (and the deprecated commands
+:command:`install_files`, :command:`install_programs`, and
+:command:`install_targets`). Certain kinds of binary installers can be
+configured such that users can select individual application components to
+install. See the :module:`CPackComponent` module for further details.
+
+Source packages (configured through ``CPackSourceConfig.cmake`` and generated
+by the :cpack_gen:`CPack Archive Generator`) will contain all source files in
+the project directory except those specified in
+:variable:`CPACK_SOURCE_IGNORE_FILES`.
CPack Generators
^^^^^^^^^^^^^^^^
@@ -37,10 +42,6 @@ generator. In a :variable:`CPACK_PROJECT_CONFIG_FILE`,
:variable:`CPACK_GENERATOR` is a *string naming a single generator*. If you
need per-cpack-generator logic to control *other* cpack settings, then you
need a :variable:`CPACK_PROJECT_CONFIG_FILE`.
-
-The CMake source tree itself contains a :variable:`CPACK_PROJECT_CONFIG_FILE`.
-See the top level file ``CMakeCPackOptions.cmake.in`` for an example.
-
If set, the :variable:`CPACK_PROJECT_CONFIG_FILE` is included automatically
on a per-generator basis. It only need contain overrides.
@@ -63,6 +64,26 @@ This is the key: For each generator listed in :variable:`CPACK_GENERATOR` in
internally to *the one currently being used* and then include the
:variable:`CPACK_PROJECT_CONFIG_FILE`.
+For a list of available generators, see :manual:`cpack-generators(7)`.
+
+.. _`packaging targets`:
+
+Targets package and package_source
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If CMake is run with the Makefile, Ninja, or Xcode generator, then
+``include(CPack)`` generates a target ``package``. This makes it possible
+to build a binary installer from CMake, Make, or Ninja: Instead of ``cpack``,
+one may call ``cmake --build . --target package`` or ``make package`` or
+``ninja package``. The VS generator creates an uppercase target ``PACKAGE``.
+
+If CMake is run with the Makefile or Ninja generator, then ``include(CPack)``
+also generates a target ``package_source``. To build a source package,
+instead of ``cpack -G TGZ --config CPackConfig.cmake`` one may call
+``cmake --build . --target package_source``, ``make package_source``,
+or ``ninja package_source``.
+
+
Variables common to all CPack Generators
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -563,11 +584,19 @@ if(NOT CPACK_GENERATOR)
if(APPLE)
option(CPACK_BINARY_BUNDLE "Enable to build OSX bundles" OFF)
option(CPACK_BINARY_DRAGNDROP "Enable to build OSX Drag And Drop package" OFF)
- option(CPACK_BINARY_OSXX11 "Enable to build OSX X11 packages" OFF)
- option(CPACK_BINARY_PACKAGEMAKER "Enable to build PackageMaker packages" OFF)
+ option(CPACK_BINARY_OSXX11 "Enable to build OSX X11 packages (deprecated)" OFF)
+ option(CPACK_BINARY_PACKAGEMAKER "Enable to build PackageMaker packages (deprecated)" OFF)
option(CPACK_BINARY_PRODUCTBUILD "Enable to build productbuild packages" OFF)
+ mark_as_advanced(
+ CPACK_BINARY_BUNDLE
+ CPACK_BINARY_DRAGNDROP
+ CPACK_BINARY_OSXX11
+ CPACK_BINARY_PACKAGEMAKER
+ CPACK_BINARY_PRODUCTBUILD
+ )
else()
option(CPACK_BINARY_TZ "Enable to build TZ packages" ON)
+ mark_as_advanced(CPACK_BINARY_TZ)
endif()
option(CPACK_BINARY_DEB "Enable to build Debian packages" OFF)
option(CPACK_BINARY_FREEBSD "Enable to build FreeBSD packages" OFF)
@@ -577,6 +606,16 @@ if(NOT CPACK_GENERATOR)
option(CPACK_BINARY_TBZ2 "Enable to build TBZ2 packages" OFF)
option(CPACK_BINARY_TGZ "Enable to build TGZ packages" ON)
option(CPACK_BINARY_TXZ "Enable to build TXZ packages" OFF)
+ mark_as_advanced(
+ CPACK_BINARY_DEB
+ CPACK_BINARY_FREEBSD
+ CPACK_BINARY_NSIS
+ CPACK_BINARY_RPM
+ CPACK_BINARY_STGZ
+ CPACK_BINARY_TBZ2
+ CPACK_BINARY_TGZ
+ CPACK_BINARY_TXZ
+ )
endif()
else()
option(CPACK_BINARY_7Z "Enable to build 7-Zip packages" OFF)
@@ -584,8 +623,16 @@ if(NOT CPACK_GENERATOR)
option(CPACK_BINARY_NUGET "Enable to build NuGet packages" OFF)
option(CPACK_BINARY_WIX "Enable to build WiX packages" OFF)
option(CPACK_BINARY_ZIP "Enable to build ZIP packages" OFF)
+ mark_as_advanced(
+ CPACK_BINARY_7Z
+ CPACK_BINARY_NSIS
+ CPACK_BINARY_NUGET
+ CPACK_BINARY_WIX
+ CPACK_BINARY_ZIP
+ )
endif()
option(CPACK_BINARY_IFW "Enable to build IFW packages" OFF)
+ mark_as_advanced(CPACK_BINARY_IFW)
cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_7Z 7Z)
cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_BUNDLE Bundle)
@@ -615,6 +662,7 @@ if(NOT CPACK_SOURCE_GENERATOR)
if(UNIX)
if(CYGWIN)
option(CPACK_SOURCE_CYGWIN "Enable to build Cygwin source packages" ON)
+ mark_as_advanced(CPACK_SOURCE_CYGWIN)
else()
option(CPACK_SOURCE_RPM "Enable to build RPM source packages" OFF)
option(CPACK_SOURCE_TBZ2 "Enable to build TBZ2 source packages" ON)
@@ -622,10 +670,22 @@ if(NOT CPACK_SOURCE_GENERATOR)
option(CPACK_SOURCE_TXZ "Enable to build TXZ source packages" ON)
option(CPACK_SOURCE_TZ "Enable to build TZ source packages" ON)
option(CPACK_SOURCE_ZIP "Enable to build ZIP source packages" OFF)
+ mark_as_advanced(
+ CPACK_SOURCE_RPM
+ CPACK_SOURCE_TBZ2
+ CPACK_SOURCE_TGZ
+ CPACK_SOURCE_TXZ
+ CPACK_SOURCE_TZ
+ CPACK_SOURCE_ZIP
+ )
endif()
else()
option(CPACK_SOURCE_7Z "Enable to build 7-Zip source packages" ON)
option(CPACK_SOURCE_ZIP "Enable to build ZIP source packages" ON)
+ mark_as_advanced(
+ CPACK_SOURCE_7Z
+ CPACK_SOURCE_ZIP
+ )
endif()
cpack_optional_append(CPACK_SOURCE_GENERATOR CPACK_SOURCE_7Z 7Z)
@@ -638,38 +698,6 @@ if(NOT CPACK_SOURCE_GENERATOR)
cpack_optional_append(CPACK_SOURCE_GENERATOR CPACK_SOURCE_ZIP ZIP)
endif()
-# mark the above options as advanced
-mark_as_advanced(
- CPACK_BINARY_7Z
- CPACK_BINARY_BUNDLE
- CPACK_BINARY_CYGWIN
- CPACK_BINARY_DEB
- CPACK_BINARY_DRAGNDROP
- CPACK_BINARY_FREEBSD
- CPACK_BINARY_IFW
- CPACK_BINARY_NSIS
- CPACK_BINARY_NUGET
- CPACK_BINARY_OSXX11
- CPACK_BINARY_PACKAGEMAKER
- CPACK_BINARY_PRODUCTBUILD
- CPACK_BINARY_RPM
- CPACK_BINARY_STGZ
- CPACK_BINARY_TBZ2
- CPACK_BINARY_TGZ
- CPACK_BINARY_TXZ
- CPACK_BINARY_TZ
- CPACK_BINARY_WIX
- CPACK_BINARY_ZIP
- CPACK_SOURCE_7Z
- CPACK_SOURCE_CYGWIN
- CPACK_SOURCE_RPM
- CPACK_SOURCE_TBZ2
- CPACK_SOURCE_TGZ
- CPACK_SOURCE_TXZ
- CPACK_SOURCE_TZ
- CPACK_SOURCE_ZIP
- )
-
# Set some other variables
_cpack_set_default(CPACK_INSTALL_CMAKE_PROJECTS
"${CMAKE_BINARY_DIR};${CMAKE_PROJECT_NAME};ALL;/")
@@ -684,6 +712,8 @@ endif()
# value of CPACK_NSIS_PACKAGE_NAME instead
# of CPACK_PACKAGE_INSTALL_DIRECTORY
_cpack_set_default(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY}")
+# Specify the name of the Uninstall file in NSIS
+_cpack_set_default(CPACK_NSIS_UNINSTALL_NAME "Uninstall")
if(CPACK_NSIS_DISPLAY_NAME_SET)
_cpack_set_default(CPACK_NSIS_PACKAGE_NAME "${CPACK_NSIS_DISPLAY_NAME}")
diff --git a/Modules/CPackComponent.cmake b/Modules/CPackComponent.cmake
index 211d767..1f8c38c 100644
--- a/Modules/CPackComponent.cmake
+++ b/Modules/CPackComponent.cmake
@@ -5,29 +5,34 @@
CPackComponent
--------------
-Build binary and source package installers
+Configure components for binary installers and source packages.
-Variables concerning CPack Components
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+.. only:: html
-The CPackComponent module is the module which handles the component
-part of CPack. See CPack module for general information about CPack.
+ .. contents::
-For certain kinds of binary installers (including the graphical
-installers on macOS and Windows), CPack generates installers that
-allow users to select individual application components to install.
-The contents of each of the components are identified by the COMPONENT
-argument of CMake's INSTALL command. These components can be
+Introduction
+^^^^^^^^^^^^
+
+This module is automatically included by :module:`CPack`.
+
+Certain binary installers (especially the graphical installers) generated
+by CPack allow users to select individual application *components* to install.
+This module allows developers to configure the packaging of such components.
+
+Contents is assigned to components by the ``COMPONENT``
+argument of CMake's :command:`install` command. Components can be
annotated with user-friendly names and descriptions, inter-component
dependencies, etc., and grouped in various ways to customize the
-resulting installer. See the cpack_add_* commands, described below,
-for more information about component-specific installations.
+resulting installer, using the commands described below.
+
+To specify different groupings for different CPack generators use
+a CPACK_PROJECT_CONFIG_FILE.
-Component-specific installation allows users to select specific sets
-of components to install during the install process. Installation
-components are identified by the COMPONENT argument of CMake's INSTALL
-commands, and should be further described by the following CPack
-commands:
+Variables
+^^^^^^^^^
+
+The following variables influence the component-specific packaging:
.. variable:: CPACK_COMPONENTS_ALL
@@ -61,16 +66,14 @@ commands:
Specify how components are grouped for multi-package component-aware CPack
generators.
- Some generators like RPM or ARCHIVE family (TGZ, ZIP, ...) generates
- several packages files when asked for component packaging. They group
- the component differently depending on the value of this variable:
-
- * ONE_PER_GROUP (default): creates one package file per component group
- * ALL_COMPONENTS_IN_ONE : creates a single package with all (requested) components
- * IGNORE : creates one package per component, i.e. IGNORE component group
+ Some generators like RPM or ARCHIVE (TGZ, ZIP, ...) may generate
+ several packages files when there are components, depending
+ on the value of this variable:
- One can specify different grouping for different CPack generator by
- using a CPACK_PROJECT_CONFIG_FILE.
+ * ONE_PER_GROUP (default): create one package per component group
+ * IGNORE : create one package per component (ignore the groups)
+ * ALL_COMPONENTS_IN_ONE : create a single package with all requested
+ components
.. variable:: CPACK_COMPONENT_<compName>_DISPLAY_NAME
@@ -100,10 +103,15 @@ commands:
True if this component is not selected to be installed by default.
+Commands
+^^^^^^^^
+
+Add component
+"""""""""""""
+
.. command:: cpack_add_component
-Describes a CPack installation
-component named by the COMPONENT argument to a CMake INSTALL command.
+Describe an installation component.
::
@@ -118,13 +126,11 @@ component named by the COMPONENT argument to a CMake INSTALL command.
[ARCHIVE_FILE filename]
[PLIST filename])
-
-
-The cmake_add_component command describes an installation component,
-which the user can opt to install or remove as part of the graphical
-installation process. compname is the name of the component, as
-provided to the COMPONENT argument of one or more CMake INSTALL
-commands.
+``compname`` is the name of an installation component, as defined by the
+``COMPONENT`` argument of one or more CMake :command:`install` commands.
+With the ``cpack_add_component`` command one can set a name, a description,
+and other attributes of an installation component.
+One can also assign a component to a component group.
DISPLAY_NAME is the displayed name of the component, used in graphical
installers to display the component name. This value can be any
@@ -177,6 +183,9 @@ the component. See cpack_configure_downloads for more information.
PLIST gives a filename that is passed to pkgbuild with the
``--component-plist`` argument when using the productbuild generator.
+Add component group
+"""""""""""""""""""
+
.. command:: cpack_add_component_group
Describes a group of related CPack installation components.
@@ -225,6 +234,9 @@ single entry.
BOLD_TITLE indicates that the group title should appear in bold, to
call the user's attention to the group.
+Add installation type
+"""""""""""""""""""""
+
.. command:: cpack_add_install_type
Add a new installation type containing
@@ -249,6 +261,9 @@ DISPLAY_NAME is the displayed name of the install type, which will
typically show up in a drop-down box within a graphical installer.
This value can be any string.
+Configure downloads
+"""""""""""""""""""
+
.. command:: cpack_configure_downloads
Configure CPack to download
@@ -281,8 +296,6 @@ requires the ZipDLL plug-in for NSIS, available at:
http://nsis.sourceforge.net/ZipDLL_plug-in
-
-
On macOS, installers that download components on-the-fly can only
be built and installed on system using macOS 10.5 or later.
diff --git a/Modules/CPackIFW.cmake b/Modules/CPackIFW.cmake
index 42ef8c7..f58f9ef 100644
--- a/Modules/CPackIFW.cmake
+++ b/Modules/CPackIFW.cmake
@@ -5,15 +5,12 @@
CPackIFW
--------
-The documentation for the CPack IFW generator has moved here: :cpack_gen:`CPack IFW Generator`
-
-.. _QtIFW: http://doc.qt.io/qtinstallerframework/index.html
-
-This module looks for the location of the command line utilities supplied
-with the Qt Installer Framework (QtIFW_).
+This module looks for the location of the command-line utilities supplied with the
+`Qt Installer Framework <http://doc.qt.io/qtinstallerframework/index.html>`_
+(QtIFW).
The module also defines several commands to control the behavior of the
-CPack ``IFW`` generator.
+:cpack_gen:`CPack IFW Generator`.
Commands
^^^^^^^^
@@ -102,10 +99,10 @@ The module defines the following commands:
``DEPENDS`` | ``DEPENDENCIES``
list of dependency component or component group identifiers in
- QtIFW_ style.
+ QtIFW style.
``AUTO_DEPEND_ON``
- list of identifiers of component or component group in QtIFW_ style
+ list of identifiers of component or component group in QtIFW style
that this component has an automatic dependency on.
``LICENSES``
@@ -207,10 +204,10 @@ The module defines the following commands:
``DEPENDS`` | ``DEPENDENCIES``
list of dependency component or component group identifiers in
- QtIFW_ style.
+ QtIFW style.
``AUTO_DEPEND_ON``
- list of identifiers of component or component group in QtIFW_ style
+ list of identifiers of component or component group in QtIFW style
that this component group has an automatic dependency on.
``LICENSES``
@@ -242,7 +239,7 @@ The module defines the following commands:
.. command:: cpack_ifw_add_repository
- Add QtIFW_ specific remote repository to binary installer.
+ Add QtIFW specific remote repository to binary installer.
::
@@ -273,7 +270,7 @@ The module defines the following commands:
.. command:: cpack_ifw_update_repository
- Update QtIFW_ specific repository from remote repository.
+ Update QtIFW specific repository from remote repository.
::
diff --git a/Modules/CTest.cmake b/Modules/CTest.cmake
index 3a111ca..8109108 100644
--- a/Modules/CTest.cmake
+++ b/Modules/CTest.cmake
@@ -174,7 +174,7 @@ if(BUILD_TESTING)
"How many times to retry timed-out CTest submissions.")
find_program(MEMORYCHECK_COMMAND
- NAMES purify valgrind boundscheck
+ NAMES purify valgrind boundscheck drmemory
PATHS
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Rational Software\\Purify\\Setup;InstallFolder]"
DOC "Path to the memory checking command, used for memory error detection."
@@ -243,7 +243,6 @@ if(BUILD_TESTING)
mark_as_advanced(
BZRCOMMAND
- BZR_UPDATE_OPTIONS
COVERAGE_COMMAND
COVERAGE_EXTRA_FLAGS
CTEST_SUBMIT_RETRY_DELAY
@@ -257,13 +256,10 @@ if(BUILD_TESTING)
MAKECOMMAND
MEMORYCHECK_COMMAND
MEMORYCHECK_SUPPRESSIONS_FILE
- PURIFYCOMMAND
- SCPCOMMAND
SLURM_SBATCH_COMMAND
SLURM_SRUN_COMMAND
SITE
SVNCOMMAND
- SVN_UPDATE_OPTIONS
)
if(NOT RUN_FROM_DART)
set(RUN_FROM_CTEST_OR_DART 1)
diff --git a/Modules/CTestCoverageCollectGCOV.cmake b/Modules/CTestCoverageCollectGCOV.cmake
index ff48cc2..b1268be 100644
--- a/Modules/CTestCoverageCollectGCOV.cmake
+++ b/Modules/CTestCoverageCollectGCOV.cmake
@@ -37,6 +37,17 @@ After generating this tar file, it can be sent to CDash for display with the
upload to CDash. Relative paths will be interpreted with respect
to the top-level build directory.
+ ``TARBALL_COMPRESSION <option>`` Specify a compression algorithm for the
+ ``TARBALL`` data file. Using this option reduces the size of the data file
+ before it is submitted to CDash. ``<option>`` must be one of ``GZIP``,
+ ``BZIP2``, ``XZ``, ``ZSTD``, ``FROM_EXT``, or an expression that CMake
+ evaluates as ``FALSE``. The default value is ``BZIP2``.
+
+ If ``FROM_EXT`` is specified, the resulting file will be compressed based on
+ the file extension of the ``<tarfile>`` (i.e. ``.tar.gz`` will use ``GZIP``
+ compression). File extensions that will produce compressed output include
+ ``.tar.gz``, ``.tgz``, ``.tar.bzip2``, ``.tbz``, ``.tar.xz``, and ``.txz``.
+
``SOURCE <source_dir>``
Specify the top-level source directory for the build.
Default is the value of :variable:`CTEST_SOURCE_DIRECTORY`.
@@ -68,7 +79,7 @@ After generating this tar file, it can be sent to CDash for display with the
function(ctest_coverage_collect_gcov)
set(options QUIET GLOB DELETE)
- set(oneValueArgs TARBALL SOURCE BUILD GCOV_COMMAND)
+ set(oneValueArgs TARBALL SOURCE BUILD GCOV_COMMAND TARBALL_COMPRESSION)
set(multiValueArgs GCOV_OPTIONS)
cmake_parse_arguments(GCOV "${options}" "${oneValueArgs}"
"${multiValueArgs}" "" ${ARGN} )
@@ -91,6 +102,13 @@ function(ctest_coverage_collect_gcov)
else()
set(gcov_command "${GCOV_GCOV_COMMAND}")
endif()
+ if(NOT DEFINED GCOV_TARBALL_COMPRESSION)
+ set(GCOV_TARBALL_COMPRESSION "BZIP2")
+ elseif( GCOV_TARBALL_COMPRESSION AND
+ NOT GCOV_TARBALL_COMPRESSION MATCHES "^(GZIP|BZIP2|XZ|ZSTD|FROM_EXT)$")
+ message(FATAL_ERROR "TARBALL_COMPRESSION must be one of OFF, GZIP, "
+ "BZIP2, XZ, ZSTD, or FROM_EXT for ctest_coverage_collect_gcov")
+ endif()
# run gcov on each gcda file in the binary tree
set(gcda_files)
set(label_files)
@@ -137,11 +155,23 @@ function(ctest_coverage_collect_gcov)
if(NOT DEFINED GCOV_GCOV_OPTIONS)
set(GCOV_GCOV_OPTIONS -b -x)
endif()
+ if (GCOV_QUIET)
+ set(coverage_out_opts
+ OUTPUT_QUIET
+ ERROR_QUIET
+ )
+ else()
+ set(coverage_out_opts
+ OUTPUT_FILE "${coverage_dir}/gcov.log"
+ ERROR_FILE "${coverage_dir}/gcov.log"
+ )
+ endif()
execute_process(COMMAND
${gcov_command} ${GCOV_GCOV_OPTIONS} ${gcda_files}
- OUTPUT_VARIABLE out
RESULT_VARIABLE res
- WORKING_DIRECTORY ${coverage_dir})
+ WORKING_DIRECTORY ${coverage_dir}
+ ${coverage_out_opts}
+ )
if (GCOV_DELETE)
file(REMOVE ${gcda_files})
@@ -149,7 +179,7 @@ function(ctest_coverage_collect_gcov)
if(NOT "${res}" EQUAL 0)
if (NOT GCOV_QUIET)
- message(STATUS "Error running gcov: ${res} ${out}")
+ message(STATUS "Error running gcov: ${res}, see\n ${coverage_dir}/gcov.log")
endif()
endif()
# create json file with project information
@@ -258,14 +288,38 @@ ${label_files}
${uncovered_files_for_tar}
")
- if (GCOV_QUIET)
- set(tar_opts "cfj")
- else()
- set(tar_opts "cvfj")
+ # Prepare tar command line arguments
+
+ set(tar_opts "")
+ # Select data compression mode
+ if( GCOV_TARBALL_COMPRESSION STREQUAL "FROM_EXT")
+ if( GCOV_TARBALL MATCHES [[\.(tgz|tar.gz)$]] )
+ string(APPEND tar_opts "z")
+ elseif( GCOV_TARBALL MATCHES [[\.(txz|tar.xz)$]] )
+ string(APPEND tar_opts "J")
+ elseif( GCOV_TARBALL MATCHES [[\.(tbz|tar.bz)$]] )
+ string(APPEND tar_opts "j")
+ endif()
+ elseif(GCOV_TARBALL_COMPRESSION STREQUAL "GZIP")
+ string(APPEND tar_opts "z")
+ elseif(GCOV_TARBALL_COMPRESSION STREQUAL "XZ")
+ string(APPEND tar_opts "J")
+ elseif(GCOV_TARBALL_COMPRESSION STREQUAL "BZIP2")
+ string(APPEND tar_opts "j")
+ elseif(GCOV_TARBALL_COMPRESSION STREQUAL "ZSTD")
+ set(zstd_tar_opt "--zstd")
+ endif()
+ # Verbosity options
+ if(NOT GCOV_QUIET AND NOT tar_opts MATCHES v)
+ string(APPEND tar_opts "v")
endif()
+ # Prepend option 'c' specifying 'create'
+ string(PREPEND tar_opts "c")
+ # Append option 'f' so that the next argument is the filename
+ string(APPEND tar_opts "f")
execute_process(COMMAND
- ${CMAKE_COMMAND} -E tar ${tar_opts} ${GCOV_TARBALL}
+ ${CMAKE_COMMAND} -E tar ${tar_opts} ${GCOV_TARBALL} ${zstd_tar_opt}
"--mtime=1970-01-01 0:0:0 UTC"
"--format=gnutar"
--files-from=${coverage_dir}/coverage_file_list.txt
diff --git a/Modules/CheckCCompilerFlag.cmake b/Modules/CheckCCompilerFlag.cmake
index a3e2da3..6d65313 100644
--- a/Modules/CheckCCompilerFlag.cmake
+++ b/Modules/CheckCCompilerFlag.cmake
@@ -36,28 +36,23 @@ include_guard(GLOBAL)
include(CheckCSourceCompiles)
include(CMakeCheckCompilerFlagCommonPatterns)
-macro (CHECK_C_COMPILER_FLAG _FLAG _RESULT)
- set(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}")
- set(CMAKE_REQUIRED_DEFINITIONS "${_FLAG}")
-
- # Normalize locale during test compilation.
- set(_CheckCCompilerFlag_LOCALE_VARS LC_ALL LC_MESSAGES LANG)
- foreach(v ${_CheckCCompilerFlag_LOCALE_VARS})
- set(_CheckCCompilerFlag_SAVED_${v} "$ENV{${v}}")
+function(check_c_compiler_flag _flag _var)
+ set(CMAKE_REQUIRED_DEFINITIONS "${_flag}")
+
+ # Normalize locale during test compilation.
+ set(_locale_vars LC_ALL LC_MESSAGES LANG)
+ foreach(v IN LISTS _locale_vars)
+ set(_locale_vars_saved_${v} "$ENV{${v}}")
set(ENV{${v}} C)
endforeach()
- CHECK_COMPILER_FLAG_COMMON_PATTERNS(_CheckCCompilerFlag_COMMON_PATTERNS)
- CHECK_C_SOURCE_COMPILES("int main(void) { return 0; }" ${_RESULT}
+ check_compiler_flag_common_patterns(_common_patterns)
+ check_c_source_compiles("int main(void) { return 0; }" ${_var}
# Some compilers do not fail with a bad flag
FAIL_REGEX "command line option .* is valid for .* but not for C" # GNU
- ${_CheckCCompilerFlag_COMMON_PATTERNS}
+ ${_common_patterns}
)
- foreach(v ${_CheckCCompilerFlag_LOCALE_VARS})
- set(ENV{${v}} ${_CheckCCompilerFlag_SAVED_${v}})
- unset(_CheckCCompilerFlag_SAVED_${v})
+ foreach(v IN LISTS _locale_vars)
+ set(ENV{${v}} ${_locale_vars_saved_${v}})
endforeach()
- unset(_CheckCCompilerFlag_LOCALE_VARS)
- unset(_CheckCCompilerFlag_COMMON_PATTERNS)
-
- set (CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}")
-endmacro ()
+ set(${_var} "${${_var}}" PARENT_SCOPE)
+endfunction()
diff --git a/Modules/CheckCSourceCompiles.cmake b/Modules/CheckCSourceCompiles.cmake
index 77ba0cc..67fc993 100644
--- a/Modules/CheckCSourceCompiles.cmake
+++ b/Modules/CheckCSourceCompiles.cmake
@@ -104,7 +104,7 @@ macro(CHECK_C_SOURCE_COMPILES SOURCE VAR)
"${SOURCE}\n")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR}")
+ message(CHECK_START "Performing Test ${VAR}")
endif()
try_compile(${VAR}
${CMAKE_BINARY_DIR}
@@ -125,7 +125,7 @@ macro(CHECK_C_SOURCE_COMPILES SOURCE VAR)
if(${VAR})
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Success")
+ message(CHECK_PASS "Success")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing C SOURCE FILE Test ${VAR} succeeded with the following output:\n"
@@ -133,7 +133,7 @@ macro(CHECK_C_SOURCE_COMPILES SOURCE VAR)
"Source file was:\n${SOURCE}\n")
else()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Failed")
+ message(CHECK_FAIL "Failed")
endif()
set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
diff --git a/Modules/CheckCSourceRuns.cmake b/Modules/CheckCSourceRuns.cmake
index eba70f2..7d116db 100644
--- a/Modules/CheckCSourceRuns.cmake
+++ b/Modules/CheckCSourceRuns.cmake
@@ -92,7 +92,7 @@ macro(CHECK_C_SOURCE_RUNS SOURCE VAR)
"${SOURCE}\n")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR}")
+ message(CHECK_START "Performing Test ${VAR}")
endif()
try_run(${VAR}_EXITCODE ${VAR}_COMPILED
${CMAKE_BINARY_DIR}
@@ -113,7 +113,7 @@ macro(CHECK_C_SOURCE_RUNS SOURCE VAR)
if("${${VAR}_EXITCODE}" EQUAL 0)
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Success")
+ message(CHECK_PASS "Success")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing C SOURCE FILE Test ${VAR} succeeded with the following compile output:\n"
@@ -130,7 +130,7 @@ macro(CHECK_C_SOURCE_RUNS SOURCE VAR)
endif()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Failed")
+ message(CHECK_FAIL "Failed")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing C SOURCE FILE Test ${VAR} failed with the following compile output:\n"
diff --git a/Modules/CheckCXXCompilerFlag.cmake b/Modules/CheckCXXCompilerFlag.cmake
index 5729843..5e07c25 100644
--- a/Modules/CheckCXXCompilerFlag.cmake
+++ b/Modules/CheckCXXCompilerFlag.cmake
@@ -36,28 +36,23 @@ include_guard(GLOBAL)
include(CheckCXXSourceCompiles)
include(CMakeCheckCompilerFlagCommonPatterns)
-macro (CHECK_CXX_COMPILER_FLAG _FLAG _RESULT)
- set(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}")
- set(CMAKE_REQUIRED_DEFINITIONS "${_FLAG}")
+function(check_cxx_compiler_flag _flag _var)
+ set(CMAKE_REQUIRED_DEFINITIONS "${_flag}")
# Normalize locale during test compilation.
- set(_CheckCXXCompilerFlag_LOCALE_VARS LC_ALL LC_MESSAGES LANG)
- foreach(v ${_CheckCXXCompilerFlag_LOCALE_VARS})
- set(_CheckCXXCompilerFlag_SAVED_${v} "$ENV{${v}}")
+ set(_locale_vars LC_ALL LC_MESSAGES LANG)
+ foreach(v IN LISTS _locale_vars)
+ set(_locale_vars_saved_${v} "$ENV{${v}}")
set(ENV{${v}} C)
endforeach()
- CHECK_COMPILER_FLAG_COMMON_PATTERNS(_CheckCXXCompilerFlag_COMMON_PATTERNS)
- CHECK_CXX_SOURCE_COMPILES("int main() { return 0; }" ${_RESULT}
+ check_compiler_flag_common_patterns(_common_patterns)
+ check_cxx_source_compiles("int main() { return 0; }" ${_var}
# Some compilers do not fail with a bad flag
FAIL_REGEX "command line option .* is valid for .* but not for C\\\\+\\\\+" # GNU
- ${_CheckCXXCompilerFlag_COMMON_PATTERNS}
+ ${_common_patterns}
)
- foreach(v ${_CheckCXXCompilerFlag_LOCALE_VARS})
- set(ENV{${v}} ${_CheckCXXCompilerFlag_SAVED_${v}})
- unset(_CheckCXXCompilerFlag_SAVED_${v})
+ foreach(v IN LISTS _locale_vars)
+ set(ENV{${v}} ${_locale_vars_saved_${v}})
endforeach()
- unset(_CheckCXXCompilerFlag_LOCALE_VARS)
- unset(_CheckCXXCompilerFlag_COMMON_PATTERNS)
-
- set (CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}")
-endmacro ()
+ set(${_var} "${${_var}}" PARENT_SCOPE)
+endfunction()
diff --git a/Modules/CheckCXXSourceCompiles.cmake b/Modules/CheckCXXSourceCompiles.cmake
index cc457a5..c693d32 100644
--- a/Modules/CheckCXXSourceCompiles.cmake
+++ b/Modules/CheckCXXSourceCompiles.cmake
@@ -105,7 +105,7 @@ macro(CHECK_CXX_SOURCE_COMPILES SOURCE VAR)
"${SOURCE}\n")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR}")
+ message(CHECK_START "Performing Test ${VAR}")
endif()
try_compile(${VAR}
${CMAKE_BINARY_DIR}
@@ -126,7 +126,7 @@ macro(CHECK_CXX_SOURCE_COMPILES SOURCE VAR)
if(${VAR})
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Success")
+ message(CHECK_PASS "Success")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing C++ SOURCE FILE Test ${VAR} succeeded with the following output:\n"
@@ -134,7 +134,7 @@ macro(CHECK_CXX_SOURCE_COMPILES SOURCE VAR)
"Source file was:\n${SOURCE}\n")
else()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Failed")
+ message(CHECK_FAIL "Failed")
endif()
set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
diff --git a/Modules/CheckCXXSourceRuns.cmake b/Modules/CheckCXXSourceRuns.cmake
index 5e3f195..408e183 100644
--- a/Modules/CheckCXXSourceRuns.cmake
+++ b/Modules/CheckCXXSourceRuns.cmake
@@ -92,7 +92,7 @@ macro(CHECK_CXX_SOURCE_RUNS SOURCE VAR)
"${SOURCE}\n")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR}")
+ message(CHECK_START "Performing Test ${VAR}")
endif()
try_run(${VAR}_EXITCODE ${VAR}_COMPILED
${CMAKE_BINARY_DIR}
@@ -114,7 +114,7 @@ macro(CHECK_CXX_SOURCE_RUNS SOURCE VAR)
if("${${VAR}_EXITCODE}" EQUAL 0)
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Success")
+ message(CHECK_PASS "Success")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing C++ SOURCE FILE Test ${VAR} succeeded with the following output:\n"
@@ -131,7 +131,7 @@ macro(CHECK_CXX_SOURCE_RUNS SOURCE VAR)
endif()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Failed")
+ message(CHECK_FAIL "Failed")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing C++ SOURCE FILE Test ${VAR} failed with the following output:\n"
diff --git a/Modules/CheckFortranFunctionExists.cmake b/Modules/CheckFortranFunctionExists.cmake
index 7ca205a..d06203f 100644
--- a/Modules/CheckFortranFunctionExists.cmake
+++ b/Modules/CheckFortranFunctionExists.cmake
@@ -38,7 +38,7 @@ include_guard(GLOBAL)
macro(CHECK_FORTRAN_FUNCTION_EXISTS FUNCTION VARIABLE)
if(NOT DEFINED ${VARIABLE})
- message(STATUS "Looking for Fortran ${FUNCTION}")
+ message(CHECK_START "Looking for Fortran ${FUNCTION}")
if(CMAKE_REQUIRED_LINK_OPTIONS)
set(CHECK_FUNCTION_EXISTS_ADD_LINK_OPTIONS
LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
@@ -61,21 +61,20 @@ macro(CHECK_FORTRAN_FUNCTION_EXISTS FUNCTION VARIABLE)
"
)
try_compile(${VARIABLE}
- ${CMAKE_BINARY_DIR}
- ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompiler.f
- ${CHECK_FUNCTION_EXISTS_ADD_LINK_OPTIONS}
- ${CHECK_FUNCTION_EXISTS_ADD_LIBRARIES}
- OUTPUT_VARIABLE OUTPUT
+ ${CMAKE_BINARY_DIR}
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testFortranCompiler.f
+ ${CHECK_FUNCTION_EXISTS_ADD_LINK_OPTIONS}
+ ${CHECK_FUNCTION_EXISTS_ADD_LIBRARIES}
+ OUTPUT_VARIABLE OUTPUT
)
-# message(STATUS "${OUTPUT}")
if(${VARIABLE})
set(${VARIABLE} 1 CACHE INTERNAL "Have Fortran function ${FUNCTION}")
- message(STATUS "Looking for Fortran ${FUNCTION} - found")
+ message(CHECK_PASS "found")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the Fortran ${FUNCTION} exists passed with the following output:\n"
"${OUTPUT}\n\n")
else()
- message(STATUS "Looking for Fortran ${FUNCTION} - not found")
+ message(CHECK_FAIL "not found")
set(${VARIABLE} "" CACHE INTERNAL "Have Fortran function ${FUNCTION}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the Fortran ${FUNCTION} exists failed with the following output:\n"
diff --git a/Modules/CheckFortranSourceCompiles.cmake b/Modules/CheckFortranSourceCompiles.cmake
index f94b254..3354bfb 100644
--- a/Modules/CheckFortranSourceCompiles.cmake
+++ b/Modules/CheckFortranSourceCompiles.cmake
@@ -103,8 +103,6 @@ macro(CHECK_Fortran_SOURCE_COMPILES SOURCE VAR)
if(NOT _SRC_EXT)
set(_SRC_EXT F)
endif()
- set(MACRO_CHECK_FUNCTION_DEFINITIONS
- "-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
if(CMAKE_REQUIRED_LINK_OPTIONS)
set(CHECK_Fortran_SOURCE_COMPILES_ADD_LINK_OPTIONS
LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
@@ -127,15 +125,15 @@ macro(CHECK_Fortran_SOURCE_COMPILES SOURCE VAR)
"${SOURCE}\n")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR}")
+ message(CHECK_START "Performing Test ${VAR}")
endif()
try_compile(${VAR}
${CMAKE_BINARY_DIR}
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT}
- COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+ COMPILE_DEFINITIONS -D${VAR} ${CMAKE_REQUIRED_DEFINITIONS}
${CHECK_Fortran_SOURCE_COMPILES_ADD_LINK_OPTIONS}
${CHECK_Fortran_SOURCE_COMPILES_ADD_LIBRARIES}
- CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
+ CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${CMAKE_REQUIRED_FLAGS}
"${CHECK_Fortran_SOURCE_COMPILES_ADD_INCLUDES}"
OUTPUT_VARIABLE OUTPUT)
@@ -148,7 +146,7 @@ macro(CHECK_Fortran_SOURCE_COMPILES SOURCE VAR)
if(${VAR})
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Success")
+ message(CHECK_PASS "Success")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing Fortran SOURCE FILE Test ${VAR} succeeded with the following output:\n"
@@ -156,7 +154,7 @@ macro(CHECK_Fortran_SOURCE_COMPILES SOURCE VAR)
"Source file was:\n${SOURCE}\n")
else()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Failed")
+ message(CHECK_FAIL "Failed")
endif()
set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
diff --git a/Modules/CheckFortranSourceRuns.cmake b/Modules/CheckFortranSourceRuns.cmake
index a80c13d..f858b84 100644
--- a/Modules/CheckFortranSourceRuns.cmake
+++ b/Modules/CheckFortranSourceRuns.cmake
@@ -98,8 +98,6 @@ macro(CHECK_Fortran_SOURCE_RUNS SOURCE VAR)
if(NOT _SRC_EXT)
set(_SRC_EXT F90)
endif()
- set(MACRO_CHECK_FUNCTION_DEFINITIONS
- "-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
if(CMAKE_REQUIRED_LINK_OPTIONS)
set(CHECK_Fortran_SOURCE_COMPILES_ADD_LINK_OPTIONS
LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
@@ -122,15 +120,15 @@ macro(CHECK_Fortran_SOURCE_RUNS SOURCE VAR)
"${SOURCE}\n")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR}")
+ message(CHECK_START "Performing Test ${VAR}")
endif()
try_run(${VAR}_EXITCODE ${VAR}_COMPILED
${CMAKE_BINARY_DIR}
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT}
- COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+ COMPILE_DEFINITIONS -D${VAR} ${CMAKE_REQUIRED_DEFINITIONS}
${CHECK_Fortran_SOURCE_COMPILES_ADD_LINK_OPTIONS}
${CHECK_Fortran_SOURCE_COMPILES_ADD_LIBRARIES}
- CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
+ CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${CMAKE_REQUIRED_FLAGS}
-DCMAKE_SKIP_RPATH:BOOL=${CMAKE_SKIP_RPATH}
"${CHECK_Fortran_SOURCE_COMPILES_ADD_INCLUDES}"
COMPILE_OUTPUT_VARIABLE OUTPUT
@@ -144,7 +142,7 @@ macro(CHECK_Fortran_SOURCE_RUNS SOURCE VAR)
if("${${VAR}_EXITCODE}" EQUAL 0)
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Success")
+ message(CHECK_PASS "Success")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing Fortran SOURCE FILE Test ${VAR} succeeded with the following output:\n"
@@ -161,7 +159,7 @@ macro(CHECK_Fortran_SOURCE_RUNS SOURCE VAR)
endif()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Failed")
+ message(CHECK_FAIL "Failed")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing Fortran SOURCE FILE Test ${VAR} failed with the following output:\n"
diff --git a/Modules/CheckFunctionExists.cmake b/Modules/CheckFunctionExists.cmake
index c39144f..136da89 100644
--- a/Modules/CheckFunctionExists.cmake
+++ b/Modules/CheckFunctionExists.cmake
@@ -57,7 +57,7 @@ macro(CHECK_FUNCTION_EXISTS FUNCTION VARIABLE)
set(MACRO_CHECK_FUNCTION_DEFINITIONS
"-DCHECK_FUNCTION_EXISTS=${FUNCTION} ${CMAKE_REQUIRED_FLAGS}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${FUNCTION}")
+ message(CHECK_START "Looking for ${FUNCTION}")
endif()
if(CMAKE_REQUIRED_LINK_OPTIONS)
set(CHECK_FUNCTION_EXISTS_ADD_LINK_OPTIONS
@@ -101,14 +101,14 @@ macro(CHECK_FUNCTION_EXISTS FUNCTION VARIABLE)
if(${VARIABLE})
set(${VARIABLE} 1 CACHE INTERNAL "Have function ${FUNCTION}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${FUNCTION} - found")
+ message(CHECK_PASS "found")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the function ${FUNCTION} exists passed with the following output:\n"
"${OUTPUT}\n\n")
else()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${FUNCTION} - not found")
+ message(CHECK_FAIL "not found")
endif()
set(${VARIABLE} "" CACHE INTERNAL "Have function ${FUNCTION}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
diff --git a/Modules/CheckIPOSupported.cmake b/Modules/CheckIPOSupported.cmake
index 0d6ad20..90a9f61 100644
--- a/Modules/CheckIPOSupported.cmake
+++ b/Modules/CheckIPOSupported.cmake
@@ -113,7 +113,7 @@ macro(_ipo_run_language_check language)
endforeach()
try_compile(
- result
+ _IPO_LANGUAGE_CHECK_RESULT
"${bindir}"
"${srcdir}"
"${TRY_COMPILE_PROJECT_NAME}"
@@ -122,8 +122,10 @@ macro(_ipo_run_language_check language)
"-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON"
OUTPUT_VARIABLE output
)
+ set(_IPO_LANGUAGE_CHECK_RESULT "${_IPO_LANGUAGE_CHECK_RESULT}")
+ unset(_IPO_LANGUAGE_CHECK_RESULT CACHE)
- if(NOT result)
+ if(NOT _IPO_LANGUAGE_CHECK_RESULT)
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"${language} compiler IPO check failed with the following output:\n"
"${output}\n")
diff --git a/Modules/CheckIncludeFile.cmake b/Modules/CheckIncludeFile.cmake
index d7b9481..3a10473 100644
--- a/Modules/CheckIncludeFile.cmake
+++ b/Modules/CheckIncludeFile.cmake
@@ -55,7 +55,7 @@ macro(CHECK_INCLUDE_FILE INCLUDE VARIABLE)
configure_file(${CMAKE_ROOT}/Modules/CheckIncludeFile.c.in
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.c)
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${INCLUDE}")
+ message(CHECK_START "Looking for ${INCLUDE}")
endif()
if(${ARGC} EQUAL 3)
set(CMAKE_C_FLAGS_SAVE ${CMAKE_C_FLAGS})
@@ -109,7 +109,7 @@ macro(CHECK_INCLUDE_FILE INCLUDE VARIABLE)
if(${VARIABLE})
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${INCLUDE} - found")
+ message(CHECK_PASS "found")
endif()
set(${VARIABLE} 1 CACHE INTERNAL "Have include ${INCLUDE}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
@@ -118,7 +118,7 @@ macro(CHECK_INCLUDE_FILE INCLUDE VARIABLE)
"${OUTPUT}\n\n")
else()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${INCLUDE} - not found")
+ message(CHECK_FAIL "not found")
endif()
set(${VARIABLE} "" CACHE INTERNAL "Have include ${INCLUDE}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
diff --git a/Modules/CheckIncludeFileCXX.cmake b/Modules/CheckIncludeFileCXX.cmake
index de5a83b..496550f 100644
--- a/Modules/CheckIncludeFileCXX.cmake
+++ b/Modules/CheckIncludeFileCXX.cmake
@@ -54,7 +54,7 @@ macro(CHECK_INCLUDE_FILE_CXX INCLUDE VARIABLE)
configure_file(${CMAKE_ROOT}/Modules/CheckIncludeFile.cxx.in
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.cxx)
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for C++ include ${INCLUDE}")
+ message(CHECK_START "Looking for C++ include ${INCLUDE}")
endif()
if(${ARGC} EQUAL 3)
set(CMAKE_CXX_FLAGS_SAVE ${CMAKE_CXX_FLAGS})
@@ -108,7 +108,7 @@ macro(CHECK_INCLUDE_FILE_CXX INCLUDE VARIABLE)
if(${VARIABLE})
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for C++ include ${INCLUDE} - found")
+ message(CHECK_PASS "found")
endif()
set(${VARIABLE} 1 CACHE INTERNAL "Have include ${INCLUDE}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
@@ -117,7 +117,7 @@ macro(CHECK_INCLUDE_FILE_CXX INCLUDE VARIABLE)
"${OUTPUT}\n\n")
else()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for C++ include ${INCLUDE} - not found")
+ message(CHECK_FAIL "not found")
endif()
set(${VARIABLE} "" CACHE INTERNAL "Have include ${INCLUDE}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
diff --git a/Modules/CheckIncludeFiles.cmake b/Modules/CheckIncludeFiles.cmake
index f52ab55..8e10cd6 100644
--- a/Modules/CheckIncludeFiles.cmake
+++ b/Modules/CheckIncludeFiles.cmake
@@ -131,7 +131,7 @@ macro(CHECK_INCLUDE_FILES INCLUDE VARIABLE)
endif()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${_description}")
+ message(CHECK_START "Looking for ${_description}")
endif()
try_compile(${VARIABLE}
${CMAKE_BINARY_DIR}
@@ -147,7 +147,7 @@ macro(CHECK_INCLUDE_FILES INCLUDE VARIABLE)
unset(_CIF_LINK_LIBRARIES)
if(${VARIABLE})
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${_description} - found")
+ message(CHECK_PASS "found")
endif()
set(${VARIABLE} 1 CACHE INTERNAL "Have include ${INCLUDE}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
@@ -156,7 +156,7 @@ macro(CHECK_INCLUDE_FILES INCLUDE VARIABLE)
"${OUTPUT}\n\n")
else()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${_description} - not found")
+ message(CHECK_FAIL "not found")
endif()
set(${VARIABLE} "" CACHE INTERNAL "Have includes ${INCLUDE}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
diff --git a/Modules/CheckLanguage.cmake b/Modules/CheckLanguage.cmake
index 95e4fbe..d67d8d3 100644
--- a/Modules/CheckLanguage.cmake
+++ b/Modules/CheckLanguage.cmake
@@ -39,7 +39,7 @@ include_guard(GLOBAL)
macro(check_language lang)
if(NOT DEFINED CMAKE_${lang}_COMPILER)
set(_desc "Looking for a ${lang} compiler")
- message(STATUS ${_desc})
+ message(CHECK_START "${_desc}")
file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/Check${lang})
set(extra_compiler_variables)
@@ -47,7 +47,7 @@ macro(check_language lang)
set(extra_compiler_variables "set(CMAKE_CUDA_HOST_COMPILER \\\"\${CMAKE_CUDA_HOST_COMPILER}\\\")")
endif()
- set(content
+ set(_cl_content
"cmake_minimum_required(VERSION ${CMAKE_VERSION})
project(Check${lang} ${lang})
file(WRITE \"\${CMAKE_CURRENT_BINARY_DIR}/result.cmake\"
@@ -57,34 +57,42 @@ file(WRITE \"\${CMAKE_CURRENT_BINARY_DIR}/result.cmake\"
)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/Check${lang}/CMakeLists.txt"
- "${content}")
+ "${_cl_content}")
if(CMAKE_GENERATOR_INSTANCE)
set(_D_CMAKE_GENERATOR_INSTANCE "-DCMAKE_GENERATOR_INSTANCE:INTERNAL=${CMAKE_GENERATOR_INSTANCE}")
else()
set(_D_CMAKE_GENERATOR_INSTANCE "")
endif()
+ if(CMAKE_GENERATOR MATCHES "^(Xcode$|Green Hills MULTI$|Visual Studio)")
+ set(_D_CMAKE_MAKE_PROGRAM "")
+ else()
+ set(_D_CMAKE_MAKE_PROGRAM "-DCMAKE_MAKE_PROGRAM:FILEPATH=${CMAKE_MAKE_PROGRAM}")
+ endif()
execute_process(
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/Check${lang}
COMMAND ${CMAKE_COMMAND} . -G ${CMAKE_GENERATOR}
-A "${CMAKE_GENERATOR_PLATFORM}"
-T "${CMAKE_GENERATOR_TOOLSET}"
${_D_CMAKE_GENERATOR_INSTANCE}
- OUTPUT_VARIABLE output
- ERROR_VARIABLE output
- RESULT_VARIABLE result
+ ${_D_CMAKE_MAKE_PROGRAM}
+ OUTPUT_VARIABLE _cl_output
+ ERROR_VARIABLE _cl_output
+ RESULT_VARIABLE _cl_result
)
include(${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/Check${lang}/result.cmake OPTIONAL)
- if(CMAKE_${lang}_COMPILER AND "${result}" STREQUAL "0")
+ if(CMAKE_${lang}_COMPILER AND "${_cl_result}" STREQUAL "0")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"${_desc} passed with the following output:\n"
- "${output}\n")
+ "${_cl_output}\n")
+ set(_CHECK_COMPILER_STATUS CHECK_PASS)
else()
set(CMAKE_${lang}_COMPILER NOTFOUND)
+ set(_CHECK_COMPILER_STATUS CHECK_FAIL)
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"${_desc} failed with the following output:\n"
- "${output}\n")
+ "${_cl_output}\n")
endif()
- message(STATUS "${_desc} - ${CMAKE_${lang}_COMPILER}")
+ message(${_CHECK_COMPILER_STATUS} "${CMAKE_${lang}_COMPILER}")
set(CMAKE_${lang}_COMPILER "${CMAKE_${lang}_COMPILER}" CACHE FILEPATH "${lang} compiler")
mark_as_advanced(CMAKE_${lang}_COMPILER)
diff --git a/Modules/CheckLibraryExists.cmake b/Modules/CheckLibraryExists.cmake
index 6504df5..6470dfd 100644
--- a/Modules/CheckLibraryExists.cmake
+++ b/Modules/CheckLibraryExists.cmake
@@ -42,7 +42,7 @@ macro(CHECK_LIBRARY_EXISTS LIBRARY FUNCTION LOCATION VARIABLE)
set(MACRO_CHECK_LIBRARY_EXISTS_DEFINITION
"-DCHECK_FUNCTION_EXISTS=${FUNCTION} ${CMAKE_REQUIRED_FLAGS}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${FUNCTION} in ${LIBRARY}")
+ message(CHECK_START "Looking for ${FUNCTION} in ${LIBRARY}")
endif()
set(CHECK_LIBRARY_EXISTS_LINK_OPTIONS)
if(CMAKE_REQUIRED_LINK_OPTIONS)
@@ -78,7 +78,7 @@ macro(CHECK_LIBRARY_EXISTS LIBRARY FUNCTION LOCATION VARIABLE)
if(${VARIABLE})
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${FUNCTION} in ${LIBRARY} - found")
+ message(CHECK_PASS "found")
endif()
set(${VARIABLE} 1 CACHE INTERNAL "Have library ${LIBRARY}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
@@ -87,7 +87,7 @@ macro(CHECK_LIBRARY_EXISTS LIBRARY FUNCTION LOCATION VARIABLE)
"${OUTPUT}\n\n")
else()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${FUNCTION} in ${LIBRARY} - not found")
+ message(CHECK_FAIL "not found")
endif()
set(${VARIABLE} "" CACHE INTERNAL "Have library ${LIBRARY}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
diff --git a/Modules/CheckOBJCSourceCompiles.cmake b/Modules/CheckOBJCSourceCompiles.cmake
index a4676ad..601f1fa 100644
--- a/Modules/CheckOBJCSourceCompiles.cmake
+++ b/Modules/CheckOBJCSourceCompiles.cmake
@@ -104,7 +104,7 @@ macro(CHECK_OBJC_SOURCE_COMPILES SOURCE VAR)
"${SOURCE}\n")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR}")
+ message(CHECK_START "Performing Test ${VAR}")
endif()
try_compile(${VAR}
${CMAKE_BINARY_DIR}
@@ -125,7 +125,7 @@ macro(CHECK_OBJC_SOURCE_COMPILES SOURCE VAR)
if(${VAR})
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Success")
+ message(CHECK_PASS "Success")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing Objective-C SOURCE FILE Test ${VAR} succeeded with the following output:\n"
@@ -133,7 +133,7 @@ macro(CHECK_OBJC_SOURCE_COMPILES SOURCE VAR)
"Source file was:\n${SOURCE}\n")
else()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Failed")
+ message(CHECK_FAIL "Failed")
endif()
set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
diff --git a/Modules/CheckOBJCSourceRuns.cmake b/Modules/CheckOBJCSourceRuns.cmake
index 00a1ebd..6684693 100644
--- a/Modules/CheckOBJCSourceRuns.cmake
+++ b/Modules/CheckOBJCSourceRuns.cmake
@@ -92,7 +92,7 @@ macro(CHECK_OBJC_SOURCE_RUNS SOURCE VAR)
"${SOURCE}\n")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR}")
+ message(CHECK_START "Performing Test ${VAR}")
endif()
try_run(${VAR}_EXITCODE ${VAR}_COMPILED
${CMAKE_BINARY_DIR}
@@ -113,7 +113,7 @@ macro(CHECK_OBJC_SOURCE_RUNS SOURCE VAR)
if("${${VAR}_EXITCODE}" EQUAL 0)
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Success")
+ message(CHECK_PASS "Success")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing Objective-C SOURCE FILE Test ${VAR} succeeded with the following compile output:\n"
@@ -130,7 +130,7 @@ macro(CHECK_OBJC_SOURCE_RUNS SOURCE VAR)
endif()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Failed")
+ message(CHECK_FAIL "Failed")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing Objective-C SOURCE FILE Test ${VAR} failed with the following compile output:\n"
diff --git a/Modules/CheckOBJCXXSourceCompiles.cmake b/Modules/CheckOBJCXXSourceCompiles.cmake
index 4c0fdd0..2ee79f4 100644
--- a/Modules/CheckOBJCXXSourceCompiles.cmake
+++ b/Modules/CheckOBJCXXSourceCompiles.cmake
@@ -105,7 +105,7 @@ macro(CHECK_OBJCXX_SOURCE_COMPILES SOURCE VAR)
"${SOURCE}\n")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR}")
+ message(CHECK_START "Performing Test ${VAR}")
endif()
try_compile(${VAR}
${CMAKE_BINARY_DIR}
@@ -126,7 +126,7 @@ macro(CHECK_OBJCXX_SOURCE_COMPILES SOURCE VAR)
if(${VAR})
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Success")
+ message(CHECK_PASS "Success")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing Objective-C++ SOURCE FILE Test ${VAR} succeeded with the following output:\n"
@@ -134,7 +134,7 @@ macro(CHECK_OBJCXX_SOURCE_COMPILES SOURCE VAR)
"Source file was:\n${SOURCE}\n")
else()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Failed")
+ message(CHECK_FAIL "Failed")
endif()
set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
diff --git a/Modules/CheckOBJCXXSourceRuns.cmake b/Modules/CheckOBJCXXSourceRuns.cmake
index a3d5923..7f7e04f 100644
--- a/Modules/CheckOBJCXXSourceRuns.cmake
+++ b/Modules/CheckOBJCXXSourceRuns.cmake
@@ -92,7 +92,7 @@ macro(CHECK_OBJCXX_SOURCE_RUNS SOURCE VAR)
"${SOURCE}\n")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR}")
+ message(CHECK_START "Performing Test ${VAR}")
endif()
try_run(${VAR}_EXITCODE ${VAR}_COMPILED
${CMAKE_BINARY_DIR}
@@ -114,7 +114,7 @@ macro(CHECK_OBJCXX_SOURCE_RUNS SOURCE VAR)
if("${${VAR}_EXITCODE}" EQUAL 0)
set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Success")
+ message(CHECK_PASS "Success")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Performing Objective-C++ SOURCE FILE Test ${VAR} succeeded with the following output:\n"
@@ -131,7 +131,7 @@ macro(CHECK_OBJCXX_SOURCE_RUNS SOURCE VAR)
endif()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Performing Test ${VAR} - Failed")
+ message(CHECK_FAIL "Failed")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Performing Objective-C++ SOURCE FILE Test ${VAR} failed with the following output:\n"
diff --git a/Modules/CheckPrototypeDefinition.cmake b/Modules/CheckPrototypeDefinition.cmake
index a7b020c..8b06403 100644
--- a/Modules/CheckPrototypeDefinition.cmake
+++ b/Modules/CheckPrototypeDefinition.cmake
@@ -54,6 +54,9 @@ include_guard(GLOBAL)
function(check_prototype_definition _FUNCTION _PROTOTYPE _RETURN _HEADER _VARIABLE)
if (NOT DEFINED ${_VARIABLE})
+ if(NOT CMAKE_REQUIRED_QUIET)
+ message(CHECK_START "Checking prototype ${_FUNCTION} for ${_VARIABLE}")
+ endif()
set(CHECK_PROTOTYPE_DEFINITION_CONTENT "/* */\n")
set(CHECK_PROTOTYPE_DEFINITION_FLAGS ${CMAKE_REQUIRED_FLAGS})
@@ -103,14 +106,14 @@ function(check_prototype_definition _FUNCTION _PROTOTYPE _RETURN _HEADER _VARIAB
if (${_VARIABLE})
set(${_VARIABLE} 1 CACHE INTERNAL "Have correct prototype for ${_FUNCTION}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Checking prototype ${_FUNCTION} for ${_VARIABLE} - True")
+ message(CHECK_PASS "True")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the prototype ${_FUNCTION} exists for ${_VARIABLE} passed with the following output:\n"
"${OUTPUT}\n\n")
else ()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Checking prototype ${_FUNCTION} for ${_VARIABLE} - False")
+ message(CHECK_FAIL "False")
endif()
set(${_VARIABLE} 0 CACHE INTERNAL "Have correct prototype for ${_FUNCTION}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
diff --git a/Modules/CheckSymbolExists.cmake b/Modules/CheckSymbolExists.cmake
index 1053383..4f202c4 100644
--- a/Modules/CheckSymbolExists.cmake
+++ b/Modules/CheckSymbolExists.cmake
@@ -126,7 +126,7 @@ int main(int argc, char** argv)
"${SOURCEFILE}" @ONLY)
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${SYMBOL}")
+ message(CHECK_START "Looking for ${SYMBOL}")
endif()
try_compile(${VARIABLE}
${CMAKE_BINARY_DIR}
@@ -140,7 +140,7 @@ int main(int argc, char** argv)
OUTPUT_VARIABLE OUTPUT)
if(${VARIABLE})
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${SYMBOL} - found")
+ message(CHECK_PASS "found")
endif()
set(${VARIABLE} 1 CACHE INTERNAL "Have symbol ${SYMBOL}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
@@ -150,7 +150,7 @@ int main(int argc, char** argv)
"${CMAKE_CONFIGURABLE_FILE_CONTENT}\n")
else()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${SYMBOL} - not found")
+ message(CHECK_FAIL "not found")
endif()
set(${VARIABLE} "" CACHE INTERNAL "Have symbol ${SYMBOL}")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
diff --git a/Modules/CheckTypeSize.c.in b/Modules/CheckTypeSize.c.in
index 82035a3..fb93073 100644
--- a/Modules/CheckTypeSize.c.in
+++ b/Modules/CheckTypeSize.c.in
@@ -5,10 +5,14 @@
# define KEY '_','_','i','3','8','6'
#elif defined(__x86_64)
# define KEY '_','_','x','8','6','_','6','4'
-#elif defined(__ppc__)
-# define KEY '_','_','p','p','c','_','_'
+#elif defined(__PPC64__)
+# define KEY '_','_','P','P','C','6','4','_','_'
#elif defined(__ppc64__)
# define KEY '_','_','p','p','c','6','4','_','_'
+#elif defined(__PPC__)
+# define KEY '_','_','P','P','C','_','_'
+#elif defined(__ppc__)
+# define KEY '_','_','p','p','c','_','_'
#elif defined(__aarch64__)
# define KEY '_','_','a','a','r','c','h','6','4','_','_'
#elif defined(__ARM_ARCH_7A__)
diff --git a/Modules/CheckTypeSize.cmake b/Modules/CheckTypeSize.cmake
index 3727373..2b07b7c 100644
--- a/Modules/CheckTypeSize.cmake
+++ b/Modules/CheckTypeSize.cmake
@@ -86,7 +86,7 @@ cmake_policy(SET CMP0054 NEW)
# Helper function. DO NOT CALL DIRECTLY.
function(__check_type_size_impl type var map builtin language)
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Check size of ${type}")
+ message(CHECK_START "Check size of ${type}")
endif()
# Include header files.
@@ -173,7 +173,7 @@ function(__check_type_size_impl type var map builtin language)
endif()
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Check size of ${type} - done")
+ message(CHECK_PASS "done")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining size of ${type} passed with the following output:\n${output}\n\n")
@@ -181,7 +181,7 @@ function(__check_type_size_impl type var map builtin language)
else()
# The check failed to compile.
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Check size of ${type} - failed")
+ message(CHECK_FAIL "failed")
endif()
file(READ ${src} content)
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
diff --git a/Modules/CheckVariableExists.cmake b/Modules/CheckVariableExists.cmake
index f4953a3..8a93535 100644
--- a/Modules/CheckVariableExists.cmake
+++ b/Modules/CheckVariableExists.cmake
@@ -42,7 +42,7 @@ macro(CHECK_VARIABLE_EXISTS VAR VARIABLE)
set(MACRO_CHECK_VARIABLE_DEFINITIONS
"-DCHECK_VARIABLE_EXISTS=${VAR} ${CMAKE_REQUIRED_FLAGS}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${VAR}")
+ message(CHECK_START "Looking for ${VAR}")
endif()
if(CMAKE_REQUIRED_LINK_OPTIONS)
set(CHECK_VARIABLE_EXISTS_ADD_LINK_OPTIONS
@@ -67,7 +67,7 @@ macro(CHECK_VARIABLE_EXISTS VAR VARIABLE)
if(${VARIABLE})
set(${VARIABLE} 1 CACHE INTERNAL "Have variable ${VAR}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${VAR} - found")
+ message(CHECK_PASS "found")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the variable ${VAR} exists passed with the following output:\n"
@@ -75,7 +75,7 @@ macro(CHECK_VARIABLE_EXISTS VAR VARIABLE)
else()
set(${VARIABLE} "" CACHE INTERNAL "Have variable ${VAR}")
if(NOT CMAKE_REQUIRED_QUIET)
- message(STATUS "Looking for ${VAR} - not found")
+ message(CHECK_FAIL "not found")
endif()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the variable ${VAR} exists failed with the following output:\n"
diff --git a/Modules/Compiler/AppleClang-CXX.cmake b/Modules/Compiler/AppleClang-CXX.cmake
index 3fa6990..15edc21 100644
--- a/Modules/Compiler/AppleClang-CXX.cmake
+++ b/Modules/Compiler/AppleClang-CXX.cmake
@@ -25,7 +25,10 @@ elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.1)
set(CMAKE_CXX14_STANDARD__HAS_FULL_SUPPORT ON)
endif()
-if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.1)
+if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 10.0)
+ set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std=c++17")
+ set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std=gnu++17")
+elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.1)
set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std=c++1z")
set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std=gnu++1z")
endif()
diff --git a/Modules/Compiler/AppleClang-OBJCXX.cmake b/Modules/Compiler/AppleClang-OBJCXX.cmake
index 2c084af..409bd4a 100644
--- a/Modules/Compiler/AppleClang-OBJCXX.cmake
+++ b/Modules/Compiler/AppleClang-OBJCXX.cmake
@@ -22,7 +22,10 @@ elseif(NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 5.1)
set(CMAKE_OBJCXX14_STANDARD__HAS_FULL_SUPPORT ON)
endif()
-if (NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 6.1)
+if (NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 10.0)
+ set(CMAKE_OBJCXX17_STANDARD_COMPILE_OPTION "-std=c++17")
+ set(CMAKE_OBJCXX17_EXTENSION_COMPILE_OPTION "-std=gnu++17")
+elseif (NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 6.1)
set(CMAKE_OBJCXX17_STANDARD_COMPILE_OPTION "-std=c++1z")
set(CMAKE_OBJCXX17_EXTENSION_COMPILE_OPTION "-std=gnu++1z")
endif()
diff --git a/Modules/Compiler/CMakeCommonCompilerMacros.cmake b/Modules/Compiler/CMakeCommonCompilerMacros.cmake
index 96537f8..409b65a 100644
--- a/Modules/Compiler/CMakeCommonCompilerMacros.cmake
+++ b/Modules/Compiler/CMakeCommonCompilerMacros.cmake
@@ -134,3 +134,47 @@ macro(cmake_record_cxx_compile_features)
unset(CMAKE_CXX98_STANDARD__HAS_FULL_SUPPORT)
endif()
endmacro()
+
+macro(cmake_record_cuda_compile_features)
+ set(_result 0)
+ if(_result EQUAL 0 AND DEFINED CMAKE_CUDA20_STANDARD_COMPILE_OPTION)
+ if(CMAKE_CUDA20_STANDARD__HAS_FULL_SUPPORT)
+ _has_compiler_features_cuda(20)
+ else()
+ _record_compiler_features_cuda(20)
+ endif()
+ unset(CMAKE_CUDA20_STANDARD__HAS_FULL_SUPPORT)
+ endif()
+ if(_result EQUAL 0 AND DEFINED CMAKE_CUDA17_STANDARD_COMPILE_OPTION)
+ if(CMAKE_CUDA17_STANDARD__HAS_FULL_SUPPORT)
+ _has_compiler_features_cuda(17)
+ else()
+ _record_compiler_features_cuda(17)
+ endif()
+ unset(CMAKE_CUDA17_STANDARD__HAS_FULL_SUPPORT)
+ endif()
+ if(_result EQUAL 0 AND DEFINED CMAKE_CUDA14_STANDARD_COMPILE_OPTION)
+ if(CMAKE_CUDA14_STANDARD__HAS_FULL_SUPPORT)
+ _has_compiler_features_cuda(14)
+ else()
+ _record_compiler_features_cuda(14)
+ endif()
+ unset(CMAKE_CUDA14_STANDARD__HAS_FULL_SUPPORT)
+ endif()
+ if(_result EQUAL 0 AND DEFINED CMAKE_CUDA11_STANDARD_COMPILE_OPTION)
+ if(CMAKE_CUDA11_STANDARD__HAS_FULL_SUPPORT)
+ _has_compiler_features_cuda(11)
+ else()
+ _record_compiler_features_cuda(11)
+ endif()
+ unset(CMAKE_CUDA11_STANDARD__HAS_FULL_SUPPORT)
+ endif()
+ if(_result EQUAL 0 AND DEFINED CMAKE_CUDA03_STANDARD_COMPILE_OPTION)
+ if(CMAKE_CUDA03_STANDARD__HAS_FULL_SUPPORT)
+ _has_compiler_features_cuda(03)
+ else()
+ _record_compiler_features_cuda(03)
+ endif()
+ unset(CMAKE_CUDA03_STANDARD__HAS_FULL_SUPPORT)
+ endif()
+endmacro()
diff --git a/Modules/Compiler/Clang-C.cmake b/Modules/Compiler/Clang-C.cmake
index 0448965..7c4a263 100644
--- a/Modules/Compiler/Clang-C.cmake
+++ b/Modules/Compiler/Clang-C.cmake
@@ -6,6 +6,10 @@ if(APPLE AND NOT appleClangPolicy STREQUAL NEW)
return()
endif()
+if("x${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC")
+ set(CMAKE_C_CLANG_TIDY_DRIVER_MODE "cl")
+endif()
+
if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.4)
if(NOT "x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC")
set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90")
diff --git a/Modules/Compiler/Clang-CXX.cmake b/Modules/Compiler/Clang-CXX.cmake
index 61709f8..789e991 100644
--- a/Modules/Compiler/Clang-CXX.cmake
+++ b/Modules/Compiler/Clang-CXX.cmake
@@ -1,5 +1,6 @@
include(Compiler/Clang)
__compiler_clang(CXX)
+__compiler_clang_cxx_standards(CXX)
if("x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU")
set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
@@ -10,121 +11,6 @@ if(APPLE AND NOT appleClangPolicy STREQUAL NEW)
return()
endif()
-
-if("x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU")
- if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 2.1)
- set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "-std=c++98")
- set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "-std=gnu++98")
- endif()
-
- if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.1)
- set(CMAKE_CXX98_STANDARD__HAS_FULL_SUPPORT ON)
- set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++11")
- set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++11")
- set(CMAKE_CXX11_STANDARD__HAS_FULL_SUPPORT ON)
- elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 2.1)
- set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++0x")
- set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++0x")
- endif()
-
- if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5)
- set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std=c++14")
- set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=gnu++14")
- set(CMAKE_CXX14_STANDARD__HAS_FULL_SUPPORT ON)
- elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4)
- set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std=c++1y")
- set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=gnu++1y")
- set(CMAKE_CXX14_STANDARD__HAS_FULL_SUPPORT ON)
- endif()
-
- set(_clang_version_std17 5.0)
- if(CMAKE_SYSTEM_NAME STREQUAL "Android")
- set(_clang_version_std17 6.0)
- endif()
-
- if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "${_clang_version_std17}")
- set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std=c++17")
- set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std=gnu++17")
- elseif (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5)
- set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std=c++1z")
- set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std=gnu++1z")
- endif()
-
- if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "${_clang_version_std17}")
- set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std=c++2a")
- set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std=gnu++2a")
- endif()
-
- unset(_clang_version_std17)
-
- if("x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
- # The MSVC standard library requires C++14, and MSVC itself has no
- # notion of operating in a mode not aware of at least that standard.
- set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "-std=c++14")
- set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "-std=gnu++14")
- set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++14")
- set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++14")
-
- # This clang++ is missing some features because of MSVC compatibility.
- unset(CMAKE_CXX11_STANDARD__HAS_FULL_SUPPORT)
- unset(CMAKE_CXX14_STANDARD__HAS_FULL_SUPPORT)
- unset(CMAKE_CXX17_STANDARD__HAS_FULL_SUPPORT)
- unset(CMAKE_CXX20_STANDARD__HAS_FULL_SUPPORT)
- endif()
-
- __compiler_check_default_language_standard(CXX 2.1 98)
-elseif(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 3.9
- AND CMAKE_CXX_SIMULATE_VERSION VERSION_GREATER_EQUAL 19.0)
- # This version of clang-cl and the MSVC version it simulates have
- # support for -std: flags.
- set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "")
- set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "")
- set(CMAKE_CXX98_STANDARD__HAS_FULL_SUPPORT ON)
- set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "")
- set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "")
- set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-std:c++14")
- set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std:c++14")
- if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 6.0)
- set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std:c++17")
- set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std:c++17")
- set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std:c++latest")
- set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std:c++latest")
- else()
- set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-std:c++latest")
- set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-std:c++latest")
- endif()
-
- __compiler_check_default_language_standard(CXX 3.9 14)
-else()
- # This version of clang-cl, or the MSVC version it simulates, does not have
- # language standards. Set these options as empty strings so the feature
- # test infrastructure can at least check to see if they are defined.
- set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "")
- set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "")
- set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "")
- set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "")
- set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "")
- set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "")
- set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "")
- set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "")
- set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "")
- set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "")
-
- # There is no meaningful default for this
- set(CMAKE_CXX_STANDARD_DEFAULT "")
-
- # There are no compiler modes so we only need to test features once.
- # Override the default macro for this special case. Pretend that
- # all language standards are available so that at least compilation
- # can be attempted.
- macro(cmake_record_cxx_compile_features)
- list(APPEND CMAKE_CXX_COMPILE_FEATURES
- cxx_std_98
- cxx_std_11
- cxx_std_14
- cxx_std_17
- cxx_std_20
- )
- _record_compiler_features(CXX "" CMAKE_CXX_COMPILE_FEATURES)
- endmacro()
+if("x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC")
+ set(CMAKE_CXX_CLANG_TIDY_DRIVER_MODE "cl")
endif()
diff --git a/Modules/Compiler/Clang-OBJCXX.cmake b/Modules/Compiler/Clang-OBJCXX.cmake
index b01ce64..453b5fd 100644
--- a/Modules/Compiler/Clang-OBJCXX.cmake
+++ b/Modules/Compiler/Clang-OBJCXX.cmake
@@ -1,70 +1,3 @@
include(Compiler/Clang)
__compiler_clang(OBJCXX)
-
-if("x${CMAKE_OBJCXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU")
- if(NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 2.1)
- set(CMAKE_OBJCXX98_STANDARD_COMPILE_OPTION "-std=c++98")
- set(CMAKE_OBJCXX98_EXTENSION_COMPILE_OPTION "-std=gnu++98")
- endif()
-
- if(NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 3.1)
- set(CMAKE_OBJCXX98_STANDARD__HAS_FULL_SUPPORT ON)
- set(CMAKE_OBJCXX11_STANDARD_COMPILE_OPTION "-std=c++11")
- set(CMAKE_OBJCXX11_EXTENSION_COMPILE_OPTION "-std=gnu++11")
- set(CMAKE_OBJCXX11_STANDARD__HAS_FULL_SUPPORT ON)
- elseif(NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 2.1)
- set(CMAKE_OBJCXX11_STANDARD_COMPILE_OPTION "-std=c++0x")
- set(CMAKE_OBJCXX11_EXTENSION_COMPILE_OPTION "-std=gnu++0x")
- endif()
-
- if(NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 3.5)
- set(CMAKE_OBJCXX14_STANDARD_COMPILE_OPTION "-std=c++14")
- set(CMAKE_OBJCXX14_EXTENSION_COMPILE_OPTION "-std=gnu++14")
- set(CMAKE_OBJCXX14_STANDARD__HAS_FULL_SUPPORT ON)
- elseif(NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 3.4)
- set(CMAKE_OBJCXX14_STANDARD_COMPILE_OPTION "-std=c++1y")
- set(CMAKE_OBJCXX14_EXTENSION_COMPILE_OPTION "-std=gnu++1y")
- set(CMAKE_OBJCXX14_STANDARD__HAS_FULL_SUPPORT ON)
- endif()
-
- set(_clang_version_std17 5.0)
-
- if (NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS "${_clang_version_std17}")
- set(CMAKE_OBJCXX17_STANDARD_COMPILE_OPTION "-std=c++17")
- set(CMAKE_OBJCXX17_EXTENSION_COMPILE_OPTION "-std=gnu++17")
- elseif (NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 3.5)
- set(CMAKE_OBJCXX17_STANDARD_COMPILE_OPTION "-std=c++1z")
- set(CMAKE_OBJCXX17_EXTENSION_COMPILE_OPTION "-std=gnu++1z")
- endif()
-
- if (NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS "${_clang_version_std17}")
- set(CMAKE_OBJCXX20_STANDARD_COMPILE_OPTION "-std=c++2a")
- set(CMAKE_OBJCXX20_EXTENSION_COMPILE_OPTION "-std=gnu++2a")
- endif()
-
- unset(_clang_version_std17)
-
- __compiler_check_default_language_standard(OBJCXX 2.1 98)
-elseif(CMAKE_OBJCXX_COMPILER_VERSION VERSION_GREATER_EQUAL 3.9
- AND CMAKE_OBJCXX_SIMULATE_VERSION VERSION_GREATER_EQUAL 19.0)
- # This version of clang-cl and the MSVC version it simulates have
- # support for -std: flags.
- set(CMAKE_OBJCXX98_STANDARD_COMPILE_OPTION "")
- set(CMAKE_OBJCXX98_EXTENSION_COMPILE_OPTION "")
- set(CMAKE_OBJCXX98_STANDARD__HAS_FULL_SUPPORT ON)
- set(CMAKE_OBJCXX11_STANDARD_COMPILE_OPTION "")
- set(CMAKE_OBJCXX11_EXTENSION_COMPILE_OPTION "")
- set(CMAKE_OBJCXX14_STANDARD_COMPILE_OPTION "-std:c++14")
- set(CMAKE_OBJCXX14_EXTENSION_COMPILE_OPTION "-std:c++14")
- if (CMAKE_OBJCXX_COMPILER_VERSION VERSION_GREATER_EQUAL 6.0)
- set(CMAKE_OBJCXX17_STANDARD_COMPILE_OPTION "-std:c++17")
- set(CMAKE_OBJCXX17_EXTENSION_COMPILE_OPTION "-std:c++17")
- set(CMAKE_OBJCXX20_STANDARD_COMPILE_OPTION "-std:c++latest")
- set(CMAKE_OBJCXX20_EXTENSION_COMPILE_OPTION "-std:c++latest")
- else()
- set(CMAKE_OBJCXX17_STANDARD_COMPILE_OPTION "-std:c++latest")
- set(CMAKE_OBJCXX17_EXTENSION_COMPILE_OPTION "-std:c++latest")
- endif()
-
- __compiler_check_default_language_standard(OBJCXX 3.9 14)
-endif()
+__compiler_clang_cxx_standards(OBJCXX)
diff --git a/Modules/Compiler/Clang.cmake b/Modules/Compiler/Clang.cmake
index 5cc9328..cd47aa6 100644
--- a/Modules/Compiler/Clang.cmake
+++ b/Modules/Compiler/Clang.cmake
@@ -101,7 +101,127 @@ else()
if (NOT CMAKE_GENERATOR MATCHES "Xcode")
set(CMAKE_PCH_PROLOGUE "#pragma clang system_header")
endif()
- set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Xclang -include-pch -Xclang <PCH_FILE>)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Xclang -include-pch -Xclang <PCH_FILE> -Xclang -include -Xclang <PCH_HEADER>)
set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Xclang -emit-pch -Xclang -include -Xclang <PCH_HEADER>)
endmacro()
endif()
+
+macro(__compiler_clang_cxx_standards lang)
+ if("x${CMAKE_${lang}_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU")
+ if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 2.1)
+ set(CMAKE_${lang}98_STANDARD_COMPILE_OPTION "-std=c++98")
+ set(CMAKE_${lang}98_EXTENSION_COMPILE_OPTION "-std=gnu++98")
+ endif()
+
+ if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 3.1)
+ set(CMAKE_${lang}98_STANDARD__HAS_FULL_SUPPORT ON)
+ set(CMAKE_${lang}11_STANDARD_COMPILE_OPTION "-std=c++11")
+ set(CMAKE_${lang}11_EXTENSION_COMPILE_OPTION "-std=gnu++11")
+ set(CMAKE_${lang}11_STANDARD__HAS_FULL_SUPPORT ON)
+ elseif(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 2.1)
+ set(CMAKE_${lang}11_STANDARD_COMPILE_OPTION "-std=c++0x")
+ set(CMAKE_${lang}11_EXTENSION_COMPILE_OPTION "-std=gnu++0x")
+ endif()
+
+ if(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 3.5)
+ set(CMAKE_${lang}14_STANDARD_COMPILE_OPTION "-std=c++14")
+ set(CMAKE_${lang}14_EXTENSION_COMPILE_OPTION "-std=gnu++14")
+ set(CMAKE_${lang}14_STANDARD__HAS_FULL_SUPPORT ON)
+ elseif(NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 3.4)
+ set(CMAKE_${lang}14_STANDARD_COMPILE_OPTION "-std=c++1y")
+ set(CMAKE_${lang}14_EXTENSION_COMPILE_OPTION "-std=gnu++1y")
+ set(CMAKE_${lang}14_STANDARD__HAS_FULL_SUPPORT ON)
+ endif()
+
+ set(_clang_version_std17 5.0)
+ if(CMAKE_SYSTEM_NAME STREQUAL "Android")
+ set(_clang_version_std17 6.0)
+ endif()
+
+ if (NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS "${_clang_version_std17}")
+ set(CMAKE_${lang}17_STANDARD_COMPILE_OPTION "-std=c++17")
+ set(CMAKE_${lang}17_EXTENSION_COMPILE_OPTION "-std=gnu++17")
+ elseif (NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 3.5)
+ set(CMAKE_${lang}17_STANDARD_COMPILE_OPTION "-std=c++1z")
+ set(CMAKE_${lang}17_EXTENSION_COMPILE_OPTION "-std=gnu++1z")
+ endif()
+
+ if (NOT CMAKE_${lang}_COMPILER_VERSION VERSION_LESS "${_clang_version_std17}")
+ set(CMAKE_${lang}20_STANDARD_COMPILE_OPTION "-std=c++2a")
+ set(CMAKE_${lang}20_EXTENSION_COMPILE_OPTION "-std=gnu++2a")
+ endif()
+
+ unset(_clang_version_std17)
+
+ if("x${CMAKE_${lang}_SIMULATE_ID}" STREQUAL "xMSVC")
+ # The MSVC standard library requires C++14, and MSVC itself has no
+ # notion of operating in a mode not aware of at least that standard.
+ set(CMAKE_${lang}98_STANDARD_COMPILE_OPTION "-std=c++14")
+ set(CMAKE_${lang}98_EXTENSION_COMPILE_OPTION "-std=gnu++14")
+ set(CMAKE_${lang}11_STANDARD_COMPILE_OPTION "-std=c++14")
+ set(CMAKE_${lang}11_EXTENSION_COMPILE_OPTION "-std=gnu++14")
+
+ # This clang++ is missing some features because of MSVC compatibility.
+ unset(CMAKE_${lang}11_STANDARD__HAS_FULL_SUPPORT)
+ unset(CMAKE_${lang}14_STANDARD__HAS_FULL_SUPPORT)
+ unset(CMAKE_${lang}17_STANDARD__HAS_FULL_SUPPORT)
+ unset(CMAKE_${lang}20_STANDARD__HAS_FULL_SUPPORT)
+ endif()
+
+ __compiler_check_default_language_standard(${lang} 2.1 98)
+ elseif(CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL 3.9
+ AND CMAKE_${lang}_SIMULATE_VERSION VERSION_GREATER_EQUAL 19.0)
+ # This version of clang-cl and the MSVC version it simulates have
+ # support for -std: flags.
+ set(CMAKE_${lang}98_STANDARD_COMPILE_OPTION "")
+ set(CMAKE_${lang}98_EXTENSION_COMPILE_OPTION "")
+ set(CMAKE_${lang}98_STANDARD__HAS_FULL_SUPPORT ON)
+ set(CMAKE_${lang}11_STANDARD_COMPILE_OPTION "")
+ set(CMAKE_${lang}11_EXTENSION_COMPILE_OPTION "")
+ set(CMAKE_${lang}14_STANDARD_COMPILE_OPTION "-std:c++14")
+ set(CMAKE_${lang}14_EXTENSION_COMPILE_OPTION "-std:c++14")
+ if (CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL 6.0)
+ set(CMAKE_${lang}17_STANDARD_COMPILE_OPTION "-std:c++17")
+ set(CMAKE_${lang}17_EXTENSION_COMPILE_OPTION "-std:c++17")
+ set(CMAKE_${lang}20_STANDARD_COMPILE_OPTION "-std:c++latest")
+ set(CMAKE_${lang}20_EXTENSION_COMPILE_OPTION "-std:c++latest")
+ else()
+ set(CMAKE_${lang}17_STANDARD_COMPILE_OPTION "-std:c++latest")
+ set(CMAKE_${lang}17_EXTENSION_COMPILE_OPTION "-std:c++latest")
+ endif()
+
+ __compiler_check_default_language_standard(${lang} 3.9 14)
+ else()
+ # This version of clang-cl, or the MSVC version it simulates, does not have
+ # language standards. Set these options as empty strings so the feature
+ # test infrastructure can at least check to see if they are defined.
+ set(CMAKE_${lang}98_STANDARD_COMPILE_OPTION "")
+ set(CMAKE_${lang}98_EXTENSION_COMPILE_OPTION "")
+ set(CMAKE_${lang}11_STANDARD_COMPILE_OPTION "")
+ set(CMAKE_${lang}11_EXTENSION_COMPILE_OPTION "")
+ set(CMAKE_${lang}14_STANDARD_COMPILE_OPTION "")
+ set(CMAKE_${lang}14_EXTENSION_COMPILE_OPTION "")
+ set(CMAKE_${lang}17_STANDARD_COMPILE_OPTION "")
+ set(CMAKE_${lang}17_EXTENSION_COMPILE_OPTION "")
+ set(CMAKE_${lang}20_STANDARD_COMPILE_OPTION "")
+ set(CMAKE_${lang}20_EXTENSION_COMPILE_OPTION "")
+
+ # There is no meaningful default for this
+ set(CMAKE_${lang}_STANDARD_DEFAULT "")
+
+ # There are no compiler modes so we only need to test features once.
+ # Override the default macro for this special case. Pretend that
+ # all language standards are available so that at least compilation
+ # can be attempted.
+ macro(cmake_record_${lang}_compile_features)
+ list(APPEND CMAKE_${lang}_COMPILE_FEATURES
+ ${lang}_std_98
+ ${lang}_std_11
+ ${lang}_std_14
+ ${lang}_std_17
+ ${lang}_std_20
+ )
+ _record_compiler_features(${lang} "" CMAKE_${lang}_COMPILE_FEATURES)
+ endmacro()
+ endif()
+endmacro()
diff --git a/Modules/Compiler/GNU-ASM.cmake b/Modules/Compiler/GNU-ASM.cmake
index e07401d..3daa57d 100644
--- a/Modules/Compiler/GNU-ASM.cmake
+++ b/Modules/Compiler/GNU-ASM.cmake
@@ -4,3 +4,9 @@ include(Compiler/GNU)
set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS s;S;asm)
__compiler_gnu(ASM)
+
+if(CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_MATCH STREQUAL "GNU assembler")
+ set(CMAKE_DEPFILE_FLAGS_ASM${ASM_DIALECT} "--MD <DEPFILE>")
+ set(CMAKE_ASM${ASM_DIALECT}_LINK_EXECUTABLE
+ "<CMAKE_LINKER> <FLAGS> <CMAKE_ASM${ASM_DIALECT}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
+endif()
diff --git a/Modules/Compiler/GNU.cmake b/Modules/Compiler/GNU.cmake
index 1c050a2..df6d6b8 100644
--- a/Modules/Compiler/GNU.cmake
+++ b/Modules/Compiler/GNU.cmake
@@ -44,7 +44,8 @@ macro(__compiler_gnu lang)
# tests to always succeed. Work around this by disabling dependency tracking
# in try_compile mode.
get_property(_IN_TC GLOBAL PROPERTY IN_TRY_COMPILE)
- if(NOT _IN_TC OR CMAKE_FORCE_DEPFILES)
+ if(CMAKE_${lang}_COMPILER_ID STREQUAL "GNU" AND _IN_TC AND NOT CMAKE_FORCE_DEPFILES)
+ else()
# distcc does not transform -o to -MT when invoking the preprocessor
# internally, as it ought to. Work around this bug by setting -MT here
# even though it isn't strictly necessary.
@@ -114,6 +115,7 @@ macro(__compiler_gnu lang)
if (NOT CMAKE_GENERATOR MATCHES "Xcode")
set(CMAKE_PCH_PROLOGUE "#pragma GCC system_header")
endif()
- set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Winvalid-pch -include <PCH_HEADER>)
- set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Winvalid-pch -x ${__pch_header_${lang}} -include <PCH_HEADER>)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_INVALID_PCH -Winvalid-pch)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -include <PCH_HEADER>)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -x ${__pch_header_${lang}} -include <PCH_HEADER>)
endmacro()
diff --git a/Modules/Compiler/Intel-C.cmake b/Modules/Compiler/Intel-C.cmake
index e9e59a2..ec3bfd8 100644
--- a/Modules/Compiler/Intel-C.cmake
+++ b/Modules/Compiler/Intel-C.cmake
@@ -9,6 +9,8 @@ set(CMAKE_DEPFILE_FLAGS_C "-MD -MT <OBJECT> -MF <DEPFILE>")
if("x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC")
+ set(CMAKE_C_CLANG_TIDY_DRIVER_MODE "cl")
+
if (NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 16.0.0)
set(CMAKE_C11_STANDARD_COMPILE_OPTION "-Qstd=c11")
set(CMAKE_C11_EXTENSION_COMPILE_OPTION "-Qstd=c11")
diff --git a/Modules/Compiler/Intel-CXX.cmake b/Modules/Compiler/Intel-CXX.cmake
index b630a6b..1ed1b08 100644
--- a/Modules/Compiler/Intel-CXX.cmake
+++ b/Modules/Compiler/Intel-CXX.cmake
@@ -9,6 +9,8 @@ set(CMAKE_DEPFILE_FLAGS_CXX "-MD -MT <OBJECT> -MF <DEPFILE>")
if("x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
+ set(CMAKE_CXX_CLANG_TIDY_DRIVER_MODE "cl")
+
if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 18.0.0)
set(CMAKE_CXX17_STANDARD_COMPILE_OPTION "-Qstd=c++17")
set(CMAKE_CXX17_EXTENSION_COMPILE_OPTION "-Qstd=c++17")
diff --git a/Modules/Compiler/Intel.cmake b/Modules/Compiler/Intel.cmake
index d895ed0..63a20af 100644
--- a/Modules/Compiler/Intel.cmake
+++ b/Modules/Compiler/Intel.cmake
@@ -37,7 +37,8 @@ else()
set(CMAKE_PCH_EXTENSION .pchi)
set(CMAKE_LINK_PCH ON)
set(CMAKE_PCH_EPILOGUE "#pragma hdrstop")
- set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Winvalid-pch -Wno-pch-messages -pch-use <PCH_FILE> -include <PCH_HEADER>)
- set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Winvalid-pch -Wno-pch-messages -pch-create <PCH_FILE> -include <PCH_HEADER>)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_INVALID_PCH -Winvalid-pch)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Wno-pch-messages -pch-use <PCH_FILE> -include <PCH_HEADER>)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Wno-pch-messages -pch-create <PCH_FILE> -include <PCH_HEADER>)
endmacro()
endif()
diff --git a/Modules/Compiler/MSVC-C.cmake b/Modules/Compiler/MSVC-C.cmake
index 20787a3..bca9764 100644
--- a/Modules/Compiler/MSVC-C.cmake
+++ b/Modules/Compiler/MSVC-C.cmake
@@ -11,6 +11,8 @@ set(CMAKE_C11_EXTENSION_COMPILE_OPTION "")
# There is no meaningful default for this
set(CMAKE_C_STANDARD_DEFAULT "")
+set(CMAKE_C_CLANG_TIDY_DRIVER_MODE "cl")
+
# There are no C compiler modes so we hard-code the known compiler supported
# features. Override the default macro for this special case. Pretend that
# all language standards are available so that at least compilation
diff --git a/Modules/Compiler/MSVC-CXX.cmake b/Modules/Compiler/MSVC-CXX.cmake
index 915295d..1dfc760 100644
--- a/Modules/Compiler/MSVC-CXX.cmake
+++ b/Modules/Compiler/MSVC-CXX.cmake
@@ -3,6 +3,8 @@
include(Compiler/CMakeCommonCompilerMacros)
+set(CMAKE_CXX_CLANG_TIDY_DRIVER_MODE "cl")
+
if ((CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.0.24215.1 AND
CMAKE_CXX_COMPILER_VERSION VERSION_LESS 19.10) OR
CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.10.25017)
diff --git a/Modules/Compiler/NAG-Fortran.cmake b/Modules/Compiler/NAG-Fortran.cmake
index edc56fd..2111c65 100644
--- a/Modules/Compiler/NAG-Fortran.cmake
+++ b/Modules/Compiler/NAG-Fortran.cmake
@@ -1,6 +1,6 @@
# Help CMAKE_PARSE_IMPLICIT_LINK_INFO detect NAG Fortran object files.
if(NOT CMAKE_Fortran_COMPILER_WORKS AND NOT CMAKE_Fortran_COMPILER_FORCED)
- message(STATUS "Detecting NAG Fortran directory")
+ message(CHECK_START "Detecting NAG Fortran directory")
# Run with -dryrun to see sample "link" line.
execute_process(
COMMAND ${CMAKE_Fortran_COMPILER} dummy.o -dryrun
@@ -20,11 +20,11 @@ if(NOT CMAKE_Fortran_COMPILER_WORKS AND NOT CMAKE_Fortran_COMPILER_FORCED)
" directory: ${_nag_dir}\n"
" regex: ${CMAKE_Fortran_IMPLICIT_OBJECT_REGEX}\n"
"from output:\n${_dryrun}\n\n")
- message(STATUS "Detecting NAG Fortran directory - ${_nag_dir}")
+ message(CHECK_PASS "${_nag_dir}")
else()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Detecting NAG Fortran directory with -dryrun failed:\n${_dryrun}\n\n")
- message(STATUS "Detecting NAG Fortran directory - failed")
+ message(CHECK_FAIL "failed")
endif()
endif()
diff --git a/Modules/Compiler/NVIDIA-CUDA.cmake b/Modules/Compiler/NVIDIA-CUDA.cmake
index ae40100..4b09e6f 100644
--- a/Modules/Compiler/NVIDIA-CUDA.cmake
+++ b/Modules/Compiler/NVIDIA-CUDA.cmake
@@ -1,7 +1,35 @@
+include(Compiler/CMakeCommonCompilerMacros)
+
set(CMAKE_CUDA_COMPILER_HAS_DEVICE_LINK_PHASE True)
set(CMAKE_CUDA_VERBOSE_FLAG "-v")
set(CMAKE_CUDA_VERBOSE_COMPILE_FLAG "-Xcompiler=-v")
+set(_CMAKE_COMPILE_AS_CUDA_FLAG "-x cu")
+set(_CMAKE_CUDA_PTX_FLAG "-ptx")
+
+if (CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 10.2.89)
+ # The -forward-unknown-to-host-compiler flag was only
+ # added to nvcc in 10.2 so before that we had no good
+ # way to invoke the CUDA compiler and propagate unknown
+ # flags such as -pthread to the host compiler
+ set(_CMAKE_CUDA_EXTRA_FLAGS "-forward-unknown-to-host-compiler")
+else()
+ set(_CMAKE_CUDA_EXTRA_FLAGS "")
+endif()
+
+if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "8.0.0")
+ set(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS "-Wno-deprecated-gpu-targets")
+else()
+ set(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS "")
+endif()
+
+if (CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 10.2.89)
+ # The -MD flag was only added to nvcc in 10.2 so
+ # before that we had to invoke the compiler twice
+ # to get header dependency information
+ set(CMAKE_DEPFILE_FLAGS_CUDA "-MD -MT <OBJECT> -MF <DEPFILE>")
+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)
@@ -18,18 +46,45 @@ endif()
set(CMAKE_SHARED_LIBRARY_CREATE_CUDA_FLAGS -shared)
set(CMAKE_INCLUDE_SYSTEM_FLAG_CUDA -isystem=)
+if (CMAKE_CUDA_SIMULATE_ID STREQUAL "GNU")
+ set(CMAKE_CUDA_LINKER_WRAPPER_FLAG "-Wl,")
+ set(CMAKE_CUDA_LINKER_WRAPPER_FLAG_SEP ",")
+elseif(CMAKE_CUDA_SIMULATE_ID STREQUAL "Clang")
+ set(CMAKE_CUDA_LINKER_WRAPPER_FLAG "-Xlinker" " ")
+ set(CMAKE_CUDA_LINKER_WRAPPER_FLAG_SEP)
+endif()
+
+set(CMAKE_CUDA_DEVICE_COMPILER_WRAPPER_FLAG "-Xcompiler=")
+set(CMAKE_CUDA_DEVICE_COMPILER_WRAPPER_FLAG_SEP ",")
+set(CMAKE_CUDA_DEVICE_LINKER_WRAPPER_FLAG "-Xlinker=")
+set(CMAKE_CUDA_DEVICE_LINKER_WRAPPER_FLAG_SEP ",")
+
+set(CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT "STATIC")
+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 "")
+
if("x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC")
- set(CMAKE_CUDA_STANDARD_DEFAULT "")
+ set(CMAKE_CUDA03_STANDARD_COMPILE_OPTION "")
+ set(CMAKE_CUDA03_EXTENSION_COMPILE_OPTION "")
+
+ set(CMAKE_CUDA11_STANDARD_COMPILE_OPTION "")
+ set(CMAKE_CUDA11_EXTENSION_COMPILE_OPTION "")
+
+ if (NOT CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 9.0)
+ set(CMAKE_CUDA14_STANDARD_COMPILE_OPTION "")
+ set(CMAKE_CUDA14_EXTENSION_COMPILE_OPTION "")
+ endif()
else()
- set(CMAKE_CUDA_STANDARD_DEFAULT 98)
- set(CMAKE_CUDA98_STANDARD_COMPILE_OPTION "")
- set(CMAKE_CUDA98_EXTENSION_COMPILE_OPTION "")
+ set(CMAKE_CUDA03_STANDARD_COMPILE_OPTION "")
+ set(CMAKE_CUDA03_EXTENSION_COMPILE_OPTION "")
+
set(CMAKE_CUDA11_STANDARD_COMPILE_OPTION "-std=c++11")
set(CMAKE_CUDA11_EXTENSION_COMPILE_OPTION "-std=c++11")
if (NOT CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 9.0)
- set(CMAKE_CUDA98_STANDARD_COMPILE_OPTION "-std=c++03")
- set(CMAKE_CUDA98_EXTENSION_COMPILE_OPTION "-std=c++03")
+ set(CMAKE_CUDA03_STANDARD_COMPILE_OPTION "-std=c++03")
+ set(CMAKE_CUDA03_EXTENSION_COMPILE_OPTION "-std=c++03")
set(CMAKE_CUDA14_STANDARD_COMPILE_OPTION "-std=c++14")
set(CMAKE_CUDA14_EXTENSION_COMPILE_OPTION "-std=c++14")
endif()
@@ -46,3 +101,5 @@ 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()
+
+__compiler_check_default_language_standard(CUDA 6.0 03)
diff --git a/Modules/Compiler/NVIDIA-DetermineCompiler.cmake b/Modules/Compiler/NVIDIA-DetermineCompiler.cmake
index bf9111a..4f6ddc2 100644
--- a/Modules/Compiler/NVIDIA-DetermineCompiler.cmake
+++ b/Modules/Compiler/NVIDIA-DetermineCompiler.cmake
@@ -11,9 +11,19 @@ set(_compiler_id_version_compute "
/* _MSC_VER = VVRR */
# define @PREFIX@SIMULATE_VERSION_MAJOR @MACRO_DEC@(_MSC_VER / 100)
# define @PREFIX@SIMULATE_VERSION_MINOR @MACRO_DEC@(_MSC_VER % 100)
+# elif defined(__clang__)
+# define @PREFIX@SIMULATE_VERSION_MAJOR @MACRO_DEC@(__clang_major__)
+# define @PREFIX@SIMULATE_VERSION_MINOR @MACRO_DEC@(__clang_minor__)
+# elif defined(__GNUC__)
+# define @PREFIX@SIMULATE_VERSION_MAJOR @MACRO_DEC@(__GNUC__)
+# define @PREFIX@SIMULATE_VERSION_MINOR @MACRO_DEC@(__GNUC_MINOR__)
# endif")
set(_compiler_id_simulate "
# if defined(_MSC_VER)
# define @PREFIX@SIMULATE_ID \"MSVC\"
+# elif defined(__clang__)
+# define @PREFIX@SIMULATE_ID \"Clang\"
+# elif defined(__GNUC__)
+# define @PREFIX@SIMULATE_ID \"GNU\"
# endif")
diff --git a/Modules/Compiler/OpenWatcom-C.cmake b/Modules/Compiler/OpenWatcom-C.cmake
new file mode 100644
index 0000000..19e3359
--- /dev/null
+++ b/Modules/Compiler/OpenWatcom-C.cmake
@@ -0,0 +1 @@
+include(Compiler/OpenWatcom)
diff --git a/Modules/Compiler/OpenWatcom-CXX.cmake b/Modules/Compiler/OpenWatcom-CXX.cmake
new file mode 100644
index 0000000..19e3359
--- /dev/null
+++ b/Modules/Compiler/OpenWatcom-CXX.cmake
@@ -0,0 +1 @@
+include(Compiler/OpenWatcom)
diff --git a/Modules/Compiler/OpenWatcom.cmake b/Modules/Compiler/OpenWatcom.cmake
new file mode 100644
index 0000000..9efbfc2
--- /dev/null
+++ b/Modules/Compiler/OpenWatcom.cmake
@@ -0,0 +1,118 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+# This module is shared by multiple languages; use include blocker.
+include_guard()
+
+set(CMAKE_LIBRARY_PATH_FLAG "libpath ")
+set(CMAKE_LINK_LIBRARY_FLAG "library ")
+set(CMAKE_LINK_LIBRARY_FILE_FLAG "library ")
+
+if(CMAKE_VERBOSE_MAKEFILE)
+ set(CMAKE_WCL_QUIET)
+ set(CMAKE_WLINK_QUIET)
+ set(CMAKE_LIB_QUIET)
+else()
+ set(CMAKE_WCL_QUIET "-zq")
+ set(CMAKE_WLINK_QUIET "option quiet")
+ set(CMAKE_LIB_QUIET "-q")
+endif()
+
+foreach(type CREATE_SHARED_LIBRARY CREATE_SHARED_MODULE LINK_EXECUTABLE)
+ set(CMAKE_C_${type}_USE_WATCOM_QUOTE 1)
+ set(CMAKE_CXX_${type}_USE_WATCOM_QUOTE 1)
+endforeach()
+
+foreach(type SHARED MODULE EXE)
+ # linker map file creation directives
+ string(APPEND CMAKE_${type}_LINKER_FLAGS_INIT " opt map")
+ # linker debug directives
+ string(APPEND CMAKE_${type}_LINKER_FLAGS_DEBUG_INIT " debug all")
+ string(APPEND CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO_INIT " debug all")
+endforeach()
+
+foreach(lang C CXX)
+ # warning level
+ string(APPEND CMAKE_${lang}_FLAGS_INIT " -w3")
+ # debug options
+ string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT " -d2")
+ string(APPEND CMAKE_${lang}_FLAGS_MINSIZEREL_INIT " -s -os -d0 -dNDEBUG")
+ string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT " -s -ot -d0 -dNDEBUG")
+ string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT " -s -ot -d1 -dNDEBUG")
+endforeach()
+
+# C create import library
+set(CMAKE_C_CREATE_IMPORT_LIBRARY
+ "wlib -c -q -n -b <TARGET_IMPLIB> +<TARGET_QUOTED>")
+# C++ create import library
+set(CMAKE_CXX_CREATE_IMPORT_LIBRARY ${CMAKE_C_CREATE_IMPORT_LIBRARY})
+
+# C link a object files into an executable file
+set(CMAKE_C_LINK_EXECUTABLE
+ "wlink ${CMAKE_WLINK_QUIET} name <TARGET> <LINK_FLAGS> file {<OBJECTS>} <LINK_LIBRARIES>")
+# C++ link a object files into an executable file
+set(CMAKE_CXX_LINK_EXECUTABLE ${CMAKE_C_LINK_EXECUTABLE})
+
+# C compile a file into an object file
+set(CMAKE_C_COMPILE_OBJECT
+ "<CMAKE_C_COMPILER> ${CMAKE_WCL_QUIET} -d+ <DEFINES> <INCLUDES> <FLAGS> -fo<OBJECT> -c -cc <SOURCE>")
+# C++ compile a file into an object file
+set(CMAKE_CXX_COMPILE_OBJECT
+ "<CMAKE_CXX_COMPILER> ${CMAKE_WCL_QUIET} -d+ <DEFINES> <INCLUDES> <FLAGS> -fo<OBJECT> -c -cc++ <SOURCE>")
+
+# C preprocess a source file
+set(CMAKE_C_CREATE_PREPROCESSED_SOURCE
+ "<CMAKE_C_COMPILER> ${CMAKE_WCL_QUIET} -d+ <DEFINES> <INCLUDES> <FLAGS> -fo<PREPROCESSED_SOURCE> -pl -cc <SOURCE>")
+# C++ preprocess a source file
+set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE
+ "<CMAKE_CXX_COMPILER> ${CMAKE_WCL_QUIET} -d+ <DEFINES> <INCLUDES> <FLAGS> -fo<PREPROCESSED_SOURCE> -pl -cc++ <SOURCE>")
+
+# C create a shared library
+set(CMAKE_C_CREATE_SHARED_LIBRARY
+ "wlink ${CMAKE_WLINK_QUIET} name <TARGET> <LINK_FLAGS> option implib=<TARGET_IMPLIB> file {<OBJECTS>} <LINK_LIBRARIES>")
+# C++ create a shared library
+set(CMAKE_CXX_CREATE_SHARED_LIBRARY ${CMAKE_C_CREATE_SHARED_LIBRARY})
+
+# C create a shared module
+set(CMAKE_C_CREATE_SHARED_MODULE
+ "wlink ${CMAKE_WLINK_QUIET} name <TARGET> <LINK_FLAGS> file {<OBJECTS>} <LINK_LIBRARIES>")
+# C++ create a shared module
+set(CMAKE_CXX_CREATE_SHARED_MODULE ${CMAKE_C_CREATE_SHARED_MODULE})
+
+# C create a static library
+set(CMAKE_C_CREATE_STATIC_LIBRARY
+ "wlib ${CMAKE_LIB_QUIET} -c -n -b <TARGET_QUOTED> <LINK_FLAGS> <OBJECTS> ")
+# C++ create a static library
+set(CMAKE_CXX_CREATE_STATIC_LIBRARY ${CMAKE_C_CREATE_STATIC_LIBRARY})
+
+
+# old CMake internaly used OpenWatcom version macros
+# for backward compatibility
+if(NOT _CMAKE_WATCOM_VERSION)
+ set(_CMAKE_WATCOM_VERSION 1)
+ if(CMAKE_C_COMPILER_VERSION)
+ set(_compiler_version ${CMAKE_C_COMPILER_VERSION})
+ set(_compiler_id ${CMAKE_C_COMPILER_ID})
+ else()
+ set(_compiler_version ${CMAKE_CXX_COMPILER_VERSION})
+ set(_compiler_id ${CMAKE_CXX_COMPILER_ID})
+ endif()
+ set(WATCOM16)
+ set(WATCOM17)
+ set(WATCOM18)
+ set(WATCOM19)
+ if("${_compiler_id}" STREQUAL "OpenWatcom")
+ if("${_compiler_version}" VERSION_LESS 1.7)
+ set(WATCOM16 1)
+ endif()
+ if("${_compiler_version}" VERSION_EQUAL 1.7)
+ set(WATCOM17 1)
+ endif()
+ if("${_compiler_version}" VERSION_EQUAL 1.8)
+ set(WATCOM18 1)
+ endif()
+ if("${_compiler_version}" VERSION_EQUAL 1.9)
+ set(WATCOM19 1)
+ endif()
+ endif()
+endif()
diff --git a/Modules/Compiler/QCC-CXX.cmake b/Modules/Compiler/QCC-CXX.cmake
index 0e7314a..42303f4 100644
--- a/Modules/Compiler/QCC-CXX.cmake
+++ b/Modules/Compiler/QCC-CXX.cmake
@@ -10,6 +10,6 @@ set(CMAKE_CXX_COMPILE_OBJECT
"<CMAKE_CXX_COMPILER> -lang-c++ <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
set(CMAKE_CXX_LINK_EXECUTABLE
- "<CMAKE_CXX_COMPILER> -lang-c++ <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
+ "<CMAKE_CXX_COMPILER> -lang-c++ <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
diff --git a/Modules/Compiler/QCC.cmake b/Modules/Compiler/QCC.cmake
index 9df8269..10e1389 100644
--- a/Modules/Compiler/QCC.cmake
+++ b/Modules/Compiler/QCC.cmake
@@ -10,6 +10,9 @@ macro(__compiler_qcc lang)
# http://www.qnx.com/developers/docs/6.4.0/neutrino/utilities/q/qcc.html#examples
set(CMAKE_${lang}_COMPILE_OPTIONS_TARGET "-V")
+ set(CMAKE_PREFIX_LIBRARY_ARCHITECTURE "ON")
+
+ set(CMAKE_${lang}_COMPILE_OPTIONS_SYSROOT "-Wc,-isysroot,")
set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-Wp,-isystem,")
set(CMAKE_DEPFILE_FLAGS_${lang} "-Wp,-MD,<DEPFILE> -Wp,-MT,<OBJECT> -Wp,-MF,<DEPFILE>")
diff --git a/Modules/Compiler/TI-C.cmake b/Modules/Compiler/TI-C.cmake
index 1c0f4bc..b060ee9 100644
--- a/Modules/Compiler/TI-C.cmake
+++ b/Modules/Compiler/TI-C.cmake
@@ -14,5 +14,9 @@ set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> --compile_only --skip_ass
set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> --preproc_only --c_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<PREPROCESSED_SOURCE>")
set(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER> --compile_only --c_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<OBJECT>")
-set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> -r <TARGET> <OBJECTS>")
-set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> --run_linker --output_file=<TARGET> --map_file=<TARGET>.map <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES>")
+set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> qr <TARGET> <OBJECTS>")
+set(CMAKE_C_ARCHIVE_APPEND "<CMAKE_AR> qa <TARGET> <OBJECTS>")
+set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> --run_linker --output_file=<TARGET> --map_file=<TARGET_NAME>.map <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES>")
+set(CMAKE_ASM_RESPONSE_FILE_FLAG "--cmd_file=")
+set(CMAKE_C_RESPONSE_FILE_FLAG "--cmd_file=")
+set(CMAKE_C_RESPONSE_FILE_LINK_FLAG " ")
diff --git a/Modules/Compiler/TI-CXX.cmake b/Modules/Compiler/TI-CXX.cmake
index 4c6af06..7836543 100644
--- a/Modules/Compiler/TI-CXX.cmake
+++ b/Modules/Compiler/TI-CXX.cmake
@@ -8,5 +8,8 @@ set(CMAKE_CXX_CREATE_ASSEMBLY_SOURCE "<CMAKE_CXX_COMPILER> --compile_only --skip
set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE "<CMAKE_CXX_COMPILER> --preproc_only --cpp_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<PREPROCESSED_SOURCE>")
set(CMAKE_CXX_COMPILE_OBJECT "<CMAKE_CXX_COMPILER> --compile_only --cpp_file=<SOURCE> <DEFINES> <INCLUDES> <FLAGS> --output_file=<OBJECT>")
-set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> -r <TARGET> <OBJECTS>")
-set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> --run_linker --output_file=<TARGET> --map_file=<TARGET>.map <CMAKE_CXX_LINK_FLAGS> <LINK_LIBRARIES> <LINK_FLAGS> <OBJECTS>")
+set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> qr <TARGET> <OBJECTS>")
+set(CMAKE_CXX_ARCHIVE_APPEND "<CMAKE_AR> qa <TARGET> <OBJECTS>")
+set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> --run_linker --output_file=<TARGET> --map_file=<TARGET_NAME>.map <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES>")
+set(CMAKE_CXX_RESPONSE_FILE_FLAG "--cmd_file=")
+set(CMAKE_CXX_RESPONSE_FILE_LINK_FLAG " ")
diff --git a/Modules/Compiler/XL-CXX.cmake b/Modules/Compiler/XL-CXX.cmake
index 3037851..41e3e11 100644
--- a/Modules/Compiler/XL-CXX.cmake
+++ b/Modules/Compiler/XL-CXX.cmake
@@ -17,8 +17,14 @@ if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 10.1)
set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-qlanglvl=extended0x")
set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-qlanglvl=extended0x")
set(CMAKE_CXX98_STANDARD__HAS_FULL_SUPPORT ON)
+
+ # XL does not really have full C++11 or C++14 support, but since we do not
+ # have a granular XL-CXX-FeatureTests table for it just pretend it does.
+ # This way projects that specify granular features will at least get a
+ # compiler mode for the corresponding standard.
set(CMAKE_CXX11_STANDARD__HAS_FULL_SUPPORT ON)
- if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 16.1.0)
+
+ if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 16.1.0 AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(CMAKE_CXX14_STANDARD_COMPILE_OPTION "-qlanglvl=extended1y")
set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-qlanglvl=extended1y")
set(CMAKE_CXX14_STANDARD__HAS_FULL_SUPPORT ON)
diff --git a/Modules/Compiler/XL-Fortran.cmake b/Modules/Compiler/XL-Fortran.cmake
index c4fb097..e01ec8e 100644
--- a/Modules/Compiler/XL-Fortran.cmake
+++ b/Modules/Compiler/XL-Fortran.cmake
@@ -8,6 +8,7 @@ set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-qfixed") # [=<right_margin>]
set(CMAKE_Fortran_FORMAT_FREE_FLAG "-qfree") # [=f90|ibm]
set(CMAKE_Fortran_MODDIR_FLAG "-qmoddir=")
+set(CMAKE_Fortran_MODDIR_INCLUDE_FLAG "-I") # -qmoddir= does not affect search path
set(CMAKE_Fortran_DEFINE_FLAG "-WF,-D")
@@ -18,3 +19,7 @@ string(APPEND CMAKE_Fortran_FLAGS_INIT " -qthreaded -qhalt=e")
# xlf: 1501-214 (W) command option E reserved for future use - ignored
set(CMAKE_Fortran_CREATE_PREPROCESSED_SOURCE)
set(CMAKE_Fortran_CREATE_ASSEMBLY_SOURCE)
+
+set(CMAKE_Fortran_PREPROCESS_SOURCE
+ "<CMAKE_Fortran_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -qpreprocess -qnoobject -qsuppress=1517-020 -tF -B \"${CMAKE_CURRENT_LIST_DIR}/XL-Fortran/\" -WF,--cpp,\"${CMAKE_Fortran_XL_CPP}\",--out,<PREPROCESSED_SOURCE> <SOURCE>"
+ )
diff --git a/Modules/Compiler/XL-Fortran/cpp b/Modules/Compiler/XL-Fortran/cpp
new file mode 100755
index 0000000..1fd62c2
--- /dev/null
+++ b/Modules/Compiler/XL-Fortran/cpp
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+
+# Source file.
+src="$(printf %q "$1")"
+shift
+
+# Output file the compiler expects.
+out="$(printf %q "$1")"
+shift
+
+# Create the file the compiler expects. It will check syntax.
+>"$out"
+
+cpp='cpp'
+opts=''
+while test "$#" != 0; do
+ case "$1" in
+ # Extract the option for the path to cpp.
+ --cpp) shift; cpp="$(printf %q "$1")" ;;
+ # Extract the option for our own output file.
+ --out) shift; out="$(printf %q "$1")" ;;
+ # Collect the rest of the command line.
+ *) opts="$opts $(printf %q "$1")" ;;
+ esac
+ shift
+done
+
+# Execute the real preprocessor tool.
+eval "exec $cpp $src $out $opts"
diff --git a/Modules/CompilerId/VS-10.vcxproj.in b/Modules/CompilerId/VS-10.vcxproj.in
index d742274..b48a332 100644
--- a/Modules/CompilerId/VS-10.vcxproj.in
+++ b/Modules/CompilerId/VS-10.vcxproj.in
@@ -15,6 +15,8 @@
@id_WindowsTargetPlatformVersion@
@id_WindowsSDKDesktopARMSupport@
@id_CudaToolkitCustomDir@
+ @id_ToolsetVCTargetsDir@
+ @id_CustomGlobals@
</PropertyGroup>
@id_toolset_version_props@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
diff --git a/Modules/DartConfiguration.tcl.in b/Modules/DartConfiguration.tcl.in
index e4513b3..086ba07 100644
--- a/Modules/DartConfiguration.tcl.in
+++ b/Modules/DartConfiguration.tcl.in
@@ -69,6 +69,8 @@ CompilerVersion: @CMAKE_CXX_COMPILER_VERSION@
PurifyCommand: @PURIFYCOMMAND@
ValgrindCommand: @VALGRIND_COMMAND@
ValgrindCommandOptions: @VALGRIND_COMMAND_OPTIONS@
+DrMemoryCommand: @DRMEMORY_COMMAND@
+DrMemoryCommandOptions: @DRMEMORY_COMMAND_OPTIONS@
MemoryCheckType: @MEMORYCHECK_TYPE@
MemoryCheckSanitizerOptions: @MEMORYCHECK_SANITIZER_OPTIONS@
MemoryCheckCommand: @MEMORYCHECK_COMMAND@
diff --git a/Modules/DeployQt4.cmake b/Modules/DeployQt4.cmake
index 4a18927..9aa4383 100644
--- a/Modules/DeployQt4.cmake
+++ b/Modules/DeployQt4.cmake
@@ -106,7 +106,6 @@ and plugin installation. See documentation of FIXUP_QT4_BUNDLE.
# The functions defined in this file depend on the fixup_bundle function
# (and others) found in BundleUtilities.cmake
-set(DeployQt4_cmake_dir "${CMAKE_CURRENT_LIST_DIR}")
set(DeployQt4_apple_plugins_dir "PlugIns")
function(write_qt4_conf qt_conf_dir qt_conf_contents)
@@ -392,7 +391,7 @@ function(install_qt4_executable executable)
resolve_qt4_paths(libs "")
install(CODE
-"include(\"${DeployQt4_cmake_dir}/DeployQt4.cmake\")
+"include(\"${CMAKE_CURRENT_FUNCTION_LIST_DIR}/DeployQt4.cmake\")
set(BU_CHMOD_BUNDLE_ITEMS TRUE)
FIXUP_QT4_EXECUTABLE(\"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${executable}\" \"\" \"${libs}\" \"${dirs}\" \"${plugins_dir}\" \"${request_qt_conf}\")"
${component}
diff --git a/Modules/Documentation.cmake b/Modules/Documentation.cmake
index aaf24f6..c297231 100644
--- a/Modules/Documentation.cmake
+++ b/Modules/Documentation.cmake
@@ -9,6 +9,30 @@ This module provides support for the VTK documentation framework. It
relies on several tools (Doxygen, Perl, etc).
#]=======================================================================]
+cmake_policy(GET CMP0106 _Documentation_policy)
+
+if (_Documentation_policy STREQUAL "NEW")
+ message(FATAL_ERROR
+ "Documentation.cmake is VTK-specific code and should not be used in "
+ "non-VTK projects. This logic in this module is best shipped with the "
+ "project using it rather than with CMake. This is now an error according "
+ "to policy CMP0106.")
+else ()
+
+if (_Documentation_policy STREQUAL "")
+ # Ignore the warning if the project is detected as VTK itself.
+ if (NOT CMAKE_PROJECT_NAME STREQUAL "VTK" AND
+ NOT PROJECT_NAME STREQUAL "VTK")
+ cmake_policy(GET_WARNING CMP0106 _Documentation_policy_warning)
+ message(AUTHOR_WARNING
+ "${_Documentation_policy_warning}\n"
+ "Documentation.cmake is VTK-specific code and should not be used in "
+ "non-VTK projects. This logic in this module is best shipped with the "
+ "project using it rather than with CMake.")
+ endif ()
+ unset(_Documentation_policy_warning)
+endif ()
+
#
# Build the documentation ?
#
@@ -44,3 +68,7 @@ if (BUILD_DOCUMENTATION)
#
endif ()
+
+endif ()
+
+unset(_Documentation_policy)
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index 66061a1..f9f7a4f 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -9,8 +9,11 @@ ExternalProject
.. contents::
+Commands
+^^^^^^^^
+
External Project Definition
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
+"""""""""""""""""""""""""""
.. command:: ExternalProject_Add
@@ -265,6 +268,11 @@ External Project Definition
is set to ``NEW`` if this value is set to an empty string then no submodules
are initialized or updated.
+ ``GIT_SUBMODULES_RECURSE <bool>``
+ Specify whether git submodules (if any) should update recursively by
+ passing the ``--recursive`` flag to ``git submodule update``.
+ If not specified, the default is on.
+
``GIT_SHALLOW <bool>``
When this option is enabled, the ``git clone`` operation will be given
the ``--depth 1`` option. This performs a shallow clone, which avoids
@@ -660,7 +668,7 @@ External Project Definition
automatic substitutions that are supported for some options.
Obtaining Project Properties
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+""""""""""""""""""""""""""""
.. command:: ExternalProject_Get_Property
@@ -681,7 +689,7 @@ Obtaining Project Properties
message("Source dir of myExtProj = ${SOURCE_DIR}")
Explicit Step Management
-^^^^^^^^^^^^^^^^^^^^^^^^
+""""""""""""""""""""""""
The ``ExternalProject_Add()`` function on its own is often sufficient for
incorporating an external project into the main build. Certain scenarios
@@ -1065,7 +1073,7 @@ define_property(DIRECTORY PROPERTY "EP_UPDATE_DISCONNECTED" INHERITED
"ExternalProject module."
)
-function(_ep_write_gitclone_script script_filename source_dir git_EXECUTABLE git_repository git_tag git_remote_name init_submodules git_submodules git_shallow git_progress git_config src_name work_dir gitclone_infofile gitclone_stampfile tls_verify)
+function(_ep_write_gitclone_script script_filename source_dir git_EXECUTABLE git_repository git_tag git_remote_name init_submodules git_submodules_recurse git_submodules git_shallow git_progress git_config src_name work_dir gitclone_infofile gitclone_stampfile tls_verify)
if(NOT GIT_VERSION_STRING VERSION_LESS 1.8.5)
# Use `git checkout <tree-ish> --` to avoid ambiguity with a local path.
set(git_checkout_explicit-- "--")
@@ -1091,7 +1099,7 @@ function(_ep_write_gitclone_script script_filename source_dir git_EXECUTABLE git
list(APPEND git_clone_options --progress)
endif()
foreach(config IN LISTS git_config)
- list(APPEND git_clone_options --config ${config})
+ list(APPEND git_clone_options --config \"${config}\")
endforeach()
if(NOT ${git_remote_name} STREQUAL "origin")
list(APPEND git_clone_options --origin \"${git_remote_name}\")
@@ -1115,7 +1123,7 @@ if(NOT \"${gitclone_infofile}\" IS_NEWER_THAN \"${gitclone_stampfile}\")
endif()
execute_process(
- COMMAND \${CMAKE_COMMAND} -E remove_directory \"${source_dir}\"
+ COMMAND \${CMAKE_COMMAND} -E rm -rf \"${source_dir}\"
RESULT_VARIABLE error_code
)
if(error_code)
@@ -1153,7 +1161,7 @@ endif()
set(init_submodules ${init_submodules})
if(init_submodules)
execute_process(
- COMMAND \"${git_EXECUTABLE}\" ${git_options} submodule update --recursive --init ${git_submodules}
+ COMMAND \"${git_EXECUTABLE}\" ${git_options} submodule update ${git_submodules_recurse} --init ${git_submodules}
WORKING_DIRECTORY \"${work_dir}/${src_name}\"
RESULT_VARIABLE error_code
)
@@ -1191,7 +1199,7 @@ if(NOT \"${hgclone_infofile}\" IS_NEWER_THAN \"${hgclone_stampfile}\")
endif()
execute_process(
- COMMAND \${CMAKE_COMMAND} -E remove_directory \"${source_dir}\"
+ COMMAND \${CMAKE_COMMAND} -E rm -rf \"${source_dir}\"
RESULT_VARIABLE error_code
)
if(error_code)
@@ -1234,7 +1242,7 @@ endif()
endfunction()
-function(_ep_write_gitupdate_script script_filename git_EXECUTABLE git_tag git_remote_name init_submodules git_submodules git_repository work_dir)
+function(_ep_write_gitupdate_script script_filename git_EXECUTABLE git_tag git_remote_name init_submodules git_submodules_recurse git_submodules git_repository work_dir)
if("${git_tag}" STREQUAL "")
message(FATAL_ERROR "Tag for git checkout should not be empty.")
endif()
@@ -1394,7 +1402,7 @@ if(error_code OR is_remote_ref OR NOT (\"\${tag_sha}\" STREQUAL \"\${head_sha}\"
set(init_submodules ${init_submodules})
if(init_submodules)
execute_process(
- COMMAND \"${git_EXECUTABLE}\" submodule update --recursive --init ${git_submodules}
+ COMMAND \"${git_EXECUTABLE}\" submodule update ${git_submodules_recurse} --init ${git_submodules}
WORKING_DIRECTORY \"${work_dir}/${src_name}\"
RESULT_VARIABLE error_code
)
@@ -1772,6 +1780,11 @@ function(_ep_write_initial_cache target_name script_filename script_initial_cach
# Replace location tags.
_ep_replace_location_tags(${target_name} script_initial_cache)
_ep_replace_location_tags(${target_name} script_filename)
+ # Replace list separators.
+ get_property(sep TARGET ${target_name} PROPERTY _EP_LIST_SEPARATOR)
+ if(sep AND script_initial_cache)
+ string(REPLACE "${sep}" ";" script_initial_cache "${script_initial_cache}")
+ endif()
# Write out the initial cache file to the location specified.
file(GENERATE OUTPUT "${script_filename}" CONTENT "${script_initial_cache}")
endfunction()
@@ -2269,7 +2282,7 @@ function(ExternalProject_Add_StepDependencies name step)
get_property(steps TARGET ${name} PROPERTY _EP_STEPS)
list(FIND steps ${step} is_step)
- if(NOT is_step)
+ if(is_step LESS 0)
message(FATAL_ERROR "External project \"${name}\" does not have a step \"${step}\".")
endif()
@@ -2329,6 +2342,29 @@ function(_ep_is_dir_empty dir empty_var)
endif()
endfunction()
+function(_ep_get_git_submodules_recurse git_submodules_recurse)
+ # Checks for GIT_SUBMODULES_RECURSE property
+ # Default is ON, which sets git_submodules_recurse output variable to "--recursive"
+ # Otherwise, the output variable is set to an empty value ""
+ get_property(git_submodules_recurse_set TARGET ${name} PROPERTY _EP_GIT_SUBMODULES_RECURSE SET)
+ if(NOT git_submodules_recurse_set)
+ set(recurseFlag "--recursive")
+ else()
+ get_property(git_submodules_recurse_value TARGET ${name} PROPERTY _EP_GIT_SUBMODULES_RECURSE)
+ if(git_submodules_recurse_value)
+ set(recurseFlag "--recursive")
+ else()
+ set(recurseFlag "")
+ endif()
+ endif()
+ set(${git_submodules_recurse} "${recurseFlag}" PARENT_SCOPE)
+
+ # The git submodule update '--recursive' flag requires git >= v1.6.5
+ if(recurseFlag AND GIT_VERSION_STRING VERSION_LESS 1.6.5)
+ message(FATAL_ERROR "error: git version 1.6.5 or later required for --recursive flag with 'git submodule ...': GIT_VERSION_STRING='${GIT_VERSION_STRING}'")
+ endif()
+endfunction()
+
function(_ep_add_download_command name)
ExternalProject_Get_Property(${name} source_dir stamp_dir download_dir tmp_dir)
@@ -2421,11 +2457,7 @@ function(_ep_add_download_command name)
message(FATAL_ERROR "error: could not find git for clone of ${name}")
endif()
- # The git submodule update '--recursive' flag requires git >= v1.6.5
- #
- if(GIT_VERSION_STRING VERSION_LESS 1.6.5)
- message(FATAL_ERROR "error: git version 1.6.5 or later required for 'git submodule update --recursive': GIT_VERSION_STRING='${GIT_VERSION_STRING}'")
- endif()
+ _ep_get_git_submodules_recurse(git_submodules_recurse)
get_property(git_tag TARGET ${name} PROPERTY _EP_GIT_TAG)
if(NOT git_tag)
@@ -2477,7 +2509,7 @@ function(_ep_add_download_command name)
# The script will delete the source directory and then call git clone.
#
_ep_write_gitclone_script(${tmp_dir}/${name}-gitclone.cmake ${source_dir}
- ${GIT_EXECUTABLE} ${git_repository} ${git_tag} ${git_remote_name} ${git_init_submodules} "${git_submodules}" "${git_shallow}" "${git_progress}" "${git_config}" ${src_name} ${work_dir}
+ ${GIT_EXECUTABLE} ${git_repository} ${git_tag} ${git_remote_name} ${git_init_submodules} "${git_submodules_recurse}" "${git_submodules}" "${git_shallow}" "${git_progress}" "${git_config}" ${src_name} ${work_dir}
${stamp_dir}/${name}-gitinfo.txt ${stamp_dir}/${name}-gitclone-lastrun.txt "${tls_verify}"
)
set(comment "Performing download step (git clone) for '${name}'")
@@ -2563,10 +2595,10 @@ function(_ep_add_download_command name)
if(IS_DIRECTORY "${url}")
get_filename_component(abs_dir "${url}" ABSOLUTE)
set(comment "Performing download step (DIR copy) for '${name}'")
- set(cmd ${CMAKE_COMMAND} -E remove_directory ${source_dir}
+ set(cmd ${CMAKE_COMMAND} -E rm -rf ${source_dir}
COMMAND ${CMAKE_COMMAND} -E copy_directory ${abs_dir} ${source_dir})
else()
- get_property(no_extract TARGET "${name}" PROPERTY _EP_DOWNLOAD_NO_EXTRACT SET)
+ get_property(no_extract TARGET "${name}" PROPERTY _EP_DOWNLOAD_NO_EXTRACT)
if("${url}" MATCHES "^[a-z]+://")
# TODO: Should download and extraction be different steps?
if("x${fname}" STREQUAL "x")
@@ -2668,6 +2700,15 @@ function(_ep_add_download_command name)
)
endfunction()
+function(_ep_get_update_disconnected var name)
+ get_property(update_disconnected_set TARGET ${name} PROPERTY _EP_UPDATE_DISCONNECTED SET)
+ if(update_disconnected_set)
+ get_property(update_disconnected TARGET ${name} PROPERTY _EP_UPDATE_DISCONNECTED)
+ else()
+ get_property(update_disconnected DIRECTORY PROPERTY EP_UPDATE_DISCONNECTED)
+ endif()
+ set(${var} "${update_disconnected}" PARENT_SCOPE)
+endfunction()
function(_ep_add_update_command name)
ExternalProject_Get_Property(${name} source_dir tmp_dir)
@@ -2678,12 +2719,8 @@ function(_ep_add_update_command name)
get_property(svn_repository TARGET ${name} PROPERTY _EP_SVN_REPOSITORY)
get_property(git_repository TARGET ${name} PROPERTY _EP_GIT_REPOSITORY)
get_property(hg_repository TARGET ${name} PROPERTY _EP_HG_REPOSITORY )
- get_property(update_disconnected_set TARGET ${name} PROPERTY _EP_UPDATE_DISCONNECTED SET)
- if(update_disconnected_set)
- get_property(update_disconnected TARGET ${name} PROPERTY _EP_UPDATE_DISCONNECTED)
- else()
- get_property(update_disconnected DIRECTORY PROPERTY EP_UPDATE_DISCONNECTED)
- endif()
+
+ _ep_get_update_disconnected(update_disconnected ${name})
set(work_dir)
set(comment)
@@ -2752,8 +2789,10 @@ function(_ep_add_update_command name)
endif()
endif()
+ _ep_get_git_submodules_recurse(git_submodules_recurse)
+
_ep_write_gitupdate_script(${tmp_dir}/${name}-gitupdate.cmake
- ${GIT_EXECUTABLE} ${git_tag} ${git_remote_name} ${git_init_submodules} "${git_submodules}" ${git_repository} ${work_dir}
+ ${GIT_EXECUTABLE} ${git_tag} ${git_remote_name} ${git_init_submodules} "${git_submodules_recurse}" "${git_submodules}" ${git_repository} ${work_dir}
)
set(cmd ${CMAKE_COMMAND} -P ${tmp_dir}/${name}-gitupdate.cmake)
set(always 1)
@@ -2843,10 +2882,17 @@ function(_ep_add_patch_command name)
set(log "")
endif()
+ _ep_get_update_disconnected(update_disconnected ${name})
+ if(update_disconnected)
+ set(update_dep skip-update)
+ else()
+ set(update_dep update)
+ endif()
+
ExternalProject_Add_Step(${name} patch
COMMAND ${cmd}
WORKING_DIRECTORY ${work_dir}
- DEPENDEES download
+ DEPENDEES download ${update_dep}
${log}
)
endfunction()
@@ -2943,6 +2989,10 @@ function(_ep_extract_configure_command var name)
endif()
_ep_write_initial_cache(${name} "${_ep_cache_args_script}" "${script_initial_cache_force}${script_initial_cache_default}")
list(APPEND cmd "-C${_ep_cache_args_script}")
+ _ep_replace_location_tags(${name} _ep_cache_args_script)
+ set(_ep_cache_args_script
+ "${_ep_cache_args_script}"
+ PARENT_SCOPE)
endif()
list(APPEND cmd "<SOURCE_DIR><SOURCE_SUBDIR>")
@@ -2997,12 +3047,7 @@ function(_ep_add_configure_command name)
set(uses_terminal "")
endif()
- get_property(update_disconnected_set TARGET ${name} PROPERTY _EP_UPDATE_DISCONNECTED SET)
- if(update_disconnected_set)
- get_property(update_disconnected TARGET ${name} PROPERTY _EP_UPDATE_DISCONNECTED)
- else()
- get_property(update_disconnected DIRECTORY PROPERTY EP_UPDATE_DISCONNECTED)
- endif()
+ _ep_get_update_disconnected(update_disconnected ${name})
if(update_disconnected)
set(update_dep skip-update)
else()
diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake
index 5716b01..400754c 100644
--- a/Modules/FetchContent.cmake
+++ b/Modules/FetchContent.cmake
@@ -76,8 +76,11 @@ sometimes useful as part of implementing some higher level feature or to
populate some content in CMake's script mode.
+Commands
+^^^^^^^^
+
Declaring Content Details
-^^^^^^^^^^^^^^^^^^^^^^^^^
+"""""""""""""""""""""""""
.. command:: FetchContent_Declare
@@ -130,7 +133,7 @@ Declaring Content Details
)
Populating The Content
-^^^^^^^^^^^^^^^^^^^^^^
+""""""""""""""""""""""
For most common scenarios, population means making content available to the
main build according to previously declared details for that dependency.
@@ -596,9 +599,6 @@ current working directory.
#]=======================================================================]
-
-set(__FetchContent_privateDir "${CMAKE_CURRENT_LIST_DIR}/FetchContent")
-
#=======================================================================
# Recording and retrieving content details for later population
#=======================================================================
@@ -796,6 +796,8 @@ function(__FetchContent_directPopulate contentName)
SUBBUILD_DIR
SOURCE_DIR
BINARY_DIR
+ # We need special processing if DOWNLOAD_NO_EXTRACT is true
+ DOWNLOAD_NO_EXTRACT
# Prevent the following from being passed through
CONFIGURE_COMMAND
BUILD_COMMAND
@@ -846,6 +848,26 @@ function(__FetchContent_directPopulate contentName)
set(ARG_EXTRA "${ARG_EXTRA} \"${arg}\"")
endforeach()
+ if(ARG_DOWNLOAD_NO_EXTRACT)
+ set(ARG_EXTRA "${ARG_EXTRA} DOWNLOAD_NO_EXTRACT YES")
+ set(__FETCHCONTENT_COPY_FILE
+"
+ExternalProject_Get_Property(${contentName}-populate DOWNLOADED_FILE)
+get_filename_component(dlFileName \"\${DOWNLOADED_FILE}\" NAME)
+
+ExternalProject_Add_Step(${contentName}-populate copyfile
+ COMMAND \"${CMAKE_COMMAND}\" -E copy_if_different
+ \"<DOWNLOADED_FILE>\" \"${ARG_SOURCE_DIR}\"
+ DEPENDEES patch
+ DEPENDERS configure
+ BYPRODUCTS \"${ARG_SOURCE_DIR}/\${dlFileName}\"
+ COMMENT \"Copying file to SOURCE_DIR\"
+)
+")
+ else()
+ unset(__FETCHCONTENT_COPY_FILE)
+ endif()
+
# Hide output if requested, but save it to a variable in case there's an
# error so we can show the output upon failure. When not quiet, don't
# capture the output to a variable because the user may want to see the
@@ -888,7 +910,7 @@ function(__FetchContent_directPopulate contentName)
# anything to be updated, so extra rebuilds of the project won't occur.
# Make sure to pass through CMAKE_MAKE_PROGRAM in case the main project
# has this set to something not findable on the PATH.
- configure_file("${__FetchContent_privateDir}/CMakeLists.cmake.in"
+ configure_file("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/FetchContent/CMakeLists.cmake.in"
"${ARG_SUBBUILD_DIR}/CMakeLists.txt")
execute_process(
COMMAND ${CMAKE_COMMAND} ${generatorOpts} .
diff --git a/Modules/FetchContent/CMakeLists.cmake.in b/Modules/FetchContent/CMakeLists.cmake.in
index 0095b11..45e4df0 100644
--- a/Modules/FetchContent/CMakeLists.cmake.in
+++ b/Modules/FetchContent/CMakeLists.cmake.in
@@ -21,3 +21,5 @@ ExternalProject_Add(${contentName}-populate
USES_TERMINAL_DOWNLOAD YES
USES_TERMINAL_UPDATE YES
)
+
+@__FETCHCONTENT_COPY_FILE@
diff --git a/Modules/FindArmadillo.cmake b/Modules/FindArmadillo.cmake
index c4e55ce..243b9e0 100644
--- a/Modules/FindArmadillo.cmake
+++ b/Modules/FindArmadillo.cmake
@@ -6,7 +6,7 @@ FindArmadillo
-------------
Find the Armadillo C++ library.
-Armadillo is library for linear algebra & scientific computing.
+Armadillo is a library for linear algebra & scientific computing.
Using Armadillo:
@@ -31,19 +31,13 @@ This module sets the following variables:
ARMADILLO_VERSION_NAME - name of the version (ex: "Antipodean Antileech")
#]=======================================================================]
-# UNIX paths are standard, no need to write.
-find_library(ARMADILLO_LIBRARY
- NAMES armadillo
- PATHS "$ENV{ProgramFiles}/Armadillo/lib" "$ENV{ProgramFiles}/Armadillo/lib64" "$ENV{ProgramFiles}/Armadillo"
- )
find_path(ARMADILLO_INCLUDE_DIR
NAMES armadillo
PATHS "$ENV{ProgramFiles}/Armadillo/include"
)
-
+mark_as_advanced(ARMADILLO_INCLUDE_DIR)
if(ARMADILLO_INCLUDE_DIR)
-
# ------------------------------------------------------------------------
# Extract version information from <armadillo>
# ------------------------------------------------------------------------
@@ -59,32 +53,79 @@ if(ARMADILLO_INCLUDE_DIR)
if(EXISTS "${ARMADILLO_INCLUDE_DIR}/armadillo_bits/arma_version.hpp")
# Read and parse armdillo version header file for version number
- file(STRINGS "${ARMADILLO_INCLUDE_DIR}/armadillo_bits/arma_version.hpp" _armadillo_HEADER_CONTENTS REGEX "#define ARMA_VERSION_[A-Z]+ ")
- string(REGEX REPLACE ".*#define ARMA_VERSION_MAJOR ([0-9]+).*" "\\1" ARMADILLO_VERSION_MAJOR "${_armadillo_HEADER_CONTENTS}")
- string(REGEX REPLACE ".*#define ARMA_VERSION_MINOR ([0-9]+).*" "\\1" ARMADILLO_VERSION_MINOR "${_armadillo_HEADER_CONTENTS}")
- string(REGEX REPLACE ".*#define ARMA_VERSION_PATCH ([0-9]+).*" "\\1" ARMADILLO_VERSION_PATCH "${_armadillo_HEADER_CONTENTS}")
+ file(STRINGS "${ARMADILLO_INCLUDE_DIR}/armadillo_bits/arma_version.hpp" _ARMA_HEADER_CONTENTS REGEX "#define ARMA_VERSION_[A-Z]+ ")
+ string(REGEX REPLACE ".*#define ARMA_VERSION_MAJOR ([0-9]+).*" "\\1" ARMADILLO_VERSION_MAJOR "${_ARMA_HEADER_CONTENTS}")
+ string(REGEX REPLACE ".*#define ARMA_VERSION_MINOR ([0-9]+).*" "\\1" ARMADILLO_VERSION_MINOR "${_ARMA_HEADER_CONTENTS}")
+ string(REGEX REPLACE ".*#define ARMA_VERSION_PATCH ([0-9]+).*" "\\1" ARMADILLO_VERSION_PATCH "${_ARMA_HEADER_CONTENTS}")
# WARNING: The number of spaces before the version name is not one.
- string(REGEX REPLACE ".*#define ARMA_VERSION_NAME +\"([0-9a-zA-Z _-]+)\".*" "\\1" ARMADILLO_VERSION_NAME "${_armadillo_HEADER_CONTENTS}")
+ string(REGEX REPLACE ".*#define ARMA_VERSION_NAME\ +\"([0-9a-zA-Z\ _-]+)\".*" "\\1" ARMADILLO_VERSION_NAME "${_ARMA_HEADER_CONTENTS}")
- unset(_armadillo_HEADER_CONTENTS)
endif()
set(ARMADILLO_VERSION_STRING "${ARMADILLO_VERSION_MAJOR}.${ARMADILLO_VERSION_MINOR}.${ARMADILLO_VERSION_PATCH}")
endif ()
+if(EXISTS "${ARMADILLO_INCLUDE_DIR}/armadillo_bits/config.hpp")
+ file(STRINGS "${ARMADILLO_INCLUDE_DIR}/armadillo_bits/config.hpp" _ARMA_CONFIG_CONTENTS REGEX "^#define ARMA_USE_[A-Z]+")
+ string(REGEX MATCH "ARMA_USE_WRAPPER" _ARMA_USE_WRAPPER "${_ARMA_CONFIG_CONTENTS}")
+ string(REGEX MATCH "ARMA_USE_LAPACK" _ARMA_USE_LAPACK "${_ARMA_CONFIG_CONTENTS}")
+ string(REGEX MATCH "ARMA_USE_BLAS" _ARMA_USE_BLAS "${_ARMA_CONFIG_CONTENTS}")
+ string(REGEX MATCH "ARMA_USE_ARPACK" _ARMA_USE_ARPACK "${_ARMA_CONFIG_CONTENTS}")
+ string(REGEX MATCH "ARMA_USE_HDF5" _ARMA_USE_HDF5 "${_ARMA_CONFIG_CONTENTS}")
+endif()
+
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+
+# If _ARMA_USE_WRAPPER is set, then we just link to armadillo, but if it's not then we need support libraries instead
+set(_ARMA_SUPPORT_LIBRARIES)
+
+if(_ARMA_USE_WRAPPER)
+ # Link to the armadillo wrapper library.
+ find_library(ARMADILLO_LIBRARY
+ NAMES armadillo
+ PATHS
+ "$ENV{ProgramFiles}/Armadillo/lib"
+ "$ENV{ProgramFiles}/Armadillo/lib64"
+ "$ENV{ProgramFiles}/Armadillo"
+ )
+ mark_as_advanced(ARMADILLO_LIBRARY)
+ set(_ARMA_REQUIRED_VARS ARMADILLO_LIBRARY)
+else()
+ # Link directly to individual components.
+ set(ARMADILLO_LIBRARY "")
+ foreach(pkg
+ LAPACK
+ BLAS
+ ARPACK
+ HDF5
+ )
+ if(_ARMA_USE_${pkg})
+ find_package(${pkg} QUIET)
+ list(APPEND _ARMA_REQUIRED_VARS "${pkg}_FOUND")
+ if(${pkg}_FOUND)
+ list(APPEND _ARMA_SUPPORT_LIBRARIES ${${pkg}_LIBRARIES})
+ endif()
+ endif()
+ endforeach()
+endif()
+
find_package_handle_standard_args(Armadillo
- REQUIRED_VARS ARMADILLO_LIBRARY ARMADILLO_INCLUDE_DIR
+ REQUIRED_VARS ARMADILLO_INCLUDE_DIR ${_ARMA_REQUIRED_VARS}
VERSION_VAR ARMADILLO_VERSION_STRING)
-# version_var fails with cmake < 2.8.4.
if (ARMADILLO_FOUND)
set(ARMADILLO_INCLUDE_DIRS ${ARMADILLO_INCLUDE_DIR})
- set(ARMADILLO_LIBRARIES ${ARMADILLO_LIBRARY})
+ set(ARMADILLO_LIBRARIES ${ARMADILLO_LIBRARY} ${_ARMA_SUPPORT_LIBRARIES})
endif ()
-# Hide internal variables
-mark_as_advanced(
- ARMADILLO_INCLUDE_DIR
- ARMADILLO_LIBRARY)
+# Clean up internal variables
+unset(_ARMA_REQUIRED_VARS)
+unset(_ARMA_SUPPORT_LIBRARIES)
+unset(_ARMA_USE_WRAPPER)
+unset(_ARMA_USE_LAPACK)
+unset(_ARMA_USE_BLAS)
+unset(_ARMA_USE_ARPACK)
+unset(_ARMA_USE_HDF5)
+unset(_ARMA_CONFIG_CONTENTS)
+unset(_ARMA_HEADER_CONTENTS)
diff --git a/Modules/FindBLAS.cmake b/Modules/FindBLAS.cmake
index d3acafc..4c569b3 100644
--- a/Modules/FindBLAS.cmake
+++ b/Modules/FindBLAS.cmake
@@ -8,8 +8,9 @@ FindBLAS
Find Basic Linear Algebra Subprograms (BLAS) library
This module finds an installed Fortran library that implements the
-BLAS linear-algebra interface (see http://www.netlib.org/blas/). The
-list of libraries searched for is taken from the ``autoconf`` macro file,
+BLAS linear-algebra interface (see http://www.netlib.org/blas/).
+
+The approach follows that taken for the ``autoconf`` macro file,
``acx_blas.m4`` (distributed at
http://ac-archive.sourceforge.net/ac-archive/acx_blas.html).
@@ -25,28 +26,33 @@ The following variables may be set to influence this module's behavior:
If set, checks only the specified vendor, if not set checks all the
possibilities. List of vendors valid in this module:
- * Goto
- * OpenBLAS
- * FLAME
- * ATLAS PhiPACK
- * CXML
- * DXML
- * SunPerf
- * SCSL
- * SGIMATH
- * IBMESSL
- * Intel10_32 (intel mkl v10 32 bit)
- * Intel10_64lp (intel mkl v10+ 64 bit, threaded code, lp64 model)
- * Intel10_64lp_seq (intel mkl v10+ 64 bit, sequential code, lp64 model)
- * Intel10_64ilp (intel mkl v10+ 64 bit, threaded code, ilp64 model)
- * Intel10_64ilp_seq (intel mkl v10+ 64 bit, sequential code, ilp64 model)
- * Intel (obsolete versions of mkl 32 and 64 bit)
- * ACML
- * ACML_MP
- * ACML_GPU
- * Apple
- * NAS
- * Generic
+ * ``Goto``
+ * ``OpenBLAS``
+ * ``FLAME``
+ * ``ATLAS PhiPACK``
+ * ``CXML``
+ * ``DXML``
+ * ``SunPerf``
+ * ``SCSL``
+ * ``SGIMATH``
+ * ``IBMESSL``
+ * ``Intel10_32`` (intel mkl v10 32 bit)
+ * ``Intel10_64lp`` (intel mkl v10+ 64 bit, threaded code, lp64 model)
+ * ``Intel10_64lp_seq`` (intel mkl v10+ 64 bit, sequential code, lp64 model)
+ * ``Intel10_64ilp`` (intel mkl v10+ 64 bit, threaded code, ilp64 model)
+ * ``Intel10_64ilp_seq`` (intel mkl v10+ 64 bit, sequential code, ilp64 model)
+ * ``Intel10_64_dyn`` (intel mkl v10+ 64 bit, single dynamic library)
+ * ``Intel`` (obsolete versions of mkl 32 and 64 bit)
+ * ``ACML``
+ * ``ACML_MP``
+ * ``ACML_GPU``
+ * ``Apple``
+ * ``NAS``
+ * ``Arm``
+ * ``Arm_mp``
+ * ``Arm_ilp64``
+ * ``Arm_ilp64_mp``
+ * ``Generic``
``BLA_F95``
if ``ON`` tries to find the BLAS95 interfaces
@@ -55,6 +61,15 @@ 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
+Imported targets
+^^^^^^^^^^^^^^^^
+
+This module defines the following :prop_tgt:`IMPORTED` target:
+
+``BLAS::BLAS``
+ The libraries to use for BLAS, if found.
+
+
Result Variables
^^^^^^^^^^^^^^^^
@@ -75,7 +90,8 @@ This module defines the following variables:
.. note::
- C or CXX must be enabled to use Intel Math Kernel Library (MKL)
+ C, CXX or Fortran must be enabled to detect a BLAS library.
+ C or CXX must be enabled to use Intel Math Kernel Library (MKL).
For example, to use Intel MKL libraries and/or Intel compiler:
@@ -87,22 +103,15 @@ This module defines the following variables:
Hints
^^^^^
-Set ``MKLROOT`` environment variable to a directory that contains an MKL
-installation.
+Set the ``MKLROOT`` environment variable to a directory that contains an MKL
+installation, or add the directory to the dynamic library loader environment
+variable for your platform (``LIB``, ``DYLD_LIBRARY_PATH`` or
+``LD_LIBRARY_PATH``).
#]=======================================================================]
-include(${CMAKE_CURRENT_LIST_DIR}/CheckFunctionExists.cmake)
-include(${CMAKE_CURRENT_LIST_DIR}/CheckFortranFunctionExists.cmake)
-include(${CMAKE_CURRENT_LIST_DIR}/CMakePushCheckState.cmake)
-include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
-cmake_push_check_state()
-set(CMAKE_REQUIRED_QUIET ${BLAS_FIND_QUIETLY})
-
-set(_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
-
# Check the language being used
-if( NOT (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED) )
+if(NOT (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED))
if(BLAS_FIND_REQUIRED)
message(FATAL_ERROR "FindBLAS requires Fortran, C, or C++ to be enabled.")
else()
@@ -111,17 +120,55 @@ if( NOT (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_C
endif()
endif()
+function(_add_blas_target)
+ if(NOT TARGET BLAS::BLAS)
+ add_library(BLAS::BLAS INTERFACE IMPORTED)
+ if(BLAS_LIBRARIES)
+ set_target_properties(BLAS::BLAS PROPERTIES
+ INTERFACE_LINK_LIBRARIES "${BLAS_LIBRARIES}"
+ )
+ endif()
+ endif()
+endfunction()
+
+if(CMAKE_Fortran_COMPILER_LOADED)
+ include(${CMAKE_CURRENT_LIST_DIR}/CheckFortranFunctionExists.cmake)
+else()
+ include(${CMAKE_CURRENT_LIST_DIR}/CheckFunctionExists.cmake)
+endif()
+include(${CMAKE_CURRENT_LIST_DIR}/CMakePushCheckState.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+cmake_push_check_state()
+set(CMAKE_REQUIRED_QUIET ${BLAS_FIND_QUIETLY})
+
if(BLA_PREFER_PKGCONFIG)
find_package(PkgConfig)
pkg_check_modules(PKGC_BLAS blas)
if(PKGC_BLAS_FOUND)
set(BLAS_FOUND ${PKGC_BLAS_FOUND})
set(BLAS_LIBRARIES "${PKGC_BLAS_LINK_LIBRARIES}")
+ _add_blas_target()
return()
endif()
endif()
-macro(Check_Fortran_Libraries LIBRARIES _prefix _name _flags _list _thread)
+set(_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
+if(BLA_STATIC)
+ if(WIN32)
+ set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES})
+ else()
+ set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
+ endif()
+else()
+ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ # for ubuntu's libblas3gf and liblapack3gf packages
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf)
+ endif()
+endif()
+
+# TODO: move this stuff to a separate module
+
+macro(CHECK_BLAS_LIBRARIES LIBRARIES _prefix _name _flags _list _threadlibs _addlibdir _subdirs)
# This macro checks for the existence of the combination of fortran libraries
# given by _list. If the combination is found, this macro checks (using the
# Check_Fortran_Function_Exists macro) whether can link against that library
@@ -132,59 +179,51 @@ macro(Check_Fortran_Libraries LIBRARIES _prefix _name _flags _list _thread)
# N.B. _prefix is the prefix applied to the names of all cached variables that
# are generated internally and marked advanced by this macro.
-
- set(_libdir ${ARGN})
+ # _addlibdir is a list of additional search paths. _subdirs is a list of path
+ # suffixes to be used by find_library().
set(_libraries_work TRUE)
set(${LIBRARIES})
set(_combined_name)
- if (NOT _libdir)
- if (WIN32)
- set(_libdir ENV LIB)
- elseif (APPLE)
- set(_libdir ENV DYLD_LIBRARY_PATH)
- else ()
- set(_libdir ENV LD_LIBRARY_PATH)
- endif ()
- endif ()
-
- list(APPEND _libdir "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}")
+
+ set(_extaddlibdir "${_addlibdir}")
+ if(WIN32)
+ list(APPEND _extaddlibdir ENV LIB)
+ elseif(APPLE)
+ list(APPEND _extaddlibdir ENV DYLD_LIBRARY_PATH)
+ else()
+ list(APPEND _extaddlibdir ENV LD_LIBRARY_PATH)
+ endif()
+ list(APPEND _extaddlibdir "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}")
foreach(_library ${_list})
- set(_combined_name ${_combined_name}_${_library})
- if(NOT "${_thread}" STREQUAL "")
- set(_combined_name ${_combined_name}_thread)
- endif()
- if(_libraries_work)
- if (BLA_STATIC)
- if (WIN32)
- set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES})
- endif ()
- if (APPLE)
- set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES})
- else ()
- set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
- endif ()
- else ()
- if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
- # for ubuntu's libblas3gf and liblapack3gf packages
- set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf)
- endif ()
- endif ()
- find_library(${_prefix}_${_library}_LIBRARY
- NAMES ${_library}
- PATHS ${_libdir}
+ if(_library MATCHES "^-Wl,--(start|end)-group$")
+ # Respect linker flags like --start/end-group (required by MKL)
+ set(${LIBRARIES} ${${LIBRARIES}} "${_library}")
+ else()
+ set(_combined_name ${_combined_name}_${_library})
+ if(NOT "${_threadlibs}" STREQUAL "")
+ set(_combined_name ${_combined_name}_threadlibs)
+ endif()
+ if(_libraries_work)
+ find_library(${_prefix}_${_library}_LIBRARY
+ NAMES ${_library}
+ PATHS ${_extaddlibdir}
+ PATH_SUFFIXES ${_subdirs}
)
- mark_as_advanced(${_prefix}_${_library}_LIBRARY)
- set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY})
- set(_libraries_work ${${_prefix}_${_library}_LIBRARY})
+ #message("DEBUG: find_library(${_library}) got ${${_prefix}_${_library}_LIBRARY}")
+ mark_as_advanced(${_prefix}_${_library}_LIBRARY)
+ set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY})
+ set(_libraries_work ${${_prefix}_${_library}_LIBRARY})
+ endif()
endif()
endforeach()
+
if(_libraries_work)
# Test this combination of libraries.
- set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_thread})
- # message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}")
- if (CMAKE_Fortran_COMPILER_LOADED)
+ set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_threadlibs})
+ #message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}")
+ if(CMAKE_Fortran_COMPILER_LOADED)
check_fortran_function_exists("${_name}" ${_prefix}${_combined_name}_WORKS)
else()
check_function_exists("${_name}_" ${_prefix}${_combined_name}_WORKS)
@@ -192,11 +231,12 @@ macro(Check_Fortran_Libraries LIBRARIES _prefix _name _flags _list _thread)
set(CMAKE_REQUIRED_LIBRARIES)
set(_libraries_work ${${_prefix}${_combined_name}_WORKS})
endif()
+
if(_libraries_work)
if("${_list}" STREQUAL "")
set(${LIBRARIES} "${LIBRARIES}-PLACEHOLDER-FOR-EMPTY-LIBRARIES")
else()
- set(${LIBRARIES} ${${LIBRARIES}} ${_thread}) # for static link
+ set(${LIBRARIES} ${${LIBRARIES}} ${_threadlibs})
endif()
else()
set(${LIBRARIES} FALSE)
@@ -207,91 +247,96 @@ endmacro()
set(BLAS_LINKER_FLAGS)
set(BLAS_LIBRARIES)
set(BLAS95_LIBRARIES)
-if (NOT $ENV{BLA_VENDOR} STREQUAL "")
+if(NOT $ENV{BLA_VENDOR} STREQUAL "")
set(BLA_VENDOR $ENV{BLA_VENDOR})
-else ()
+else()
if(NOT BLA_VENDOR)
set(BLA_VENDOR "All")
endif()
-endif ()
+endif()
-if (BLA_VENDOR STREQUAL "All")
+# Implicitly linked BLAS libraries?
+if(BLA_VENDOR STREQUAL "All")
if(NOT BLAS_LIBRARIES)
- # Implicitly linked BLAS libraries
- check_fortran_libraries(
+ check_blas_libraries(
BLAS_LIBRARIES
BLAS
sgemm
""
""
""
+ ""
+ ""
)
endif()
-endif ()
-
-#BLAS in intel mkl 10+ library? (em64t 64bit)
-if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All")
- if (NOT BLAS_LIBRARIES)
+endif()
- # System-specific settings
- if (WIN32)
- if (BLA_STATIC)
- set(BLAS_mkl_DLL_SUFFIX "")
- else()
- set(BLAS_mkl_DLL_SUFFIX "_dll")
- endif()
- else()
- # Switch to GNU Fortran support layer if needed (but not on Apple, where MKL does not provide it)
- if(CMAKE_Fortran_COMPILER_LOADED AND CMAKE_Fortran_COMPILER_ID STREQUAL "GNU" AND NOT APPLE)
- set(BLAS_mkl_INTFACE "gf")
- set(BLAS_mkl_THREADING "gnu")
- set(BLAS_mkl_OMP "gomp")
+# BLAS in the Intel MKL 10+ library?
+if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All")
+ if(NOT BLAS_LIBRARIES)
+ if(CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED)
+ # System-specific settings
+ if(WIN32)
+ if(BLA_STATIC)
+ set(BLAS_mkl_DLL_SUFFIX "")
+ else()
+ set(BLAS_mkl_DLL_SUFFIX "_dll")
+ endif()
else()
- set(BLAS_mkl_INTFACE "intel")
- set(BLAS_mkl_THREADING "intel")
- set(BLAS_mkl_OMP "iomp5")
+ if(BLA_STATIC)
+ set(BLAS_mkl_START_GROUP "-Wl,--start-group")
+ set(BLAS_mkl_END_GROUP "-Wl,--end-group")
+ else()
+ set(BLAS_mkl_START_GROUP "")
+ set(BLAS_mkl_END_GROUP "")
+ endif()
+ # Switch to GNU Fortran support layer if needed (but not on Apple, where MKL does not provide it)
+ if(CMAKE_Fortran_COMPILER_LOADED AND CMAKE_Fortran_COMPILER_ID STREQUAL "GNU" AND NOT APPLE)
+ set(BLAS_mkl_INTFACE "gf")
+ set(BLAS_mkl_THREADING "gnu")
+ set(BLAS_mkl_OMP "gomp")
+ else()
+ set(BLAS_mkl_INTFACE "intel")
+ set(BLAS_mkl_THREADING "intel")
+ set(BLAS_mkl_OMP "iomp5")
+ endif()
+ set(BLAS_mkl_LM "-lm")
+ set(BLAS_mkl_LDL "-ldl")
endif()
- set(BLAS_mkl_LM "-lm")
- set(BLAS_mkl_LDL "-ldl")
- endif()
-
- if (BLA_VENDOR MATCHES "_64ilp")
- set(BLAS_mkl_ILP_MODE "ilp64")
- else ()
- set(BLAS_mkl_ILP_MODE "lp64")
- endif ()
- if (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED)
if(BLAS_FIND_QUIETLY OR NOT BLAS_FIND_REQUIRED)
find_package(Threads)
else()
find_package(Threads REQUIRED)
endif()
+ if(BLA_VENDOR MATCHES "_64ilp")
+ set(BLAS_mkl_ILP_MODE "ilp64")
+ else()
+ set(BLAS_mkl_ILP_MODE "lp64")
+ endif()
+
set(BLAS_SEARCH_LIBS "")
if(BLA_F95)
- set(BLAS_mkl_SEARCH_SYMBOL sgemm_f95)
+ set(BLAS_mkl_SEARCH_SYMBOL "sgemm_f95")
set(_LIBRARIES BLAS95_LIBRARIES)
- if (WIN32)
+ if(WIN32)
# Find the main file (32-bit or 64-bit)
set(BLAS_SEARCH_LIBS_WIN_MAIN "")
- if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
+ if(BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN
"mkl_blas95${BLAS_mkl_DLL_SUFFIX} mkl_intel_c${BLAS_mkl_DLL_SUFFIX}")
endif()
- if (BLA_VENDOR MATCHES "^Intel10_64i?lp" OR BLA_VENDOR STREQUAL "All")
+
+ if(BLA_VENDOR MATCHES "^Intel10_64i?lp" OR BLA_VENDOR STREQUAL "All")
list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN
"mkl_blas95_${BLAS_mkl_ILP_MODE}${BLAS_mkl_DLL_SUFFIX} mkl_intel_${BLAS_mkl_ILP_MODE}${BLAS_mkl_DLL_SUFFIX}")
- endif ()
+ endif()
# Add threading/sequential libs
set(BLAS_SEARCH_LIBS_WIN_THREAD "")
- if (BLA_VENDOR MATCHES "_seq$" OR BLA_VENDOR STREQUAL "All")
- list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
- "mkl_sequential${BLAS_mkl_DLL_SUFFIX}")
- endif()
- if (NOT BLA_VENDOR MATCHES "_seq$" OR BLA_VENDOR STREQUAL "All")
+ if(BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR STREQUAL "All")
# old version
list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
"libguide40 mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}")
@@ -299,56 +344,60 @@ if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All")
list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
"libiomp5md mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}")
endif()
+ if(BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$" OR BLA_VENDOR STREQUAL "All")
+ list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
+ "mkl_sequential${BLAS_mkl_DLL_SUFFIX}")
+ endif()
# Cartesian product of the above
- foreach (MAIN ${BLAS_SEARCH_LIBS_WIN_MAIN})
- foreach (THREAD ${BLAS_SEARCH_LIBS_WIN_THREAD})
+ foreach(MAIN ${BLAS_SEARCH_LIBS_WIN_MAIN})
+ foreach(THREAD ${BLAS_SEARCH_LIBS_WIN_THREAD})
list(APPEND BLAS_SEARCH_LIBS
"${MAIN} ${THREAD} mkl_core${BLAS_mkl_DLL_SUFFIX}")
endforeach()
endforeach()
- else ()
- if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
+ else()
+ if(BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
# old version
list(APPEND BLAS_SEARCH_LIBS
"mkl_blas95 mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core guide")
# mkl >= 10.3
list(APPEND BLAS_SEARCH_LIBS
- "mkl_blas95 mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_OMP}")
- endif ()
- if (BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR STREQUAL "All")
+ "${BLAS_mkl_START_GROUP} mkl_blas95 mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_END_GROUP} ${BLAS_mkl_OMP}")
+ endif()
+ if(BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR STREQUAL "All")
# old version
list(APPEND BLAS_SEARCH_LIBS
"mkl_blas95 mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core guide")
# mkl >= 10.3
list(APPEND BLAS_SEARCH_LIBS
- "mkl_blas95_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_OMP}")
- endif ()
- if (BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$" OR BLA_VENDOR STREQUAL "All")
+ "${BLAS_mkl_START_GROUP} mkl_blas95_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_END_GROUP} ${BLAS_mkl_OMP}")
+ endif()
+ if(BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$" OR BLA_VENDOR STREQUAL "All")
list(APPEND BLAS_SEARCH_LIBS
- "mkl_blas95_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_sequential mkl_core")
- endif ()
- endif ()
- else ()
+ "${BLAS_mkl_START_GROUP} mkl_blas95_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_sequential mkl_core ${BLAS_mkl_END_GROUP}")
+ endif()
+ endif()
+ else()
set(BLAS_mkl_SEARCH_SYMBOL sgemm)
set(_LIBRARIES BLAS_LIBRARIES)
- if (WIN32)
+ if(WIN32)
# Find the main file (32-bit or 64-bit)
set(BLAS_SEARCH_LIBS_WIN_MAIN "")
- if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
+ if(BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN
"mkl_intel_c${BLAS_mkl_DLL_SUFFIX}")
endif()
- if (BLA_VENDOR MATCHES "^Intel10_64i?lp" OR BLA_VENDOR STREQUAL "All")
+ if(BLA_VENDOR MATCHES "^Intel10_64i?lp" OR BLA_VENDOR STREQUAL "All")
list(APPEND BLAS_SEARCH_LIBS_WIN_MAIN
"mkl_intel_${BLAS_mkl_ILP_MODE}${BLAS_mkl_DLL_SUFFIX}")
- endif ()
+ endif()
# Add threading/sequential libs
set(BLAS_SEARCH_LIBS_WIN_THREAD "")
- if (NOT BLA_VENDOR MATCHES "_seq$" OR BLA_VENDOR STREQUAL "All")
+ if(BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR STREQUAL "All")
# old version
list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
"libguide40 mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}")
@@ -356,96 +405,118 @@ if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All")
list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
"libiomp5md mkl_intel_thread${BLAS_mkl_DLL_SUFFIX}")
endif()
- if (BLA_VENDOR MATCHES "_seq$" OR BLA_VENDOR STREQUAL "All")
+ if(BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$" OR BLA_VENDOR STREQUAL "All")
list(APPEND BLAS_SEARCH_LIBS_WIN_THREAD
"mkl_sequential${BLAS_mkl_DLL_SUFFIX}")
endif()
# Cartesian product of the above
- foreach (MAIN ${BLAS_SEARCH_LIBS_WIN_MAIN})
- foreach (THREAD ${BLAS_SEARCH_LIBS_WIN_THREAD})
+ foreach(MAIN ${BLAS_SEARCH_LIBS_WIN_MAIN})
+ foreach(THREAD ${BLAS_SEARCH_LIBS_WIN_THREAD})
list(APPEND BLAS_SEARCH_LIBS
"${MAIN} ${THREAD} mkl_core${BLAS_mkl_DLL_SUFFIX}")
endforeach()
endforeach()
- else ()
- if (BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
+ else()
+ if(BLA_VENDOR STREQUAL "Intel10_32" OR BLA_VENDOR STREQUAL "All")
# old version
list(APPEND BLAS_SEARCH_LIBS
"mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core guide")
# mkl >= 10.3
list(APPEND BLAS_SEARCH_LIBS
- "mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_OMP}")
- endif ()
- if (BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR STREQUAL "All")
+ "${BLAS_mkl_START_GROUP} mkl_${BLAS_mkl_INTFACE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_END_GROUP} ${BLAS_mkl_OMP}")
+ endif()
+ if(BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR STREQUAL "All")
# old version
list(APPEND BLAS_SEARCH_LIBS
"mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core guide")
# mkl >= 10.3
list(APPEND BLAS_SEARCH_LIBS
- "mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_OMP}")
- endif ()
- if (BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$" OR BLA_VENDOR STREQUAL "All")
+ "${BLAS_mkl_START_GROUP} mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_${BLAS_mkl_THREADING}_thread mkl_core ${BLAS_mkl_END_GROUP} ${BLAS_mkl_OMP}")
+ endif()
+ if(BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$" OR BLA_VENDOR STREQUAL "All")
list(APPEND BLAS_SEARCH_LIBS
- "mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_sequential mkl_core")
- endif ()
+ "${BLAS_mkl_START_GROUP} mkl_${BLAS_mkl_INTFACE}_${BLAS_mkl_ILP_MODE} mkl_sequential mkl_core ${BLAS_mkl_END_GROUP}")
+ endif()
#older vesions of intel mkl libs
- if (BLA_VENDOR STREQUAL "Intel" OR BLA_VENDOR STREQUAL "All")
+ if(BLA_VENDOR STREQUAL "Intel" OR BLA_VENDOR STREQUAL "All")
list(APPEND BLAS_SEARCH_LIBS
"mkl")
list(APPEND BLAS_SEARCH_LIBS
"mkl_ia32")
list(APPEND BLAS_SEARCH_LIBS
"mkl_em64t")
- endif ()
- endif ()
- endif ()
-
- if (DEFINED ENV{MKLROOT})
- if (BLA_VENDOR STREQUAL "Intel10_32")
- set(_BLAS_MKLROOT_LIB_DIR "$ENV{MKLROOT}/lib/ia32")
- elseif (BLA_VENDOR MATCHES "^Intel10_64i?lp$" OR BLA_VENDOR MATCHES "^Intel10_64i?lp_seq$")
- set(_BLAS_MKLROOT_LIB_DIR "$ENV{MKLROOT}/lib/intel64")
- endif ()
- endif ()
- if (_BLAS_MKLROOT_LIB_DIR)
- if (WIN32)
- string(APPEND _BLAS_MKLROOT_LIB_DIR "_win")
- elseif (APPLE)
- string(APPEND _BLAS_MKLROOT_LIB_DIR "_mac")
- else ()
- string(APPEND _BLAS_MKLROOT_LIB_DIR "_lin")
- endif ()
- endif ()
-
- foreach (IT ${BLAS_SEARCH_LIBS})
+ endif()
+ endif()
+ endif()
+
+ if(BLA_VENDOR MATCHES "^Intel10_64_dyn$" OR BLA_VENDOR STREQUAL "All")
+ # mkl >= 10.3 with single dynamic library
+ list(APPEND BLAS_SEARCH_LIBS
+ "mkl_rt")
+ endif()
+
+ # MKL uses a multitude of partially platform-specific subdirectories:
+ if(BLA_VENDOR STREQUAL "Intel10_32")
+ set(BLAS_mkl_ARCH_NAME "ia32")
+ else()
+ set(BLAS_mkl_ARCH_NAME "intel64")
+ endif()
+ if(WIN32)
+ set(BLAS_mkl_OS_NAME "win")
+ elseif(APPLE)
+ set(BLAS_mkl_OS_NAME "mac")
+ else()
+ set(BLAS_mkl_OS_NAME "lin")
+ endif()
+ if(DEFINED ENV{MKLROOT})
+ set(BLAS_mkl_MKLROOT "$ENV{MKLROOT}")
+ # If MKLROOT points to the subdirectory 'mkl', use the parent directory instead
+ # so we can better detect other relevant libraries in 'compiler' or 'tbb':
+ get_filename_component(BLAS_mkl_MKLROOT_LAST_DIR "${BLAS_mkl_MKLROOT}" NAME)
+ if(BLAS_mkl_MKLROOT_LAST_DIR STREQUAL "mkl")
+ get_filename_component(BLAS_mkl_MKLROOT "${BLAS_mkl_MKLROOT}" DIRECTORY)
+ endif()
+ endif()
+ set(BLAS_mkl_LIB_PATH_SUFFIXES
+ "compiler/lib" "compiler/lib/${BLAS_mkl_ARCH_NAME}_${BLAS_mkl_OS_NAME}"
+ "mkl/lib" "mkl/lib/${BLAS_mkl_ARCH_NAME}_${BLAS_mkl_OS_NAME}"
+ "lib/${BLAS_mkl_ARCH_NAME}_${BLAS_mkl_OS_NAME}")
+
+ foreach(IT ${BLAS_SEARCH_LIBS})
string(REPLACE " " ";" SEARCH_LIBS ${IT})
- if (NOT ${_LIBRARIES})
- check_fortran_libraries(
+ if(NOT ${_LIBRARIES})
+ check_blas_libraries(
${_LIBRARIES}
BLAS
${BLAS_mkl_SEARCH_SYMBOL}
""
"${SEARCH_LIBS}"
"${CMAKE_THREAD_LIBS_INIT};${BLAS_mkl_LM};${BLAS_mkl_LDL}"
- "${_BLAS_MKLROOT_LIB_DIR}"
+ "${BLAS_mkl_MKLROOT}"
+ "${BLAS_mkl_LIB_PATH_SUFFIXES}"
)
- endif ()
- endforeach ()
-
- endif ()
- unset(BLAS_mkl_ILP_MODE)
- unset(BLAS_mkl_INTFACE)
- unset(BLAS_mkl_THREADING)
- unset(BLAS_mkl_OMP)
- unset(BLAS_mkl_DLL_SUFFIX)
- unset(BLAS_mkl_LM)
- unset(BLAS_mkl_LDL)
- endif ()
-endif ()
+ endif()
+ endforeach()
+
+ unset(BLAS_mkl_ILP_MODE)
+ unset(BLAS_mkl_INTFACE)
+ unset(BLAS_mkl_THREADING)
+ unset(BLAS_mkl_OMP)
+ unset(BLAS_mkl_DLL_SUFFIX)
+ unset(BLAS_mkl_LM)
+ unset(BLAS_mkl_LDL)
+ unset(BLAS_mkl_MKLROOT)
+ unset(BLAS_mkl_MKLROOT_LAST_DIR)
+ unset(BLAS_mkl_ARCH_NAME)
+ unset(BLAS_mkl_OS_NAME)
+ unset(BLAS_mkl_LIB_PATH_SUFFIXES)
+ endif()
+ endif()
+endif()
if(BLA_F95)
find_package_handle_standard_args(BLAS REQUIRED_VARS BLAS95_LIBRARIES)
@@ -455,30 +526,34 @@ if(BLA_F95)
endif()
endif()
-if (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All")
+# gotoblas? (http://www.tacc.utexas.edu/tacc-projects/gotoblas2)
+if(BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All")
if(NOT BLAS_LIBRARIES)
- # gotoblas (http://www.tacc.utexas.edu/tacc-projects/gotoblas2)
- check_fortran_libraries(
+ check_blas_libraries(
BLAS_LIBRARIES
BLAS
sgemm
""
"goto2"
""
+ ""
+ ""
)
endif()
-endif ()
+endif()
-if (BLA_VENDOR STREQUAL "OpenBLAS" OR BLA_VENDOR STREQUAL "All")
+# OpenBLAS? (http://www.openblas.net)
+if(BLA_VENDOR STREQUAL "OpenBLAS" OR BLA_VENDOR STREQUAL "All")
if(NOT BLAS_LIBRARIES)
- # OpenBLAS (http://www.openblas.net)
- check_fortran_libraries(
+ check_blas_libraries(
BLAS_LIBRARIES
BLAS
sgemm
""
"openblas"
""
+ ""
+ ""
)
endif()
if(NOT BLAS_LIBRARIES AND (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED))
@@ -487,246 +562,295 @@ if (BLA_VENDOR STREQUAL "OpenBLAS" OR BLA_VENDOR STREQUAL "All")
else()
find_package(Threads REQUIRED)
endif()
- # OpenBLAS (http://www.openblas.net)
- check_fortran_libraries(
+ check_blas_libraries(
BLAS_LIBRARIES
BLAS
sgemm
""
"openblas"
"${CMAKE_THREAD_LIBS_INIT}"
+ ""
+ ""
+ )
+ endif()
+endif()
+
+# ArmPL blas library? (https://developer.arm.com/tools-and-software/server-and-hpc/compile/arm-compiler-for-linux/arm-performance-libraries)
+if(BLA_VENDOR MATCHES "Arm" OR BLA_VENDOR STREQUAL "All")
+
+ # Check for 64bit Integer support
+ if(BLA_VENDOR MATCHES "_ilp64")
+ set(BLAS_armpl_LIB "armpl_ilp64")
+ else()
+ set(BLAS_armpl_LIB "armpl_lp64")
+ endif()
+
+ # Check for OpenMP support, VIA BLA_VENDOR of Arm_mp or Arm_ipl64_mp
+ if(BLA_VENDOR MATCHES "_mp")
+ set(BLAS_armpl_LIB "${BLAS_armpl_LIB}_mp")
+ endif()
+
+ if(NOT BLAS_LIBRARIES)
+ check_blas_libraries(
+ BLAS_LIBRARIES
+ BLAS
+ sgemm
+ ""
+ "${BLAS_armpl_LIB}"
+ ""
+ ""
+ ""
)
endif()
-endif ()
-if (BLA_VENDOR STREQUAL "FLAME" OR BLA_VENDOR STREQUAL "All")
+endif()
+
+# FLAME's blis library? (https://github.com/flame/blis)
+if(BLA_VENDOR STREQUAL "FLAME" OR BLA_VENDOR STREQUAL "All")
if(NOT BLAS_LIBRARIES)
- # FLAME's blis library (https://github.com/flame/blis)
- check_fortran_libraries(
+ check_blas_libraries(
BLAS_LIBRARIES
BLAS
sgemm
""
"blis"
""
+ ""
+ ""
)
endif()
-endif ()
+endif()
-if (BLA_VENDOR STREQUAL "ATLAS" OR BLA_VENDOR STREQUAL "All")
+# BLAS in the ATLAS library? (http://math-atlas.sourceforge.net/)
+if(BLA_VENDOR STREQUAL "ATLAS" OR BLA_VENDOR STREQUAL "All")
if(NOT BLAS_LIBRARIES)
- # BLAS in ATLAS library? (http://math-atlas.sourceforge.net/)
- check_fortran_libraries(
+ check_blas_libraries(
BLAS_LIBRARIES
BLAS
dgemm
""
- "f77blas;atlas"
+ "blas;f77blas;atlas"
+ ""
+ ""
""
)
endif()
-endif ()
+endif()
# BLAS in PhiPACK libraries? (requires generic BLAS lib, too)
-if (BLA_VENDOR STREQUAL "PhiPACK" OR BLA_VENDOR STREQUAL "All")
+if(BLA_VENDOR STREQUAL "PhiPACK" OR BLA_VENDOR STREQUAL "All")
if(NOT BLAS_LIBRARIES)
- check_fortran_libraries(
+ check_blas_libraries(
BLAS_LIBRARIES
BLAS
sgemm
""
"sgemm;dgemm;blas"
""
+ ""
+ ""
)
endif()
-endif ()
+endif()
# BLAS in Alpha CXML library?
-if (BLA_VENDOR STREQUAL "CXML" OR BLA_VENDOR STREQUAL "All")
+if(BLA_VENDOR STREQUAL "CXML" OR BLA_VENDOR STREQUAL "All")
if(NOT BLAS_LIBRARIES)
- check_fortran_libraries(
+ check_blas_libraries(
BLAS_LIBRARIES
BLAS
sgemm
""
"cxml"
""
+ ""
+ ""
)
endif()
-endif ()
+endif()
# BLAS in Alpha DXML library? (now called CXML, see above)
-if (BLA_VENDOR STREQUAL "DXML" OR BLA_VENDOR STREQUAL "All")
+if(BLA_VENDOR STREQUAL "DXML" OR BLA_VENDOR STREQUAL "All")
if(NOT BLAS_LIBRARIES)
- check_fortran_libraries(
+ check_blas_libraries(
BLAS_LIBRARIES
BLAS
sgemm
""
"dxml"
""
+ ""
+ ""
)
endif()
-endif ()
+endif()
# BLAS in Sun Performance library?
-if (BLA_VENDOR STREQUAL "SunPerf" OR BLA_VENDOR STREQUAL "All")
+if(BLA_VENDOR STREQUAL "SunPerf" OR BLA_VENDOR STREQUAL "All")
if(NOT BLAS_LIBRARIES)
- check_fortran_libraries(
+ check_blas_libraries(
BLAS_LIBRARIES
BLAS
sgemm
"-xlic_lib=sunperf"
"sunperf;sunmath"
""
+ ""
+ ""
)
if(BLAS_LIBRARIES)
set(BLAS_LINKER_FLAGS "-xlic_lib=sunperf")
endif()
endif()
-endif ()
+endif()
# BLAS in SCSL library? (SGI/Cray Scientific Library)
-if (BLA_VENDOR STREQUAL "SCSL" OR BLA_VENDOR STREQUAL "All")
+if(BLA_VENDOR STREQUAL "SCSL" OR BLA_VENDOR STREQUAL "All")
if(NOT BLAS_LIBRARIES)
- check_fortran_libraries(
+ check_blas_libraries(
BLAS_LIBRARIES
BLAS
sgemm
""
"scsl"
""
+ ""
+ ""
)
endif()
-endif ()
+endif()
# BLAS in SGIMATH library?
-if (BLA_VENDOR STREQUAL "SGIMATH" OR BLA_VENDOR STREQUAL "All")
+if(BLA_VENDOR STREQUAL "SGIMATH" OR BLA_VENDOR STREQUAL "All")
if(NOT BLAS_LIBRARIES)
- check_fortran_libraries(
+ check_blas_libraries(
BLAS_LIBRARIES
BLAS
sgemm
""
"complib.sgimath"
""
+ ""
+ ""
)
endif()
-endif ()
+endif()
# BLAS in IBM ESSL library? (requires generic BLAS lib, too)
-if (BLA_VENDOR STREQUAL "IBMESSL" OR BLA_VENDOR STREQUAL "All")
+if(BLA_VENDOR STREQUAL "IBMESSL" OR BLA_VENDOR STREQUAL "All")
if(NOT BLAS_LIBRARIES)
- check_fortran_libraries(
+ check_blas_libraries(
BLAS_LIBRARIES
BLAS
sgemm
""
"essl;blas"
""
+ ""
+ ""
)
endif()
-endif ()
+endif()
-#BLAS in acml library?
-if (BLA_VENDOR MATCHES "ACML" OR BLA_VENDOR STREQUAL "All")
- if( ((BLA_VENDOR STREQUAL "ACML") AND (NOT BLAS_ACML_LIB_DIRS)) OR
+# BLAS in acml library?
+if(BLA_VENDOR MATCHES "ACML" OR BLA_VENDOR STREQUAL "All")
+ if(((BLA_VENDOR STREQUAL "ACML") AND (NOT BLAS_ACML_LIB_DIRS)) OR
((BLA_VENDOR STREQUAL "ACML_MP") AND (NOT BLAS_ACML_MP_LIB_DIRS)) OR
((BLA_VENDOR STREQUAL "ACML_GPU") AND (NOT BLAS_ACML_GPU_LIB_DIRS))
)
# try to find acml in "standard" paths
- if( WIN32 )
- file( GLOB _ACML_ROOT "C:/AMD/acml*/ACML-EULA.txt" )
+ if(WIN32)
+ file(GLOB _ACML_ROOT "C:/AMD/acml*/ACML-EULA.txt")
else()
- file( GLOB _ACML_ROOT "/opt/acml*/ACML-EULA.txt" )
+ file(GLOB _ACML_ROOT "/opt/acml*/ACML-EULA.txt")
endif()
- if( WIN32 )
- file( GLOB _ACML_GPU_ROOT "C:/AMD/acml*/GPGPUexamples" )
+ if(WIN32)
+ file(GLOB _ACML_GPU_ROOT "C:/AMD/acml*/GPGPUexamples")
else()
- file( GLOB _ACML_GPU_ROOT "/opt/acml*/GPGPUexamples" )
+ file(GLOB _ACML_GPU_ROOT "/opt/acml*/GPGPUexamples")
endif()
list(GET _ACML_ROOT 0 _ACML_ROOT)
list(GET _ACML_GPU_ROOT 0 _ACML_GPU_ROOT)
- if( _ACML_ROOT )
- get_filename_component( _ACML_ROOT ${_ACML_ROOT} PATH )
- if( SIZEOF_INTEGER EQUAL 8 )
- set( _ACML_PATH_SUFFIX "_int64" )
+ if(_ACML_ROOT)
+ get_filename_component(_ACML_ROOT ${_ACML_ROOT} PATH)
+ if(SIZEOF_INTEGER EQUAL 8)
+ set(_ACML_PATH_SUFFIX "_int64")
else()
- set( _ACML_PATH_SUFFIX "" )
+ set(_ACML_PATH_SUFFIX "")
endif()
- if( CMAKE_Fortran_COMPILER_ID STREQUAL "Intel" )
- set( _ACML_COMPILER32 "ifort32" )
- set( _ACML_COMPILER64 "ifort64" )
- elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "SunPro" )
- set( _ACML_COMPILER32 "sun32" )
- set( _ACML_COMPILER64 "sun64" )
- elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "PGI" )
- set( _ACML_COMPILER32 "pgi32" )
- if( WIN32 )
- set( _ACML_COMPILER64 "win64" )
+ if(CMAKE_Fortran_COMPILER_ID STREQUAL "Intel")
+ set(_ACML_COMPILER32 "ifort32")
+ set(_ACML_COMPILER64 "ifort64")
+ elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "SunPro")
+ set(_ACML_COMPILER32 "sun32")
+ set(_ACML_COMPILER64 "sun64")
+ elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "PGI")
+ set(_ACML_COMPILER32 "pgi32")
+ if(WIN32)
+ set(_ACML_COMPILER64 "win64")
else()
- set( _ACML_COMPILER64 "pgi64" )
+ set(_ACML_COMPILER64 "pgi64")
endif()
- elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "Open64" )
+ elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "Open64")
# 32 bit builds not supported on Open64 but for code simplicity
# We'll just use the same directory twice
- set( _ACML_COMPILER32 "open64_64" )
- set( _ACML_COMPILER64 "open64_64" )
- elseif( CMAKE_Fortran_COMPILER_ID STREQUAL "NAG" )
- set( _ACML_COMPILER32 "nag32" )
- set( _ACML_COMPILER64 "nag64" )
+ set(_ACML_COMPILER32 "open64_64")
+ set(_ACML_COMPILER64 "open64_64")
+ elseif(CMAKE_Fortran_COMPILER_ID STREQUAL "NAG")
+ set(_ACML_COMPILER32 "nag32")
+ set(_ACML_COMPILER64 "nag64")
else()
- set( _ACML_COMPILER32 "gfortran32" )
- set( _ACML_COMPILER64 "gfortran64" )
+ set(_ACML_COMPILER32 "gfortran32")
+ set(_ACML_COMPILER64 "gfortran64")
endif()
- if( BLA_VENDOR STREQUAL "ACML_MP" )
+ if(BLA_VENDOR STREQUAL "ACML_MP")
set(_ACML_MP_LIB_DIRS
"${_ACML_ROOT}/${_ACML_COMPILER32}_mp${_ACML_PATH_SUFFIX}/lib"
- "${_ACML_ROOT}/${_ACML_COMPILER64}_mp${_ACML_PATH_SUFFIX}/lib" )
+ "${_ACML_ROOT}/${_ACML_COMPILER64}_mp${_ACML_PATH_SUFFIX}/lib")
else()
set(_ACML_LIB_DIRS
"${_ACML_ROOT}/${_ACML_COMPILER32}${_ACML_PATH_SUFFIX}/lib"
- "${_ACML_ROOT}/${_ACML_COMPILER64}${_ACML_PATH_SUFFIX}/lib" )
+ "${_ACML_ROOT}/${_ACML_COMPILER64}${_ACML_PATH_SUFFIX}/lib")
endif()
endif()
elseif(BLAS_${BLA_VENDOR}_LIB_DIRS)
set(_${BLA_VENDOR}_LIB_DIRS ${BLAS_${BLA_VENDOR}_LIB_DIRS})
endif()
-if( BLA_VENDOR STREQUAL "ACML_MP" )
- foreach( BLAS_ACML_MP_LIB_DIRS ${_ACML_MP_LIB_DIRS})
- check_fortran_libraries (
+if(BLA_VENDOR STREQUAL "ACML_MP")
+ foreach(BLAS_ACML_MP_LIB_DIRS ${_ACML_MP_LIB_DIRS})
+ check_blas_libraries(
BLAS_LIBRARIES
BLAS
sgemm
- "" "acml_mp;acml_mv" "" ${BLAS_ACML_MP_LIB_DIRS}
+ "" "acml_mp;acml_mv" "" ${BLAS_ACML_MP_LIB_DIRS} ""
)
- if( BLAS_LIBRARIES )
+ if(BLAS_LIBRARIES)
break()
endif()
endforeach()
-elseif( BLA_VENDOR STREQUAL "ACML_GPU" )
- foreach( BLAS_ACML_GPU_LIB_DIRS ${_ACML_GPU_LIB_DIRS})
- check_fortran_libraries (
+elseif(BLA_VENDOR STREQUAL "ACML_GPU")
+ foreach(BLAS_ACML_GPU_LIB_DIRS ${_ACML_GPU_LIB_DIRS})
+ check_blas_libraries(
BLAS_LIBRARIES
BLAS
sgemm
- "" "acml;acml_mv;CALBLAS" "" ${BLAS_ACML_GPU_LIB_DIRS}
+ "" "acml;acml_mv;CALBLAS" "" ${BLAS_ACML_GPU_LIB_DIRS} ""
)
- if( BLAS_LIBRARIES )
+ if(BLAS_LIBRARIES)
break()
endif()
endforeach()
else()
- foreach( BLAS_ACML_LIB_DIRS ${_ACML_LIB_DIRS} )
- check_fortran_libraries (
+ foreach(BLAS_ACML_LIB_DIRS ${_ACML_LIB_DIRS})
+ check_blas_libraries(
BLAS_LIBRARIES
BLAS
sgemm
- "" "acml;acml_mv" "" ${BLAS_ACML_LIB_DIRS}
+ "" "acml;acml_mv" "" ${BLAS_ACML_LIB_DIRS} ""
)
- if( BLAS_LIBRARIES )
+ if(BLAS_LIBRARIES)
break()
endif()
endforeach()
@@ -734,87 +858,102 @@ endif()
# Either acml or acml_mp should be in LD_LIBRARY_PATH but not both
if(NOT BLAS_LIBRARIES)
- check_fortran_libraries(
+ check_blas_libraries(
BLAS_LIBRARIES
BLAS
sgemm
""
"acml;acml_mv"
""
+ ""
+ ""
)
endif()
if(NOT BLAS_LIBRARIES)
- check_fortran_libraries(
+ check_blas_libraries(
BLAS_LIBRARIES
BLAS
sgemm
""
"acml_mp;acml_mv"
""
+ ""
+ ""
)
endif()
if(NOT BLAS_LIBRARIES)
- check_fortran_libraries(
+ check_blas_libraries(
BLAS_LIBRARIES
BLAS
sgemm
""
"acml;acml_mv;CALBLAS"
""
+ ""
+ ""
)
endif()
-endif () # ACML
+endif() # ACML
# Apple BLAS library?
-if (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All")
+if(BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All")
if(NOT BLAS_LIBRARIES)
- check_fortran_libraries(
+ check_blas_libraries(
BLAS_LIBRARIES
BLAS
dgemm
""
"Accelerate"
""
+ ""
+ ""
)
endif()
-endif ()
+endif()
-if (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All")
- if ( NOT BLAS_LIBRARIES )
- check_fortran_libraries(
+# Apple NAS (vecLib) library?
+if(BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All")
+ if(NOT BLAS_LIBRARIES)
+ check_blas_libraries(
BLAS_LIBRARIES
BLAS
dgemm
""
"vecLib"
""
+ ""
+ ""
)
- endif ()
-endif ()
+ endif()
+endif()
# Generic BLAS library?
-if (BLA_VENDOR STREQUAL "Generic" OR BLA_VENDOR STREQUAL "All")
+if(BLA_VENDOR STREQUAL "Generic" OR BLA_VENDOR STREQUAL "All")
if(NOT BLAS_LIBRARIES)
- check_fortran_libraries(
+ check_blas_libraries(
BLAS_LIBRARIES
BLAS
sgemm
""
"blas"
""
+ ""
+ ""
)
endif()
-endif ()
+endif()
if(NOT BLA_F95)
find_package_handle_standard_args(BLAS REQUIRED_VARS BLAS_LIBRARIES)
endif()
+
# On compilers that implicitly link BLAS (such as ftn, cc, and CC on Cray HPC machines)
# we used a placeholder for empty BLAS_LIBRARIES to get through our logic above.
-if (BLAS_LIBRARIES STREQUAL "BLAS_LIBRARIES-PLACEHOLDER-FOR-EMPTY-LIBRARIES")
+if(BLAS_LIBRARIES STREQUAL "BLAS_LIBRARIES-PLACEHOLDER-FOR-EMPTY-LIBRARIES")
set(BLAS_LIBRARIES "")
endif()
+_add_blas_target()
cmake_pop_check_state()
set(CMAKE_FIND_LIBRARY_SUFFIXES ${_blas_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake
index 0e84fab..13981d3 100644
--- a/Modules/FindBoost.cmake
+++ b/Modules/FindBoost.cmake
@@ -155,6 +155,10 @@ setting variables::
used if multiple compatible suffixes should
be tested for, in decreasing order of
preference.
+ Boost_LIB_PREFIX - Set to the platform-specific library name
+ prefix (e.g. "lib") used by Boost static libs.
+ This is needed only on platforms where CMake
+ does not know the prefix by default.
Boost_ARCHITECTURE - Set to the architecture-specific library suffix
(e.g. "-x64"). Default is auto-computed for the
C++ compiler in use.
@@ -248,6 +252,7 @@ include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
# Save project's policies
cmake_policy(PUSH)
cmake_policy(SET CMP0057 NEW) # if IN_LIST
+cmake_policy(SET CMP0102 NEW) # if mark_as_advanced(non_cache_var)
function(_boost_get_existing_target component target_var)
set(names "${component}")
@@ -441,7 +446,9 @@ if (NOT Boost_NO_BOOST_CMAKE)
# Note that args are passed in the Boost_FIND_xxxxx variables, so there is no
# need to delegate them to this find_package call.
find_package(Boost QUIET NO_MODULE)
- mark_as_advanced(Boost_DIR)
+ if (DEFINED Boost_DIR)
+ mark_as_advanced(Boost_DIR)
+ endif ()
# If we found a boost cmake package, then we're done. Print out what we found.
# Otherwise let the rest of the module try to find it.
@@ -747,7 +754,11 @@ function(_Boost_GUESS_COMPILER_PREFIX _ret)
set(_boost_COMPILER "-mgw") # no GCC version encoding prior to 1.34
else()
_Boost_COMPILER_DUMPVERSION(_boost_COMPILER_VERSION _boost_COMPILER_VERSION_MAJOR _boost_COMPILER_VERSION_MINOR)
- set(_boost_COMPILER "-mgw${_boost_COMPILER_VERSION}")
+ if(Boost_VERSION_STRING VERSION_GREATER_EQUAL 1.73 AND _boost_COMPILER_VERSION_MAJOR VERSION_GREATER_EQUAL 5)
+ set(_boost_COMPILER "-mgw${_boost_COMPILER_VERSION_MAJOR}")
+ else()
+ set(_boost_COMPILER "-mgw${_boost_COMPILER_VERSION}")
+ endif()
endif()
elseif (UNIX)
_Boost_COMPILER_DUMPVERSION(_boost_COMPILER_VERSION _boost_COMPILER_VERSION_MAJOR _boost_COMPILER_VERSION_MINOR)
@@ -847,318 +858,334 @@ function(_Boost_COMPONENT_DEPENDENCIES component _ret)
endif()
set(_Boost_IMPORTED_TARGETS TRUE)
- if(Boost_VERSION_STRING AND Boost_VERSION_STRING VERSION_LESS 1.33.0)
- message(WARNING "Imported targets and dependency information not available for Boost version ${Boost_VERSION_STRING} (all versions older than 1.33)")
- set(_Boost_IMPORTED_TARGETS FALSE)
- elseif(NOT Boost_VERSION_STRING VERSION_LESS 1.33.0 AND Boost_VERSION_STRING VERSION_LESS 1.35.0)
- set(_Boost_IOSTREAMS_DEPENDENCIES regex thread)
- set(_Boost_REGEX_DEPENDENCIES thread)
- set(_Boost_WAVE_DEPENDENCIES filesystem thread)
- set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
- elseif(NOT Boost_VERSION_STRING VERSION_LESS 1.35.0 AND Boost_VERSION_STRING VERSION_LESS 1.36.0)
- set(_Boost_FILESYSTEM_DEPENDENCIES system)
- set(_Boost_IOSTREAMS_DEPENDENCIES regex)
- set(_Boost_MPI_DEPENDENCIES serialization)
- set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
- set(_Boost_WAVE_DEPENDENCIES filesystem system thread)
- set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
- elseif(NOT Boost_VERSION_STRING VERSION_LESS 1.36.0 AND Boost_VERSION_STRING VERSION_LESS 1.38.0)
- set(_Boost_FILESYSTEM_DEPENDENCIES system)
- set(_Boost_IOSTREAMS_DEPENDENCIES regex)
- set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l)
- set(_Boost_MPI_DEPENDENCIES serialization)
- set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
- set(_Boost_WAVE_DEPENDENCIES filesystem system thread)
- set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
- elseif(NOT Boost_VERSION_STRING VERSION_LESS 1.38.0 AND Boost_VERSION_STRING VERSION_LESS 1.43.0)
- set(_Boost_FILESYSTEM_DEPENDENCIES system)
- set(_Boost_IOSTREAMS_DEPENDENCIES regex)
- set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l)
- set(_Boost_MPI_DEPENDENCIES serialization)
- set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
- set(_Boost_THREAD_DEPENDENCIES date_time)
- set(_Boost_WAVE_DEPENDENCIES filesystem system thread date_time)
- set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
- elseif(NOT Boost_VERSION_STRING VERSION_LESS 1.43.0 AND Boost_VERSION_STRING VERSION_LESS 1.44.0)
- set(_Boost_FILESYSTEM_DEPENDENCIES system)
- set(_Boost_IOSTREAMS_DEPENDENCIES regex)
- set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random)
- set(_Boost_MPI_DEPENDENCIES serialization)
- set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
- set(_Boost_THREAD_DEPENDENCIES date_time)
- set(_Boost_WAVE_DEPENDENCIES filesystem system thread date_time)
- set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
- elseif(NOT Boost_VERSION_STRING VERSION_LESS 1.44.0 AND Boost_VERSION_STRING VERSION_LESS 1.45.0)
- set(_Boost_FILESYSTEM_DEPENDENCIES system)
- set(_Boost_IOSTREAMS_DEPENDENCIES regex)
- set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random serialization)
- set(_Boost_MPI_DEPENDENCIES serialization)
- set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
- set(_Boost_THREAD_DEPENDENCIES date_time)
- set(_Boost_WAVE_DEPENDENCIES serialization filesystem system thread date_time)
- set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
- elseif(NOT Boost_VERSION_STRING VERSION_LESS 1.45.0 AND Boost_VERSION_STRING VERSION_LESS 1.47.0)
- set(_Boost_FILESYSTEM_DEPENDENCIES system)
- set(_Boost_IOSTREAMS_DEPENDENCIES regex)
- set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random)
- set(_Boost_MPI_DEPENDENCIES serialization)
- set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
- set(_Boost_THREAD_DEPENDENCIES date_time)
- set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread date_time)
- set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
- elseif(NOT Boost_VERSION_STRING VERSION_LESS 1.47.0 AND Boost_VERSION_STRING VERSION_LESS 1.48.0)
- set(_Boost_CHRONO_DEPENDENCIES system)
- set(_Boost_FILESYSTEM_DEPENDENCIES system)
- set(_Boost_IOSTREAMS_DEPENDENCIES regex)
- set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random)
- set(_Boost_MPI_DEPENDENCIES serialization)
- set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
- set(_Boost_THREAD_DEPENDENCIES date_time)
- set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread date_time)
- set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
- elseif(NOT Boost_VERSION_STRING VERSION_LESS 1.48.0 AND Boost_VERSION_STRING VERSION_LESS 1.50.0)
- set(_Boost_CHRONO_DEPENDENCIES system)
- set(_Boost_FILESYSTEM_DEPENDENCIES system)
- set(_Boost_IOSTREAMS_DEPENDENCIES regex)
- set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random)
- set(_Boost_MPI_DEPENDENCIES serialization)
- set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
- set(_Boost_THREAD_DEPENDENCIES date_time)
- set(_Boost_TIMER_DEPENDENCIES chrono system)
- set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread date_time)
- set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
- elseif(NOT Boost_VERSION_STRING VERSION_LESS 1.50.0 AND Boost_VERSION_STRING VERSION_LESS 1.53.0)
- set(_Boost_CHRONO_DEPENDENCIES system)
- set(_Boost_FILESYSTEM_DEPENDENCIES system)
- set(_Boost_IOSTREAMS_DEPENDENCIES regex)
- set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l regex random)
- set(_Boost_MPI_DEPENDENCIES serialization)
- set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
- set(_Boost_THREAD_DEPENDENCIES chrono system date_time)
- set(_Boost_TIMER_DEPENDENCIES chrono system)
- set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time)
- set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
- elseif(NOT Boost_VERSION_STRING VERSION_LESS 1.53.0 AND Boost_VERSION_STRING VERSION_LESS 1.54.0)
- set(_Boost_ATOMIC_DEPENDENCIES thread chrono system date_time)
- set(_Boost_CHRONO_DEPENDENCIES system)
- set(_Boost_FILESYSTEM_DEPENDENCIES system)
- set(_Boost_IOSTREAMS_DEPENDENCIES regex)
- set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l regex random)
- set(_Boost_MPI_DEPENDENCIES serialization)
- set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
- set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
- set(_Boost_TIMER_DEPENDENCIES chrono system)
- set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time)
- set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
- elseif(NOT Boost_VERSION_STRING VERSION_LESS 1.54.0 AND Boost_VERSION_STRING VERSION_LESS 1.55.0)
- set(_Boost_ATOMIC_DEPENDENCIES thread chrono system date_time)
- set(_Boost_CHRONO_DEPENDENCIES system)
- set(_Boost_FILESYSTEM_DEPENDENCIES system)
- set(_Boost_IOSTREAMS_DEPENDENCIES regex)
- set(_Boost_LOG_DEPENDENCIES log_setup date_time system filesystem thread regex chrono)
- set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l regex random)
- set(_Boost_MPI_DEPENDENCIES serialization)
- set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
- set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
- set(_Boost_TIMER_DEPENDENCIES chrono system)
- set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic)
- set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
- elseif(NOT Boost_VERSION_STRING VERSION_LESS 1.55.0 AND Boost_VERSION_STRING VERSION_LESS 1.56.0)
- set(_Boost_CHRONO_DEPENDENCIES system)
- set(_Boost_COROUTINE_DEPENDENCIES context system)
- set(_Boost_FILESYSTEM_DEPENDENCIES system)
- set(_Boost_IOSTREAMS_DEPENDENCIES regex)
- set(_Boost_LOG_DEPENDENCIES log_setup date_time system filesystem thread regex chrono)
- set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l regex random)
- set(_Boost_MPI_DEPENDENCIES serialization)
- set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
- set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
- set(_Boost_TIMER_DEPENDENCIES chrono system)
- set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic)
- set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
- elseif(NOT Boost_VERSION_STRING VERSION_LESS 1.56.0 AND Boost_VERSION_STRING VERSION_LESS 1.59.0)
- set(_Boost_CHRONO_DEPENDENCIES system)
- set(_Boost_COROUTINE_DEPENDENCIES context system)
- set(_Boost_FILESYSTEM_DEPENDENCIES system)
- set(_Boost_IOSTREAMS_DEPENDENCIES regex)
- set(_Boost_LOG_DEPENDENCIES log_setup date_time system filesystem thread regex chrono)
- set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic)
- set(_Boost_MPI_DEPENDENCIES serialization)
- set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
- set(_Boost_RANDOM_DEPENDENCIES system)
- set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
- set(_Boost_TIMER_DEPENDENCIES chrono system)
- set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic)
- set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
- elseif(NOT Boost_VERSION_STRING VERSION_LESS 1.59.0 AND Boost_VERSION_STRING VERSION_LESS 1.60.0)
- set(_Boost_CHRONO_DEPENDENCIES system)
- set(_Boost_COROUTINE_DEPENDENCIES context system)
- set(_Boost_FILESYSTEM_DEPENDENCIES system)
- set(_Boost_IOSTREAMS_DEPENDENCIES regex)
- set(_Boost_LOG_DEPENDENCIES log_setup date_time system filesystem thread regex chrono atomic)
- set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic)
- set(_Boost_MPI_DEPENDENCIES serialization)
- set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
- set(_Boost_RANDOM_DEPENDENCIES system)
- set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
- set(_Boost_TIMER_DEPENDENCIES chrono system)
- set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic)
- set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
- elseif(NOT Boost_VERSION_STRING VERSION_LESS 1.60.0 AND Boost_VERSION_STRING VERSION_LESS 1.61.0)
- set(_Boost_CHRONO_DEPENDENCIES system)
- set(_Boost_COROUTINE_DEPENDENCIES context system)
- set(_Boost_FILESYSTEM_DEPENDENCIES system)
- set(_Boost_IOSTREAMS_DEPENDENCIES regex)
- set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic)
- set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic)
- set(_Boost_MPI_DEPENDENCIES serialization)
- set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
- set(_Boost_RANDOM_DEPENDENCIES system)
- set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
- set(_Boost_TIMER_DEPENDENCIES chrono system)
- set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic)
- set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
- elseif(NOT Boost_VERSION_STRING VERSION_LESS 1.61.0 AND Boost_VERSION_STRING VERSION_LESS 1.62.0)
- set(_Boost_CHRONO_DEPENDENCIES system)
- set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time)
- set(_Boost_COROUTINE_DEPENDENCIES context system)
- set(_Boost_FILESYSTEM_DEPENDENCIES system)
- set(_Boost_IOSTREAMS_DEPENDENCIES regex)
- set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic)
- set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic)
- set(_Boost_MPI_DEPENDENCIES serialization)
- set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
- set(_Boost_RANDOM_DEPENDENCIES system)
- set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
- set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic)
- set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
- elseif(NOT Boost_VERSION_STRING VERSION_LESS 1.62.0 AND Boost_VERSION_STRING VERSION_LESS 1.63.0)
- set(_Boost_CHRONO_DEPENDENCIES system)
- set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time)
- set(_Boost_COROUTINE_DEPENDENCIES context system)
- set(_Boost_FIBER_DEPENDENCIES context thread chrono system date_time)
- set(_Boost_FILESYSTEM_DEPENDENCIES system)
- set(_Boost_IOSTREAMS_DEPENDENCIES regex)
- set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic)
- set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic)
- set(_Boost_MPI_DEPENDENCIES serialization)
- set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
- set(_Boost_RANDOM_DEPENDENCIES system)
- set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
- set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic)
- set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
- elseif(NOT Boost_VERSION_STRING VERSION_LESS 1.63.0 AND Boost_VERSION_STRING VERSION_LESS 1.65.0)
- set(_Boost_CHRONO_DEPENDENCIES system)
- set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time)
- set(_Boost_COROUTINE_DEPENDENCIES context system)
- set(_Boost_COROUTINE2_DEPENDENCIES context fiber thread chrono system date_time)
- set(_Boost_FIBER_DEPENDENCIES context thread chrono system date_time)
- set(_Boost_FILESYSTEM_DEPENDENCIES system)
- set(_Boost_IOSTREAMS_DEPENDENCIES regex)
- set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic)
- set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic)
- set(_Boost_MPI_DEPENDENCIES serialization)
- set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
- set(_Boost_RANDOM_DEPENDENCIES system)
- set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
- set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic)
- set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
- elseif(NOT Boost_VERSION_STRING VERSION_LESS 1.65.0 AND Boost_VERSION_STRING VERSION_LESS 1.67.0)
- set(_Boost_CHRONO_DEPENDENCIES system)
- set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time)
- set(_Boost_COROUTINE_DEPENDENCIES context system)
- set(_Boost_FIBER_DEPENDENCIES context thread chrono system date_time)
- set(_Boost_FILESYSTEM_DEPENDENCIES system)
- set(_Boost_IOSTREAMS_DEPENDENCIES regex)
- set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic)
- set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic)
- set(_Boost_MPI_DEPENDENCIES serialization)
- set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
- set(_Boost_NUMPY_DEPENDENCIES python${component_python_version})
- set(_Boost_RANDOM_DEPENDENCIES system)
- set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
- set(_Boost_TIMER_DEPENDENCIES chrono system)
- set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic)
- set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
- elseif(NOT Boost_VERSION_STRING VERSION_LESS 1.67.0 AND Boost_VERSION_STRING VERSION_LESS 1.68.0)
- set(_Boost_CHRONO_DEPENDENCIES system)
- set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time)
- set(_Boost_COROUTINE_DEPENDENCIES context system)
- set(_Boost_FIBER_DEPENDENCIES context thread chrono system date_time)
- set(_Boost_FILESYSTEM_DEPENDENCIES system)
- set(_Boost_IOSTREAMS_DEPENDENCIES regex)
- set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic)
- set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic)
- set(_Boost_MPI_DEPENDENCIES serialization)
- set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
- set(_Boost_NUMPY_DEPENDENCIES python${component_python_version})
- set(_Boost_RANDOM_DEPENDENCIES system)
- set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
- set(_Boost_TIMER_DEPENDENCIES chrono system)
- set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic)
- set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
- elseif(NOT Boost_VERSION_STRING VERSION_LESS 1.68.0 AND Boost_VERSION_STRING VERSION_LESS 1.69.0)
- set(_Boost_CHRONO_DEPENDENCIES system)
- set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time)
- set(_Boost_CONTRACT_DEPENDENCIES thread chrono system date_time)
- set(_Boost_COROUTINE_DEPENDENCIES context system)
- set(_Boost_FIBER_DEPENDENCIES context thread chrono system date_time)
- set(_Boost_FILESYSTEM_DEPENDENCIES system)
- set(_Boost_IOSTREAMS_DEPENDENCIES regex)
- set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic)
- set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic)
- set(_Boost_MPI_DEPENDENCIES serialization)
- set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
- set(_Boost_NUMPY_DEPENDENCIES python${component_python_version})
- set(_Boost_RANDOM_DEPENDENCIES system)
- set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
- set(_Boost_TIMER_DEPENDENCIES chrono system)
- set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic)
- set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
- elseif(NOT Boost_VERSION_STRING VERSION_LESS 1.69.0 AND Boost_VERSION_STRING VERSION_LESS 1.70.0)
- set(_Boost_CONTRACT_DEPENDENCIES thread chrono date_time)
- set(_Boost_COROUTINE_DEPENDENCIES context)
- set(_Boost_FIBER_DEPENDENCIES context)
- set(_Boost_IOSTREAMS_DEPENDENCIES regex)
- set(_Boost_LOG_DEPENDENCIES date_time log_setup filesystem thread regex chrono atomic)
- set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic)
- set(_Boost_MPI_DEPENDENCIES serialization)
- set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
- set(_Boost_NUMPY_DEPENDENCIES python${component_python_version})
- set(_Boost_THREAD_DEPENDENCIES chrono date_time atomic)
- set(_Boost_TIMER_DEPENDENCIES chrono system)
- set(_Boost_WAVE_DEPENDENCIES filesystem serialization thread chrono date_time atomic)
- set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
- elseif(NOT Boost_VERSION_STRING VERSION_LESS 1.70.0 AND Boost_VERSION_STRING VERSION_LESS 1.72.0)
- set(_Boost_CONTRACT_DEPENDENCIES thread chrono date_time)
- set(_Boost_COROUTINE_DEPENDENCIES context)
- set(_Boost_FIBER_DEPENDENCIES context)
- set(_Boost_IOSTREAMS_DEPENDENCIES regex)
- set(_Boost_LOG_DEPENDENCIES date_time log_setup filesystem thread regex chrono atomic)
- set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic)
- set(_Boost_MPI_DEPENDENCIES serialization)
- set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
- set(_Boost_NUMPY_DEPENDENCIES python${component_python_version})
- set(_Boost_THREAD_DEPENDENCIES chrono date_time atomic)
- set(_Boost_TIMER_DEPENDENCIES chrono)
- set(_Boost_WAVE_DEPENDENCIES filesystem serialization thread chrono date_time atomic)
- set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
- elseif(NOT Boost_VERSION_STRING VERSION_LESS 1.72.0)
- set(_Boost_CONTRACT_DEPENDENCIES thread chrono date_time)
- set(_Boost_COROUTINE_DEPENDENCIES context)
- set(_Boost_FIBER_DEPENDENCIES context)
- set(_Boost_IOSTREAMS_DEPENDENCIES regex)
- set(_Boost_LOG_DEPENDENCIES date_time log_setup filesystem thread regex chrono atomic)
- set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l chrono atomic)
- set(_Boost_MPI_DEPENDENCIES serialization)
- set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
- set(_Boost_NUMPY_DEPENDENCIES python${component_python_version})
- set(_Boost_THREAD_DEPENDENCIES chrono date_time atomic)
- set(_Boost_TIMER_DEPENDENCIES chrono)
- set(_Boost_WAVE_DEPENDENCIES filesystem serialization thread chrono date_time atomic)
- set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
- if(NOT Boost_VERSION_STRING VERSION_LESS 1.73.0)
- message(WARNING "New Boost version may have incorrect or missing dependencies and imported targets")
+ if(Boost_VERSION_STRING)
+ if(Boost_VERSION_STRING VERSION_LESS 1.33.0)
+ message(WARNING "Imported targets and dependency information not available for Boost version ${Boost_VERSION_STRING} (all versions older than 1.33)")
+ set(_Boost_IMPORTED_TARGETS FALSE)
+ elseif(Boost_VERSION_STRING VERSION_LESS 1.35.0)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex thread)
+ set(_Boost_REGEX_DEPENDENCIES thread)
+ set(_Boost_WAVE_DEPENDENCIES filesystem thread)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(Boost_VERSION_STRING VERSION_LESS 1.36.0)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system thread)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(Boost_VERSION_STRING VERSION_LESS 1.38.0)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system thread)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(Boost_VERSION_STRING VERSION_LESS 1.43.0)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
+ set(_Boost_THREAD_DEPENDENCIES date_time)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system thread date_time)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(Boost_VERSION_STRING VERSION_LESS 1.44.0)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
+ set(_Boost_THREAD_DEPENDENCIES date_time)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system thread date_time)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(Boost_VERSION_STRING VERSION_LESS 1.45.0)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random serialization)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
+ set(_Boost_THREAD_DEPENDENCIES date_time)
+ set(_Boost_WAVE_DEPENDENCIES serialization filesystem system thread date_time)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(Boost_VERSION_STRING VERSION_LESS 1.47.0)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
+ set(_Boost_THREAD_DEPENDENCIES date_time)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread date_time)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(Boost_VERSION_STRING VERSION_LESS 1.48.0)
+ set(_Boost_CHRONO_DEPENDENCIES system)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
+ set(_Boost_THREAD_DEPENDENCIES date_time)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread date_time)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(Boost_VERSION_STRING VERSION_LESS 1.50.0)
+ set(_Boost_CHRONO_DEPENDENCIES system)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
+ set(_Boost_THREAD_DEPENDENCIES date_time)
+ set(_Boost_TIMER_DEPENDENCIES chrono system)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread date_time)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(Boost_VERSION_STRING VERSION_LESS 1.53.0)
+ set(_Boost_CHRONO_DEPENDENCIES system)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l regex random)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
+ set(_Boost_THREAD_DEPENDENCIES chrono system date_time)
+ set(_Boost_TIMER_DEPENDENCIES chrono system)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(Boost_VERSION_STRING VERSION_LESS 1.54.0)
+ set(_Boost_ATOMIC_DEPENDENCIES thread chrono system date_time)
+ set(_Boost_CHRONO_DEPENDENCIES system)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l regex random)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
+ set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
+ set(_Boost_TIMER_DEPENDENCIES chrono system)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(Boost_VERSION_STRING VERSION_LESS 1.55.0)
+ set(_Boost_ATOMIC_DEPENDENCIES thread chrono system date_time)
+ set(_Boost_CHRONO_DEPENDENCIES system)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_LOG_DEPENDENCIES log_setup date_time system filesystem thread regex chrono)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l regex random)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
+ set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
+ set(_Boost_TIMER_DEPENDENCIES chrono system)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(Boost_VERSION_STRING VERSION_LESS 1.56.0)
+ set(_Boost_CHRONO_DEPENDENCIES system)
+ set(_Boost_COROUTINE_DEPENDENCIES context system)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_LOG_DEPENDENCIES log_setup date_time system filesystem thread regex chrono)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l regex random)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
+ set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
+ set(_Boost_TIMER_DEPENDENCIES chrono system)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(Boost_VERSION_STRING VERSION_LESS 1.59.0)
+ set(_Boost_CHRONO_DEPENDENCIES system)
+ set(_Boost_COROUTINE_DEPENDENCIES context system)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_LOG_DEPENDENCIES log_setup date_time system filesystem thread regex chrono)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
+ set(_Boost_RANDOM_DEPENDENCIES system)
+ set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
+ set(_Boost_TIMER_DEPENDENCIES chrono system)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(Boost_VERSION_STRING VERSION_LESS 1.60.0)
+ set(_Boost_CHRONO_DEPENDENCIES system)
+ set(_Boost_COROUTINE_DEPENDENCIES context system)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_LOG_DEPENDENCIES log_setup date_time system filesystem thread regex chrono atomic)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
+ set(_Boost_RANDOM_DEPENDENCIES system)
+ set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
+ set(_Boost_TIMER_DEPENDENCIES chrono system)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(Boost_VERSION_STRING VERSION_LESS 1.61.0)
+ set(_Boost_CHRONO_DEPENDENCIES system)
+ set(_Boost_COROUTINE_DEPENDENCIES context system)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
+ set(_Boost_RANDOM_DEPENDENCIES system)
+ set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
+ set(_Boost_TIMER_DEPENDENCIES chrono system)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(Boost_VERSION_STRING VERSION_LESS 1.62.0)
+ set(_Boost_CHRONO_DEPENDENCIES system)
+ set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time)
+ set(_Boost_COROUTINE_DEPENDENCIES context system)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
+ set(_Boost_RANDOM_DEPENDENCIES system)
+ set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(Boost_VERSION_STRING VERSION_LESS 1.63.0)
+ set(_Boost_CHRONO_DEPENDENCIES system)
+ set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time)
+ set(_Boost_COROUTINE_DEPENDENCIES context system)
+ set(_Boost_FIBER_DEPENDENCIES context thread chrono system date_time)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
+ set(_Boost_RANDOM_DEPENDENCIES system)
+ set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(Boost_VERSION_STRING VERSION_LESS 1.65.0)
+ set(_Boost_CHRONO_DEPENDENCIES system)
+ set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time)
+ set(_Boost_COROUTINE_DEPENDENCIES context system)
+ set(_Boost_COROUTINE2_DEPENDENCIES context fiber thread chrono system date_time)
+ set(_Boost_FIBER_DEPENDENCIES context thread chrono system date_time)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
+ set(_Boost_RANDOM_DEPENDENCIES system)
+ set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(Boost_VERSION_STRING VERSION_LESS 1.67.0)
+ set(_Boost_CHRONO_DEPENDENCIES system)
+ set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time)
+ set(_Boost_COROUTINE_DEPENDENCIES context system)
+ set(_Boost_FIBER_DEPENDENCIES context thread chrono system date_time)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
+ set(_Boost_NUMPY_DEPENDENCIES python${component_python_version})
+ set(_Boost_RANDOM_DEPENDENCIES system)
+ set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
+ set(_Boost_TIMER_DEPENDENCIES chrono system)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(Boost_VERSION_STRING VERSION_LESS 1.68.0)
+ set(_Boost_CHRONO_DEPENDENCIES system)
+ set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time)
+ set(_Boost_COROUTINE_DEPENDENCIES context system)
+ set(_Boost_FIBER_DEPENDENCIES context thread chrono system date_time)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
+ set(_Boost_NUMPY_DEPENDENCIES python${component_python_version})
+ set(_Boost_RANDOM_DEPENDENCIES system)
+ set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
+ set(_Boost_TIMER_DEPENDENCIES chrono system)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(Boost_VERSION_STRING VERSION_LESS 1.69.0)
+ set(_Boost_CHRONO_DEPENDENCIES system)
+ set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time)
+ set(_Boost_CONTRACT_DEPENDENCIES thread chrono system date_time)
+ set(_Boost_COROUTINE_DEPENDENCIES context system)
+ set(_Boost_FIBER_DEPENDENCIES context thread chrono system date_time)
+ set(_Boost_FILESYSTEM_DEPENDENCIES system)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
+ set(_Boost_NUMPY_DEPENDENCIES python${component_python_version})
+ set(_Boost_RANDOM_DEPENDENCIES system)
+ set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic)
+ set(_Boost_TIMER_DEPENDENCIES chrono system)
+ set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(Boost_VERSION_STRING VERSION_LESS 1.70.0)
+ set(_Boost_CONTRACT_DEPENDENCIES thread chrono date_time)
+ set(_Boost_COROUTINE_DEPENDENCIES context)
+ set(_Boost_FIBER_DEPENDENCIES context)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_LOG_DEPENDENCIES date_time log_setup filesystem thread regex chrono atomic)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
+ set(_Boost_NUMPY_DEPENDENCIES python${component_python_version})
+ set(_Boost_THREAD_DEPENDENCIES chrono date_time atomic)
+ set(_Boost_TIMER_DEPENDENCIES chrono system)
+ set(_Boost_WAVE_DEPENDENCIES filesystem serialization thread chrono date_time atomic)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(Boost_VERSION_STRING VERSION_LESS 1.72.0)
+ set(_Boost_CONTRACT_DEPENDENCIES thread chrono date_time)
+ set(_Boost_COROUTINE_DEPENDENCIES context)
+ set(_Boost_FIBER_DEPENDENCIES context)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_LOG_DEPENDENCIES date_time log_setup filesystem thread regex chrono atomic)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
+ set(_Boost_NUMPY_DEPENDENCIES python${component_python_version})
+ set(_Boost_THREAD_DEPENDENCIES chrono date_time atomic)
+ set(_Boost_TIMER_DEPENDENCIES chrono)
+ set(_Boost_WAVE_DEPENDENCIES filesystem serialization thread chrono date_time atomic)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ elseif(Boost_VERSION_STRING VERSION_LESS 1.73.0)
+ set(_Boost_CONTRACT_DEPENDENCIES thread chrono date_time)
+ set(_Boost_COROUTINE_DEPENDENCIES context)
+ set(_Boost_FIBER_DEPENDENCIES context)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_LOG_DEPENDENCIES date_time log_setup filesystem thread regex chrono atomic)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l chrono atomic)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
+ set(_Boost_NUMPY_DEPENDENCIES python${component_python_version})
+ set(_Boost_THREAD_DEPENDENCIES chrono date_time atomic)
+ set(_Boost_TIMER_DEPENDENCIES chrono)
+ set(_Boost_WAVE_DEPENDENCIES filesystem serialization thread chrono date_time atomic)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ else()
+ set(_Boost_CONTRACT_DEPENDENCIES thread chrono date_time)
+ set(_Boost_COROUTINE_DEPENDENCIES context)
+ set(_Boost_FIBER_DEPENDENCIES context)
+ set(_Boost_IOSTREAMS_DEPENDENCIES regex)
+ set(_Boost_LOG_DEPENDENCIES date_time log_setup filesystem thread regex chrono atomic)
+ set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic)
+ set(_Boost_MPI_DEPENDENCIES serialization)
+ set(_Boost_MPI_PYTHON_DEPENDENCIES python${component_python_version} mpi serialization)
+ set(_Boost_NUMPY_DEPENDENCIES python${component_python_version})
+ set(_Boost_THREAD_DEPENDENCIES chrono date_time atomic)
+ set(_Boost_TIMER_DEPENDENCIES chrono)
+ set(_Boost_WAVE_DEPENDENCIES filesystem serialization thread chrono date_time atomic)
+ set(_Boost_WSERIALIZATION_DEPENDENCIES serialization)
+ if(Boost_VERSION_STRING VERSION_GREATER_EQUAL 1.74.0)
+ message(WARNING "New Boost version may have incorrect or missing dependencies and imported targets")
+ endif()
endif()
endif()
@@ -1221,6 +1248,7 @@ function(_Boost_COMPONENT_HEADERS component _hdrs)
set(_Boost_MPI_HEADERS "boost/mpi.hpp")
set(_Boost_MPI_PYTHON_HEADERS "boost/mpi/python/config.hpp")
set(_Boost_NUMPY_HEADERS "boost/python/numpy.hpp")
+ set(_Boost_NOWIDE_HEADERS "boost/nowide/cstdlib.hpp")
set(_Boost_PRG_EXEC_MONITOR_HEADERS "boost/test/prg_exec_monitor.hpp")
set(_Boost_PROGRAM_OPTIONS_HEADERS "boost/program_options.hpp")
set(_Boost_PYTHON_HEADERS "boost/python.hpp")
@@ -1429,7 +1457,7 @@ else()
# _Boost_COMPONENT_HEADERS. See the instructions at the top of
# _Boost_COMPONENT_DEPENDENCIES.
set(_Boost_KNOWN_VERSIONS ${Boost_ADDITIONAL_VERSIONS}
- "1.72.0" "1.72" "1.71.0" "1.71" "1.70.0" "1.70" "1.69.0" "1.69"
+ "1.73.0" "1.73" "1.72.0" "1.72" "1.71.0" "1.71" "1.70.0" "1.70" "1.69.0" "1.69"
"1.68.0" "1.68" "1.67.0" "1.67" "1.66.0" "1.66" "1.65.1" "1.65.0" "1.65"
"1.64.0" "1.64" "1.63.0" "1.63" "1.62.0" "1.62" "1.61.0" "1.61" "1.60.0" "1.60"
"1.59.0" "1.59" "1.58.0" "1.58" "1.57.0" "1.57" "1.56.0" "1.56" "1.55.0" "1.55"
@@ -1467,43 +1495,6 @@ _Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}"
_Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "Boost_ADDITIONAL_VERSIONS")
_Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "Boost_NO_SYSTEM_PATHS")
-# Supply Boost_LIB_DIAGNOSTIC_DEFINITIONS as a convenience target. It
-# will only contain any interface definitions on WIN32, but is created
-# on all platforms to keep end user code free from platform dependent
-# code. Also provide convenience targets to disable autolinking and
-# enable dynamic linking.
-if(NOT TARGET Boost::diagnostic_definitions)
- add_library(Boost::diagnostic_definitions INTERFACE IMPORTED)
- add_library(Boost::disable_autolinking INTERFACE IMPORTED)
- add_library(Boost::dynamic_linking INTERFACE IMPORTED)
- set_target_properties(Boost::dynamic_linking PROPERTIES
- INTERFACE_COMPILE_DEFINITIONS "BOOST_ALL_DYN_LINK")
-endif()
-if(WIN32)
- # In windows, automatic linking is performed, so you do not have
- # to specify the libraries. If you are linking to a dynamic
- # runtime, then you can choose to link to either a static or a
- # dynamic Boost library, the default is to do a static link. You
- # can alter this for a specific library "whatever" by defining
- # BOOST_WHATEVER_DYN_LINK to force Boost library "whatever" to be
- # linked dynamically. Alternatively you can force all Boost
- # libraries to dynamic link by defining BOOST_ALL_DYN_LINK.
-
- # This feature can be disabled for Boost library "whatever" by
- # defining BOOST_WHATEVER_NO_LIB, or for all of Boost by defining
- # BOOST_ALL_NO_LIB.
-
- # If you want to observe which libraries are being linked against
- # then defining BOOST_LIB_DIAGNOSTIC will cause the auto-linking
- # code to emit a #pragma message each time a library is selected
- # for linking.
- set(Boost_LIB_DIAGNOSTIC_DEFINITIONS "-DBOOST_LIB_DIAGNOSTIC")
- set_target_properties(Boost::diagnostic_definitions PROPERTIES
- INTERFACE_COMPILE_DEFINITIONS "BOOST_LIB_DIAGNOSTIC")
- set_target_properties(Boost::disable_autolinking PROPERTIES
- INTERFACE_COMPILE_DEFINITIONS "BOOST_ALL_NO_LIB")
-endif()
-
cmake_policy(GET CMP0074 _Boost_CMP0074)
if(NOT "x${_Boost_CMP0074}x" STREQUAL "xNEWx")
_Boost_CHECK_SPELLING(Boost_ROOT)
@@ -1680,10 +1671,17 @@ endif()
# Prefix initialization
# ------------------------------------------------------------------------
-set(Boost_LIB_PREFIX "")
-if ( (GHSMULTI AND Boost_USE_STATIC_LIBS) OR
- (WIN32 AND Boost_USE_STATIC_LIBS AND NOT CYGWIN) )
- set(Boost_LIB_PREFIX "lib")
+if ( NOT DEFINED Boost_LIB_PREFIX )
+ # Boost's static libraries use a "lib" prefix on DLL platforms
+ # to distinguish them from the DLL import libraries.
+ if (Boost_USE_STATIC_LIBS AND (
+ (WIN32 AND NOT CYGWIN)
+ OR GHSMULTI
+ ))
+ set(Boost_LIB_PREFIX "lib")
+ else()
+ set(Boost_LIB_PREFIX "")
+ endif()
endif()
if ( NOT Boost_NAMESPACE )
@@ -2296,6 +2294,43 @@ if(Boost_FOUND)
endif()
endif()
endforeach()
+
+ # Supply Boost_LIB_DIAGNOSTIC_DEFINITIONS as a convenience target. It
+ # will only contain any interface definitions on WIN32, but is created
+ # on all platforms to keep end user code free from platform dependent
+ # code. Also provide convenience targets to disable autolinking and
+ # enable dynamic linking.
+ if(NOT TARGET Boost::diagnostic_definitions)
+ add_library(Boost::diagnostic_definitions INTERFACE IMPORTED)
+ add_library(Boost::disable_autolinking INTERFACE IMPORTED)
+ add_library(Boost::dynamic_linking INTERFACE IMPORTED)
+ set_target_properties(Boost::dynamic_linking PROPERTIES
+ INTERFACE_COMPILE_DEFINITIONS "BOOST_ALL_DYN_LINK")
+ endif()
+ if(WIN32)
+ # In windows, automatic linking is performed, so you do not have
+ # to specify the libraries. If you are linking to a dynamic
+ # runtime, then you can choose to link to either a static or a
+ # dynamic Boost library, the default is to do a static link. You
+ # can alter this for a specific library "whatever" by defining
+ # BOOST_WHATEVER_DYN_LINK to force Boost library "whatever" to be
+ # linked dynamically. Alternatively you can force all Boost
+ # libraries to dynamic link by defining BOOST_ALL_DYN_LINK.
+
+ # This feature can be disabled for Boost library "whatever" by
+ # defining BOOST_WHATEVER_NO_LIB, or for all of Boost by defining
+ # BOOST_ALL_NO_LIB.
+
+ # If you want to observe which libraries are being linked against
+ # then defining BOOST_LIB_DIAGNOSTIC will cause the auto-linking
+ # code to emit a #pragma message each time a library is selected
+ # for linking.
+ set(Boost_LIB_DIAGNOSTIC_DEFINITIONS "-DBOOST_LIB_DIAGNOSTIC")
+ set_target_properties(Boost::diagnostic_definitions PROPERTIES
+ INTERFACE_COMPILE_DEFINITIONS "BOOST_LIB_DIAGNOSTIC")
+ set_target_properties(Boost::disable_autolinking PROPERTIES
+ INTERFACE_COMPILE_DEFINITIONS "BOOST_ALL_NO_LIB")
+ endif()
endif()
# ------------------------------------------------------------------------
diff --git a/Modules/FindCUDA.cmake b/Modules/FindCUDA.cmake
index b6859aa..e1af2d6 100644
--- a/Modules/FindCUDA.cmake
+++ b/Modules/FindCUDA.cmake
@@ -5,17 +5,22 @@ FindCUDA
.. deprecated:: 3.10
Superseded by first-class support for the CUDA language in CMake.
+ Superseded by the :module:`FindCUDAToolkit` for CUDA toolkit libraries.
Replacement
^^^^^^^^^^^
-It is no longer necessary to use this module or call ``find_package(CUDA)``.
-Instead, list ``CUDA`` among the languages named in the top-level
-call to the :command:`project` command, or call the
+It is no longer necessary to use this module or call ``find_package(CUDA)``
+for compiling CUDA code. Instead, list ``CUDA`` among the languages named
+in the top-level call to the :command:`project` command, or call the
:command:`enable_language` command with ``CUDA``.
Then one can add CUDA (``.cu``) sources to programs directly
in calls to :command:`add_library` and :command:`add_executable`.
+To find and use the CUDA toolkit libraries the :module:`FindCUDAToolkit`
+module has superseded this module. It works whether or not the ``CUDA``
+language is enabled.
+
Documentation of Deprecated Usage
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -676,7 +681,7 @@ endif()
# Search for the cuda distribution.
if(NOT CUDA_TOOLKIT_ROOT_DIR AND NOT CMAKE_CROSSCOMPILING)
# Search in the CUDA_BIN_PATH first.
- find_path(CUDA_TOOLKIT_ROOT_DIR
+ find_program(CUDA_TOOLKIT_ROOT_DIR_NVCC
NAMES nvcc nvcc.exe
PATHS
ENV CUDA_TOOLKIT_ROOT
@@ -688,19 +693,22 @@ if(NOT CUDA_TOOLKIT_ROOT_DIR AND NOT CMAKE_CROSSCOMPILING)
)
# Now search default paths
- find_path(CUDA_TOOLKIT_ROOT_DIR
+ find_program(CUDA_TOOLKIT_ROOT_DIR_NVCC
NAMES nvcc nvcc.exe
PATHS /opt/cuda/bin
PATH_SUFFIXES cuda/bin
DOC "Toolkit location."
)
- if (CUDA_TOOLKIT_ROOT_DIR)
+ if (CUDA_TOOLKIT_ROOT_DIR_NVCC)
+ get_filename_component(CUDA_TOOLKIT_ROOT_DIR_NVCC_PAR "${CUDA_TOOLKIT_ROOT_DIR_NVCC}" DIRECTORY)
+ get_filename_component(CUDA_TOOLKIT_ROOT_DIR "${CUDA_TOOLKIT_ROOT_DIR_NVCC_PAR}" DIRECTORY CACHE)
string(REGEX REPLACE "[/\\\\]?bin[64]*[/\\\\]?$" "" CUDA_TOOLKIT_ROOT_DIR ${CUDA_TOOLKIT_ROOT_DIR})
# We need to force this back into the cache.
set(CUDA_TOOLKIT_ROOT_DIR ${CUDA_TOOLKIT_ROOT_DIR} CACHE PATH "Toolkit location." FORCE)
set(CUDA_TOOLKIT_TARGET_DIR ${CUDA_TOOLKIT_ROOT_DIR})
endif()
+ unset(CUDA_TOOLKIT_ROOT_DIR_NVCC CACHE)
if (NOT EXISTS ${CUDA_TOOLKIT_ROOT_DIR})
if(CUDA_FIND_REQUIRED)
@@ -921,7 +929,11 @@ set(CUDA_LIBRARIES)
if(CUDA_BUILD_EMULATION AND CUDA_CUDARTEMU_LIBRARY)
list(APPEND CUDA_LIBRARIES ${CUDA_CUDARTEMU_LIBRARY})
elseif(CUDA_USE_STATIC_CUDA_RUNTIME AND CUDA_cudart_static_LIBRARY)
- list(APPEND CUDA_LIBRARIES ${CUDA_cudart_static_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS})
+ list(APPEND CUDA_LIBRARIES ${CUDA_cudart_static_LIBRARY})
+ if (TARGET Threads::Threads)
+ list(APPEND CUDA_LIBRARIES Threads::Threads)
+ endif()
+ list(APPEND CUDA_LIBRARIES ${CMAKE_DL_LIBS})
if (CUDA_rt_LIBRARY)
list(APPEND CUDA_LIBRARIES ${CUDA_rt_LIBRARY})
endif()
@@ -2003,7 +2015,7 @@ macro(CUDA_BUILD_CLEAN_TARGET)
string(TOUPPER ${cuda_clean_target_name} cuda_clean_target_name)
endif()
add_custom_target(${cuda_clean_target_name}
- COMMAND ${CMAKE_COMMAND} -E remove ${CUDA_ADDITIONAL_CLEAN_FILES})
+ COMMAND ${CMAKE_COMMAND} -E rm -f ${CUDA_ADDITIONAL_CLEAN_FILES})
# Clear out the variable, so the next time we configure it will be empty.
# This is useful so that the files won't persist in the list after targets
diff --git a/Modules/FindCUDA/run_nvcc.cmake b/Modules/FindCUDA/run_nvcc.cmake
index af15d55..ba35433 100644
--- a/Modules/FindCUDA/run_nvcc.cmake
+++ b/Modules/FindCUDA/run_nvcc.cmake
@@ -174,7 +174,7 @@ endmacro()
# Delete the target file
cuda_execute_process(
"Removing ${generated_file}"
- COMMAND "${CMAKE_COMMAND}" -E remove "${generated_file}"
+ COMMAND "${CMAKE_COMMAND}" -E rm -f "${generated_file}"
)
# For CUDA 2.3 and below, -G -M doesn't work, so remove the -G flag
@@ -241,7 +241,7 @@ endif()
# Delete the temporary file
cuda_execute_process(
"Removing ${cmake_dependency_file}.tmp and ${NVCC_generated_dependency_file}"
- COMMAND "${CMAKE_COMMAND}" -E remove "${cmake_dependency_file}.tmp" "${NVCC_generated_dependency_file}"
+ COMMAND "${CMAKE_COMMAND}" -E rm -f "${cmake_dependency_file}.tmp" "${NVCC_generated_dependency_file}"
)
if(CUDA_result)
@@ -267,7 +267,7 @@ if(CUDA_result)
# Since nvcc can sometimes leave half done files make sure that we delete the output file.
cuda_execute_process(
"Removing ${generated_file}"
- COMMAND "${CMAKE_COMMAND}" -E remove "${generated_file}"
+ COMMAND "${CMAKE_COMMAND}" -E rm -f "${generated_file}"
)
message(FATAL_ERROR "Error generating file ${generated_file}")
else()
diff --git a/Modules/FindCUDAToolkit.cmake b/Modules/FindCUDAToolkit.cmake
new file mode 100644
index 0000000..8d20ff9
--- /dev/null
+++ b/Modules/FindCUDAToolkit.cmake
@@ -0,0 +1,888 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+#[=======================================================================[.rst:
+FindCUDAToolkit
+---------------
+
+This script locates the NVIDIA CUDA toolkit and the associated libraries, but
+does not require the ``CUDA`` language be enabled for a given project. This
+module does not search for the NVIDIA CUDA Samples.
+
+Search Behavior
+^^^^^^^^^^^^^^^
+
+Finding the CUDA Toolkit requires finding the ``nvcc`` executable, which is
+searched for in the following order:
+
+1. If the ``CUDA`` language has been enabled we will use the directory
+ containing the compiler as the first search location for ``nvcc``.
+
+2. If the ``CUDAToolkit_ROOT`` cmake configuration variable (e.g.,
+ ``-DCUDAToolkit_ROOT=/some/path``) *or* environment variable is defined, it
+ will be searched. If both an environment variable **and** a
+ configuration variable are specified, the *configuration* variable takes
+ precedence.
+
+ The directory specified here must be such that the executable ``nvcc`` can be
+ found underneath the directory specified by ``CUDAToolkit_ROOT``. If
+ ``CUDAToolkit_ROOT`` is specified, but no ``nvcc`` is found underneath, this
+ package is marked as **not** found. No subsequent search attempts are
+ performed.
+
+3. If the CUDA_PATH environment variable is defined, it will be searched.
+
+4. The user's path is searched for ``nvcc`` using :command:`find_program`. If
+ this is found, no subsequent search attempts are performed. Users are
+ responsible for ensuring that the first ``nvcc`` to show up in the path is
+ the desired path in the event that multiple CUDA Toolkits are installed.
+
+5. On Unix systems, if the symbolic link ``/usr/local/cuda`` exists, this is
+ used. No subsequent search attempts are performed. No default symbolic link
+ location exists for the Windows platform.
+
+6. The platform specific default install locations are searched. If exactly one
+ candidate is found, this is used. The default CUDA Toolkit install locations
+ searched are:
+
+ +-------------+-------------------------------------------------------------+
+ | Platform | Search Pattern |
+ +=============+=============================================================+
+ | macOS | ``/Developer/NVIDIA/CUDA-X.Y`` |
+ +-------------+-------------------------------------------------------------+
+ | Other Unix | ``/usr/local/cuda-X.Y`` |
+ +-------------+-------------------------------------------------------------+
+ | Windows | ``C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\vX.Y`` |
+ +-------------+-------------------------------------------------------------+
+
+ Where ``X.Y`` would be a specific version of the CUDA Toolkit, such as
+ ``/usr/local/cuda-9.0`` or
+ ``C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.0``
+
+ .. note::
+
+ When multiple CUDA Toolkits are installed in the default location of a
+ system (e.g., both ``/usr/local/cuda-9.0`` and ``/usr/local/cuda-10.0``
+ exist but the ``/usr/local/cuda`` symbolic link does **not** exist), this
+ package is marked as **not** found.
+
+ There are too many factors involved in making an automatic decision in
+ the presence of multiple CUDA Toolkits being installed. In this
+ situation, users are encouraged to either (1) set ``CUDAToolkit_ROOT`` or
+ (2) ensure that the correct ``nvcc`` executable shows up in ``$PATH`` for
+ :command:`find_program` to find.
+
+Options
+^^^^^^^
+
+``VERSION``
+ If specified, describes the version of the CUDA Toolkit to search for.
+
+``REQUIRED``
+ If specified, configuration will error if a suitable CUDA Toolkit is not
+ found.
+
+``QUIET``
+ If specified, the search for a suitable CUDA Toolkit will not produce any
+ messages.
+
+``EXACT``
+ If specified, the CUDA Toolkit is considered found only if the exact
+ ``VERSION`` specified is recovered.
+
+Imported targets
+^^^^^^^^^^^^^^^^
+
+An :ref:`imported target <Imported targets>` named ``CUDA::toolkit`` is provided.
+
+This module defines :prop_tgt:`IMPORTED` targets for each
+of the following libraries that are part of the CUDAToolkit:
+
+- :ref:`CUDA Runtime Library<cuda_toolkit_rt_lib>`
+- :ref:`CUDA Driver Library<cuda_toolkit_driver_lib>`
+- :ref:`cuBLAS<cuda_toolkit_cuBLAS>`
+- :ref:`cuFFT<cuda_toolkit_cuFFT>`
+- :ref:`cuRAND<cuda_toolkit_cuRAND>`
+- :ref:`cuSOLVER<cuda_toolkit_cuSOLVER>`
+- :ref:`cuSPARSE<cuda_toolkit_cuSPARSE>`
+- :ref:`cuPTI<cuda_toolkit_cupti>`
+- :ref:`NPP<cuda_toolkit_NPP>`
+- :ref:`nvBLAS<cuda_toolkit_nvBLAS>`
+- :ref:`nvGRAPH<cuda_toolkit_nvGRAPH>`
+- :ref:`nvJPEG<cuda_toolkit_nvJPEG>`
+- :ref:`nvidia-ML<cuda_toolkit_nvML>`
+- :ref:`nvRTC<cuda_toolkit_nvRTC>`
+- :ref:`nvToolsExt<cuda_toolkit_nvToolsExt>`
+- :ref:`OpenCL<cuda_toolkit_opencl>`
+- :ref:`cuLIBOS<cuda_toolkit_cuLIBOS>`
+
+.. _`cuda_toolkit_rt_lib`:
+
+CUDA Runtime Library
+""""""""""""""""""""
+
+The CUDA Runtime library (cudart) are what most applications will typically
+need to link against to make any calls such as `cudaMalloc`, and `cudaFree`.
+
+Targets Created:
+
+- ``CUDA::cudart``
+- ``CUDA::cudart_static``
+
+.. _`cuda_toolkit_driver_lib`:
+
+CUDA Driver Library
+""""""""""""""""""""
+
+The CUDA Driver library (cuda) are used by applications that use calls
+such as `cuMemAlloc`, and `cuMemFree`. This is generally used by advanced
+
+
+Targets Created:
+
+- ``CUDA::cuda_driver``
+- ``CUDA::cuda_driver``
+
+.. _`cuda_toolkit_cuBLAS`:
+
+cuBLAS
+""""""
+
+The `cuBLAS <https://docs.nvidia.com/cuda/cublas/index.html>`_ library.
+
+Targets Created:
+
+- ``CUDA::cublas``
+- ``CUDA::cublas_static``
+
+.. _`cuda_toolkit_cuFFT`:
+
+cuFFT
+"""""
+
+The `cuFFT <https://docs.nvidia.com/cuda/cufft/index.html>`_ library.
+
+Targets Created:
+
+- ``CUDA::cufft``
+- ``CUDA::cufftw``
+- ``CUDA::cufft_static``
+- ``CUDA::cufftw_static``
+
+cuRAND
+""""""
+
+The `cuRAND <https://docs.nvidia.com/cuda/curand/index.html>`_ library.
+
+Targets Created:
+
+- ``CUDA::curand``
+- ``CUDA::curand_static``
+
+.. _`cuda_toolkit_cuSOLVER`:
+
+cuSOLVER
+""""""""
+
+The `cuSOLVER <https://docs.nvidia.com/cuda/cusolver/index.html>`_ library.
+
+Targets Created:
+
+- ``CUDA::cusolver``
+- ``CUDA::cusolver_static``
+
+.. _`cuda_toolkit_cuSPARSE`:
+
+cuSPARSE
+""""""""
+
+The `cuSPARSE <https://docs.nvidia.com/cuda/cusparse/index.html>`_ library.
+
+Targets Created:
+
+- ``CUDA::cusparse``
+- ``CUDA::cusparse_static``
+
+.. _`cuda_toolkit_cupti`:
+
+cupti
+"""""
+
+The `NVIDIA CUDA Profiling Tools Interface <https://developer.nvidia.com/CUPTI>`_.
+
+Targets Created:
+
+- ``CUDA::cupti``
+- ``CUDA::cupti_static``
+
+.. _`cuda_toolkit_NPP`:
+
+NPP
+"""
+
+The `NPP <https://docs.nvidia.com/cuda/npp/index.html>`_ libraries.
+
+Targets Created:
+
+- `nppc`:
+
+ - ``CUDA::nppc``
+ - ``CUDA::nppc_static``
+
+- `nppial`: Arithmetic and logical operation functions in `nppi_arithmetic_and_logical_operations.h`
+
+ - ``CUDA::nppial``
+ - ``CUDA::nppial_static``
+
+- `nppicc`: Color conversion and sampling functions in `nppi_color_conversion.h`
+
+ - ``CUDA::nppicc``
+ - ``CUDA::nppicc_static``
+
+- `nppicom`: JPEG compression and decompression functions in `nppi_compression_functions.h`
+
+ - ``CUDA::nppicom``
+ - ``CUDA::nppicom_static``
+
+- `nppidei`: Data exchange and initialization functions in `nppi_data_exchange_and_initialization.h`
+
+ - ``CUDA::nppidei``
+ - ``CUDA::nppidei_static``
+
+- `nppif`: Filtering and computer vision functions in `nppi_filter_functions.h`
+
+ - ``CUDA::nppif``
+ - ``CUDA::nppif_static``
+
+- `nppig`: Geometry transformation functions found in `nppi_geometry_transforms.h`
+
+ - ``CUDA::nppig``
+ - ``CUDA::nppig_static``
+
+- `nppim`: Morphological operation functions found in `nppi_morphological_operations.h`
+
+ - ``CUDA::nppim``
+ - ``CUDA::nppim_static``
+
+- `nppist`: Statistics and linear transform in `nppi_statistics_functions.h` and `nppi_linear_transforms.h`
+
+ - ``CUDA::nppist``
+ - ``CUDA::nppist_static``
+
+- `nppisu`: Memory support functions in `nppi_support_functions.h`
+
+ - ``CUDA::nppisu``
+ - ``CUDA::nppisu_static``
+
+- `nppitc`: Threshold and compare operation functions in `nppi_threshold_and_compare_operations.h`
+
+ - ``CUDA::nppitc``
+ - ``CUDA::nppitc_static``
+
+- `npps`:
+
+ - ``CUDA::npps``
+ - ``CUDA::npps_static``
+
+.. _`cuda_toolkit_nvBLAS`:
+
+nvBLAS
+""""""
+
+The `nvBLAS <https://docs.nvidia.com/cuda/nvblas/index.html>`_ libraries.
+This is a shared library only.
+
+Targets Created:
+
+- ``CUDA::nvblas``
+
+.. _`cuda_toolkit_nvGRAPH`:
+
+nvGRAPH
+"""""""
+
+The `nvGRAPH <https://docs.nvidia.com/cuda/nvgraph/index.html>`_ library.
+
+Targets Created:
+
+- ``CUDA::nvgraph``
+- ``CUDA::nvgraph_static``
+
+
+.. _`cuda_toolkit_nvJPEG`:
+
+nvJPEG
+""""""
+
+The `nvJPEG <https://docs.nvidia.com/cuda/nvjpeg/index.html>`_ library.
+Introduced in CUDA 10.
+
+Targets Created:
+
+- ``CUDA::nvjpeg``
+- ``CUDA::nvjpeg_static``
+
+.. _`cuda_toolkit_nvRTC`:
+
+nvRTC
+"""""
+
+The `nvRTC <https://docs.nvidia.com/cuda/nvrtc/index.html>`_ (Runtime Compilation) library.
+This is a shared library only.
+
+Targets Created:
+
+- ``CUDA::nvrtc``
+
+.. _`cuda_toolkit_nvml`:
+
+nvidia-ML
+"""""""""
+
+The `NVIDIA Management Library <https://developer.nvidia.com/nvidia-management-library-nvml>`_.
+This is a shared library only.
+
+Targets Created:
+
+- ``CUDA::nvml``
+
+.. _`cuda_toolkit_nvToolsExt`:
+
+nvToolsExt
+""""""""""
+
+The `NVIDIA Tools Extension <https://docs.nvidia.com/gameworks/content/gameworkslibrary/nvtx/nvidia_tools_extension_library_nvtx.htm>`_.
+This is a shared library only.
+
+Targets Created:
+
+- ``CUDA::nvToolsExt``
+
+.. _`cuda_toolkit_opencl`:
+
+OpenCL
+""""""
+
+The `NVIDIA OpenCL Library <https://developer.nvidia.com/opencl>`_.
+This is a shared library only.
+
+Targets Created:
+
+- ``CUDA::OpenCL``
+
+.. _`cuda_toolkit_cuLIBOS`:
+
+cuLIBOS
+"""""""
+
+The cuLIBOS library is a backend thread abstraction layer library which is
+static only. The ``CUDA::cublas_static``, ``CUDA::cusparse_static``,
+``CUDA::cufft_static``, ``CUDA::curand_static``, and (when implemented) NPP
+libraries all automatically have this dependency linked.
+
+Target Created:
+
+- ``CUDA::culibos``
+
+**Note**: direct usage of this target by consumers should not be necessary.
+
+.. _`cuda_toolkit_cuRAND`:
+
+
+
+Result variables
+^^^^^^^^^^^^^^^^
+
+``CUDAToolkit_FOUND``
+ A boolean specifying whether or not the CUDA Toolkit was found.
+
+``CUDAToolkit_VERSION``
+ The exact version of the CUDA Toolkit found (as reported by
+ ``nvcc --version``).
+
+``CUDAToolkit_VERSION_MAJOR``
+ The major version of the CUDA Toolkit.
+
+``CUDAToolkit_VERSION_MAJOR``
+ The minor version of the CUDA Toolkit.
+
+``CUDAToolkit_VERSION_PATCH``
+ The patch version of the CUDA Toolkit.
+
+``CUDAToolkit_BIN_DIR``
+ The path to the CUDA Toolkit library directory that contains the CUDA
+ executable ``nvcc``.
+
+``CUDAToolkit_INCLUDE_DIRS``
+ The path to the CUDA Toolkit ``include`` folder containing the header files
+ required to compile a project linking against CUDA.
+
+``CUDAToolkit_LIBRARY_DIR``
+ The path to the CUDA Toolkit library directory that contains the CUDA
+ Runtime library ``cudart``.
+
+``CUDAToolkit_TARGET_DIR``
+ The path to the CUDA Toolkit directory including the target architecture
+ when cross-compiling. When not cross-compiling this will be equivalant to
+ ``CUDAToolkit_ROOT_DIR``.
+
+``CUDAToolkit_NVCC_EXECUTABLE``
+ The path to the NVIDIA CUDA compiler ``nvcc``. Note that this path may
+ **not** be the same as
+ :variable:`CMAKE_CUDA_COMPILER <CMAKE_<LANG>_COMPILER>`. ``nvcc`` must be
+ found to determine the CUDA Toolkit version as well as determining other
+ features of the Toolkit. This variable is set for the convenience of
+ modules that depend on this one.
+
+
+#]=======================================================================]
+
+# NOTE: much of this was simply extracted from FindCUDA.cmake.
+
+# James Bigler, NVIDIA Corp (nvidia.com - jbigler)
+# Abe Stephens, SCI Institute -- http://www.sci.utah.edu/~abe/FindCuda.html
+#
+# Copyright (c) 2008 - 2009 NVIDIA Corporation. All rights reserved.
+#
+# Copyright (c) 2007-2009
+# Scientific Computing and Imaging Institute, University of Utah
+#
+# This code is licensed under the MIT License. See the FindCUDA.cmake script
+# for the text of the license.
+
+# The MIT License
+#
+# License for the specific language governing rights and limitations under
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+###############################################################################
+
+# For NVCC we can easily deduce the SDK binary directory from the compiler path.
+if(CMAKE_CUDA_COMPILER_LOADED AND NOT CUDAToolkit_BIN_DIR AND CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
+ get_filename_component(cuda_dir "${CMAKE_CUDA_COMPILER}" DIRECTORY)
+ set(CUDAToolkit_BIN_DIR "${cuda_dir}" CACHE PATH "")
+ mark_as_advanced(CUDAToolkit_BIN_DIR)
+ unset(cuda_dir)
+endif()
+
+# Try language- or user-provided path first.
+if(CUDAToolkit_BIN_DIR)
+ find_program(CUDAToolkit_NVCC_EXECUTABLE
+ NAMES nvcc nvcc.exe
+ PATHS ${CUDAToolkit_BIN_DIR}
+ NO_DEFAULT_PATH
+ )
+endif()
+
+# Search using CUDAToolkit_ROOT
+find_program(CUDAToolkit_NVCC_EXECUTABLE
+ NAMES nvcc nvcc.exe
+ PATHS ENV CUDA_PATH
+ PATH_SUFFIXES bin
+)
+
+# If the user specified CUDAToolkit_ROOT but nvcc could not be found, this is an error.
+if (NOT CUDAToolkit_NVCC_EXECUTABLE AND (DEFINED CUDAToolkit_ROOT OR DEFINED ENV{CUDAToolkit_ROOT}))
+ # Declare error messages now, print later depending on find_package args.
+ set(fail_base "Could not find nvcc executable in path specified by")
+ set(cuda_root_fail "${fail_base} CUDAToolkit_ROOT=${CUDAToolkit_ROOT}")
+ set(env_cuda_root_fail "${fail_base} environment variable CUDAToolkit_ROOT=$ENV{CUDAToolkit_ROOT}")
+
+ if (CUDAToolkit_FIND_REQUIRED)
+ if (DEFINED CUDAToolkit_ROOT)
+ message(FATAL_ERROR ${cuda_root_fail})
+ elseif (DEFINED ENV{CUDAToolkit_ROOT})
+ message(FATAL_ERROR ${env_cuda_root_fail})
+ endif()
+ else()
+ if (NOT CUDAToolkit_FIND_QUIETLY)
+ if (DEFINED CUDAToolkit_ROOT)
+ message(STATUS ${cuda_root_fail})
+ elseif (DEFINED ENV{CUDAToolkit_ROOT})
+ message(STATUS ${env_cuda_root_fail})
+ endif()
+ endif()
+ set(CUDAToolkit_FOUND FALSE)
+ unset(fail_base)
+ unset(cuda_root_fail)
+ unset(env_cuda_root_fail)
+ return()
+ endif()
+endif()
+
+# CUDAToolkit_ROOT cmake / env variable not specified, try platform defaults.
+#
+# - Linux: /usr/local/cuda-X.Y
+# - macOS: /Developer/NVIDIA/CUDA-X.Y
+# - Windows: C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\vX.Y
+#
+# We will also search the default symlink location /usr/local/cuda first since
+# if CUDAToolkit_ROOT is not specified, it is assumed that the symlinked
+# directory is the desired location.
+if (NOT CUDAToolkit_NVCC_EXECUTABLE)
+ if (UNIX)
+ if (NOT APPLE)
+ set(platform_base "/usr/local/cuda-")
+ else()
+ set(platform_base "/Developer/NVIDIA/CUDA-")
+ endif()
+ else()
+ set(platform_base "C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v")
+ endif()
+
+ # Build out a descending list of possible cuda installations, e.g.
+ file(GLOB possible_paths "${platform_base}*")
+ # Iterate the glob results and create a descending list.
+ set(possible_versions)
+ foreach (p ${possible_paths})
+ # Extract version number from end of string
+ string(REGEX MATCH "[0-9][0-9]?\\.[0-9]$" p_version ${p})
+ if (IS_DIRECTORY ${p} AND p_version)
+ list(APPEND possible_versions ${p_version})
+ endif()
+ endforeach()
+
+ # Cannot use list(SORT) because that is alphabetical, we need numerical.
+ # NOTE: this is not an efficient sorting strategy. But even if a user had
+ # every possible version of CUDA installed, this wouldn't create any
+ # significant overhead.
+ set(versions)
+ foreach (v ${possible_versions})
+ list(LENGTH versions num_versions)
+ # First version, nothing to compare with so just append.
+ if (num_versions EQUAL 0)
+ list(APPEND versions ${v})
+ else()
+ # Loop through list. Insert at an index when comparison is
+ # VERSION_GREATER since we want a descending list. Duplicates will not
+ # happen since this came from a glob list of directories.
+ set(i 0)
+ set(early_terminate FALSE)
+ while (i LESS num_versions)
+ list(GET versions ${i} curr)
+ if (v VERSION_GREATER curr)
+ list(INSERT versions ${i} ${v})
+ set(early_terminate TRUE)
+ break()
+ endif()
+ math(EXPR i "${i} + 1")
+ endwhile()
+ # If it did not get inserted, place it at the end.
+ if (NOT early_terminate)
+ list(APPEND versions ${v})
+ endif()
+ endif()
+ endforeach()
+
+ # With a descending list of versions, populate possible paths to search.
+ set(search_paths)
+ foreach (v ${versions})
+ list(APPEND search_paths "${platform_base}${v}")
+ endforeach()
+
+ # Force the global default /usr/local/cuda to the front on Unix.
+ if (UNIX)
+ list(INSERT search_paths 0 "/usr/local/cuda")
+ endif()
+
+ # Now search for nvcc again using the platform default search paths.
+ find_program(CUDAToolkit_NVCC_EXECUTABLE
+ NAMES nvcc nvcc.exe
+ PATHS ${search_paths}
+ PATH_SUFFIXES bin
+ )
+
+ # We are done with these variables now, cleanup for caller.
+ unset(platform_base)
+ unset(possible_paths)
+ unset(possible_versions)
+ unset(versions)
+ unset(i)
+ unset(early_terminate)
+ unset(search_paths)
+
+ if (NOT CUDAToolkit_NVCC_EXECUTABLE)
+ if (CUDAToolkit_FIND_REQUIRED)
+ message(FATAL_ERROR "Could not find nvcc, please set CUDAToolkit_ROOT.")
+ elseif(NOT CUDAToolkit_FIND_QUIETLY)
+ message(STATUS "Could not find nvcc, please set CUDAToolkit_ROOT.")
+ endif()
+
+ set(CUDAToolkit_FOUND FALSE)
+ return()
+ endif()
+endif()
+
+if(NOT CUDAToolkit_BIN_DIR AND CUDAToolkit_NVCC_EXECUTABLE)
+ get_filename_component(cuda_dir "${CUDAToolkit_NVCC_EXECUTABLE}" DIRECTORY)
+ set(CUDAToolkit_BIN_DIR "${cuda_dir}" CACHE PATH "" FORCE)
+ mark_as_advanced(CUDAToolkit_BIN_DIR)
+ unset(cuda_dir)
+endif()
+
+if(CUDAToolkit_NVCC_EXECUTABLE AND
+ CUDAToolkit_NVCC_EXECUTABLE STREQUAL CMAKE_CUDA_COMPILER)
+ # Need to set these based off the already computed CMAKE_CUDA_COMPILER_VERSION value
+ # This if statement will always match, but is used to provide variables for MATCH 1,2,3...
+ if(CMAKE_CUDA_COMPILER_VERSION MATCHES [=[([0-9]+)\.([0-9]+)\.([0-9]+)]=])
+ set(CUDAToolkit_VERSION_MAJOR "${CMAKE_MATCH_1}")
+ set(CUDAToolkit_VERSION_MINOR "${CMAKE_MATCH_2}")
+ set(CUDAToolkit_VERSION_PATCH "${CMAKE_MATCH_3}")
+ set(CUDAToolkit_VERSION "${CMAKE_CUDA_COMPILER_VERSION}")
+ endif()
+else()
+ # Compute the version by invoking nvcc
+ execute_process (COMMAND ${CUDAToolkit_NVCC_EXECUTABLE} "--version" OUTPUT_VARIABLE NVCC_OUT)
+ if(NVCC_OUT MATCHES [=[ V([0-9]+)\.([0-9]+)\.([0-9]+)]=])
+ set(CUDAToolkit_VERSION_MAJOR "${CMAKE_MATCH_1}")
+ set(CUDAToolkit_VERSION_MINOR "${CMAKE_MATCH_2}")
+ set(CUDAToolkit_VERSION_PATCH "${CMAKE_MATCH_3}")
+ set(CUDAToolkit_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}")
+ endif()
+ unset(NVCC_OUT)
+endif()
+
+
+get_filename_component(CUDAToolkit_ROOT_DIR ${CUDAToolkit_BIN_DIR} DIRECTORY ABSOLUTE)
+
+# Handle cross compilation
+if(CMAKE_CROSSCOMPILING)
+ if(CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7-a")
+ # Support for NVPACK
+ set (CUDAToolkit_TARGET_NAME "armv7-linux-androideabi")
+ elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm")
+ # Support for arm cross compilation
+ set(CUDAToolkit_TARGET_NAME "armv7-linux-gnueabihf")
+ elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
+ # Support for aarch64 cross compilation
+ if (ANDROID_ARCH_NAME STREQUAL "arm64")
+ set(CUDAToolkit_TARGET_NAME "aarch64-linux-androideabi")
+ else()
+ set(CUDAToolkit_TARGET_NAME "aarch64-linux")
+ endif (ANDROID_ARCH_NAME STREQUAL "arm64")
+ elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
+ set(CUDAToolkit_TARGET_NAME "x86_64-linux")
+ endif()
+
+ if (EXISTS "${CUDAToolkit_ROOT_DIR}/targets/${CUDAToolkit_TARGET_NAME}")
+ set(CUDAToolkit_TARGET_DIR "${CUDAToolkit_ROOT_DIR}/targets/${CUDAToolkit_TARGET_NAME}")
+ # add known CUDA target root path to the set of directories we search for programs, libraries and headers
+ list(PREPEND CMAKE_FIND_ROOT_PATH "${CUDAToolkit_TARGET_DIR}")
+
+ # Mark that we need to pop the root search path changes after we have
+ # found all cuda libraries so that searches for our cross-compilation
+ # libraries work when another cuda sdk is in CMAKE_PREFIX_PATH or
+ # PATh
+ set(_CUDAToolkit_Pop_ROOT_PATH True)
+ endif()
+else()
+ # Not cross compiling
+ set(CUDAToolkit_TARGET_DIR "${CUDAToolkit_ROOT_DIR}")
+ # Now that we have the real ROOT_DIR, find components inside it.
+ list(APPEND CMAKE_PREFIX_PATH ${CUDAToolkit_ROOT_DIR})
+
+ # Mark that we need to pop the prefix path changes after we have
+ # found the cudart library.
+ set(_CUDAToolkit_Pop_Prefix True)
+endif()
+
+
+# Find the include/ directory
+find_path(CUDAToolkit_INCLUDE_DIR
+ NAMES cuda_runtime.h
+)
+
+# And find the CUDA Runtime Library libcudart
+find_library(CUDA_CUDART
+ NAMES cudart
+ PATH_SUFFIXES lib64 lib/x64
+)
+if (NOT CUDA_CUDART)
+ find_library(CUDA_CUDART
+ NAMES cudart
+ PATH_SUFFIXES lib64/stubs lib/x64/stubs
+ )
+endif()
+
+if (NOT CUDA_CUDART AND NOT CUDAToolkit_FIND_QUIETLY)
+ message(STATUS "Unable to find cudart library.")
+endif()
+
+unset(CUDAToolkit_ROOT_DIR)
+if(_CUDAToolkit_Pop_Prefix)
+ list(REMOVE_AT CMAKE_PREFIX_PATH -1)
+ unset(_CUDAToolkit_Pop_Prefix)
+endif()
+
+#-----------------------------------------------------------------------------
+# Perform version comparison and validate all required variables are set.
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+find_package_handle_standard_args(CUDAToolkit
+ REQUIRED_VARS
+ CUDAToolkit_INCLUDE_DIR
+ CUDA_CUDART
+ CUDAToolkit_NVCC_EXECUTABLE
+ VERSION_VAR
+ CUDAToolkit_VERSION
+)
+mark_as_advanced(CUDA_CUDART
+ CUDAToolkit_INCLUDE_DIR
+ CUDAToolkit_NVCC_EXECUTABLE
+ )
+
+#-----------------------------------------------------------------------------
+# Construct result variables
+if(CUDAToolkit_FOUND)
+ set(CUDAToolkit_INCLUDE_DIRS ${CUDAToolkit_INCLUDE_DIR})
+ get_filename_component(CUDAToolkit_LIBRARY_DIR ${CUDA_CUDART} DIRECTORY ABSOLUTE)
+endif()
+
+#-----------------------------------------------------------------------------
+# Construct import targets
+if(CUDAToolkit_FOUND)
+
+ function(_CUDAToolkit_find_and_add_import_lib lib_name)
+ cmake_parse_arguments(arg "" "" "ALT;DEPS;EXTRA_PATH_SUFFIXES" ${ARGN})
+
+ set(search_names ${lib_name} ${arg_ALT})
+
+ find_library(CUDA_${lib_name}_LIBRARY
+ NAMES ${search_names}
+ HINTS ${CUDAToolkit_LIBRARY_DIR}
+ ENV CUDA_PATH
+ PATH_SUFFIXES nvidia/current lib64 lib/x64 lib
+ ${arg_EXTRA_PATH_SUFFIXES}
+ )
+ # Don't try any stub directories intil we have exhausted all other
+ # search locations.
+ if(NOT CUDA_${lib_name}_LIBRARY)
+ find_library(CUDA_${lib_name}_LIBRARY
+ NAMES ${search_names}
+ HINTS ${CUDAToolkit_LIBRARY_DIR}
+ ENV CUDA_PATH
+ PATH_SUFFIXES lib64/stubs lib/x64/stubs lib/stubs stubs
+ )
+ endif()
+
+ mark_as_advanced(CUDA_${lib_name}_LIBRARY)
+
+ if (NOT TARGET CUDA::${lib_name} AND CUDA_${lib_name}_LIBRARY)
+ add_library(CUDA::${lib_name} IMPORTED INTERFACE)
+ target_include_directories(CUDA::${lib_name} SYSTEM INTERFACE "${CUDAToolkit_INCLUDE_DIRS}")
+ target_link_libraries(CUDA::${lib_name} INTERFACE "${CUDA_${lib_name}_LIBRARY}")
+ foreach(dep ${arg_DEPS})
+ if(TARGET CUDA::${dep})
+ target_link_libraries(CUDA::${lib_name} INTERFACE CUDA::${dep})
+ endif()
+ endforeach()
+ endif()
+ endfunction()
+
+ if(NOT TARGET CUDA::toolkit)
+ add_library(CUDA::toolkit IMPORTED INTERFACE)
+ target_include_directories(CUDA::toolkit SYSTEM INTERFACE "${CUDAToolkit_INCLUDE_DIRS}")
+ target_link_directories(CUDA::toolkit INTERFACE "${CUDAToolkit_LIBRARY_DIR}")
+ endif()
+
+ _CUDAToolkit_find_and_add_import_lib(cuda_driver ALT cuda)
+
+ _CUDAToolkit_find_and_add_import_lib(cudart)
+ _CUDAToolkit_find_and_add_import_lib(cudart_static)
+
+ # setup dependencies that are required for cudart_static when building
+ # on linux. These are generally only required when using the CUDA toolkit
+ # when CUDA language is disabled
+ if(NOT TARGET CUDA::cudart_static_deps
+ AND TARGET CUDA::cudart_static)
+
+ add_library(CUDA::cudart_static_deps IMPORTED INTERFACE)
+ target_link_libraries(CUDA::cudart_static INTERFACE CUDA::cudart_static_deps)
+
+ if(UNIX AND (CMAKE_C_COMPILER OR CMAKE_CXX_COMPILER))
+ find_package(Threads REQUIRED)
+ target_link_libraries(CUDA::cudart_static_deps INTERFACE Threads::Threads ${CMAKE_DL_LIBS})
+ endif()
+
+ if(UNIX AND NOT APPLE)
+ # On Linux, you must link against librt when using the static cuda runtime.
+ find_library(CUDAToolkit_rt_LIBRARY rt)
+ mark_as_advanced(CUDAToolkit_rt_LIBRARY)
+ if(NOT CUDAToolkit_rt_LIBRARY)
+ message(WARNING "Could not find librt library, needed by CUDA::cudart_static")
+ else()
+ target_link_libraries(CUDA::cudart_static_deps INTERFACE ${CUDAToolkit_rt_LIBRARY})
+ endif()
+ endif()
+ endif()
+
+ _CUDAToolkit_find_and_add_import_lib(culibos) # it's a static library
+ foreach (cuda_lib cublas cufft curand cusparse nppc nvjpeg)
+ _CUDAToolkit_find_and_add_import_lib(${cuda_lib})
+ _CUDAToolkit_find_and_add_import_lib(${cuda_lib}_static DEPS culibos)
+ endforeach()
+
+ # cuFFTW depends on cuFFT
+ _CUDAToolkit_find_and_add_import_lib(cufftw DEPS cufft)
+ _CUDAToolkit_find_and_add_import_lib(cufftw DEPS cufft_static)
+
+ # cuSOLVER depends on cuBLAS, and cuSPARSE
+ _CUDAToolkit_find_and_add_import_lib(cusolver DEPS cublas cusparse)
+ _CUDAToolkit_find_and_add_import_lib(cusolver_static DEPS cublas_static cusparse_static culibos)
+
+ # nvGRAPH depends on cuRAND, and cuSOLVER.
+ _CUDAToolkit_find_and_add_import_lib(nvgraph DEPS curand cusolver)
+ _CUDAToolkit_find_and_add_import_lib(nvgraph_static DEPS curand_static cusolver_static)
+
+ # Process the majority of the NPP libraries.
+ foreach (cuda_lib nppial nppicc nppidei nppif nppig nppim nppist nppitc npps nppicom nppisu)
+ _CUDAToolkit_find_and_add_import_lib(${cuda_lib} DEPS nppc)
+ _CUDAToolkit_find_and_add_import_lib(${cuda_lib}_static DEPS nppc_static)
+ endforeach()
+
+ _CUDAToolkit_find_and_add_import_lib(cupti
+ EXTRA_PATH_SUFFIXES ../extras/CUPTI/lib64/
+ ../extras/CUPTI/lib/)
+ _CUDAToolkit_find_and_add_import_lib(cupti_static
+ EXTRA_PATH_SUFFIXES ../extras/CUPTI/lib64/
+ ../extras/CUPTI/lib/)
+
+ _CUDAToolkit_find_and_add_import_lib(nvrtc DEPS cuda_driver)
+
+ _CUDAToolkit_find_and_add_import_lib(nvml ALT nvidia-ml nvml)
+
+ if(WIN32)
+ # nvtools can be installed outside the CUDA toolkit directory
+ # so prefer the NVTOOLSEXT_PATH windows only environment variable
+ # In addition on windows the most common name is nvToolsExt64_1
+ find_library(CUDA_nvToolsExt_LIBRARY
+ NAMES nvToolsExt64_1 nvToolsExt64 nvToolsExt
+ PATHS ENV NVTOOLSEXT_PATH
+ ENV CUDA_PATH
+ PATH_SUFFIXES lib/x64 lib
+ )
+ endif()
+ _CUDAToolkit_find_and_add_import_lib(nvToolsExt ALT nvToolsExt64)
+
+ _CUDAToolkit_find_and_add_import_lib(OpenCL)
+endif()
+
+if(_CUDAToolkit_Pop_ROOT_PATH)
+ list(REMOVE_AT CMAKE_FIND_ROOT_PATH 0)
+ unset(_CUDAToolkit_Pop_ROOT_PATH)
+endif()
diff --git a/Modules/FindCURL.cmake b/Modules/FindCURL.cmake
index aeebc84..919babc 100644
--- a/Modules/FindCURL.cmake
+++ b/Modules/FindCURL.cmake
@@ -37,8 +37,35 @@ This module defines the following variables:
``CURL_VERSION_STRING``
The version of ``curl`` found.
+
+CURL CMake
+^^^^^^^^^^
+
+If CURL was built using the CMake buildsystem then it provides its own
+``CURLConfig.cmake`` file for use with the :command:`find_package` command's
+config mode. This module looks for this file and, if found,
+returns its results with no further action.
+
+Set ``CURL_NO_CURL_CMAKE`` to ``ON`` to disable this search.
+
#]=======================================================================]
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+
+if(NOT CURL_NO_CURL_CMAKE)
+ # do a find package call to specifically look for the CMake version
+ # of curl
+ find_package(CURL QUIET NO_MODULE)
+ mark_as_advanced(CURL_DIR)
+
+ # if we found the CURL cmake package then we are done, and
+ # can print what we found and return.
+ if(CURL_FOUND)
+ find_package_handle_standard_args(CURL HANDLE_COMPONENTS CONFIG_MODE)
+ return()
+ endif()
+endif()
+
find_package(PkgConfig QUIET)
if(PKG_CONFIG_FOUND)
pkg_check_modules(PC_CURL QUIET libcurl)
@@ -139,7 +166,6 @@ if(CURL_FIND_COMPONENTS)
endforeach()
endif()
-include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
find_package_handle_standard_args(CURL
REQUIRED_VARS CURL_LIBRARY CURL_INCLUDE_DIR
VERSION_VAR CURL_VERSION_STRING
diff --git a/Modules/FindCurses.cmake b/Modules/FindCurses.cmake
index e3e7273..ba56078 100644
--- a/Modules/FindCurses.cmake
+++ b/Modules/FindCurses.cmake
@@ -159,6 +159,10 @@ if(CURSES_USE_NCURSES)
if(NOT CURSES_NCURSES_HAS_CBREAK)
find_library(CURSES_EXTRA_LIBRARY "${CURSES_TINFO_LIBRARY_NAME}" HINTS "${_cursesLibDir}")
find_library(CURSES_EXTRA_LIBRARY "${CURSES_TINFO_LIBRARY_NAME}" )
+
+ mark_as_advanced(
+ CURSES_EXTRA_LIBRARY
+ )
endif()
else()
get_filename_component(_cursesLibDir "${CURSES_CURSES_LIBRARY}" PATH)
@@ -262,6 +266,5 @@ mark_as_advanced(
CURSES_INCLUDE_PATH
CURSES_CURSES_LIBRARY
CURSES_NCURSES_LIBRARY
- CURSES_EXTRA_LIBRARY
CURSES_FORM_LIBRARY
)
diff --git a/Modules/FindDCMTK.cmake b/Modules/FindDCMTK.cmake
index d48de08..b2e00df 100644
--- a/Modules/FindDCMTK.cmake
+++ b/Modules/FindDCMTK.cmake
@@ -102,7 +102,7 @@ set(_SAVED_DCMTK_DIR ${DCMTK_DIR})
# Step1: Attempt to find a version of DCMTK providing a DCMTKConfig.cmake file.
#
if(NOT DCMTK_FIND_QUIETLY)
- message(STATUS "Trying to find DCMTK expecting DCMTKConfig.cmake")
+ message(CHECK_START "Trying to find DCMTK expecting DCMTKConfig.cmake")
endif()
find_package(DCMTK QUIET NO_MODULE)
if(DCMTK_FOUND
@@ -110,12 +110,12 @@ if(DCMTK_FOUND
AND NOT "x" STREQUAL "x${DCMTK_INCLUDE_DIRS}")
if(NOT DCMTK_FIND_QUIETLY)
- message(STATUS "Trying to find DCMTK expecting DCMTKConfig.cmake - ok")
+ message(CHECK_PASS "ok")
endif()
return()
else()
if(NOT DCMTK_FIND_QUIETLY)
- message(STATUS "Trying to find DCMTK expecting DCMTKConfig.cmake - failed")
+ message(CHECK_FAIL "failed")
endif()
endif()
diff --git a/Modules/FindDoxygen.cmake b/Modules/FindDoxygen.cmake
index faa03f9..184a9a2 100644
--- a/Modules/FindDoxygen.cmake
+++ b/Modules/FindDoxygen.cmake
@@ -999,9 +999,11 @@ doxygen_add_docs() for target ${targetName}")
foreach(_item IN LISTS DOXYGEN_INPUT)
get_filename_component(_abs_item "${_item}" ABSOLUTE
BASE_DIR "${_args_WORKING_DIRECTORY}")
- if(EXISTS "${_abs_item}" AND
- NOT IS_DIRECTORY "${_abs_item}" AND
- NOT IS_SYMLINK "${_abs_item}")
+ get_source_file_property(_isGenerated "${_abs_item}" GENERATED)
+ if(_isGenerated OR
+ (EXISTS "${_abs_item}" AND
+ NOT IS_DIRECTORY "${_abs_item}" AND
+ NOT IS_SYMLINK "${_abs_item}"))
list(APPEND _sources "${_abs_item}")
elseif(_args_USE_STAMP_FILE)
message(FATAL_ERROR "Source does not exist or is not a file:\n"
diff --git a/Modules/FindFLEX.cmake b/Modules/FindFLEX.cmake
index d22b7ec..90e5f86 100644
--- a/Modules/FindFLEX.cmake
+++ b/Modules/FindFLEX.cmake
@@ -142,8 +142,6 @@ if(FLEX_EXECUTABLE)
#============================================================
#
macro(FLEX_TARGET Name Input Output)
- set(FLEX_TARGET_outputs "${Output}")
- set(FLEX_EXECUTABLE_opts "")
set(FLEX_TARGET_PARAM_OPTIONS)
set(FLEX_TARGET_PARAM_ONE_VALUE_KEYWORDS
@@ -165,31 +163,68 @@ if(FLEX_EXECUTABLE)
if(NOT "${FLEX_TARGET_ARG_UNPARSED_ARGUMENTS}" STREQUAL "")
message(SEND_ERROR ${FLEX_TARGET_usage})
else()
+
+ cmake_policy(GET CMP0098 _flex_CMP0098
+ PARENT_SCOPE # undocumented, do not use outside of CMake
+ )
+ set(_flex_INPUT "${Input}")
+ if("x${_flex_CMP0098}x" STREQUAL "xNEWx")
+ set(_flex_WORKING_DIR "${CMAKE_CURRENT_BINARY_DIR}")
+ if(NOT IS_ABSOLUTE "${_flex_INPUT}")
+ set(_flex_INPUT "${CMAKE_CURRENT_SOURCE_DIR}/${_flex_INPUT}")
+ endif()
+ else()
+ set(_flex_WORKING_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+ endif()
+ unset(_flex_CMP0098)
+
+ set(_flex_OUTPUT "${Output}")
+ if(NOT IS_ABSOLUTE ${_flex_OUTPUT})
+ set(_flex_OUTPUT "${_flex_WORKING_DIR}/${_flex_OUTPUT}")
+ endif()
+ set(_flex_TARGET_OUTPUTS "${_flex_OUTPUT}")
+
+ set(_flex_EXE_OPTS "")
if(NOT "${FLEX_TARGET_ARG_COMPILE_FLAGS}" STREQUAL "")
- set(FLEX_EXECUTABLE_opts "${FLEX_TARGET_ARG_COMPILE_FLAGS}")
- separate_arguments(FLEX_EXECUTABLE_opts)
+ set(_flex_EXE_OPTS "${FLEX_TARGET_ARG_COMPILE_FLAGS}")
+ separate_arguments(_flex_EXE_OPTS)
endif()
+
+ set(_flex_OUTPUT_HEADER "")
if(NOT "${FLEX_TARGET_ARG_DEFINES_FILE}" STREQUAL "")
- list(APPEND FLEX_TARGET_outputs "${FLEX_TARGET_ARG_DEFINES_FILE}")
- list(APPEND FLEX_EXECUTABLE_opts --header-file=${FLEX_TARGET_ARG_DEFINES_FILE})
+ set(_flex_OUTPUT_HEADER "${FLEX_TARGET_ARG_DEFINES_FILE}")
+ if(IS_ABSOLUTE "${_flex_OUTPUT_HEADER}")
+ set(_flex_OUTPUT_HEADER_ABS "${_flex_OUTPUT_HEADER}")
+ else()
+ set(_flex_OUTPUT_HEADER_ABS "${_flex_WORKING_DIR}/${_flex_OUTPUT_HEADER}")
+ endif()
+ list(APPEND _flex_TARGET_OUTPUTS "${_flex_OUTPUT_HEADER_ABS}")
+ list(APPEND _flex_EXE_OPTS --header-file=${_flex_OUTPUT_HEADER_ABS})
endif()
- add_custom_command(OUTPUT ${FLEX_TARGET_outputs}
- COMMAND ${FLEX_EXECUTABLE} ${FLEX_EXECUTABLE_opts} -o${Output} ${Input}
+ get_filename_component(_flex_EXE_NAME_WE "${FLEX_EXECUTABLE}" NAME_WE)
+ add_custom_command(OUTPUT ${_flex_TARGET_OUTPUTS}
+ COMMAND ${FLEX_EXECUTABLE} ${_flex_EXE_OPTS} -o${_flex_OUTPUT} ${_flex_INPUT}
VERBATIM
- DEPENDS ${Input}
- COMMENT "[FLEX][${Name}] Building scanner with flex ${FLEX_VERSION}"
- WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
+ DEPENDS ${_flex_INPUT}
+ COMMENT "[FLEX][${Name}] Building scanner with ${_flex_EXE_NAME_WE} ${FLEX_VERSION}"
+ WORKING_DIRECTORY ${_flex_WORKING_DIR})
set(FLEX_${Name}_DEFINED TRUE)
- set(FLEX_${Name}_OUTPUTS ${Output})
- set(FLEX_${Name}_INPUT ${Input})
- set(FLEX_${Name}_COMPILE_FLAGS ${FLEX_EXECUTABLE_opts})
- if("${FLEX_TARGET_ARG_DEFINES_FILE}" STREQUAL "")
- set(FLEX_${Name}_OUTPUT_HEADER "")
- else()
- set(FLEX_${Name}_OUTPUT_HEADER ${FLEX_TARGET_ARG_DEFINES_FILE})
- endif()
+ set(FLEX_${Name}_OUTPUTS ${_flex_TARGET_OUTPUTS})
+ set(FLEX_${Name}_INPUT ${_flex_INPUT})
+ set(FLEX_${Name}_COMPILE_FLAGS ${_flex_EXE_OPTS})
+ set(FLEX_${Name}_OUTPUT_HEADER ${_flex_OUTPUT_HEADER})
+
+ unset(_flex_EXE_NAME_WE)
+ unset(_flex_EXE_OPTS)
+ unset(_flex_INPUT)
+ unset(_flex_OUTPUT)
+ unset(_flex_OUTPUT_HEADER)
+ unset(_flex_OUTPUT_HEADER_ABS)
+ unset(_flex_TARGET_OUTPUTS)
+ unset(_flex_WORKING_DIR)
+
endif()
endmacro()
#============================================================
diff --git a/Modules/FindGLEW.cmake b/Modules/FindGLEW.cmake
index bd69819..27ffa13 100644
--- a/Modules/FindGLEW.cmake
+++ b/Modules/FindGLEW.cmake
@@ -10,7 +10,7 @@ Find the OpenGL Extension Wrangler Library (GLEW)
Input Variables
^^^^^^^^^^^^^^^
-The following variables may be set to influence this module’s behavior:
+The following variables may be set to influence this module's behavior:
``GLEW_USE_STATIC_LIBS``
to find and create :prop_tgt:`IMPORTED` target for static linkage.
diff --git a/Modules/FindGTK2.cmake b/Modules/FindGTK2.cmake
index 600e4aa..62f1614 100644
--- a/Modules/FindGTK2.cmake
+++ b/Modules/FindGTK2.cmake
@@ -5,96 +5,83 @@
FindGTK2
--------
-Find the GTK2 widget libraries and several of its
-other optional components like ``gtkmm``, ``glade``, and ``glademm``.
-
-NOTE: If you intend to use version checking, CMake 2.6.2 or later is
-
-::
-
- required.
-
-
+Find the GTK2 widget libraries and several of its other optional components
+like ``gtkmm``, ``glade``, and ``glademm``.
Specify one or more of the following components as you call this find
module. See example below.
-::
-
- gtk
- gtkmm
- glade
- glademm
-
+* ``gtk``
+* ``gtkmm``
+* ``glade``
+* ``glademm``
+Result Variables
+^^^^^^^^^^^^^^^^
The following variables will be defined for your use
-::
-
- GTK2_FOUND - Were all of your specified components found?
- GTK2_INCLUDE_DIRS - All include directories
- GTK2_LIBRARIES - All libraries
- GTK2_TARGETS - All imported targets
- GTK2_DEFINITIONS - Additional compiler flags
-
-
-
-::
-
- GTK2_VERSION - The version of GTK2 found (x.y.z)
- GTK2_MAJOR_VERSION - The major version of GTK2
- GTK2_MINOR_VERSION - The minor version of GTK2
- GTK2_PATCH_VERSION - The patch version of GTK2
-
-
+``GTK2_FOUND``
+ Were all of your specified components found?
+``GTK2_INCLUDE_DIRS``
+ All include directories
+``GTK2_LIBRARIES``
+ All libraries
+``GTK2_TARGETS``
+ All imported targets
+``GTK2_DEFINITIONS``
+ Additional compiler flags
+``GTK2_VERSION``
+ The version of GTK2 found (x.y.z)
+``GTK2_MAJOR_VERSION``
+ The major version of GTK2
+``GTK2_MINOR_VERSION``
+ The minor version of GTK2
+``GTK2_PATCH_VERSION``
+ The patch version of GTK2
+
+Input Variables
+^^^^^^^^^^^^^^^
Optional variables you can define prior to calling this module:
-::
-
- GTK2_DEBUG - Enables verbose debugging of the module
- GTK2_ADDITIONAL_SUFFIXES - Allows defining additional directories to
- search for include files
-
-
-
-================= Example Usage:
-
-::
-
- Call find_package() once, here are some examples to pick from:
-
-
+``GTK2_DEBUG``
+ Enables verbose debugging of the module
+``GTK2_ADDITIONAL_SUFFIXES``
+ Allows defining additional directories to search for include files
-::
+Example Usage
+^^^^^^^^^^^^^
- Require GTK 2.6 or later
- find_package(GTK2 2.6 REQUIRED gtk)
+Call :command:`find_package` once. Here are some examples to pick from:
+Require GTK 2.6 or later:
+.. code-block:: cmake
-::
+ find_package(GTK2 2.6 REQUIRED gtk)
- Require GTK 2.10 or later and Glade
- find_package(GTK2 2.10 REQUIRED gtk glade)
+Require GTK 2.10 or later and Glade:
+.. code-block:: cmake
+ find_package(GTK2 2.10 REQUIRED gtk glade)
-::
+Search for GTK/GTKMM 2.8 or later:
- Search for GTK/GTKMM 2.8 or later
- find_package(GTK2 2.8 COMPONENTS gtk gtkmm)
+.. code-block:: cmake
+ find_package(GTK2 2.8 COMPONENTS gtk gtkmm)
+Use the results:
-::
+.. code-block:: cmake
- if(GTK2_FOUND)
- include_directories(${GTK2_INCLUDE_DIRS})
- add_executable(mygui mygui.cc)
- target_link_libraries(mygui ${GTK2_LIBRARIES})
- endif()
+ if(GTK2_FOUND)
+ include_directories(${GTK2_INCLUDE_DIRS})
+ add_executable(mygui mygui.cc)
+ target_link_libraries(mygui ${GTK2_LIBRARIES})
+ endif()
#]=======================================================================]
# Version 1.6 (CMake 3.0)
@@ -884,6 +871,7 @@ foreach(_GTK2_component ${GTK2_FIND_COMPONENTS})
set(GTK2_${_COMPONENT_UPPER}_FIND_QUIETLY ${GTK2_FIND_QUIETLY})
+ set(FPHSA_NAME_MISMATCHED 1)
if(_GTK2_component STREQUAL "gtk")
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTK2_${_COMPONENT_UPPER} "Some or all of the gtk libraries were not found."
GTK2_GTK_LIBRARY
@@ -926,6 +914,7 @@ foreach(_GTK2_component ${GTK2_FIND_COMPONENTS})
GTK2_GLADEMMCONFIG_INCLUDE_DIR
)
endif()
+ unset(FPHSA_NAME_MISMATCHED)
if(NOT GTK2_${_COMPONENT_UPPER}_FOUND)
set(_GTK2_did_we_find_everything false)
diff --git a/Modules/FindGTest.cmake b/Modules/FindGTest.cmake
index e015a98..53cab1a 100644
--- a/Modules/FindGTest.cmake
+++ b/Modules/FindGTest.cmake
@@ -240,4 +240,15 @@ if(GTEST_FOUND)
__gtest_import_library(GTest::Main GTEST_MAIN_LIBRARY "RELEASE")
__gtest_import_library(GTest::Main GTEST_MAIN_LIBRARY "DEBUG")
endif()
+
+ # Add targets mapping the same library names as defined in
+ # GTest's CMake package config.
+ if(NOT TARGET GTest::gtest)
+ add_library(GTest::gtest INTERFACE IMPORTED)
+ target_link_libraries(GTest::gtest INTERFACE GTest::GTest)
+ endif()
+ if(NOT TARGET GTest::gtest_main)
+ add_library(GTest::gtest_main INTERFACE IMPORTED)
+ target_link_libraries(GTest::gtest_main INTERFACE GTest::Main)
+ endif()
endif()
diff --git a/Modules/FindHDF5.cmake b/Modules/FindHDF5.cmake
index b488418..c1888a4 100644
--- a/Modules/FindHDF5.cmake
+++ b/Modules/FindHDF5.cmake
@@ -19,9 +19,12 @@ The module will optionally accept the ``COMPONENTS`` argument. If no
``COMPONENTS`` are specified, then the find module will default to finding
only the ``HDF5`` C library. If one or more ``COMPONENTS`` are specified, the
module will attempt to find the language bindings for the specified
-components. The only valid components are ``C``, ``CXX``, ``Fortran``, ``HL``,
-and ``Fortran_HL``. If the ``COMPONENTS`` argument is not given, the module will
+components. The valid components are ``C``, ``CXX``, ``Fortran``, ``HL``.
+``HL`` refers to the "high-level" HDF5 functions for C and Fortran.
+If the ``COMPONENTS`` argument is not given, the module will
attempt to find only the C bindings.
+For example, to use Fortran HDF5 and HDF5-HL functions, do:
+``find_package(HDF5 COMPONENTS Fortran HL)``.
This module will read the variable
``HDF5_USE_STATIC_LIBRARIES`` to determine whether or not to prefer a
@@ -29,11 +32,6 @@ static link to a dynamic link for ``HDF5`` and all of it's dependencies.
To use this feature, make sure that the ``HDF5_USE_STATIC_LIBRARIES``
variable is set before the call to find_package.
-To provide the module with a hint about where to find your ``HDF5``
-installation, you can set the environment variable ``HDF5_ROOT``. The
-Find module will then look in this path when searching for ``HDF5``
-executables, paths, and libraries.
-
Both the serial and parallel ``HDF5`` wrappers are considered and the first
directory to contain either one will be used. In the event that both appear
in the same directory the serial version is preferentially selected. This
@@ -115,10 +113,10 @@ also be defined. With all components enabled, the following variables will be d
Hints
^^^^^
-The following variable can be set to guide the search for HDF5 libraries and includes:
+The following variables can be set to guide the search for HDF5 libraries and includes:
-``HDF5_ROOT``
- Specify the path to the HDF5 installation to use.
+``HDF5_PREFER_PARALLEL``
+ set ``true`` to prefer parallel HDF5 (by default, serial is preferred)
``HDF5_FIND_DEBUG``
Set ``true`` to get extra debugging output.
@@ -343,35 +341,46 @@ macro( _HDF5_invoke_compiler language output return_value version is_parallel)
elseif("${language}" STREQUAL "Fortran")
set(test_file ${scratch_dir}/cmake_hdf5_test.f90)
endif()
+ # Verify that the compiler wrapper can actually compile: sometimes the compiler
+ # wrapper exists, but not the compiler. E.g. Miniconda / Anaconda Python
execute_process(
- COMMAND ${HDF5_${language}_COMPILER_EXECUTABLE} -show ${lib_type_args} ${test_file}
- OUTPUT_VARIABLE ${output}
- ERROR_VARIABLE ${output}
+ COMMAND ${HDF5_${language}_COMPILER_EXECUTABLE} ${test_file}
RESULT_VARIABLE ${return_value}
)
if(NOT ${${return_value}} EQUAL 0)
- message(STATUS
- "Unable to determine HDF5 ${language} flags from HDF5 wrapper.")
- endif()
- execute_process(
- COMMAND ${HDF5_${language}_COMPILER_EXECUTABLE} -showconfig
- OUTPUT_VARIABLE config_output
- ERROR_VARIABLE config_output
- RESULT_VARIABLE config_return
- )
- if(NOT ${return_value} EQUAL 0)
- message( STATUS
- "Unable to determine HDF5 ${language} version from HDF5 wrapper.")
- endif()
- string(REGEX MATCH "HDF5 Version: ([a-zA-Z0-9\\.\\-]*)" version_match "${config_output}")
- if(version_match)
- string(REPLACE "HDF5 Version: " "" ${version} "${version_match}")
- string(REPLACE "-patch" "." ${version} "${${version}}")
- endif()
- if(config_output MATCHES "Parallel HDF5: yes")
- set(${is_parallel} TRUE)
+ message(STATUS
+ "HDF5 ${language} compiler wrapper is unable to compile a minimal HDF5 program.")
else()
- set(${is_parallel} FALSE)
+ execute_process(
+ COMMAND ${HDF5_${language}_COMPILER_EXECUTABLE} -show ${lib_type_args} ${test_file}
+ OUTPUT_VARIABLE ${output}
+ ERROR_VARIABLE ${output}
+ RESULT_VARIABLE ${return_value}
+ )
+ if(NOT ${${return_value}} EQUAL 0)
+ message(STATUS
+ "Unable to determine HDF5 ${language} flags from HDF5 wrapper.")
+ endif()
+ execute_process(
+ COMMAND ${HDF5_${language}_COMPILER_EXECUTABLE} -showconfig
+ OUTPUT_VARIABLE config_output
+ ERROR_VARIABLE config_output
+ RESULT_VARIABLE config_return
+ )
+ if(NOT ${return_value} EQUAL 0)
+ message( STATUS
+ "Unable to determine HDF5 ${language} version from HDF5 wrapper.")
+ endif()
+ string(REGEX MATCH "HDF5 Version: ([a-zA-Z0-9\\.\\-]*)" version_match "${config_output}")
+ if(version_match)
+ string(REPLACE "HDF5 Version: " "" ${version} "${version_match}")
+ string(REPLACE "-patch" "." ${version} "${${version}}")
+ endif()
+ if(config_output MATCHES "Parallel HDF5: yes")
+ set(${is_parallel} TRUE)
+ else()
+ set(${is_parallel} FALSE)
+ endif()
endif()
endmacro()
@@ -769,6 +778,17 @@ if( NOT HDF5_FOUND )
set(HDF5_Fortran_LIBRARY_NAMES hdf5_fortran ${HDF5_C_LIBRARY_NAMES})
set(HDF5_Fortran_HL_LIBRARY_NAMES hdf5hl_fortran ${HDF5_C_HL_LIBRARY_NAMES} ${HDF5_Fortran_LIBRARY_NAMES})
+ # suffixes as seen on Linux, MSYS2, ...
+ set(_lib_suffixes hdf5)
+ if(NOT HDF5_PREFER_PARALLEL)
+ list(APPEND _lib_suffixes hdf5/serial)
+ endif()
+ if(HDF5_USE_STATIC_LIBRARIES)
+ set(_inc_suffixes include/static)
+ else()
+ set(_inc_suffixes include/shared)
+ endif()
+
foreach(__lang IN LISTS HDF5_LANGUAGE_BINDINGS)
# find the HDF5 include directories
if("${__lang}" STREQUAL "Fortran")
@@ -782,7 +802,7 @@ if( NOT HDF5_FOUND )
find_path(HDF5_${__lang}_INCLUDE_DIR ${HDF5_INCLUDE_FILENAME}
HINTS ${HDF5_ROOT}
PATHS $ENV{HOME}/.local/include
- PATH_SUFFIXES include Include
+ PATH_SUFFIXES include Include ${_inc_suffixes} ${_lib_suffixes}
${_HDF5_SEARCH_OPTS}
)
mark_as_advanced(HDF5_${__lang}_INCLUDE_DIR)
@@ -811,14 +831,15 @@ if( NOT HDF5_FOUND )
endif()
find_library(HDF5_${LIB}_LIBRARY_DEBUG
NAMES ${THIS_LIBRARY_SEARCH_DEBUG}
- HINTS ${HDF5_ROOT} PATH_SUFFIXES lib Lib
+ HINTS ${HDF5_ROOT} PATH_SUFFIXES lib Lib ${_lib_suffixes}
${_HDF5_SEARCH_OPTS}
)
- find_library( HDF5_${LIB}_LIBRARY_RELEASE
+ find_library(HDF5_${LIB}_LIBRARY_RELEASE
NAMES ${THIS_LIBRARY_SEARCH_RELEASE}
- HINTS ${HDF5_ROOT} PATH_SUFFIXES lib Lib
+ HINTS ${HDF5_ROOT} PATH_SUFFIXES lib Lib ${_lib_suffixes}
${_HDF5_SEARCH_OPTS}
)
+
select_library_configurations( HDF5_${LIB} )
list(APPEND HDF5_${__lang}_LIBRARIES ${HDF5_${LIB}_LIBRARY})
endforeach()
@@ -848,14 +869,15 @@ if( NOT HDF5_FOUND )
endif()
find_library(HDF5_${LIB}_LIBRARY_DEBUG
NAMES ${THIS_LIBRARY_SEARCH_DEBUG}
- HINTS ${HDF5_ROOT} PATH_SUFFIXES lib Lib
+ HINTS ${HDF5_ROOT} PATH_SUFFIXES lib Lib ${_lib_suffixes}
${_HDF5_SEARCH_OPTS}
)
- find_library( HDF5_${LIB}_LIBRARY_RELEASE
+ find_library(HDF5_${LIB}_LIBRARY_RELEASE
NAMES ${THIS_LIBRARY_SEARCH_RELEASE}
- HINTS ${HDF5_ROOT} PATH_SUFFIXES lib Lib
+ HINTS ${HDF5_ROOT} PATH_SUFFIXES lib Lib ${_lib_suffixes}
${_HDF5_SEARCH_OPTS}
)
+
select_library_configurations( HDF5_${LIB} )
list(APPEND HDF5_${__lang}_HL_LIBRARIES ${HDF5_${LIB}_LIBRARY})
endforeach()
diff --git a/Modules/FindLAPACK.cmake b/Modules/FindLAPACK.cmake
index 3cb3653..e275946 100644
--- a/Modules/FindLAPACK.cmake
+++ b/Modules/FindLAPACK.cmake
@@ -7,10 +7,10 @@ FindLAPACK
Find Linear Algebra PACKage (LAPACK) library
-This module finds an installed fortran library that implements the
+This module finds an installed Fortran library that implements the
LAPACK linear-algebra interface (see http://www.netlib.org/lapack/).
-The approach follows that taken for the autoconf macro file,
+The approach follows that taken for the ``autoconf`` macro file,
``acx_lapack.m4`` (distributed at
http://ac-archive.sourceforge.net/ac-archive/acx_lapack.html).
@@ -26,21 +26,34 @@ The following variables may be set to influence this module's behavior:
If set, checks only the specified vendor, if not set checks all the
possibilities. List of vendors valid in this module:
+ * ``OpenBLAS``
+ * ``FLAME``
* ``Intel10_32`` (intel mkl v10 32 bit)
* ``Intel10_64lp`` (intel mkl v10+ 64 bit, threaded code, lp64 model)
* ``Intel10_64lp_seq`` (intel mkl v10+ 64 bit, sequential code, lp64 model)
* ``Intel10_64ilp`` (intel mkl v10+ 64 bit, threaded code, ilp64 model)
* ``Intel10_64ilp_seq`` (intel mkl v10+ 64 bit, sequential code, ilp64 model)
+ * ``Intel10_64_dyn`` (intel mkl v10+ 64 bit, single dynamic library)
* ``Intel`` (obsolete versions of mkl 32 and 64 bit)
- * ``OpenBLAS``
- * ``FLAME``
* ``ACML``
* ``Apple``
* ``NAS``
+ * ``Arm``
+ * ``Arm_mp``
+ * ``Arm_ilp64``
+ * ``Arm_ilp64_mp``
* ``Generic``
``BLA_F95``
- if ``ON`` tries to find BLAS95/LAPACK95
+ if ``ON`` tries to find the BLAS95/LAPACK95 interfaces
+
+Imported targets
+^^^^^^^^^^^^^^^^
+
+This module defines the following :prop_tgt:`IMPORTED` target:
+
+``LAPACK::LAPACK``
+ The libraries to use for LAPACK, if found.
Result Variables
^^^^^^^^^^^^^^^^
@@ -50,7 +63,7 @@ This module defines the following variables:
``LAPACK_FOUND``
library implementing the LAPACK interface is found
``LAPACK_LINKER_FLAGS``
- uncached list of required linker flags (excluding -l and -L).
+ uncached list of required linker flags (excluding ``-l`` and ``-L``).
``LAPACK_LIBRARIES``
uncached list of libraries (using full path name) to link against
to use LAPACK
@@ -62,7 +75,8 @@ This module defines the following variables:
.. note::
- C or CXX must be enabled to use Intel MKL
+ C, CXX or Fortran must be enabled to detect a BLAS/LAPACK library.
+ C or CXX must be enabled to use Intel Math Kernel Library (MKL).
For example, to use Intel MKL libraries and/or Intel compiler:
@@ -72,10 +86,8 @@ This module defines the following variables:
find_package(LAPACK)
#]=======================================================================]
-set(_lapack_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
-
# Check the language being used
-if( NOT (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED) )
+if(NOT (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_COMPILER_LOADED))
if(LAPACK_FIND_REQUIRED)
message(FATAL_ERROR "FindLAPACK requires Fortran, C, or C++ to be enabled.")
else()
@@ -84,11 +96,11 @@ if( NOT (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED OR CMAKE_Fortran_C
endif()
endif()
-if (CMAKE_Fortran_COMPILER_LOADED)
-include(${CMAKE_CURRENT_LIST_DIR}/CheckFortranFunctionExists.cmake)
-else ()
-include(${CMAKE_CURRENT_LIST_DIR}/CheckFunctionExists.cmake)
-endif ()
+if(CMAKE_Fortran_COMPILER_LOADED)
+ include(${CMAKE_CURRENT_LIST_DIR}/CheckFortranFunctionExists.cmake)
+else()
+ include(${CMAKE_CURRENT_LIST_DIR}/CheckFunctionExists.cmake)
+endif()
include(${CMAKE_CURRENT_LIST_DIR}/CMakePushCheckState.cmake)
cmake_push_check_state()
@@ -97,290 +109,374 @@ set(CMAKE_REQUIRED_QUIET ${LAPACK_FIND_QUIETLY})
set(LAPACK_FOUND FALSE)
set(LAPACK95_FOUND FALSE)
-# TODO: move this stuff to separate module
-
-macro(Check_Lapack_Libraries LIBRARIES _prefix _name _flags _list _blas _threads)
-# This macro checks for the existence of the combination of fortran libraries
-# given by _list. If the combination is found, this macro checks (using the
-# Check_Fortran_Function_Exists macro) whether can link against that library
-# combination using the name of a routine given by _name using the linker
-# flags given by _flags. If the combination of libraries is found and passes
-# the link test, LIBRARIES is set to the list of complete library paths that
-# have been found. Otherwise, LIBRARIES is set to FALSE.
-
-# N.B. _prefix is the prefix applied to the names of all cached variables that
-# are generated internally and marked advanced by this macro.
-
-set(_libraries_work TRUE)
-set(${LIBRARIES})
-set(_combined_name)
-if (NOT _libdir)
- if (WIN32)
- set(_libdir ENV LIB)
- elseif (APPLE)
- set(_libdir ENV DYLD_LIBRARY_PATH)
- else ()
- set(_libdir ENV LD_LIBRARY_PATH)
- endif ()
-endif ()
-
-list(APPEND _libdir "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}")
-
-foreach(_library ${_list})
- set(_combined_name ${_combined_name}_${_library})
+set(_lapack_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
+if(BLA_STATIC)
+ if(WIN32)
+ set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES})
+ else()
+ set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
+ endif()
+else()
+ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ # for ubuntu's libblas3gf and liblapack3gf packages
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf)
+ endif()
+endif()
+
+# TODO: move this stuff to a separate module
+
+macro(CHECK_LAPACK_LIBRARIES LIBRARIES _prefix _name _flags _list _threadlibs _addlibdir _subdirs _blas)
+ # This macro checks for the existence of the combination of fortran libraries
+ # given by _list. If the combination is found, this macro checks (using the
+ # Check_Fortran_Function_Exists macro) whether can link against that library
+ # combination using the name of a routine given by _name using the linker
+ # flags given by _flags. If the combination of libraries is found and passes
+ # the link test, LIBRARIES is set to the list of complete library paths that
+ # have been found. Otherwise, LIBRARIES is set to FALSE.
+
+ # N.B. _prefix is the prefix applied to the names of all cached variables that
+ # are generated internally and marked advanced by this macro.
+ # _addlibdir is a list of additional search paths. _subdirs is a list of path
+ # suffixes to be used by find_library().
+
+ set(_libraries_work TRUE)
+ set(${LIBRARIES})
+ set(_combined_name)
+
+ set(_extaddlibdir "${_addlibdir}")
+ if(WIN32)
+ list(APPEND _extaddlibdir ENV LIB)
+ elseif(APPLE)
+ list(APPEND _extaddlibdir ENV DYLD_LIBRARY_PATH)
+ else()
+ list(APPEND _extaddlibdir ENV LD_LIBRARY_PATH)
+ endif()
+ list(APPEND _extaddlibdir "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}")
+
+ foreach(_library ${_list})
+ if(_library MATCHES "^-Wl,--(start|end)-group$")
+ # Respect linker flags like --start/end-group (required by MKL)
+ set(${LIBRARIES} ${${LIBRARIES}} "${_library}")
+ else()
+ set(_combined_name ${_combined_name}_${_library})
+ if(_libraries_work)
+ find_library(${_prefix}_${_library}_LIBRARY
+ NAMES ${_library}
+ PATHS ${_extaddlibdir}
+ PATH_SUFFIXES ${_subdirs}
+ )
+ #message("DEBUG: find_library(${_library}) got ${${_prefix}_${_library}_LIBRARY}")
+ mark_as_advanced(${_prefix}_${_library}_LIBRARY)
+ set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY})
+ set(_libraries_work ${${_prefix}_${_library}_LIBRARY})
+ endif()
+ endif()
+ endforeach()
if(_libraries_work)
- if (BLA_STATIC)
- if (WIN32)
- set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES})
- endif ()
- if (APPLE)
- set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES})
- else ()
- set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
- endif ()
- else ()
- if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
- # for ubuntu's libblas3gf and liblapack3gf packages
- set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES} .so.3gf)
- endif ()
- endif ()
- find_library(${_prefix}_${_library}_LIBRARY
- NAMES ${_library}
- PATHS ${_libdir}
- )
- mark_as_advanced(${_prefix}_${_library}_LIBRARY)
- set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY})
- set(_libraries_work ${${_prefix}_${_library}_LIBRARY})
+ # Test this combination of libraries.
+ set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_blas} ${_threadlibs})
+ #message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}")
+ if(CMAKE_Fortran_COMPILER_LOADED)
+ check_fortran_function_exists("${_name}" ${_prefix}${_combined_name}_WORKS)
+ else()
+ check_function_exists("${_name}_" ${_prefix}${_combined_name}_WORKS)
+ endif()
+ set(CMAKE_REQUIRED_LIBRARIES)
+ set(_libraries_work ${${_prefix}${_combined_name}_WORKS})
endif()
-endforeach()
-if(_libraries_work)
- # Test this combination of libraries.
- if(UNIX AND BLA_STATIC)
- set(CMAKE_REQUIRED_LIBRARIES ${_flags} "-Wl,--start-group" ${${LIBRARIES}} ${_blas} "-Wl,--end-group" ${_threads})
+ if(_libraries_work)
+ if("${_list}${_blas}" STREQUAL "")
+ set(${LIBRARIES} "${LIBRARIES}-PLACEHOLDER-FOR-EMPTY-LIBRARIES")
+ else()
+ set(${LIBRARIES} ${${LIBRARIES}} ${_blas} ${_threadlibs})
+ endif()
else()
- set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_blas} ${_threads})
+ set(${LIBRARIES} FALSE)
endif()
-# message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}")
- if (NOT CMAKE_Fortran_COMPILER_LOADED)
- check_function_exists("${_name}_" ${_prefix}${_combined_name}_WORKS)
- else ()
- check_fortran_function_exists(${_name} ${_prefix}${_combined_name}_WORKS)
- endif ()
- set(CMAKE_REQUIRED_LIBRARIES)
- set(_libraries_work ${${_prefix}${_combined_name}_WORKS})
#message("DEBUG: ${LIBRARIES} = ${${LIBRARIES}}")
-endif()
-
- if(_libraries_work)
- if("${_list}${_blas}" STREQUAL "")
- set(${LIBRARIES} "${LIBRARIES}-PLACEHOLDER-FOR-EMPTY-LIBRARIES")
- else()
- set(${LIBRARIES} ${${LIBRARIES}} ${_blas} ${_threads})
- endif()
- else()
- set(${LIBRARIES} FALSE)
- endif()
-
endmacro()
-
set(LAPACK_LINKER_FLAGS)
set(LAPACK_LIBRARIES)
set(LAPACK95_LIBRARIES)
-
if(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED)
find_package(BLAS)
else()
find_package(BLAS REQUIRED)
endif()
-
if(BLAS_FOUND)
set(LAPACK_LINKER_FLAGS ${BLAS_LINKER_FLAGS})
- if (NOT $ENV{BLA_VENDOR} STREQUAL "")
+ if(NOT $ENV{BLA_VENDOR} STREQUAL "")
set(BLA_VENDOR $ENV{BLA_VENDOR})
- else ()
+ else()
if(NOT BLA_VENDOR)
set(BLA_VENDOR "All")
endif()
- endif ()
-
-#intel lapack
-if (BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All")
- if(NOT LAPACK_LIBRARIES)
- if (NOT WIN32)
- set(LAPACK_mkl_LM "-lm")
- set(LAPACK_mkl_LDL "-ldl")
- endif ()
- if (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED)
- if(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED)
- find_PACKAGE(Threads)
- else()
- find_package(Threads REQUIRED)
+ endif()
+
+ # LAPACK in the Intel MKL 10+ library?
+ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All")
+ if(NOT LAPACK_LIBRARIES)
+ if(CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED)
+ # System-specific settings
+ if(NOT WIN32)
+ set(LAPACK_mkl_LM "-lm")
+ set(LAPACK_mkl_LDL "-ldl")
+ endif()
+
+ if(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED)
+ find_package(Threads)
+ else()
+ find_package(Threads REQUIRED)
+ endif()
+
+ if(BLA_VENDOR MATCHES "_64ilp")
+ set(LAPACK_mkl_ILP_MODE "ilp64")
+ else()
+ set(LAPACK_mkl_ILP_MODE "lp64")
+ endif()
+
+ set(LAPACK_SEARCH_LIBS "")
+
+ if(BLA_F95)
+ set(LAPACK_mkl_SEARCH_SYMBOL "cheev_f95")
+ set(_LIBRARIES LAPACK95_LIBRARIES)
+ set(_BLAS_LIBRARIES ${BLAS95_LIBRARIES})
+
+ # old
+ list(APPEND LAPACK_SEARCH_LIBS
+ "mkl_lapack95")
+ # new >= 10.3
+ list(APPEND LAPACK_SEARCH_LIBS
+ "mkl_intel_c")
+ list(APPEND LAPACK_SEARCH_LIBS
+ "mkl_lapack95_${LAPACK_mkl_ILP_MODE}")
+ else()
+ set(LAPACK_mkl_SEARCH_SYMBOL "cheev")
+ set(_LIBRARIES LAPACK_LIBRARIES)
+ set(_BLAS_LIBRARIES ${BLAS_LIBRARIES})
+
+ # old and new >= 10.3
+ list(APPEND LAPACK_SEARCH_LIBS
+ "mkl_lapack")
+ endif()
+
+ # MKL uses a multitude of partially platform-specific subdirectories:
+ if(BLA_VENDOR STREQUAL "Intel10_32")
+ set(LAPACK_mkl_ARCH_NAME "ia32")
+ else()
+ set(LAPACK_mkl_ARCH_NAME "intel64")
+ endif()
+ if(WIN32)
+ set(LAPACK_mkl_OS_NAME "win")
+ elseif(APPLE)
+ set(LAPACK_mkl_OS_NAME "mac")
+ else()
+ set(LAPACK_mkl_OS_NAME "lin")
+ endif()
+ if(DEFINED ENV{MKLROOT})
+ set(LAPACK_mkl_MKLROOT "$ENV{MKLROOT}")
+ # If MKLROOT points to the subdirectory 'mkl', use the parent directory instead
+ # so we can better detect other relevant libraries in 'compiler' or 'tbb':
+ get_filename_component(LAPACK_mkl_MKLROOT_LAST_DIR "${LAPACK_mkl_MKLROOT}" NAME)
+ if(LAPACK_mkl_MKLROOT_LAST_DIR STREQUAL "mkl")
+ get_filename_component(LAPACK_mkl_MKLROOT "${LAPACK_mkl_MKLROOT}" DIRECTORY)
+ endif()
+ endif()
+ set(LAPACK_mkl_LIB_PATH_SUFFIXES
+ "compiler/lib" "compiler/lib/${LAPACK_mkl_ARCH_NAME}_${LAPACK_mkl_OS_NAME}"
+ "mkl/lib" "mkl/lib/${LAPACK_mkl_ARCH_NAME}_${LAPACK_mkl_OS_NAME}"
+ "lib/${LAPACK_mkl_ARCH_NAME}_${LAPACK_mkl_OS_NAME}")
+
+ # First try empty lapack libs
+ if(NOT ${_LIBRARIES})
+ check_lapack_libraries(
+ ${_LIBRARIES}
+ LAPACK
+ ${LAPACK_mkl_SEARCH_SYMBOL}
+ ""
+ ""
+ "${CMAKE_THREAD_LIBS_INIT};${LAPACK_mkl_LM};${LAPACK_mkl_LDL}"
+ "${LAPACK_mkl_MKLROOT}"
+ "${LAPACK_mkl_LIB_PATH_SUFFIXES}"
+ "${_BLAS_LIBRARIES}"
+ )
+ endif()
+
+ # Then try the search libs
+ foreach(IT ${LAPACK_SEARCH_LIBS})
+ string(REPLACE " " ";" SEARCH_LIBS ${IT})
+ if(NOT ${_LIBRARIES})
+ check_lapack_libraries(
+ ${_LIBRARIES}
+ LAPACK
+ ${LAPACK_mkl_SEARCH_SYMBOL}
+ ""
+ "${SEARCH_LIBS}"
+ "${CMAKE_THREAD_LIBS_INIT};${LAPACK_mkl_LM};${LAPACK_mkl_LDL}"
+ "${LAPACK_mkl_MKLROOT}"
+ "${LAPACK_mkl_LIB_PATH_SUFFIXES}"
+ "${_BLAS_LIBRARIES}"
+ )
+ endif()
+ endforeach()
+
+ unset(LAPACK_mkl_ILP_MODE)
+ unset(LAPACK_mkl_SEARCH_SYMBOL)
+ unset(LAPACK_mkl_LM)
+ unset(LAPACK_mkl_LDL)
+ unset(LAPACK_mkl_MKLROOT)
+ unset(LAPACK_mkl_ARCH_NAME)
+ unset(LAPACK_mkl_OS_NAME)
+ unset(LAPACK_mkl_LIB_PATH_SUFFIXES)
+ endif()
+ endif()
+ endif()
+
+ # gotoblas? (http://www.tacc.utexas.edu/tacc-projects/gotoblas2)
+ if(BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All")
+ if(NOT LAPACK_LIBRARIES)
+ check_lapack_libraries(
+ LAPACK_LIBRARIES
+ LAPACK
+ cheev
+ ""
+ "goto2"
+ ""
+ ""
+ ""
+ "${BLAS_LIBRARIES}"
+ )
+ endif()
+ endif()
+
+ # OpenBLAS? (http://www.openblas.net)
+ if(BLA_VENDOR STREQUAL "OpenBLAS" OR BLA_VENDOR STREQUAL "All")
+ if(NOT LAPACK_LIBRARIES)
+ check_lapack_libraries(
+ LAPACK_LIBRARIES
+ LAPACK
+ cheev
+ ""
+ "openblas"
+ ""
+ ""
+ ""
+ "${BLAS_LIBRARIES}"
+ )
endif()
+ endif()
+
+ # ArmPL? (https://developer.arm.com/tools-and-software/server-and-hpc/compile/arm-compiler-for-linux/arm-performance-libraries)
+ if(BLA_VENDOR MATCHES "Arm" OR BLA_VENDOR STREQUAL "All")
- if (BLA_VENDOR MATCHES "_64ilp")
- set(LAPACK_mkl_ILP_MODE "ilp64")
- else ()
- set(LAPACK_mkl_ILP_MODE "lp64")
- endif ()
-
- set(LAPACK_SEARCH_LIBS "")
-
- if (BLA_F95)
- set(LAPACK_mkl_SEARCH_SYMBOL "cheev_f95")
- set(_LIBRARIES LAPACK95_LIBRARIES)
- set(_BLAS_LIBRARIES ${BLAS95_LIBRARIES})
-
- # old
- list(APPEND LAPACK_SEARCH_LIBS
- "mkl_lapack95")
- # new >= 10.3
- list(APPEND LAPACK_SEARCH_LIBS
- "mkl_intel_c")
- list(APPEND LAPACK_SEARCH_LIBS
- "mkl_lapack95_${LAPACK_mkl_ILP_MODE}")
+ # Check for 64bit Integer support
+ if(BLA_VENDOR MATCHES "_ilp64")
+ set(LAPACK_armpl_LIB "armpl_ilp64")
else()
- set(LAPACK_mkl_SEARCH_SYMBOL "cheev")
- set(_LIBRARIES LAPACK_LIBRARIES)
- set(_BLAS_LIBRARIES ${BLAS_LIBRARIES})
+ set(LAPACK_armpl_LIB "armpl_lp64")
+ endif()
- # old
- list(APPEND LAPACK_SEARCH_LIBS
- "mkl_lapack")
+ # Check for OpenMP support, VIA BLA_VENDOR of Arm_mp or Arm_ipl64_mp
+ if(BLA_VENDOR MATCHES "_mp")
+ set(LAPACK_armpl_LIB "${LAPACK_armpl_LIB}_mp")
endif()
- # First try empty lapack libs
- if (NOT ${_LIBRARIES})
+ if(NOT LAPACK_LIBRARIES)
check_lapack_libraries(
- ${_LIBRARIES}
+ LAPACK_LIBRARIES
LAPACK
- ${LAPACK_mkl_SEARCH_SYMBOL}
+ cheev
""
+ "${LAPACK_armpl_LIB}"
""
- "${_BLAS_LIBRARIES}"
""
- )
- endif ()
- # Then try the search libs
- foreach (IT ${LAPACK_SEARCH_LIBS})
- if (NOT ${_LIBRARIES})
- check_lapack_libraries(
- ${_LIBRARIES}
- LAPACK
- ${LAPACK_mkl_SEARCH_SYMBOL}
- ""
- "${IT}"
- "${_BLAS_LIBRARIES}"
- "${CMAKE_THREAD_LIBS_INIT};${LAPACK_mkl_LM};${LAPACK_mkl_LDL}"
- )
- endif ()
- endforeach ()
-
- unset(LAPACK_mkl_ILP_MODE)
- unset(LAPACK_mkl_SEARCH_SYMBOL)
- unset(LAPACK_mkl_LM)
- unset(LAPACK_mkl_LDL)
- endif ()
+ ""
+ "${BLAS_LIBRARIES}"
+ )
+ endif()
endif()
-endif()
-if (BLA_VENDOR STREQUAL "Goto" OR BLA_VENDOR STREQUAL "All")
- if(NOT LAPACK_LIBRARIES)
- check_lapack_libraries(
- LAPACK_LIBRARIES
- LAPACK
- cheev
- ""
- "goto2"
- "${BLAS_LIBRARIES}"
- ""
- )
- endif()
-endif ()
-
-if (BLA_VENDOR STREQUAL "OpenBLAS" OR BLA_VENDOR STREQUAL "All")
- if(NOT LAPACK_LIBRARIES)
- check_lapack_libraries(
- LAPACK_LIBRARIES
- LAPACK
- cheev
- ""
- "openblas"
- "${BLAS_LIBRARIES}"
- ""
- )
- endif()
-endif ()
-
-if (BLA_VENDOR STREQUAL "FLAME" OR BLA_VENDOR STREQUAL "All")
- if(NOT LAPACK_LIBRARIES)
- check_lapack_libraries(
- LAPACK_LIBRARIES
- LAPACK
- cheev
- ""
- "flame"
- "${BLAS_LIBRARIES}"
- ""
- )
- endif()
-endif ()
-
-#acml lapack
-if (BLA_VENDOR MATCHES "ACML" OR BLA_VENDOR STREQUAL "All")
- if (BLAS_LIBRARIES MATCHES ".+acml.+")
- set (LAPACK_LIBRARIES ${BLAS_LIBRARIES})
- endif ()
-endif ()
-
-# Apple LAPACK library?
-if (BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All")
- if(NOT LAPACK_LIBRARIES)
- check_lapack_libraries(
- LAPACK_LIBRARIES
- LAPACK
- cheev
- ""
- "Accelerate"
- "${BLAS_LIBRARIES}"
- ""
- )
+ # FLAME's blis library? (https://github.com/flame/blis)
+ if(BLA_VENDOR STREQUAL "FLAME" OR BLA_VENDOR STREQUAL "All")
+ if(NOT LAPACK_LIBRARIES)
+ check_lapack_libraries(
+ LAPACK_LIBRARIES
+ LAPACK
+ cheev
+ ""
+ "flame"
+ ""
+ ""
+ ""
+ "${BLAS_LIBRARIES}"
+ )
+ endif()
+ endif()
+
+ # BLAS in acml library?
+ if(BLA_VENDOR MATCHES "ACML" OR BLA_VENDOR STREQUAL "All")
+ if(BLAS_LIBRARIES MATCHES ".+acml.+")
+ set(LAPACK_LIBRARIES ${BLAS_LIBRARIES})
+ endif()
+ endif()
+
+ # Apple LAPACK library?
+ if(BLA_VENDOR STREQUAL "Apple" OR BLA_VENDOR STREQUAL "All")
+ if(NOT LAPACK_LIBRARIES)
+ check_lapack_libraries(
+ LAPACK_LIBRARIES
+ LAPACK
+ cheev
+ ""
+ "Accelerate"
+ ""
+ ""
+ ""
+ "${BLAS_LIBRARIES}"
+ )
+ endif()
+ endif()
+
+ # Apple NAS (vecLib) library?
+ if(BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All")
+ if(NOT LAPACK_LIBRARIES)
+ check_lapack_libraries(
+ LAPACK_LIBRARIES
+ LAPACK
+ cheev
+ ""
+ "vecLib"
+ ""
+ ""
+ ""
+ "${BLAS_LIBRARIES}"
+ )
+ endif()
endif()
-endif ()
-if (BLA_VENDOR STREQUAL "NAS" OR BLA_VENDOR STREQUAL "All")
- if ( NOT LAPACK_LIBRARIES )
- check_lapack_libraries(
- LAPACK_LIBRARIES
- LAPACK
- cheev
- ""
- "vecLib"
- "${BLAS_LIBRARIES}"
- ""
- )
- endif ()
-endif ()
-# Generic LAPACK library?
-if (BLA_VENDOR STREQUAL "Generic" OR
- BLA_VENDOR STREQUAL "ATLAS" OR
- BLA_VENDOR STREQUAL "All")
- if ( NOT LAPACK_LIBRARIES )
- check_lapack_libraries(
- LAPACK_LIBRARIES
- LAPACK
- cheev
- ""
- "lapack"
- "${BLAS_LIBRARIES}"
- ""
- )
- endif ()
-endif ()
+ # Generic LAPACK library?
+ if(BLA_VENDOR STREQUAL "Generic" OR
+ BLA_VENDOR STREQUAL "ATLAS" OR
+ BLA_VENDOR STREQUAL "All")
+ if(NOT LAPACK_LIBRARIES)
+ check_lapack_libraries(
+ LAPACK_LIBRARIES
+ LAPACK
+ cheev
+ ""
+ "lapack"
+ ""
+ ""
+ ""
+ "${BLAS_LIBRARIES}"
+ )
+ endif()
+ endif()
else()
message(STATUS "LAPACK requires BLAS")
endif()
@@ -397,11 +493,11 @@ if(BLA_F95)
else()
if(LAPACK_FIND_REQUIRED)
message(FATAL_ERROR
- "A required library with LAPACK95 API not found. Please specify library location."
+ "A required library with LAPACK95 API not found. Please specify library location."
)
else()
message(STATUS
- "A library with LAPACK95 API not found. Please specify library location."
+ "A library with LAPACK95 API not found. Please specify library location."
)
endif()
endif()
@@ -421,11 +517,11 @@ else()
else()
if(LAPACK_FIND_REQUIRED)
message(FATAL_ERROR
- "A required library with LAPACK API not found. Please specify library location."
+ "A required library with LAPACK API not found. Please specify library location."
)
else()
message(STATUS
- "A library with LAPACK API not found. Please specify library location."
+ "A library with LAPACK API not found. Please specify library location."
)
endif()
endif()
@@ -434,9 +530,26 @@ endif()
# On compilers that implicitly link LAPACK (such as ftn, cc, and CC on Cray HPC machines)
# we used a placeholder for empty LAPACK_LIBRARIES to get through our logic above.
-if (LAPACK_LIBRARIES STREQUAL "LAPACK_LIBRARIES-PLACEHOLDER-FOR-EMPTY-LIBRARIES")
+if(LAPACK_LIBRARIES STREQUAL "LAPACK_LIBRARIES-PLACEHOLDER-FOR-EMPTY-LIBRARIES")
set(LAPACK_LIBRARIES "")
endif()
+if(NOT TARGET LAPACK::LAPACK)
+ add_library(LAPACK::LAPACK INTERFACE IMPORTED)
+ set(_lapack_libs "${LAPACK_LIBRARIES}")
+ if(_lapack_libs AND TARGET BLAS::BLAS)
+ # remove the ${BLAS_LIBRARIES} from the interface and replace it
+ # with the BLAS::BLAS target
+ list(REMOVE_ITEM _lapack_libs "${BLAS_LIBRARIES}")
+ endif()
+
+ if(_lapack_libs)
+ set_target_properties(LAPACK::LAPACK PROPERTIES
+ INTERFACE_LINK_LIBRARIES "${_lapack_libs}"
+ )
+ endif()
+ unset(_lapack_libs)
+endif()
+
cmake_pop_check_state()
set(CMAKE_FIND_LIBRARY_SUFFIXES ${_lapack_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
diff --git a/Modules/FindLibArchive.cmake b/Modules/FindLibArchive.cmake
index ef27b7d..ce3c8b8 100644
--- a/Modules/FindLibArchive.cmake
+++ b/Modules/FindLibArchive.cmake
@@ -16,18 +16,26 @@ The module defines the following variables:
LibArchive_INCLUDE_DIRS - include search path
LibArchive_LIBRARIES - libraries to link
LibArchive_VERSION - libarchive 3-component version number
+
+The module defines the following ``IMPORTED`` targets:
+
+::
+
+ LibArchive::LibArchive - target for linking against libarchive
#]=======================================================================]
find_path(LibArchive_INCLUDE_DIR
NAMES archive.h
PATHS
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\LibArchive;InstallPath]/include"
+ DOC "libarchive include directory"
)
find_library(LibArchive_LIBRARY
NAMES archive libarchive
PATHS
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\LibArchive;InstallPath]/lib"
+ DOC "libarchive library"
)
mark_as_advanced(LibArchive_INCLUDE_DIR LibArchive_LIBRARY)
@@ -58,4 +66,11 @@ unset(LIBARCHIVE_FOUND)
if(LibArchive_FOUND)
set(LibArchive_INCLUDE_DIRS ${LibArchive_INCLUDE_DIR})
set(LibArchive_LIBRARIES ${LibArchive_LIBRARY})
+
+ if (NOT TARGET LibArchive::LibArchive)
+ add_library(LibArchive::LibArchive UNKNOWN IMPORTED)
+ set_target_properties(LibArchive::LibArchive PROPERTIES
+ IMPORTED_LOCATION "${LibArchive_LIBRARY}"
+ INTERFACE_INCLUDE_DIRECTORIES "${LibArchive_INCLUDE_DIR}")
+ endif ()
endif()
diff --git a/Modules/FindLibXml2.cmake b/Modules/FindLibXml2.cmake
index da8bfe0..f551dfe 100644
--- a/Modules/FindLibXml2.cmake
+++ b/Modules/FindLibXml2.cmake
@@ -10,8 +10,12 @@ Find the XML processing library (libxml2).
IMPORTED Targets
^^^^^^^^^^^^^^^^
-This module defines :prop_tgt:`IMPORTED` target ``LibXml2::LibXml2``, if
-libxml2 has been found.
+The following :prop_tgt:`IMPORTED` targets may be defined:
+
+``LibXml2::LibXml2``
+ If the libxml2 library has been found
+``LibXml2::xmllint``
+ If the xmllint command-line executable has been found
Result variables
^^^^^^^^^^^^^^^^
@@ -48,7 +52,6 @@ The following cache variables may also be set:
# in the find_path() and find_library() calls
find_package(PkgConfig QUIET)
PKG_CHECK_MODULES(PC_LIBXML QUIET libxml-2.0)
-set(LIBXML2_DEFINITIONS ${PC_LIBXML_CFLAGS_OTHER})
find_path(LIBXML2_INCLUDE_DIR NAMES libxml/xpath.h
HINTS
@@ -74,9 +77,7 @@ find_program(LIBXML2_XMLLINT_EXECUTABLE xmllint)
# for backwards compat. with KDE 4.0.x:
set(XMLLINT_EXECUTABLE "${LIBXML2_XMLLINT_EXECUTABLE}")
-if(PC_LIBXML_VERSION)
- set(LIBXML2_VERSION_STRING ${PC_LIBXML_VERSION})
-elseif(LIBXML2_INCLUDE_DIR AND EXISTS "${LIBXML2_INCLUDE_DIR}/libxml/xmlversion.h")
+if(LIBXML2_INCLUDE_DIR AND EXISTS "${LIBXML2_INCLUDE_DIR}/libxml/xmlversion.h")
file(STRINGS "${LIBXML2_INCLUDE_DIR}/libxml/xmlversion.h" libxml2_version_str
REGEX "^#define[\t ]+LIBXML_DOTTED_VERSION[\t ]+\".*\"")
@@ -85,9 +86,20 @@ elseif(LIBXML2_INCLUDE_DIR AND EXISTS "${LIBXML2_INCLUDE_DIR}/libxml/xmlversion.
unset(libxml2_version_str)
endif()
-set(LIBXML2_INCLUDE_DIRS ${LIBXML2_INCLUDE_DIR} ${PC_LIBXML_INCLUDE_DIRS})
+set(LIBXML2_INCLUDE_DIRS ${LIBXML2_INCLUDE_DIR})
set(LIBXML2_LIBRARIES ${LIBXML2_LIBRARY})
+# Did we find the same installation as pkg-config?
+# If so, use additional information from it.
+unset(LIBXML2_DEFINITIONS)
+foreach(libxml2_pc_lib_dir IN LISTS PC_LIBXML_LIBDIR PC_LIBXML_LIBRARY_DIRS)
+ if (LIBXML2_LIBRARY MATCHES "^${libxml2_pc_lib_dir}")
+ list(APPEND LIBXML2_INCLUDE_DIRS ${PC_LIBXML_INCLUDE_DIRS})
+ set(LIBXML2_DEFINITIONS ${PC_LIBXML_CFLAGS_OTHER})
+ break()
+ endif()
+endforeach()
+
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2
REQUIRED_VARS LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR
@@ -98,5 +110,11 @@ mark_as_advanced(LIBXML2_INCLUDE_DIR LIBXML2_LIBRARY LIBXML2_XMLLINT_EXECUTABLE)
if(LibXml2_FOUND AND NOT TARGET LibXml2::LibXml2)
add_library(LibXml2::LibXml2 UNKNOWN IMPORTED)
set_target_properties(LibXml2::LibXml2 PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${LIBXML2_INCLUDE_DIRS}")
+ set_target_properties(LibXml2::LibXml2 PROPERTIES INTERFACE_COMPILE_OPTIONS "${LIBXML2_DEFINITIONS}")
set_property(TARGET LibXml2::LibXml2 APPEND PROPERTY IMPORTED_LOCATION "${LIBXML2_LIBRARY}")
endif()
+
+if(LIBXML2_XMLLINT_EXECUTABLE AND NOT TARGET LibXml2::xmllint)
+ add_executable(LibXml2::xmllint IMPORTED)
+ set_target_properties(LibXml2::xmllint PROPERTIES IMPORTED_LOCATION "${LIBXML2_XMLLINT_EXECUTABLE}")
+endif()
diff --git a/Modules/FindLibXslt.cmake b/Modules/FindLibXslt.cmake
index 01a9d8b..fc7adeb 100644
--- a/Modules/FindLibXslt.cmake
+++ b/Modules/FindLibXslt.cmake
@@ -8,9 +8,22 @@ FindLibXslt
Find the XSL Transformations, Extensible Stylesheet Language
Transformations (XSLT) library (LibXslt)
-Once done this will define
+IMPORTED Targets
+^^^^^^^^^^^^^^^^
-::
+The following :prop_tgt:`IMPORTED` targets may be defined:
+
+``LibXslt::LibXslt``
+ If the libxslt library has been found
+``LibXslt::LibExslt``
+ If the libexslt library has been found
+``LibXslt::xsltproc``
+ If the xsltproc command-line executable has been found
+
+Result variables
+^^^^^^^^^^^^^^^^
+
+This module will set the following variables in your project:
LIBXSLT_FOUND - system has LibXslt
LIBXSLT_INCLUDE_DIR - the LibXslt include directory
@@ -21,6 +34,8 @@ Once done this will define
Additionally, the following two variables are set (but not required
for using xslt):
+``LIBXSLT_EXSLT_INCLUDE_DIR``
+ The include directory for exslt.
``LIBXSLT_EXSLT_LIBRARIES``
Link to these if you need to link against the exslt library.
``LIBXSLT_XSLTPROC_EXECUTABLE``
@@ -39,16 +54,36 @@ find_path(LIBXSLT_INCLUDE_DIR NAMES libxslt/xslt.h
${PC_LIBXSLT_INCLUDE_DIRS}
)
-find_library(LIBXSLT_LIBRARIES NAMES xslt libxslt
+# CMake 3.17 and below used 'LIBXSLT_LIBRARIES' as the name of
+# the cache entry storing the find_library result. Use the
+# value if it was set by the project or user.
+if(DEFINED LIBXSLT_LIBRARIES AND NOT DEFINED LIBXSLT_LIBRARY)
+ set(LIBXSLT_LIBRARY ${LIBXSLT_LIBRARIES})
+endif()
+
+find_library(LIBXSLT_LIBRARY NAMES xslt libxslt
HINTS
${PC_LIBXSLT_LIBDIR}
${PC_LIBXSLT_LIBRARY_DIRS}
)
+set(LIBXSLT_LIBRARIES ${LIBXSLT_LIBRARY})
+
+PKG_CHECK_MODULES(PC_LIBXSLT_EXSLT QUIET libexslt)
+set(LIBXSLT_EXSLT_DEFINITIONS ${PC_LIBXSLT_EXSLT_CFLAGS_OTHER})
+
+find_path(LIBXSLT_EXSLT_INCLUDE_DIR NAMES libexslt/exslt.h
+ HINTS
+ ${PC_LIBXSLT_EXSLT_INCLUDEDIR}
+ ${PC_LIBXSLT_EXSLT_INCLUDE_DIRS}
+)
+
find_library(LIBXSLT_EXSLT_LIBRARY NAMES exslt libexslt
HINTS
${PC_LIBXSLT_LIBDIR}
${PC_LIBXSLT_LIBRARY_DIRS}
+ ${PC_LIBXSLT_EXSLT_LIBDIR}
+ ${PC_LIBXSLT_EXSLT_LIBRARY_DIRS}
)
set(LIBXSLT_EXSLT_LIBRARIES ${LIBXSLT_EXSLT_LIBRARY} )
@@ -75,3 +110,22 @@ mark_as_advanced(LIBXSLT_INCLUDE_DIR
LIBXSLT_LIBRARIES
LIBXSLT_EXSLT_LIBRARY
LIBXSLT_XSLTPROC_EXECUTABLE)
+
+if(LIBXSLT_FOUND AND NOT TARGET LibXslt::LibXslt)
+ add_library(LibXslt::LibXslt UNKNOWN IMPORTED)
+ set_target_properties(LibXslt::LibXslt PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${LIBXSLT_INCLUDE_DIR}")
+ set_target_properties(LibXslt::LibXslt PROPERTIES INTERFACE_COMPILE_OPTIONS "${LIBXSLT_DEFINITIONS}")
+ set_property(TARGET LibXslt::LibXslt APPEND PROPERTY IMPORTED_LOCATION "${LIBXSLT_LIBRARY}")
+endif()
+
+if(LIBXSLT_FOUND AND NOT TARGET LibXslt::LibExslt)
+ add_library(LibXslt::LibExslt UNKNOWN IMPORTED)
+ set_target_properties(LibXslt::LibExslt PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${LIBXSLT_EXSLT_INCLUDE_DIR}")
+ set_target_properties(LibXslt::LibExslt PROPERTIES INTERFACE_COMPILE_OPTIONS "${LIBXSLT_EXSLT_DEFINITIONS}")
+ set_property(TARGET LibXslt::LibExslt APPEND PROPERTY IMPORTED_LOCATION "${LIBXSLT_EXSLT_LIBRARY}")
+endif()
+
+if(LIBXSLT_XSLTPROC_EXECUTABLE AND NOT TARGET LibXslt::xsltproc)
+ add_executable(LibXslt::xsltproc IMPORTED)
+ set_target_properties(LibXslt::xsltproc PROPERTIES IMPORTED_LOCATION "${LIBXSLT_XSLTPROC_EXECUTABLE}")
+endif()
diff --git a/Modules/FindLua.cmake b/Modules/FindLua.cmake
index caf9d69..0b0c970 100644
--- a/Modules/FindLua.cmake
+++ b/Modules/FindLua.cmake
@@ -211,6 +211,7 @@ if (LUA_LIBRARY)
# include the math library for Unix
if (UNIX AND NOT APPLE AND NOT BEOS)
find_library(LUA_MATH_LIBRARY m)
+ mark_as_advanced(LUA_MATH_LIBRARY)
set(LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}")
# include dl library for statically-linked Lua library
@@ -232,6 +233,6 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua
REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR
VERSION_VAR LUA_VERSION_STRING)
-mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARY LUA_MATH_LIBRARY)
+mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARY)
cmake_policy(POP)
diff --git a/Modules/FindMFC.cmake b/Modules/FindMFC.cmake
index e366619..b8ca71b 100644
--- a/Modules/FindMFC.cmake
+++ b/Modules/FindMFC.cmake
@@ -31,7 +31,7 @@ if(MFC_ATTEMPT_TRY_COMPILE)
set(CHECK_INCLUDE_FILE_VAR "afxwin.h")
configure_file(${CMAKE_ROOT}/Modules/CheckIncludeFile.cxx.in
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckIncludeFile.cxx)
- message(STATUS "Looking for MFC")
+ message(CHECK_START "Looking for MFC")
# Try both shared and static as the root project may have set the /MT flag
try_compile(MFC_HAVE_MFC
${CMAKE_BINARY_DIR}
@@ -51,13 +51,13 @@ if(MFC_ATTEMPT_TRY_COMPILE)
OUTPUT_VARIABLE OUTPUT)
endif()
if(MFC_HAVE_MFC)
- message(STATUS "Looking for MFC - found")
+ message(CHECK_PASS "found")
set(MFC_HAVE_MFC 1 CACHE INTERNAL "Have MFC?")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if MFC exists passed with the following output:\n"
"${OUTPUT}\n\n")
else()
- message(STATUS "Looking for MFC - not found")
+ message(CHECK_FAIL "not found")
set(MFC_HAVE_MFC 0 CACHE INTERNAL "Have MFC?")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if MFC exists failed with the following output:\n"
diff --git a/Modules/FindMPI.cmake b/Modules/FindMPI.cmake
index 42941c9..e9b6bd2 100644
--- a/Modules/FindMPI.cmake
+++ b/Modules/FindMPI.cmake
@@ -842,8 +842,8 @@ function (_MPI_interrogate_compiler LANG)
if(NOT MPI_${LANG}_COMPILE_DEFINITIONS)
set(MPI_${LANG}_COMPILE_DEFINITIONS ${MPI_COMPILE_DEFINITIONS_WORK} CACHE STRING "MPI ${LANG} compilation definitions" FORCE)
endif()
- if(NOT MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS)
- set(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS ${MPI_INCLUDE_DIRS_WORK} CACHE STRING "MPI ${LANG} additional include directories" FORCE)
+ if(NOT MPI_${LANG}_COMPILER_INCLUDE_DIRS)
+ set(MPI_${LANG}_COMPILER_INCLUDE_DIRS ${MPI_INCLUDE_DIRS_WORK} CACHE STRING "MPI ${LANG} compiler wrapper include directories" FORCE)
endif()
if(NOT MPI_${LANG}_LINK_FLAGS)
set(MPI_${LANG}_LINK_FLAGS ${MPI_LINK_FLAGS_WORK} CACHE STRING "MPI ${LANG} linker flags" FORCE)
@@ -867,11 +867,11 @@ function(_MPI_guess_settings LANG)
# We first attempt to locate the msmpi.lib. Should be find it, we'll assume that the MPI present is indeed
# Microsoft MPI.
if("${CMAKE_SIZEOF_VOID_P}" EQUAL 8)
- set(MPI_MSMPI_LIB_PATH "$ENV{MSMPI_LIB64}")
- set(MPI_MSMPI_INC_PATH_EXTRA "$ENV{MSMPI_INC}/x64")
+ file(TO_CMAKE_PATH "$ENV{MSMPI_LIB64}" MPI_MSMPI_LIB_PATH)
+ file(TO_CMAKE_PATH "$ENV{MSMPI_INC}/x64" MPI_MSMPI_INC_PATH_EXTRA)
else()
- set(MPI_MSMPI_LIB_PATH "$ENV{MSMPI_LIB32}")
- set(MPI_MSMPI_INC_PATH_EXTRA "$ENV{MSMPI_INC}/x86")
+ file(TO_CMAKE_PATH "$ENV{MSMPI_LIB32}" MPI_MSMPI_LIB_PATH)
+ file(TO_CMAKE_PATH "$ENV{MSMPI_INC}/x86" MPI_MSMPI_INC_PATH_EXTRA)
endif()
find_library(MPI_msmpi_LIBRARY
@@ -1072,34 +1072,28 @@ macro(_MPI_assemble_libraries LANG)
endmacro()
macro(_MPI_assemble_include_dirs LANG)
- if("${MPI_${LANG}_COMPILER}" STREQUAL "${CMAKE_${LANG}_COMPILER}")
- set(MPI_${LANG}_INCLUDE_DIRS "")
- else()
- set(MPI_${LANG}_INCLUDE_DIRS "${MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS}")
- if("${LANG}" MATCHES "(C|CXX)")
- if(MPI_${LANG}_HEADER_DIR)
- list(APPEND MPI_${LANG}_INCLUDE_DIRS "${MPI_${LANG}_HEADER_DIR}")
- endif()
- else() # Fortran
- if(MPI_${LANG}_F77_HEADER_DIR)
- list(APPEND MPI_${LANG}_INCLUDE_DIRS "${MPI_${LANG}_F77_HEADER_DIR}")
- endif()
- if(MPI_${LANG}_MODULE_DIR AND NOT "${MPI_${LANG}_MODULE_DIR}" IN_LIST MPI_${LANG}_INCLUDE_DIRS)
- list(APPEND MPI_${LANG}_INCLUDE_DIRS "${MPI_${LANG}_MODULE_DIR}")
- endif()
+ set(MPI_${LANG}_INCLUDE_DIRS
+ ${MPI_${LANG}_COMPILER_INCLUDE_DIRS}
+ ${MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS}
+ )
+ if("${LANG}" MATCHES "(C|CXX)")
+ if(MPI_${LANG}_HEADER_DIR)
+ list(APPEND MPI_${LANG}_INCLUDE_DIRS "${MPI_${LANG}_HEADER_DIR}")
endif()
- if(MPI_${LANG}_ADDITIONAL_INCLUDE_VARS)
- foreach(MPI_ADDITIONAL_INC_DIR IN LISTS MPI_${LANG}_ADDITIONAL_INCLUDE_VARS)
- list(APPEND MPI_${LANG}_INCLUDE_DIRS "${MPI_${MPI_ADDITIONAL_INC_DIR}_INCLUDE_DIR}")
- endforeach()
+ else() # Fortran
+ if(MPI_${LANG}_F77_HEADER_DIR)
+ list(APPEND MPI_${LANG}_INCLUDE_DIRS "${MPI_${LANG}_F77_HEADER_DIR}")
+ endif()
+ if(MPI_${LANG}_MODULE_DIR)
+ list(APPEND MPI_${LANG}_INCLUDE_DIRS "${MPI_${LANG}_MODULE_DIR}")
endif()
endif()
+ if(MPI_${LANG}_INCLUDE_DIRS)
+ list(REMOVE_DUPLICATES MPI_${LANG}_INCLUDE_DIRS)
+ endif()
endmacro()
-function(_MPI_split_include_dirs LANG)
- if("${MPI_${LANG}_COMPILER}" STREQUAL "${CMAKE_${LANG}_COMPILER}")
- return()
- endif()
+macro(_MPI_split_include_dirs LANG)
# Backwards compatibility: Search INCLUDE_PATH if given.
if(MPI_${LANG}_INCLUDE_PATH)
list(APPEND MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS "${MPI_${LANG}_INCLUDE_PATH}")
@@ -1109,23 +1103,30 @@ function(_MPI_split_include_dirs LANG)
# For C/C++, we just need to have a look for mpi.h.
if("${LANG}" MATCHES "(C|CXX)")
find_path(MPI_${LANG}_HEADER_DIR "mpi.h"
- HINTS ${MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS}
+ HINTS
+ ${MPI_${LANG}_COMPILER_INCLUDE_DIRS}
+ ${MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS}
)
mark_as_advanced(MPI_${LANG}_HEADER_DIR)
if(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS)
list(REMOVE_ITEM MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS "${MPI_${LANG}_HEADER_DIR}")
endif()
+
# Fortran is more complicated here: An implementation could provide
# any of the Fortran 77/90/2008 APIs for MPI. For example, MSMPI
# only provides Fortran 77 and - if mpi.f90 is built - potentially
# a Fortran 90 module.
elseif("${LANG}" STREQUAL "Fortran")
find_path(MPI_${LANG}_F77_HEADER_DIR "mpif.h"
- HINTS ${MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS}
+ HINTS
+ ${MPI_${LANG}_COMPILER_INCLUDE_DIRS}
+ ${MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS}
)
find_path(MPI_${LANG}_MODULE_DIR
NAMES "mpi.mod" "mpi_f08.mod"
- HINTS ${MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS}
+ HINTS
+ ${MPI_${LANG}_COMPILER_INCLUDE_DIRS}
+ ${MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS}
)
if(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS)
list(REMOVE_ITEM MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS
@@ -1135,6 +1136,7 @@ function(_MPI_split_include_dirs LANG)
endif()
mark_as_advanced(MPI_${LANG}_F77_HEADER_DIR MPI_${LANG}_MODULE_DIR)
endif()
+
# Remove duplicates and default system directories from the list.
if(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS)
list(REMOVE_DUPLICATES MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS)
@@ -1142,8 +1144,9 @@ function(_MPI_split_include_dirs LANG)
list(REMOVE_ITEM MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS ${MPI_IMPLICIT_INC_DIR})
endforeach()
endif()
+
set(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS ${MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS} CACHE STRING "MPI ${LANG} additional include directories" FORCE)
-endfunction()
+endmacro()
macro(_MPI_create_imported_target LANG)
if(NOT TARGET MPI::MPI_${LANG})
@@ -1403,13 +1406,14 @@ foreach(LANG IN ITEMS C CXX Fortran)
endif()
else()
set(_MPI_FIND_${LANG} FALSE)
+ string(APPEND _MPI_FAIL_REASON "MPI component '${LANG}' was requested, but language ${LANG} is not enabled. ")
endif()
if(_MPI_FIND_${LANG})
if( ${LANG} STREQUAL CXX AND NOT MPICXX IN_LIST MPI_FIND_COMPONENTS )
set(MPI_CXX_SKIP_MPICXX FALSE CACHE BOOL "If true, the MPI-2 C++ bindings are disabled using definitions.")
mark_as_advanced(MPI_CXX_SKIP_MPICXX)
endif()
- if(NOT (MPI_${LANG}_LIB_NAMES AND (MPI_${LANG}_INCLUDE_PATH OR MPI_${LANG}_INCLUDE_DIRS OR MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS)))
+ if(NOT (MPI_${LANG}_LIB_NAMES AND (MPI_${LANG}_INCLUDE_PATH OR MPI_${LANG}_INCLUDE_DIRS OR MPI_${LANG}_COMPILER_INCLUDE_DIRS)))
set(MPI_${LANG}_TRIED_IMPLICIT FALSE)
set(MPI_${LANG}_WORKS_IMPLICIT FALSE)
if(NOT MPI_${LANG}_COMPILER AND NOT MPI_ASSUME_NO_BUILTIN_MPI)
@@ -1494,7 +1498,7 @@ foreach(LANG IN ITEMS C CXX Fortran)
if("${LANG}" STREQUAL "CXX" AND MPI_C_WRAPPER_FOUND)
set(MPI_${LANG}_COMPILE_OPTIONS ${MPI_C_COMPILE_OPTIONS} CACHE STRING "MPI ${LANG} compilation options" )
set(MPI_${LANG}_COMPILE_DEFINITIONS ${MPI_C_COMPILE_DEFINITIONS} CACHE STRING "MPI ${LANG} compilation definitions" )
- set(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS ${MPI_C_INCLUDE_DIRS} CACHE STRING "MPI ${LANG} additional include directories")
+ set(MPI_${LANG}_COMPILER_INCLUDE_DIRS ${MPI_C_INCLUDE_DIRS} CACHE STRING "MPI ${LANG} compiler wrapper include directories")
set(MPI_${LANG}_LINK_FLAGS ${MPI_C_LINK_FLAGS} CACHE STRING "MPI ${LANG} linker flags" )
set(MPI_${LANG}_LIB_NAMES ${MPI_C_LIB_NAMES} CACHE STRING "MPI ${LANG} libraries to link against" )
else()
@@ -1505,8 +1509,12 @@ foreach(LANG IN ITEMS C CXX Fortran)
endif()
endif()
- _MPI_split_include_dirs(${LANG})
- _MPI_assemble_include_dirs(${LANG})
+ if(NOT "${MPI_${LANG}_COMPILER}" STREQUAL "${CMAKE_${LANG}_COMPILER}")
+ _MPI_split_include_dirs(${LANG})
+ _MPI_assemble_include_dirs(${LANG})
+ else()
+ set(MPI_${LANG}_INCLUDE_DIRS "")
+ endif()
_MPI_assemble_libraries(${LANG})
_MPI_adjust_compile_definitions(${LANG})
@@ -1520,13 +1528,21 @@ foreach(LANG IN ITEMS C CXX Fortran)
# Next, we'll initialize the MPI variables that have not been previously set.
set(MPI_${LANG}_COMPILE_OPTIONS "" CACHE STRING "MPI ${LANG} compilation flags" )
set(MPI_${LANG}_COMPILE_DEFINITIONS "" CACHE STRING "MPI ${LANG} compilation definitions" )
+ set(MPI_${LANG}_COMPILER_INCLUDE_DIRS "" CACHE STRING "MPI ${LANG} compiler wrapper include directories")
set(MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS "" CACHE STRING "MPI ${LANG} additional include directories")
set(MPI_${LANG}_LINK_FLAGS "" CACHE STRING "MPI ${LANG} linker flags" )
if(NOT MPI_${LANG}_COMPILER STREQUAL CMAKE_${LANG}_COMPILER)
set(MPI_${LANG}_LIB_NAMES "" CACHE STRING "MPI ${LANG} libraries to link against" )
endif()
- mark_as_advanced(MPI_${LANG}_COMPILE_OPTIONS MPI_${LANG}_COMPILE_DEFINITIONS MPI_${LANG}_LINK_FLAGS
- MPI_${LANG}_LIB_NAMES MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS MPI_${LANG}_COMPILER)
+ mark_as_advanced(
+ MPI_${LANG}_COMPILE_OPTIONS
+ MPI_${LANG}_COMPILE_DEFINITIONS
+ MPI_${LANG}_LINK_FLAGS
+ MPI_${LANG}_LIB_NAMES
+ MPI_${LANG}_COMPILER_INCLUDE_DIRS
+ MPI_${LANG}_ADDITIONAL_INCLUDE_DIRS
+ MPI_${LANG}_COMPILER
+ )
# If we've found MPI, then we'll perform additional analysis: Determine the MPI version, MPI library version, supported
# MPI APIs (i.e. MPI-2 C++ bindings). For Fortran we also need to find specific parameters if we're under MPI-3.
@@ -1675,7 +1691,8 @@ foreach(LANG IN ITEMS C CXX Fortran)
list(APPEND MPI_${LANG}_REQUIRED_VARS "MPI_${LANG}_WORKS")
endif()
endif()
- find_package_handle_standard_args(MPI_${LANG} REQUIRED_VARS ${MPI_${LANG}_REQUIRED_VARS}
+ find_package_handle_standard_args(MPI_${LANG} NAME_MISMATCHED
+ REQUIRED_VARS ${MPI_${LANG}_REQUIRED_VARS}
VERSION_VAR MPI_${LANG}_VERSION)
if(DEFINED MPI_${LANG}_VERSION)
@@ -1700,6 +1717,7 @@ endif()
find_package_handle_standard_args(MPI
REQUIRED_VARS ${_MPI_REQ_VARS}
VERSION_VAR ${_MPI_MIN_VERSION}
+ REASON_FAILURE_MESSAGE "${_MPI_FAIL_REASON}"
HANDLE_COMPONENTS)
#=============================================================================
diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake
index 92ee729..e42c206 100644
--- a/Modules/FindMatlab.cmake
+++ b/Modules/FindMatlab.cmake
@@ -241,6 +241,7 @@ if(NOT MATLAB_ADDITIONAL_VERSIONS)
endif()
set(MATLAB_VERSIONS_MAPPING
+ "R2020a=9.8"
"R2019b=9.7"
"R2019a=9.6"
"R2018b=9.5"
diff --git a/Modules/FindOpenACC.cmake b/Modules/FindOpenACC.cmake
index 743e0e2..398dcf5 100644
--- a/Modules/FindOpenACC.cmake
+++ b/Modules/FindOpenACC.cmake
@@ -254,6 +254,7 @@ foreach (LANG IN ITEMS C CXX Fortran)
_OPENACC_SET_VERSION_BY_SPEC_DATE("${LANG}")
find_package_handle_standard_args(OpenACC_${LANG}
+ NAME_MISMATCHED
REQUIRED_VARS OpenACC_${LANG}_FLAGS
VERSION_VAR OpenACC_${LANG}_VERSION
)
diff --git a/Modules/FindOpenAL.cmake b/Modules/FindOpenAL.cmake
index 27dcaf5..b5b92c5 100644
--- a/Modules/FindOpenAL.cmake
+++ b/Modules/FindOpenAL.cmake
@@ -5,27 +5,45 @@
FindOpenAL
----------
-
Finds Open Audio Library (OpenAL).
-This module defines ``OPENAL_LIBRARY OPENAL_FOUND``, if
-false, do not try to link to OpenAL ``OPENAL_INCLUDE_DIR``, where to find
-the headers.
-``$OPENALDIR`` is an environment variable that would correspond to the
-``./configure --prefix=$OPENALDIR`` used in building OpenAL.
+Projects using this module should use ``#include "al.h"`` to include the OpenAL
+header file, **not** ``#include <AL/al.h>``. The reason for this is that the
+latter is not entirely portable. Windows/Creative Labs does not by default put
+their headers in ``AL/`` and macOS uses the convention ``<OpenAL/al.h>``.
+
+Hints
+^^^^^
+
+Environment variable ``$OPENALDIR`` can be used to set the prefix of OpenAL
+installation to be found.
+
+By default on macOS, system framework is search first. In other words,
+OpenAL is searched in the following order:
+
+1. System framework: ``/System/Library/Frameworks``, whose priority can be
+ changed via setting the :variable:`CMAKE_FIND_FRAMEWORK` variable.
+2. Environment variable ``$OPENALDIR``.
+3. System paths.
+4. User-compiled framework: ``~/Library/Frameworks``.
+5. Manually compiled framework: ``/Library/Frameworks``.
+6. Add-on package: ``/opt``.
+
+Result Variables
+^^^^^^^^^^^^^^^^
-Created by Eric Wing. This was influenced by the ``FindSDL.cmake``
-module.
+This module defines the following variables:
+
+``OPENAL_FOUND``
+ If false, do not try to link to OpenAL
+``OPENAL_INCLUDE_DIR``
+ OpenAL include directory
+``OPENAL_LIBRARY``
+ Path to the OpenAL library
+``OPENAL_VERSION_STRING``
+ Human-readable string containing the version of OpenAL
#]=======================================================================]
-# This makes the presumption that you are include al.h like
-# #include "al.h"
-# and not
-# #include <AL/al.h>
-# The reason for this is that the latter is not entirely portable.
-# Windows/Creative Labs does not by default put their headers in AL/ and
-# OS X uses the convention <OpenAL/al.h>.
-#
# For Windows, Creative Labs seems to have added a registry key for their
# OpenAL 1.1 installer. I have added that key to the list of search paths,
# however, the key looks like it could be a little fragile depending on
@@ -36,36 +54,17 @@ module.
# platforms are introduced.
# The OpenAL 1.0 installer doesn't seem to have a useful key I can use.
# I do not know if the Nvidia OpenAL SDK has a registry key.
-#
-# For OS X, remember that OpenAL was added by Apple in 10.4 (Tiger).
-# To support the framework, I originally wrote special framework detection
-# code in this module which I have now removed with CMake's introduction
-# of native support for frameworks.
-# In addition, OpenAL is open source, and it is possible to compile on Panther.
-# Furthermore, due to bugs in the initial OpenAL release, and the
-# transition to OpenAL 1.1, it is common to need to override the built-in
-# framework.
-# Per my request, CMake should search for frameworks first in
-# the following order:
-# ~/Library/Frameworks/OpenAL.framework/Headers
-# /Library/Frameworks/OpenAL.framework/Headers
-# /System/Library/Frameworks/OpenAL.framework/Headers
-#
-# On OS X, this will prefer the Framework version (if found) over others.
-# People will have to manually change the cache values of
-# OPENAL_LIBRARY to override this selection or set the CMake environment
-# CMAKE_INCLUDE_PATH to modify the search paths.
find_path(OPENAL_INCLUDE_DIR al.h
HINTS
ENV OPENALDIR
- PATH_SUFFIXES include/AL include/OpenAL include AL OpenAL
PATHS
- ~/Library/Frameworks
- /Library/Frameworks
- /opt
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Creative\ Labs\\OpenAL\ 1.1\ Software\ Development\ Kit\\1.00.0000;InstallDir]
-)
+ ~/Library/Frameworks
+ /Library/Frameworks
+ /opt
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\Creative\ Labs\\OpenAL\ 1.1\ Software\ Development\ Kit\\1.00.0000;InstallDir]
+ PATH_SUFFIXES include/AL include/OpenAL include AL OpenAL
+ )
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(_OpenAL_ARCH_DIR libs/Win64)
@@ -77,17 +76,21 @@ find_library(OPENAL_LIBRARY
NAMES OpenAL al openal OpenAL32
HINTS
ENV OPENALDIR
- PATH_SUFFIXES libx32 lib64 lib libs64 libs ${_OpenAL_ARCH_DIR}
PATHS
- ~/Library/Frameworks
- /Library/Frameworks
- /opt
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Creative\ Labs\\OpenAL\ 1.1\ Software\ Development\ Kit\\1.00.0000;InstallDir]
-)
+ ~/Library/Frameworks
+ /Library/Frameworks
+ /opt
+ [HKEY_LOCAL_MACHINE\\SOFTWARE\\Creative\ Labs\\OpenAL\ 1.1\ Software\ Development\ Kit\\1.00.0000;InstallDir]
+ PATH_SUFFIXES libx32 lib64 lib libs64 libs ${_OpenAL_ARCH_DIR}
+ )
unset(_OpenAL_ARCH_DIR)
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenAL DEFAULT_MSG OPENAL_LIBRARY OPENAL_INCLUDE_DIR)
+find_package_handle_standard_args(
+ OpenAL
+ REQUIRED_VARS OPENAL_LIBRARY OPENAL_INCLUDE_DIR
+ VERSION_VAR OPENAL_VERSION_STRING
+ )
mark_as_advanced(OPENAL_LIBRARY OPENAL_INCLUDE_DIR)
diff --git a/Modules/FindOpenCL.cmake b/Modules/FindOpenCL.cmake
index 9891724..34a203e 100644
--- a/Modules/FindOpenCL.cmake
+++ b/Modules/FindOpenCL.cmake
@@ -78,6 +78,8 @@ find_path(OpenCL_INCLUDE_DIR
ENV CUDA_PATH
ENV ATISTREAMSDKROOT
ENV OCL_ROOT
+ /usr/local/cuda
+ /opt/cuda
PATH_SUFFIXES
include
OpenCL/common/inc
@@ -126,6 +128,8 @@ else()
PATHS
ENV AMDAPPSDKROOT
ENV CUDA_PATH
+ /usr/local/cuda
+ /opt/cuda
PATH_SUFFIXES
lib/x86
lib)
@@ -135,6 +139,8 @@ else()
PATHS
ENV AMDAPPSDKROOT
ENV CUDA_PATH
+ /usr/local/cuda
+ /opt/cuda
PATH_SUFFIXES
lib/x86_64
lib/x64
diff --git a/Modules/FindOpenGL.cmake b/Modules/FindOpenGL.cmake
index 23bb001d..74392da 100644
--- a/Modules/FindOpenGL.cmake
+++ b/Modules/FindOpenGL.cmake
@@ -130,6 +130,8 @@ foreach(component ${OpenGL_FIND_COMPONENTS})
set(OPENGL_USE_${_COMPONENT} 1)
endforeach()
+set(_OpenGL_CACHE_VARS)
+
if (CYGWIN)
find_path(OPENGL_INCLUDE_DIR GL/gl.h )
list(APPEND _OpenGL_REQUIRED_VARS OPENGL_INCLUDE_DIR)
@@ -137,6 +139,11 @@ if (CYGWIN)
find_library(OPENGL_gl_LIBRARY opengl32 )
find_library(OPENGL_glu_LIBRARY glu32 )
+ list(APPEND _OpenGL_CACHE_VARS
+ OPENGL_INCLUDE_DIR
+ OPENGL_gl_LIBRARY
+ OPENGL_glu_LIBRARY
+ )
elseif (WIN32)
if(BORLAND)
@@ -147,6 +154,10 @@ elseif (WIN32)
set (OPENGL_glu_LIBRARY glu32 CACHE STRING "GLU library for win32")
endif()
+ list(APPEND _OpenGL_CACHE_VARS
+ OPENGL_gl_LIBRARY
+ OPENGL_glu_LIBRARY
+ )
elseif (APPLE)
# The OpenGL.framework provides both gl and glu
find_library(OPENGL_gl_LIBRARY OpenGL DOC "OpenGL library for OS X")
@@ -155,6 +166,11 @@ elseif (APPLE)
find_path(OPENGL_INCLUDE_DIR OpenGL/gl.h DOC "Include for OpenGL on OS X")
list(APPEND _OpenGL_REQUIRED_VARS OPENGL_INCLUDE_DIR)
+ list(APPEND _OpenGL_CACHE_VARS
+ OPENGL_INCLUDE_DIR
+ OPENGL_gl_LIBRARY
+ OPENGL_glu_LIBRARY
+ )
else()
if (CMAKE_SYSTEM_NAME MATCHES "HP-UX")
# Handle HP-UX cases where we only want to find OpenGL in either hpux64
@@ -194,6 +210,12 @@ else()
/usr/openwin/share/include
/opt/graphics/OpenGL/include
)
+ list(APPEND _OpenGL_CACHE_VARS
+ OPENGL_INCLUDE_DIR
+ OPENGL_GLX_INCLUDE_DIR
+ OPENGL_EGL_INCLUDE_DIR
+ OPENGL_xmesa_INCLUDE_DIR
+ )
# Search for the GLVND libraries. We do this regardless of COMPONENTS; we'll
# take into account the COMPONENTS logic later.
@@ -222,6 +244,13 @@ else()
/usr/shlib
)
+ list(APPEND _OpenGL_CACHE_VARS
+ OPENGL_opengl_LIBRARY
+ OPENGL_glx_LIBRARY
+ OPENGL_egl_LIBRARY
+ OPENGL_glu_LIBRARY
+ )
+
set(_OpenGL_GL_POLICY_WARN 0)
if(NOT DEFINED OpenGL_GL_PREFERENCE)
set(OpenGL_GL_PREFERENCE "")
@@ -268,6 +297,7 @@ else()
${_OPENGL_LIB_PATH}
PATH_SUFFIXES libglvnd
)
+ list(APPEND _OpenGL_CACHE_VARS OPENGL_gl_LIBRARY)
endif()
if(_OpenGL_GL_POLICY_WARN AND OPENGL_gl_LIBRARY AND OPENGL_opengl_LIBRARY AND OPENGL_glx_LIBRARY)
@@ -532,14 +562,5 @@ set(OPENGL_LIBRARY ${OPENGL_LIBRARIES})
# This deprecated setting is for backward compatibility with CMake1.4
set(OPENGL_INCLUDE_PATH ${OPENGL_INCLUDE_DIR})
-mark_as_advanced(
- OPENGL_INCLUDE_DIR
- OPENGL_xmesa_INCLUDE_DIR
- OPENGL_egl_LIBRARY
- OPENGL_glu_LIBRARY
- OPENGL_glx_LIBRARY
- OPENGL_gl_LIBRARY
- OPENGL_opengl_LIBRARY
- OPENGL_EGL_INCLUDE_DIR
- OPENGL_GLX_INCLUDE_DIR
-)
+mark_as_advanced(${_OpenGL_CACHE_VARS})
+unset(_OpenGL_CACHE_VARS)
diff --git a/Modules/FindOpenMP.cmake b/Modules/FindOpenMP.cmake
index 90d1c3e..a4b1e1e 100644
--- a/Modules/FindOpenMP.cmake
+++ b/Modules/FindOpenMP.cmake
@@ -96,7 +96,7 @@ function(_OPENMP_FLAG_CANDIDATES LANG)
unset(OpenMP_FLAG_CANDIDATES)
set(OMP_FLAG_GNU "-fopenmp")
- set(OMP_FLAG_Clang "-fopenmp=libomp" "-fopenmp=libiomp5" "-fopenmp")
+ set(OMP_FLAG_Clang "-fopenmp=libomp" "-fopenmp=libiomp5" "-fopenmp" "-Xclang -fopenmp")
set(OMP_FLAG_AppleClang "-Xclang -fopenmp")
set(OMP_FLAG_HP "+Oopenmp")
if(WIN32)
@@ -299,6 +299,25 @@ function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR)
break()
endif()
endif()
+ elseif(CMAKE_${LANG}_COMPILER_ID STREQUAL "Clang" AND WIN32)
+ # Check for separate OpenMP library for Clang on Windows
+ find_library(OpenMP_libomp_LIBRARY
+ NAMES libomp libgomp libiomp5
+ HINTS ${CMAKE_${LANG}_IMPLICIT_LINK_DIRECTORIES}
+ )
+ mark_as_advanced(OpenMP_libomp_LIBRARY)
+ if(OpenMP_libomp_LIBRARY)
+ try_compile( OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG} ${CMAKE_BINARY_DIR} ${_OPENMP_TEST_SRC}
+ CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPENMP_FLAGS_TEST}"
+ LINK_LIBRARIES ${CMAKE_${LANG}_VERBOSE_FLAG} ${OpenMP_libomp_LIBRARY}
+ OUTPUT_VARIABLE OpenMP_TRY_COMPILE_OUTPUT
+ )
+ if(OpenMP_COMPILE_RESULT_${FLAG_MODE}_${OPENMP_PLAIN_FLAG})
+ set("${OPENMP_FLAG_VAR}" "${OPENMP_FLAG}" PARENT_SCOPE)
+ set("${OPENMP_LIB_NAMES_VAR}" "libomp" PARENT_SCOPE)
+ break()
+ endif()
+ endif()
else()
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Detecting ${LANG} OpenMP failed with the following output:\n${OpenMP_TRY_COMPILE_OUTPUT}\n\n")
@@ -425,13 +444,12 @@ 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)
+ mark_as_advanced(OpenMP_${LANG}_FLAGS OpenMP_${LANG}_LIB_NAMES)
endif()
-
- set(OpenMP_${LANG}_FLAGS "${OpenMP_${LANG}_FLAGS_WORK}"
- CACHE STRING "${LANG} compiler flags for OpenMP parallelization")
- set(OpenMP_${LANG}_LIB_NAMES "${OpenMP_${LANG}_LIB_NAMES_WORK}"
- CACHE STRING "${LANG} compiler libraries for OpenMP parallelization")
- mark_as_advanced(OpenMP_${LANG}_FLAGS OpenMP_${LANG}_LIB_NAMES)
endif()
endforeach()
@@ -509,6 +527,7 @@ foreach(LANG IN LISTS OpenMP_FINDLIST)
endif()
find_package_handle_standard_args(OpenMP_${LANG}
+ NAME_MISMATCHED
REQUIRED_VARS OpenMP_${LANG}_FLAGS ${_OPENMP_${LANG}_REQUIRED_LIB_VARS}
VERSION_VAR OpenMP_${LANG}_VERSION
)
diff --git a/Modules/FindOpenSSL.cmake b/Modules/FindOpenSSL.cmake
index 478a592..af713d6 100644
--- a/Modules/FindOpenSSL.cmake
+++ b/Modules/FindOpenSSL.cmake
@@ -131,6 +131,7 @@ find_path(OPENSSL_INCLUDE_DIR
${_OPENSSL_ROOT_HINTS_AND_PATHS}
HINTS
${_OPENSSL_INCLUDEDIR}
+ ${_OPENSSL_INCLUDE_DIRS}
PATH_SUFFIXES
include
)
@@ -319,6 +320,7 @@ else()
${_OPENSSL_ROOT_HINTS_AND_PATHS}
HINTS
${_OPENSSL_LIBDIR}
+ ${_OPENSSL_LIBRARY_DIRS}
PATH_SUFFIXES
lib
)
@@ -330,6 +332,7 @@ else()
${_OPENSSL_ROOT_HINTS_AND_PATHS}
HINTS
${_OPENSSL_LIBDIR}
+ ${_OPENSSL_LIBRARY_DIRS}
PATH_SUFFIXES
lib
)
@@ -455,7 +458,7 @@ find_package_handle_standard_args(OpenSSL
"Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR"
)
-mark_as_advanced(OPENSSL_INCLUDE_DIR OPENSSL_LIBRARIES)
+mark_as_advanced(OPENSSL_INCLUDE_DIR)
if(OPENSSL_FOUND)
if(NOT TARGET OpenSSL::Crypto AND
diff --git a/Modules/FindPNG.cmake b/Modules/FindPNG.cmake
index bd400c7..f1fe89a 100644
--- a/Modules/FindPNG.cmake
+++ b/Modules/FindPNG.cmake
@@ -94,6 +94,10 @@ if(ZLIB_FOUND)
set(PNG_INCLUDE_DIRS ${PNG_PNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} )
set(PNG_INCLUDE_DIR ${PNG_INCLUDE_DIRS} ) # for backward compatibility
set(PNG_LIBRARIES ${PNG_LIBRARY} ${ZLIB_LIBRARY})
+ if((CMAKE_SYSTEM_NAME STREQUAL "Linux") AND
+ ("${PNG_LIBRARY}" MATCHES "\\${CMAKE_STATIC_LIBRARY_SUFFIX}$"))
+ list(APPEND PNG_LIBRARIES m)
+ endif()
if (CYGWIN)
if(BUILD_SHARED_LIBS)
@@ -110,6 +114,12 @@ if(ZLIB_FOUND)
INTERFACE_COMPILE_DEFINITIONS "${_PNG_COMPILE_DEFINITIONS}"
INTERFACE_INCLUDE_DIRECTORIES "${PNG_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES ZLIB::ZLIB)
+ if((CMAKE_SYSTEM_NAME STREQUAL "Linux") AND
+ ("${PNG_LIBRARY}" MATCHES "\\${CMAKE_STATIC_LIBRARY_SUFFIX}$"))
+ set_property(TARGET PNG::PNG APPEND PROPERTY
+ INTERFACE_LINK_LIBRARIES m)
+ endif()
+
if(EXISTS "${PNG_LIBRARY}")
set_target_properties(PNG::PNG PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
diff --git a/Modules/FindPackageHandleStandardArgs.cmake b/Modules/FindPackageHandleStandardArgs.cmake
index d824ee8..4fb0825 100644
--- a/Modules/FindPackageHandleStandardArgs.cmake
+++ b/Modules/FindPackageHandleStandardArgs.cmake
@@ -27,6 +27,7 @@ valid filepaths.
[VERSION_VAR <version-var>]
[HANDLE_COMPONENTS]
[CONFIG_MODE]
+ [NAME_MISMATCHED]
[REASON_FAILURE_MESSAGE <reason-failure-message>]
[FAIL_MESSAGE <custom-failure-message>]
)
@@ -56,7 +57,8 @@ valid filepaths.
These may be named in the generated failure message asking the
user to set the missing variable values. Therefore these should
typically be cache entries such as ``FOO_LIBRARY`` and not output
- variables like ``FOO_LIBRARIES``.
+ variables like ``FOO_LIBRARIES``. This option is mandatory if
+ ``HANDLE_COMPONENTS`` is not specified.
``VERSION_VAR <version-var>``
Specify the name of a variable that holds the version of the package
@@ -90,6 +92,12 @@ valid filepaths.
Specify a custom failure message instead of using the default
generated message. Not recommended.
+ ``NAME_MISMATCHED``
+ Indicate that the ``<PackageName>`` does not match
+ ``${CMAKE_FIND_PACKAGE_NAME}``. This is usually a mistake and raises a
+ warning, but it may be intentional for usage of the command for components
+ of a larger package.
+
Example for the simple signature:
.. code-block:: cmake
@@ -106,6 +114,17 @@ used or not. If it is found, success will be reported, including
the content of the first ``<required-var>``. On repeated CMake runs,
the same message will not be printed again.
+.. note::
+
+ If ``<PackageName>`` does not match ``CMAKE_FIND_PACKAGE_NAME`` for the
+ calling module, a warning that there is a mismatch is given. The
+ ``FPHSA_NAME_MISMATCHED`` variable may be set to bypass the warning if using
+ the old signature and the ``NAME_MISMATCHED`` argument using the new
+ signature. To avoid forcing the caller to require newer versions of CMake for
+ usage, the variable's value will be used if defined when the
+ ``NAME_MISMATCHED`` argument is not passed for the new signature (but using
+ both is an error)..
+
Example for the full signature:
.. code-block:: cmake
@@ -190,15 +209,32 @@ endmacro()
function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
-# Set up the arguments for `cmake_parse_arguments`.
- set(options CONFIG_MODE HANDLE_COMPONENTS)
+ # Set up the arguments for `cmake_parse_arguments`.
+ set(options CONFIG_MODE HANDLE_COMPONENTS NAME_MISMATCHED)
set(oneValueArgs FAIL_MESSAGE REASON_FAILURE_MESSAGE VERSION_VAR FOUND_VAR)
set(multiValueArgs REQUIRED_VARS)
-# Check whether we are in 'simple' or 'extended' mode:
+ # Check whether we are in 'simple' or 'extended' mode:
set(_KEYWORDS_FOR_EXTENDED_MODE ${options} ${oneValueArgs} ${multiValueArgs} )
list(FIND _KEYWORDS_FOR_EXTENDED_MODE "${_FIRST_ARG}" INDEX)
+ unset(FPHSA_NAME_MISMATCHED_override)
+ if (DEFINED FPHSA_NAME_MISMATCHED)
+ # If the variable NAME_MISMATCHED variable is set, error if it is passed as
+ # an argument. The former is for old signatures, the latter is for new
+ # signatures.
+ list(FIND ARGN "NAME_MISMATCHED" name_mismatched_idx)
+ if (NOT name_mismatched_idx EQUAL "-1")
+ message(FATAL_ERROR
+ "The `NAME_MISMATCHED` argument may only be specified by the argument or "
+ "the variable, not both.")
+ endif ()
+
+ # But use the variable if it is not an argument to avoid forcing minimum
+ # CMake version bumps for calling modules.
+ set(FPHSA_NAME_MISMATCHED_override "${FPHSA_NAME_MISMATCHED}")
+ endif ()
+
if(${INDEX} EQUAL -1)
set(FPHSA_FAIL_MESSAGE ${_FIRST_ARG})
set(FPHSA_REQUIRED_VARS ${ARGN})
@@ -222,27 +258,46 @@ function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
set(FPHSA_VERSION_VAR ${_NAME}_VERSION)
endif()
- if(NOT FPHSA_REQUIRED_VARS)
+ if(NOT FPHSA_REQUIRED_VARS AND NOT FPHSA_HANDLE_COMPONENTS)
message(FATAL_ERROR "No REQUIRED_VARS specified for FIND_PACKAGE_HANDLE_STANDARD_ARGS()")
endif()
endif()
+ if (DEFINED FPHSA_NAME_MISMATCHED_override)
+ set(FPHSA_NAME_MISMATCHED "${FPHSA_NAME_MISMATCHED_override}")
+ endif ()
+
+ if (DEFINED CMAKE_FIND_PACKAGE_NAME
+ AND NOT FPHSA_NAME_MISMATCHED
+ AND NOT _NAME STREQUAL CMAKE_FIND_PACKAGE_NAME)
+ message(AUTHOR_WARNING
+ "The package name passed to `find_package_handle_standard_args` "
+ "(${_NAME}) does not match the name of the calling package "
+ "(${CMAKE_FIND_PACKAGE_NAME}). This can lead to problems in calling "
+ "code that expects `find_package` result variables (e.g., `_FOUND`) "
+ "to follow a certain pattern.")
+ endif ()
+
# now that we collected all arguments, process them
if("x${FPHSA_FAIL_MESSAGE}" STREQUAL "xDEFAULT_MSG")
set(FPHSA_FAIL_MESSAGE "Could NOT find ${_NAME}")
endif()
- list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR)
+ if (FPHSA_REQUIRED_VARS)
+ list(GET FPHSA_REQUIRED_VARS 0 _FIRST_REQUIRED_VAR)
+ endif()
string(TOUPPER ${_NAME} _NAME_UPPER)
string(TOLOWER ${_NAME} _NAME_LOWER)
if(FPHSA_FOUND_VAR)
- if(FPHSA_FOUND_VAR MATCHES "^${_NAME}_FOUND$" OR FPHSA_FOUND_VAR MATCHES "^${_NAME_UPPER}_FOUND$")
+ set(_FOUND_VAR_UPPER ${_NAME_UPPER}_FOUND)
+ set(_FOUND_VAR_MIXED ${_NAME}_FOUND)
+ if(FPHSA_FOUND_VAR STREQUAL _FOUND_VAR_MIXED OR FPHSA_FOUND_VAR STREQUAL _FOUND_VAR_UPPER)
set(_FOUND_VAR ${FPHSA_FOUND_VAR})
else()
- message(FATAL_ERROR "The argument for FOUND_VAR is \"${FPHSA_FOUND_VAR}\", but only \"${_NAME}_FOUND\" and \"${_NAME_UPPER}_FOUND\" are valid names.")
+ message(FATAL_ERROR "The argument for FOUND_VAR is \"${FPHSA_FOUND_VAR}\", but only \"${_FOUND_VAR_MIXED}\" and \"${_FOUND_VAR_UPPER}\" are valid names.")
endif()
else()
set(_FOUND_VAR ${_NAME_UPPER}_FOUND)
@@ -388,7 +443,17 @@ function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG)
_FPHSA_HANDLE_FAILURE_CONFIG_MODE()
else()
if(NOT VERSION_OK)
- _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (found ${${_FIRST_REQUIRED_VAR}})")
+ set(RESULT_MSG)
+ if (_FIRST_REQUIRED_VAR)
+ string (APPEND RESULT_MSG "found ${${_FIRST_REQUIRED_VAR}}")
+ endif()
+ if (COMPONENT_MSG)
+ if (RESULT_MSG)
+ string (APPEND RESULT_MSG ", ")
+ endif()
+ string (APPEND RESULT_MSG "${FOUND_COMPONENTS_MSG}")
+ endif()
+ _FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE}: ${VERSION_MSG} (${RESULT_MSG})")
else()
_FPHSA_FAILURE_MESSAGE("${FPHSA_FAIL_MESSAGE} (missing:${MISSING_VARS}) ${VERSION_MSG}")
endif()
diff --git a/Modules/FindPkgConfig.cmake b/Modules/FindPkgConfig.cmake
index 2121f66..93827d8 100644
--- a/Modules/FindPkgConfig.cmake
+++ b/Modules/FindPkgConfig.cmake
@@ -34,16 +34,31 @@ endif()
find_program(PKG_CONFIG_EXECUTABLE NAMES pkg-config DOC "pkg-config executable")
mark_as_advanced(PKG_CONFIG_EXECUTABLE)
+set(_PKG_CONFIG_FAILURE_MESSAGE "")
if (PKG_CONFIG_EXECUTABLE)
execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --version
- OUTPUT_VARIABLE PKG_CONFIG_VERSION_STRING
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
+ OUTPUT_VARIABLE PKG_CONFIG_VERSION_STRING OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_VARIABLE _PKG_CONFIG_VERSION_ERROR ERROR_STRIP_TRAILING_WHITESPACE
+ RESULT_VARIABLE _PKG_CONFIG_VERSION_RESULT
+ )
+
+ if (NOT _PKG_CONFIG_VERSION_RESULT EQUAL 0)
+ string(REPLACE "\n" "\n " _PKG_CONFIG_VERSION_ERROR " ${_PKG_CONFIG_VERSION_ERROR}")
+ string(APPEND _PKG_CONFIG_FAILURE_MESSAGE
+ "The command\n"
+ " \"${PKG_CONFIG_EXECUTABLE}\" --version\n"
+ " failed with output\n${_PKG_CONFIG_VERSION_ERROR}"
+ )
+ set(PKG_CONFIG_EXECUTABLE "")
+ unset(PKG_CONFIG_VERSION_STRING)
+ endif ()
+ unset(_PKG_CONFIG_VERSION_RESULT)
endif ()
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
find_package_handle_standard_args(PkgConfig
REQUIRED_VARS PKG_CONFIG_EXECUTABLE
+ REASON_FAILURE_MESSAGE "${_PKG_CONFIG_FAILURE_MESSAGE}"
VERSION_VAR PKG_CONFIG_VERSION_STRING)
# This is needed because the module name is "PkgConfig" but the name of
@@ -197,7 +212,13 @@ function(_pkg_find_libs _prefix _no_cmake_path _no_cmake_environment_path)
endif()
unset(_search_paths)
+ unset(_next_is_framework)
foreach (flag IN LISTS ${_prefix}_LDFLAGS)
+ if (_next_is_framework)
+ list(APPEND _libs "-framework ${flag}")
+ unset(_next_is_framework)
+ continue()
+ endif ()
if (flag MATCHES "^-L(.*)")
list(APPEND _search_paths ${CMAKE_MATCH_1})
continue()
@@ -205,6 +226,9 @@ function(_pkg_find_libs _prefix _no_cmake_path _no_cmake_environment_path)
if (flag MATCHES "^-l(.*)")
set(_pkg_search "${CMAKE_MATCH_1}")
else()
+ if (flag STREQUAL "-framework")
+ set(_next_is_framework TRUE)
+ endif ()
continue()
endif()
@@ -341,7 +365,7 @@ macro(_pkg_set_path_internal)
# remove empty values from the list
list(REMOVE_ITEM _pkgconfig_path "")
file(TO_NATIVE_PATH "${_pkgconfig_path}" _pkgconfig_path)
- if(UNIX)
+ if(CMAKE_HOST_UNIX)
string(REPLACE ";" ":" _pkgconfig_path "${_pkgconfig_path}")
string(REPLACE "\\ " " " _pkgconfig_path "${_pkgconfig_path}")
endif()
@@ -364,6 +388,30 @@ macro(_pkg_restore_path_internal)
unset(_pkgconfig_path_old)
endmacro()
+# pkg-config returns frameworks in --libs-only-other
+# they need to be in ${_prefix}_LIBRARIES so "-framework a -framework b" does
+# not incorrectly be combined to "-framework a b"
+function(_pkgconfig_extract_frameworks _prefix)
+ set(ldflags "${${_prefix}_LDFLAGS_OTHER}")
+ list(FIND ldflags "-framework" FR_POS)
+ list(LENGTH ldflags LD_LENGTH)
+
+ # reduce length by 1 as we need "-framework" and the next entry
+ math(EXPR LD_LENGTH "${LD_LENGTH} - 1")
+ while (FR_POS GREATER -1 AND LD_LENGTH GREATER FR_POS)
+ list(REMOVE_AT ldflags ${FR_POS})
+ list(GET ldflags ${FR_POS} HEAD)
+ list(REMOVE_AT ldflags ${FR_POS})
+ math(EXPR LD_LENGTH "${LD_LENGTH} - 2")
+
+ list(APPEND LIBS "-framework ${HEAD}")
+
+ list(FIND ldflags "-framework" FR_POS)
+ endwhile ()
+ set(${_prefix}_LIBRARIES ${${_prefix}_LIBRARIES} ${LIBS} PARENT_SCOPE)
+ set(${_prefix}_LDFLAGS_OTHER "${ldflags}" PARENT_SCOPE)
+endfunction()
+
# pkg-config returns -isystem include directories in --cflags-only-other,
# depending on the version and if there is a space between -isystem and
# the actual path
@@ -532,6 +580,10 @@ macro(_pkg_check_modules_internal _is_required _is_silent _no_cmake_path _no_cma
_pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" LDFLAGS "" --libs )
_pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" LDFLAGS_OTHER "" --libs-only-other )
+ if (APPLE AND "-framework" IN_LIST ${_prefix}_LDFLAGS_OTHER)
+ _pkgconfig_extract_frameworks("${_prefix}")
+ endif()
+
_pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" INCLUDE_DIRS "(^| )(-I|-isystem ?)" --cflags-only-I )
_pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" CFLAGS "" --cflags )
_pkgconfig_invoke_dyn("${_pkg_check_modules_packages}" "${_prefix}" CFLAGS_OTHER "" --cflags-only-other )
diff --git a/Modules/FindProtobuf.cmake b/Modules/FindProtobuf.cmake
index 2d45965..f35978d 100644
--- a/Modules/FindProtobuf.cmake
+++ b/Modules/FindProtobuf.cmake
@@ -482,22 +482,24 @@ if(Protobuf_INCLUDE_DIR)
"${_PROTOBUF_COMMON_HEADER} reveals protobuf ${Protobuf_VERSION}")
endif()
- # Check Protobuf compiler version to be aligned with libraries version
- execute_process(COMMAND ${Protobuf_PROTOC_EXECUTABLE} --version
- OUTPUT_VARIABLE _PROTOBUF_PROTOC_EXECUTABLE_VERSION)
+ if(Protobuf_PROTOC_EXECUTABLE)
+ # Check Protobuf compiler version to be aligned with libraries version
+ execute_process(COMMAND ${Protobuf_PROTOC_EXECUTABLE} --version
+ OUTPUT_VARIABLE _PROTOBUF_PROTOC_EXECUTABLE_VERSION)
- if("${_PROTOBUF_PROTOC_EXECUTABLE_VERSION}" MATCHES "libprotoc ([0-9.]+)")
- set(_PROTOBUF_PROTOC_EXECUTABLE_VERSION "${CMAKE_MATCH_1}")
- endif()
+ if("${_PROTOBUF_PROTOC_EXECUTABLE_VERSION}" MATCHES "libprotoc ([0-9.]+)")
+ set(_PROTOBUF_PROTOC_EXECUTABLE_VERSION "${CMAKE_MATCH_1}")
+ endif()
- if(Protobuf_DEBUG)
- message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
- "${Protobuf_PROTOC_EXECUTABLE} reveals version ${_PROTOBUF_PROTOC_EXECUTABLE_VERSION}")
- endif()
+ if(Protobuf_DEBUG)
+ message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] "
+ "${Protobuf_PROTOC_EXECUTABLE} reveals version ${_PROTOBUF_PROTOC_EXECUTABLE_VERSION}")
+ endif()
- if(NOT "${_PROTOBUF_PROTOC_EXECUTABLE_VERSION}" VERSION_EQUAL "${Protobuf_VERSION}")
+ if(NOT "${_PROTOBUF_PROTOC_EXECUTABLE_VERSION}" VERSION_EQUAL "${Protobuf_VERSION}")
message(WARNING "Protobuf compiler version ${_PROTOBUF_PROTOC_EXECUTABLE_VERSION}"
- " doesn't match library version ${Protobuf_VERSION}")
+ " doesn't match library version ${Protobuf_VERSION}")
+ endif()
endif()
if(Protobuf_LIBRARY)
diff --git a/Modules/FindPython.cmake b/Modules/FindPython.cmake
index 2bdfaf3..01b82c4 100644
--- a/Modules/FindPython.cmake
+++ b/Modules/FindPython.cmake
@@ -13,13 +13,24 @@ The following components are supported:
* ``Interpreter``: search for Python interpreter.
* ``Compiler``: search for Python compiler. Only offered by IronPython.
* ``Development``: search for development artifacts (include directories and
- libraries).
+ libraries). This component includes two sub-components which can be specified
+ independently:
+
+ * ``Development.Module``: search for artifacts for Python module
+ developments.
+ * ``Development.Embed``: search for artifacts for Python embedding
+ developments.
+
* ``NumPy``: search for NumPy include directories.
If no ``COMPONENTS`` are specified, ``Interpreter`` is assumed.
+If component ``Development`` is specified, it implies sub-components
+``Development.Module`` and ``Development.Embed``.
+
To ensure consistent versions between components ``Interpreter``, ``Compiler``,
-``Development`` and ``NumPy``, specify all components at the same time::
+``Development`` (or one of its sub-components) and ``NumPy``, specify all
+components at the same time::
find_package (Python COMPONENTS Interpreter Development)
@@ -30,10 +41,11 @@ To manage concurrent versions 3 and 2 of Python, use :module:`FindPython3` and
.. note::
- If components ``Interpreter`` and ``Development`` are both specified, this
- module search only for interpreter with same platform architecture as the one
- defined by ``CMake`` configuration. This contraint does not apply if only
- ``Interpreter`` component is specified.
+ If components ``Interpreter`` and ``Development`` (or one of its
+ sub-components) are both specified, this module search only for interpreter
+ with same platform architecture as the one defined by ``CMake``
+ configuration. This contraint does not apply if only ``Interpreter``
+ component is specified.
Imported Targets
^^^^^^^^^^^^^^^^
@@ -45,12 +57,12 @@ This module defines the following :ref:`Imported Targets <Imported Targets>`
Python interpreter. Target defined if component ``Interpreter`` is found.
``Python::Compiler``
Python compiler. Target defined if component ``Compiler`` is found.
+``Python::Module``
+ Python library for Python module. Target defined if component
+ ``Development.Module`` is found.
``Python::Python``
Python library for Python embedding. Target defined if component
- ``Development`` is found.
-``Python::Module``
- Python library for Python module. Target defined if component ``Development``
- is found.
+ ``Development.Embed`` is found.
``Python::NumPy``
NumPy Python library. Target defined if component ``NumPy`` is found.
@@ -73,26 +85,40 @@ This module will set the following variables in your project
* Anaconda
* Canopy
* IronPython
+ * PyPy
``Python_STDLIB``
Standard platform independent installation directory.
Information returned by
- ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)``.
+ ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)``
+ or else ``sysconfig.get_path('stdlib')``.
``Python_STDARCH``
Standard platform dependent installation directory.
Information returned by
- ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)``.
+ ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)``
+ or else ``sysconfig.get_path('platstdlib')``.
``Python_SITELIB``
Third-party platform independent installation directory.
Information returned by
- ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)``.
+ ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)``
+ or else ``sysconfig.get_path('purelib')``.
``Python_SITEARCH``
Third-party platform dependent installation directory.
Information returned by
- ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``.
+ ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``
+ or else ``sysconfig.get_path('platlib')``.
+``Python_SOABI``
+ Extension suffix for modules.
+
+ Information returned by
+ ``distutils.sysconfig.get_config_var('SOABI')`` or computed from
+ ``distutils.sysconfig.get_config_var('EXT_SUFFIX')`` or
+ ``python-config --extension-suffix``. If package ``distutils.sysconfig`` is
+ not available, ``sysconfig.get_config_var('SOABI')`` or
+ ``sysconfig.get_config_var('EXT_SUFFIX')`` are used.
``Python_Compiler_FOUND``
System has the Python compiler.
``Python_COMPILER``
@@ -100,8 +126,14 @@ This module will set the following variables in your project
``Python_COMPILER_ID``
A short string unique to the compiler. Possible values include:
* IronPython
+``Python_DOTNET_LAUNCHER``
+ The ``.Net`` interpreter. Only used by ``IronPython`` implementation.
``Python_Development_FOUND``
System has the Python development artifacts.
+``Python_Development.Module_FOUND``
+ System has the Python development artifacts for Python module.
+``Python_Development.Embed_FOUND``
+ System has the Python development artifacts for Python embedding.
``Python_INCLUDE_DIRS``
The Python include directories.
``Python_LIBRARIES``
@@ -118,6 +150,8 @@ This module will set the following variables in your project
Python minor version.
``Python_VERSION_PATCH``
Python patch version.
+``Python_PyPy_VERSION``
+ Python PyPy version.
``Python_NumPy_FOUND``
System has the NumPy.
``Python_NumPy_INCLUDE_DIRS``
@@ -184,8 +218,7 @@ Hints
``Python_FIND_STRATEGY``
This variable defines how lookup will be done.
- The ``Python_FIND_STRATEGY`` variable can be set to empty or one of the
- following:
+ The ``Python_FIND_STRATEGY`` variable can be set to one of the following:
* ``VERSION``: Try to find the most recent version in all specified
locations.
@@ -198,8 +231,7 @@ Hints
``Python_FIND_REGISTRY``
On Windows the ``Python_FIND_REGISTRY`` variable determine the order
of preference between registry and environment variables.
- the ``Python_FIND_REGISTRY`` variable can be set to empty or one of the
- following:
+ the ``Python_FIND_REGISTRY`` variable can be set to one of the following:
* ``FIRST``: Try to use registry before environment variables.
This is the default.
@@ -209,8 +241,8 @@ Hints
``Python_FIND_FRAMEWORK``
On macOS the ``Python_FIND_FRAMEWORK`` variable determine the order of
preference between Apple-style and unix-style package components.
- This variable can be set to empty or take same values as
- :variable:`CMAKE_FIND_FRAMEWORK` variable.
+ This variable can take same values as :variable:`CMAKE_FIND_FRAMEWORK`
+ variable.
.. note::
@@ -220,11 +252,11 @@ Hints
variable will be used, if any.
``Python_FIND_VIRTUALENV``
- This variable defines the handling of virtual environments. It is meaningfull
- only when a virtual environment is active (i.e. the ``activate`` script has
- been evaluated). In this case, it takes precedence over
- ``Python_FIND_REGISTRY`` and ``CMAKE_FIND_FRAMEWORK`` variables.
- The ``Python_FIND_VIRTUALENV`` variable can be set to empty or one of the
+ This variable defines the handling of virtual environments managed by
+ ``virtualenv`` or ``conda``. It is meaningful only when a virtual environment
+ is active (i.e. the ``activate`` script has been evaluated). In this case, it
+ takes precedence over ``Python_FIND_REGISTRY`` and ``CMAKE_FIND_FRAMEWORK``
+ variables. The ``Python_FIND_VIRTUALENV`` variable can be set to one of the
following:
* ``FIRST``: The virtual environment is used before any other standard
@@ -232,8 +264,9 @@ Hints
* ``ONLY``: Only the virtual environment is used to look-up for the
interpreter.
* ``STANDARD``: The virtual environment is not used to look-up for the
- interpreter. In this case, variable ``Python_FIND_REGISTRY`` (Windows)
- or ``CMAKE_FIND_FRAMEWORK`` (macOS) can be set with value ``LAST`` or
+ interpreter but environment variable ``PATH`` is always considered.
+ In this case, variable ``Python_FIND_REGISTRY`` (Windows) or
+ ``CMAKE_FIND_FRAMEWORK`` (macOS) can be set with value ``LAST`` or
``NEVER`` to select preferably the interpreter from the virtual
environment.
@@ -243,6 +276,39 @@ Hints
recommended to also include the component ``Interpreter`` to get expected
result.
+``Python_FIND_IMPLEMENTATIONS``
+ This variable defines, in an ordered list, the different implementations
+ which will be searched. The ``Python_FIND_IMPLEMENTATIONS`` variable can
+ hold the following values:
+
+ * ``CPython``: this is the standard implementation. Various products, like
+ ``Anaconda`` or ``ActivePython``, rely on this implementation.
+ * ``IronPython``: This implementation use the ``CSharp`` language for
+ ``.NET Framework`` on top of the `Dynamic Language Runtime` (``DLR``).
+ See `IronPython <http://ironpython.net>`_.
+ * ``PyPy``: This implementation use ``RPython`` language and
+ ``RPython translation toolchain`` to produce the python interpreter.
+ See `PyPy <https://www.pypy.org>`_.
+
+ The default value is:
+
+ * Windows platform: ``CPython``, ``IronPython``
+ * Other platforms: ``CPython``
+
+ .. note::
+
+ This hint has the lowest priority of all hints, so even if, for example,
+ you specify ``IronPython`` first and ``CPython`` in second, a python
+ product based on ``CPython`` can be selected because, for example with
+ ``Python_FIND_STRATEGY=LOCATION``, each location will be search first for
+ ``IronPython`` and second for ``CPython``.
+
+ .. note::
+
+ When ``IronPython`` is specified, on platforms other than ``Windows``, the
+ ``.Net`` interpreter (i.e. ``mono`` command) is expected to be available
+ through the ``PATH`` variable.
+
Artifacts Specification
^^^^^^^^^^^^^^^^^^^^^^^
@@ -255,6 +321,9 @@ setting the following variables:
``Python_COMPILER``
The path to the compiler.
+``Python_DOTNET_LAUNCHER``
+ The ``.Net`` interpreter. Only used by ``IronPython`` implementation.
+
``Python_LIBRARY``
The path to the library. It will be used to compute the
variables ``Python_LIBRARIES``, ``Python_LIBRAY_DIRS`` and
@@ -281,6 +350,22 @@ setting the following variables:
If more than one artifact is specified, it is the user's responsability to
ensure the consistency of the various artifacts.
+By default, this module supports multiple calls in different directories of a
+project with different version/component requirements while providing correct
+and consistent results for each call. To support this behavior, ``CMake`` cache
+is not used in the traditional way which can be problematic for interactive
+specification. So, to enable also interactive specification, module behavior
+can be controled with the following variable:
+
+``Python_ARTIFACTS_INTERACTIVE``
+ Selects the behavior of the module. This is a boolean variable:
+
+ * If set to ``TRUE``: Create CMake cache entries for the above artifact
+ specification variables so that users can edit them interactively.
+ This disables support for multiple version/component requirements.
+ * If set to ``FALSE`` or undefined: Enable multiple version/component
+ requirements.
+
Commands
^^^^^^^^
@@ -290,9 +375,13 @@ This module defines the command ``Python_add_library`` (when
when library type is ``MODULE``, to target ``Python::Module`` and takes care of
Python module naming rules::
- Python_add_library (my_module MODULE src1.cpp)
+ Python_add_library (<name> [STATIC | SHARED | MODULE [WITH_SOABI]]
+ <source1> [<source2> ...])
+
+If the library type is not specified, ``MODULE`` is assumed.
-If library type is not specified, ``MODULE`` is assumed.
+For ``MODULE`` library type, if option ``WITH_SOABI`` is specified, the
+module suffix will include the ``Python_SOABI`` value, if any.
#]=======================================================================]
diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake
index 50dd7ba..cb400a5 100644
--- a/Modules/FindPython/Support.cmake
+++ b/Modules/FindPython/Support.cmake
@@ -22,9 +22,9 @@ endif()
if (NOT DEFINED _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
message (FATAL_ERROR "FindPython: INTERNAL ERROR")
endif()
-if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL 3)
+if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL "3")
set(_${_PYTHON_PREFIX}_VERSIONS 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
-elseif (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL 2)
+elseif (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL "2")
set(_${_PYTHON_PREFIX}_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
else()
message (FATAL_ERROR "FindPython: INTERNAL ERROR")
@@ -75,70 +75,135 @@ macro (_PYTHON_SELECT_LIBRARY_CONFIGURATIONS _PYTHON_BASENAME)
(_PYTHON_isMultiConfig OR CMAKE_BUILD_TYPE))
# if the generator is multi-config or if CMAKE_BUILD_TYPE is set for
# single-config generators, set optimized and debug libraries
- set (${_PYTHON_BASENAME}_LIBRARY "")
- foreach (_PYTHON_libname IN LISTS ${_PYTHON_BASENAME}_LIBRARY_RELEASE )
- list( APPEND ${_PYTHON_BASENAME}_LIBRARY optimized "${_PYTHON_libname}" )
+ set (${_PYTHON_BASENAME}_LIBRARIES "")
+ foreach (_PYTHON_libname IN LISTS ${_PYTHON_BASENAME}_LIBRARY_RELEASE)
+ list( APPEND ${_PYTHON_BASENAME}_LIBRARIES optimized "${_PYTHON_libname}")
endforeach()
- foreach (_PYTHON_libname IN LISTS ${_PYTHON_BASENAME}_LIBRARY_DEBUG )
- list( APPEND ${_PYTHON_BASENAME}_LIBRARY debug "${_PYTHON_libname}" )
+ foreach (_PYTHON_libname IN LISTS ${_PYTHON_BASENAME}_LIBRARY_DEBUG)
+ list( APPEND ${_PYTHON_BASENAME}_LIBRARIES debug "${_PYTHON_libname}")
endforeach()
elseif (${_PYTHON_BASENAME}_LIBRARY_RELEASE)
- set (${_PYTHON_BASENAME}_LIBRARY "${${_PYTHON_BASENAME}_LIBRARY_RELEASE}")
+ set (${_PYTHON_BASENAME}_LIBRARIES "${${_PYTHON_BASENAME}_LIBRARY_RELEASE}")
elseif (${_PYTHON_BASENAME}_LIBRARY_DEBUG)
- set (${_PYTHON_BASENAME}_LIBRARY "${${_PYTHON_BASENAME}_LIBRARY_DEBUG}")
+ set (${_PYTHON_BASENAME}_LIBRARIES "${${_PYTHON_BASENAME}_LIBRARY_DEBUG}")
else()
- set (${_PYTHON_BASENAME}_LIBRARY "${_PYTHON_BASENAME}_LIBRARY-NOTFOUND")
+ set (${_PYTHON_BASENAME}_LIBRARIES "${_PYTHON_BASENAME}_LIBRARY-NOTFOUND")
endif()
-
- set (${_PYTHON_BASENAME}_LIBRARIES "${${_PYTHON_BASENAME}_LIBRARY}")
endmacro()
macro (_PYTHON_FIND_FRAMEWORKS)
- set (${_PYTHON_PREFIX}_FRAMEWORKS)
if (CMAKE_HOST_APPLE OR APPLE)
+ file(TO_CMAKE_PATH "$ENV{CMAKE_FRAMEWORK_PATH}" _pff_CMAKE_FRAMEWORK_PATH)
set (_pff_frameworks ${CMAKE_FRAMEWORK_PATH}
- $ENV{CMAKE_FRAMEWORK_PATH}
- ~/Library/Frameworks
- /usr/local/Frameworks
- ${CMAKE_SYSTEM_FRAMEWORK_PATH})
+ ${_pff_CMAKE_FRAMEWORK_PATH}
+ ~/Library/Frameworks
+ /usr/local/Frameworks
+ ${CMAKE_SYSTEM_FRAMEWORK_PATH})
list (REMOVE_DUPLICATES _pff_frameworks)
- foreach (_pff_framework IN LISTS _pff_frameworks)
- if (EXISTS ${_pff_framework}/Python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}.framework)
- list (APPEND ${_PYTHON_PREFIX}_FRAMEWORKS ${_pff_framework}/Python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}.framework)
- endif()
- if (EXISTS ${_pff_framework}/Python.framework)
- list (APPEND ${_PYTHON_PREFIX}_FRAMEWORKS ${_pff_framework}/Python.framework)
+ foreach (_pff_implementation IN LISTS _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS)
+ unset (_${_PYTHON_PREFIX}_${_pff_implementation}_FRAMEWORKS)
+ if (_pff_implementation STREQUAL "CPython")
+ foreach (_pff_framework IN LISTS _pff_frameworks)
+ if (EXISTS ${_pff_framework}/Python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}.framework)
+ list (APPEND _${_PYTHON_PREFIX}_${_pff_implementation}_FRAMEWORKS ${_pff_framework}/Python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}.framework)
+ endif()
+ if (EXISTS ${_pff_framework}/Python.framework)
+ list (APPEND _${_PYTHON_PREFIX}_${_pff_implementation}_FRAMEWORKS ${_pff_framework}/Python.framework)
+ endif()
+ endforeach()
+ elseif (_pff_implementation STREQUAL "IronPython")
+ foreach (_pff_framework IN LISTS _pff_frameworks)
+ if (EXISTS ${_pff_framework}/IronPython.framework)
+ list (APPEND _${_PYTHON_PREFIX}_${_pff_implementation}_FRAMEWORKS ${_pff_framework}/IronPython.framework)
+ endif()
+ endforeach()
endif()
endforeach()
+ unset (_pff_implementation)
unset (_pff_frameworks)
unset (_pff_framework)
endif()
endmacro()
-function (_PYTHON_GET_FRAMEWORKS _PYTHON_PGF_FRAMEWORK_PATHS _PYTHON_VERSION)
- set (_PYTHON_FRAMEWORK_PATHS)
- foreach (_PYTHON_FRAMEWORK IN LISTS ${_PYTHON_PREFIX}_FRAMEWORKS)
- list (APPEND _PYTHON_FRAMEWORK_PATHS
- "${_PYTHON_FRAMEWORK}/Versions/${_PYTHON_VERSION}")
+function (_PYTHON_GET_FRAMEWORKS _PYTHON_PGF_FRAMEWORK_PATHS)
+ cmake_parse_arguments (PARSE_ARGV 1 _PGF "" "" "IMPLEMENTATIONS;VERSION")
+
+ if (NOT _PGF_IMPLEMENTATIONS)
+ set (_PGF_IMPLEMENTATIONS ${_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS})
+ endif()
+
+ set (framework_paths)
+
+ foreach (implementation IN LISTS _PGF_IMPLEMENTATIONS)
+ if (implementation STREQUAL "CPython")
+ foreach (version IN LISTS _PGF_VERSION)
+ foreach (framework IN LISTS _${_PYTHON_PREFIX}_${implementation}_FRAMEWORKS)
+ if (EXISTS "${framework}/Versions/${version}")
+ list (APPEND framework_paths "${framework}/Versions/${version}")
+ endif()
+ endforeach()
+ endforeach()
+ elseif (implementation STREQUAL "IronPython")
+ foreach (version IN LISTS _PGF_VERSION)
+ foreach (framework IN LISTS _${_PYTHON_PREFIX}_${implementation}_FRAMEWORKS)
+ # pick-up all available versions
+ file (GLOB versions LIST_DIRECTORIES true RELATIVE "${framework}/Versions/"
+ "${framework}/Versions/${version}*")
+ list (SORT versions ORDER DESCENDING)
+ list (TRANSFORM versions PREPEND "${framework}/Versions/")
+ list (APPEND framework_paths ${versions})
+ endforeach()
+ endforeach()
+ endif()
endforeach()
- set (${_PYTHON_PGF_FRAMEWORK_PATHS} ${_PYTHON_FRAMEWORK_PATHS} PARENT_SCOPE)
+
+ set (${_PYTHON_PGF_FRAMEWORK_PATHS} ${framework_paths} PARENT_SCOPE)
endfunction()
-function (_PYTHON_GET_REGISTRIES _PYTHON_PGR_REGISTRY_PATHS _PYTHON_VERSION)
- string (REPLACE "." "" _PYTHON_VERSION_NO_DOTS ${_PYTHON_VERSION})
- set (${_PYTHON_PGR_REGISTRY_PATHS}
- [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_PYTHON_VERSION}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
- [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_PYTHON_VERSION}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
- [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_PYTHON_VERSION}\\InstallPath]
- [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_PYTHON_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
- [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_PYTHON_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_PYTHON_VERSION}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_PYTHON_VERSION}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_PYTHON_VERSION}\\InstallPath]
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_PYTHON_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_PYTHON_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
- PARENT_SCOPE)
+function (_PYTHON_GET_REGISTRIES _PYTHON_PGR_REGISTRY_PATHS)
+ cmake_parse_arguments (PARSE_ARGV 1 _PGR "" "" "IMPLEMENTATIONS;VERSION")
+
+ if (NOT _PGR_IMPLEMENTATIONS)
+ set (_PGR_IMPLEMENTATIONS ${_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS})
+ endif()
+
+ set (registries)
+
+ foreach (implementation IN LISTS _PGR_IMPLEMENTATIONS)
+ if (implementation STREQUAL "CPython")
+ 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])
+ if (version VERSION_GREATER_EQUAL "3.5")
+ 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])
+ endif()
+ else()
+ list (APPEND registries
+ [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])
+ endforeach()
+ elseif (implementation STREQUAL "IronPython")
+ foreach (version IN LISTS _PGR_VERSION)
+ list (APPEND registries [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${version}\\InstallPath])
+ endforeach()
+ endif()
+ endforeach()
+
+ set (${_PYTHON_PGR_REGISTRY_PATHS} "${registries}" PARENT_SCOPE)
endfunction()
@@ -186,7 +251,11 @@ function (_PYTHON_GET_ABIFLAGS _PGABIFLAGS)
endfunction()
function (_PYTHON_GET_PATH_SUFFIXES _PYTHON_PGPS_PATH_SUFFIXES)
- cmake_parse_arguments (PARSE_ARGV 1 _PGPS "LIBRARY;INCLUDE" "VERSION" "")
+ cmake_parse_arguments (PARSE_ARGV 1 _PGPS "INTERPRETER;COMPILER;LIBRARY;INCLUDE" "" "IMPLEMENTATIONS;VERSION")
+
+ if (NOT _PGPS_IMPLEMENTATIONS)
+ set (_PGPS_IMPLEMENTATIONS ${_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS})
+ endif()
if (DEFINED _${_PYTHON_PREFIX}_ABIFLAGS)
set (abi "${_${_PYTHON_PREFIX}_ABIFLAGS}")
@@ -195,93 +264,163 @@ function (_PYTHON_GET_PATH_SUFFIXES _PYTHON_PGPS_PATH_SUFFIXES)
endif()
set (path_suffixes)
- if (_PGPS_LIBRARY)
- if (CMAKE_LIBRARY_ARCHITECTURE)
- list (APPEND path_suffixes lib/${CMAKE_LIBRARY_ARCHITECTURE})
- endif()
- list (APPEND path_suffixes lib libs)
- if (CMAKE_LIBRARY_ARCHITECTURE)
- set (suffixes "${abi}")
- if (suffixes)
- list (TRANSFORM suffixes PREPEND "lib/python${_PGPS_VERSION}/config-${_PGPS_VERSION}")
- list (TRANSFORM suffixes APPEND "-${CMAKE_LIBRARY_ARCHITECTURE}")
+ foreach (implementation IN LISTS _PGPS_IMPLEMENTATIONS)
+ if (implementation STREQUAL "CPython")
+ if (_PGPS_INTERPRETER)
+ list (APPEND path_suffixes bin Scripts)
else()
- set (suffixes "lib/python${_PGPS_VERSION}/config-${_PGPS_VERSION}-${CMAKE_LIBRARY_ARCHITECTURE}")
+ foreach (version IN LISTS _PGPS_VERSION)
+ if (_PGPS_LIBRARY)
+ if (CMAKE_LIBRARY_ARCHITECTURE)
+ list (APPEND path_suffixes lib/${CMAKE_LIBRARY_ARCHITECTURE})
+ endif()
+ list (APPEND path_suffixes lib libs)
+
+ if (CMAKE_LIBRARY_ARCHITECTURE)
+ set (suffixes "${abi}")
+ if (suffixes)
+ list (TRANSFORM suffixes PREPEND "lib/python${_PGPS_VERSION}/config-${_PGPS_VERSION}")
+ list (TRANSFORM suffixes APPEND "-${CMAKE_LIBRARY_ARCHITECTURE}")
+ else()
+ set (suffixes "lib/python${_PGPS_VERSION}/config-${_PGPS_VERSION}-${CMAKE_LIBRARY_ARCHITECTURE}")
+ endif()
+ list (APPEND path_suffixes ${suffixes})
+ endif()
+ set (suffixes "${abi}")
+ if (suffixes)
+ list (TRANSFORM suffixes PREPEND "lib/python${_PGPS_VERSION}/config-${_PGPS_VERSION}")
+ else()
+ set (suffixes "lib/python${_PGPS_VERSION}/config-${_PGPS_VERSION}")
+ endif()
+ list (APPEND path_suffixes ${suffixes})
+ elseif (_PGPS_INCLUDE)
+ set (suffixes "${abi}")
+ if (suffixes)
+ list (TRANSFORM suffixes PREPEND "include/python${_PGPS_VERSION}")
+ else()
+ set (suffixes "include/python${_PGPS_VERSION}")
+ endif()
+ list (APPEND path_suffixes ${suffixes} include)
+ endif()
+ endforeach()
+ endif()
+ elseif (implementation STREQUAL "IronPython")
+ if (_PGPS_INTERPRETER OR _PGPS_COMPILER)
+ foreach (version IN LISTS _PGPS_VERSION)
+ list (APPEND path_suffixes "share/ironpython${version}")
+ endforeach()
+ list (APPEND path_suffixes ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES})
+ endif()
+ elseif (implementation STREQUAL "PyPy")
+ if (_PGPS_INTERPRETER)
+ list (APPEND path_suffixes ${_${_PYTHON_PREFIX}_PYPY_EXECUTABLE_PATH_SUFFIXES})
+ elseif (_PGPS_LIBRARY)
+ list (APPEND path_suffixes ${_${_PYTHON_PREFIX}_PYPY_LIBRARY_PATH_SUFFIXES})
+ elseif (_PGPS_INCLUDE)
+ list (APPEND path_suffixes ${_${_PYTHON_PREFIX}_PYPY_INCLUDE_PATH_SUFFIXES})
endif()
- list (APPEND path_suffixes ${suffixes})
- endif()
- set (suffixes "${abi}")
- if (suffixes)
- list (TRANSFORM suffixes PREPEND "lib/python${_PGPS_VERSION}/config-${_PGPS_VERSION}")
- else()
- set (suffixes "lib/python${_PGPS_VERSION}/config-${_PGPS_VERSION}")
- endif()
- list (APPEND path_suffixes ${suffixes})
- elseif (_PGPS_INCLUDE)
- set (suffixes "${abi}")
- if (suffixes)
- list (TRANSFORM suffixes PREPEND "include/python${_PGPS_VERSION}")
- else()
- set (suffixes "include/python${_PGPS_VERSION}")
endif()
- list (APPEND path_suffixes ${suffixes} include)
- endif()
+ endforeach()
+ list (REMOVE_DUPLICATES path_suffixes)
set (${_PYTHON_PGPS_PATH_SUFFIXES} ${path_suffixes} PARENT_SCOPE)
endfunction()
function (_PYTHON_GET_NAMES _PYTHON_PGN_NAMES)
- cmake_parse_arguments (PARSE_ARGV 1 _PGN "POSIX;EXECUTABLE;CONFIG;LIBRARY;WIN32;DEBUG" "VERSION" "")
+ cmake_parse_arguments (PARSE_ARGV 1 _PGN "POSIX;INTERPRETER;COMPILER;CONFIG;LIBRARY;WIN32;DEBUG" "" "IMPLEMENTATIONS;VERSION")
+
+ if (NOT _PGN_IMPLEMENTATIONS)
+ set (_PGN_IMPLEMENTATIONS ${_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS})
+ endif()
set (names)
- if (_PGN_WIN32)
- string (REPLACE "." "" _PYTHON_VERSION_NO_DOTS ${_PGN_VERSION})
+ foreach (implementation IN LISTS _PGN_IMPLEMENTATIONS)
+ if (implementation STREQUAL "CPython")
+ foreach (version IN LISTS _PGN_VERSION)
+ if (_PGN_WIN32)
+ string (REPLACE "." "" version_no_dots ${version})
- set (name python${_PYTHON_VERSION_NO_DOTS})
- if (_PGN_DEBUG)
- string (APPEND name "_d")
- endif()
+ set (name python${version_no_dots})
+ if (_PGN_DEBUG)
+ string (APPEND name "_d")
+ endif()
- list (APPEND names "${name}")
- endif()
+ list (APPEND names "${name}")
+ endif()
- if (_PGN_POSIX)
- if (DEFINED _${_PYTHON_PREFIX}_ABIFLAGS)
- set (abi "${_${_PYTHON_PREFIX}_ABIFLAGS}")
- else()
- if (_PGN_EXECUTABLE OR _PGN_CONFIG)
- set (abi "")
- else()
- set (abi "mu" "m" "u" "")
- endif()
- endif()
+ if (_PGN_POSIX)
+ if (DEFINED _${_PYTHON_PREFIX}_ABIFLAGS)
+ set (abi "${_${_PYTHON_PREFIX}_ABIFLAGS}")
+ else()
+ if (_PGN_INTERPRETER OR _PGN_CONFIG)
+ set (abi "")
+ else()
+ set (abi "mu" "m" "u" "")
+ endif()
+ endif()
- if (abi)
- if (_PGN_CONFIG AND DEFINED CMAKE_LIBRARY_ARCHITECTURE)
- set (abinames "${abi}")
- list (TRANSFORM abinames PREPEND "${CMAKE_LIBRARY_ARCHITECTURE}-python${_PGN_VERSION}")
- list (TRANSFORM abinames APPEND "-config")
- list (APPEND names ${abinames})
- endif()
- set (abinames "${abi}")
- list (TRANSFORM abinames PREPEND "python${_PGN_VERSION}")
- if (_PGN_CONFIG)
- list (TRANSFORM abinames APPEND "-config")
+ if (abi)
+ if (_PGN_CONFIG AND DEFINED CMAKE_LIBRARY_ARCHITECTURE)
+ set (abinames "${abi}")
+ list (TRANSFORM abinames PREPEND "${CMAKE_LIBRARY_ARCHITECTURE}-python${version}")
+ list (TRANSFORM abinames APPEND "-config")
+ list (APPEND names ${abinames})
+ endif()
+ set (abinames "${abi}")
+ list (TRANSFORM abinames PREPEND "python${version}")
+ if (_PGN_CONFIG)
+ list (TRANSFORM abinames APPEND "-config")
+ endif()
+ list (APPEND names ${abinames})
+ else()
+ unset (abinames)
+ if (_PGN_CONFIG AND DEFINED CMAKE_LIBRARY_ARCHITECTURE)
+ set (abinames "${CMAKE_LIBRARY_ARCHITECTURE}-python${version}")
+ endif()
+ list (APPEND abinames "python${version}")
+ if (_PGN_CONFIG)
+ list (TRANSFORM abinames APPEND "-config")
+ endif()
+ list (APPEND names ${abinames})
+ endif()
+ endif()
+ endforeach()
+ if (_PGN_INTERPRETER)
+ list (APPEND names python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} python)
endif()
- list (APPEND names ${abinames})
- else()
- if (_PGN_CONFIG AND DEFINED CMAKE_LIBRARY_ARCHITECTURE)
- set (abinames "${CMAKE_LIBRARY_ARCHITECTURE}-python${_PGN_VERSION}")
+ elseif (implementation STREQUAL "IronPython")
+ if (_PGN_INTERPRETER)
+ if (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ # Do not use wrapper script on Linux because it is buggy: -c interpreter option cannot be used
+ foreach (version IN LISTS _PGN_VERSION)
+ list (APPEND names "ipy${version}")
+ endforeach()
+ endif()
+ list (APPEND names ${_${_PYTHON_PREFIX}_IRON_PYTHON_INTERPRETER_NAMES})
+ elseif (_PGN_COMPILER)
+ list (APPEND names ${_${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_NAMES})
endif()
- list (APPEND abinames "python${_PGN_VERSION}")
- if (_PGN_CONFIG)
- list (TRANSFORM abinames APPEND "-config")
+ elseif (implementation STREQUAL "PyPy")
+ if (_PGN_INTERPRETER)
+ list (APPEND names ${_${_PYTHON_PREFIX}_PYPY_NAMES})
+ elseif (_PGN_LIBRARY)
+ if (_PGN_WIN32)
+ foreach (version IN LISTS _PGN_VERSION)
+ string (REPLACE "." "" version_no_dots ${version})
+
+ set (name "python${version_no_dots}")
+ if (_PGN_DEBUG)
+ string (APPEND name "_d")
+ endif()
+ list (APPEND names "${name}")
+ endforeach()
+ endif()
+ list (APPEND names ${_${_PYTHON_PREFIX}_PYPY_LIB_NAMES})
endif()
- list (APPEND names ${abinames})
endif()
- endif()
+ endforeach()
set (${_PYTHON_PGN_NAMES} ${names} PARENT_SCOPE)
endfunction()
@@ -289,12 +428,16 @@ endfunction()
function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME)
unset (${_PYTHON_PGCV_VALUE} PARENT_SCOPE)
- if (NOT NAME MATCHES "^(PREFIX|ABIFLAGS|CONFIGDIR|INCLUDES|LIBS)$")
+ if (NOT NAME MATCHES "^(PREFIX|ABIFLAGS|CONFIGDIR|INCLUDES|LIBS|SOABI)$")
return()
endif()
if (_${_PYTHON_PREFIX}_CONFIG)
- set (config_flag "--${NAME}")
+ if (NAME STREQUAL "SOABI")
+ set (config_flag "--extension-suffix")
+ else()
+ set (config_flag "--${NAME}")
+ endif()
string (TOLOWER "${config_flag}" config_flag)
execute_process (COMMAND "${_${_PYTHON_PREFIX}_CONFIG}" ${config_flag}
RESULT_VARIABLE _result
@@ -309,13 +452,16 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME)
string (REGEX MATCHALL "(-I|-iwithsysroot)[ ]*[^ ]+" _values "${_values}")
string (REGEX REPLACE "(-I|-iwithsysroot)[ ]*" "" _values "${_values}")
list (REMOVE_DUPLICATES _values)
+ elseif (NAME STREQUAL "SOABI")
+ # clean-up: remove prefix character and suffix
+ string (REGEX REPLACE "^[.-](.+)(${CMAKE_SHARED_LIBRARY_SUFFIX}|\\.(so|pyd))$" "\\1" _values "${_values}")
endif()
endif()
endif()
if (_${_PYTHON_PREFIX}_EXECUTABLE AND NOT CMAKE_CROSSCOMPILING)
if (NAME STREQUAL "PREFIX")
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig; sys.stdout.write(';'.join([sysconfig.PREFIX,sysconfig.EXEC_PREFIX,sysconfig.BASE_EXEC_PREFIX]))"
+ execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys\ntry:\n from distutils import sysconfig\n sys.stdout.write(';'.join([sysconfig.PREFIX,sysconfig.EXEC_PREFIX,sysconfig.BASE_EXEC_PREFIX]))\nexcept Exception:\n import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_config_var('base') or '', sysconfig.get_config_var('installed_base') or '']))"
RESULT_VARIABLE _result
OUTPUT_VARIABLE _values
ERROR_QUIET
@@ -326,20 +472,50 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME)
list (REMOVE_DUPLICATES _values)
endif()
elseif (NAME STREQUAL "INCLUDES")
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig; sys.stdout.write(';'.join([sysconfig.get_python_inc(plat_specific=True),sysconfig.get_python_inc(plat_specific=False)]))"
+ if (WIN32)
+ set (_scheme "nt")
+ else()
+ set (_scheme "posix_prefix")
+ endif()
+ execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
+ "import sys\ntry:\n from distutils import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_python_inc(plat_specific=True),sysconfig.get_python_inc(plat_specific=False)]))\nexcept Exception:\n import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_path('platinclude'),sysconfig.get_path('platinclude','${_scheme}'),sysconfig.get_path('include'),sysconfig.get_path('include','${_scheme}')]))"
RESULT_VARIABLE _result
OUTPUT_VARIABLE _values
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
if (_result)
unset (_values)
+ else()
+ list (REMOVE_DUPLICATES _values)
+ endif()
+ elseif (NAME STREQUAL "SOABI")
+ execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
+ "import sys\ntry:\n from distutils import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_config_var('SOABI') or '',sysconfig.get_config_var('EXT_SUFFIX') or '']))\nexcept Exception:\n import sysconfig;sys.stdout.write(';'.join([sysconfig.get_config_var('SOABI') or '',sysconfig.get_config_var('EXT_SUFFIX') or '']))"
+ RESULT_VARIABLE _result
+ OUTPUT_VARIABLE _soabi
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if (_result)
+ unset (_values)
+ else()
+ foreach (_item IN LISTS _soabi)
+ if (_item)
+ set (_values "${_item}")
+ break()
+ endif()
+ endforeach()
+ if (_values)
+ # clean-up: remove prefix character and suffix
+ string (REGEX REPLACE "^[.-](.+)(${CMAKE_SHARED_LIBRARY_SUFFIX}|\\.(so|pyd))$" "\\1" _values "${_values}")
+ endif()
endif()
else()
set (config_flag "${NAME}")
if (NAME STREQUAL "CONFIGDIR")
set (config_flag "LIBPL")
endif()
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig; sys.stdout.write(sysconfig.get_config_var('${config_flag}'))"
+ execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
+ "import sys\ntry:\n from distutils import sysconfig\n sys.stdout.write(sysconfig.get_config_var('${config_flag}'))\nexcept Exception:\n import sysconfig\n sys.stdout.write(sysconfig.get_config_var('${config_flag}'))"
RESULT_VARIABLE _result
OUTPUT_VARIABLE _values
ERROR_QUIET
@@ -367,6 +543,10 @@ function (_PYTHON_GET_CONFIG_VAR _PYTHON_PGCV_VALUE NAME)
list (REMOVE_DUPLICATES _values)
endif()
+ if (WIN32 AND NAME MATCHES "^(PREFIX|CONFIGDIR|INCLUDES)$")
+ file (TO_CMAKE_PATH "${_values}" _values)
+ endif()
+
set (${_PYTHON_PGCV_VALUE} "${_values}" PARENT_SCOPE)
endfunction()
@@ -393,6 +573,16 @@ function (_PYTHON_GET_VERSION)
set (${_PGV_PREFIX}VERSION_MINOR "${CMAKE_MATCH_2}" PARENT_SCOPE)
set (${_PGV_PREFIX}VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}" PARENT_SCOPE)
set (${_PGV_PREFIX}ABI "${CMAKE_MATCH_3}" PARENT_SCOPE)
+ elseif (_${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "pypy(3)?")
+ set (version "${CMAKE_MATCH_1}")
+ if (version EQUAL "3")
+ set (${_PGV_PREFIX}VERSION_MAJOR "3" PARENT_SCOPE)
+ set (${_PGV_PREFIX}VERSION "3" PARENT_SCOPE)
+ else()
+ set (${_PGV_PREFIX}VERSION_MAJOR "2" PARENT_SCOPE)
+ set (${_PGV_PREFIX}VERSION "2" PARENT_SCOPE)
+ endif()
+ set (${_PGV_PREFIX}ABI "" PARENT_SCOPE)
endif()
endif()
else()
@@ -407,13 +597,13 @@ function (_PYTHON_GET_VERSION)
list (GET versions 1 version_minor)
list (GET versions 2 version_patch)
- set (${_PGV_PREFIX}VERSION "${version_major}.${version_minor}" PARENT_SCOPE)
+ set (${_PGV_PREFIX}VERSION "${version_major}.${version_minor}.${version_patch}" PARENT_SCOPE)
set (${_PGV_PREFIX}VERSION_MAJOR ${version_major} PARENT_SCOPE)
set (${_PGV_PREFIX}VERSION_MINOR ${version_minor} PARENT_SCOPE)
set (${_PGV_PREFIX}VERSION_PATCH ${version_patch} PARENT_SCOPE)
# compute ABI flags
- if (version_major VERSION_GREATER 2)
+ if (version_major VERSION_GREATER "2")
file (STRINGS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}/pyconfig.h" config REGEX "(Py_DEBUG|WITH_PYMALLOC|Py_UNICODE_SIZE|MS_WIN32)")
set (abi)
if (config MATCHES "#[ ]*define[ ]+MS_WIN32")
@@ -439,6 +629,36 @@ function (_PYTHON_GET_VERSION)
endif()
endfunction()
+function (_PYTHON_GET_LAUNCHER _PYTHON_PGL_NAME)
+ cmake_parse_arguments (PARSE_ARGV 1 _PGL "INTERPRETER;COMPILER" "" "")
+
+ unset ({_PYTHON_PGL_NAME} PARENT_SCOPE)
+
+ if ((_PGL_INTERPRETER AND NOT _${_PYTHON_PREFIX}_EXECUTABLE)
+ OR (_PGL_COMPILER AND NOT _${_PYTHON_PREFIX}_COMPILER))
+ return()
+ endif()
+
+ if ("IronPython" IN_LIST _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS
+ AND NOT SYSTEM_NAME MATCHES "Windows|Linux")
+ if (_PGL_INTERPRETER)
+ get_filename_component (name "${_${_PYTHON_PREFIX}_EXECUTABLE}" NAME)
+ get_filename_component (ext "${_${_PYTHON_PREFIX}_EXECUTABLE}" LAST_EXT)
+ if (name IN_LIST _${_PYTHON_PREFIX}_IRON_PYTHON_INTERPRETER_NAMES
+ AND ext STREQUAL ".exe")
+ set (${_PYTHON_PGL_NAME} "${${_PYTHON_PREFIX}_DOTNET_LAUNCHER}" PARENT_SCOPE)
+ endif()
+ else()
+ get_filename_component (name "${_${_PYTHON_PREFIX}_COMPILER}" NAME)
+ get_filename_component (ext "${_${_PYTHON_PREFIX}_COMPILER}" LAST_EXT)
+ if (name IN_LIST _${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_NAMES
+ AND ext STREQUAL ".exe")
+ set (${_PYTHON_PGL_NAME} "${${_PYTHON_PREFIX}_DOTNET_LAUNCHER}" PARENT_SCOPE)
+ endif()
+ endif()
+ endif()
+endfunction()
+
function (_PYTHON_VALIDATE_INTERPRETER)
if (NOT _${_PYTHON_PREFIX}_EXECUTABLE)
@@ -447,20 +667,23 @@ function (_PYTHON_VALIDATE_INTERPRETER)
cmake_parse_arguments (PARSE_ARGV 0 _PVI "EXACT;CHECK_EXISTS" "" "")
if (_PVI_UNPARSED_ARGUMENTS)
- set (expected_version ${_PVI_UNPARSED_ARGUMENTS})
+ set (expected_version "${_PVI_UNPARSED_ARGUMENTS}")
else()
unset (expected_version)
endif()
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}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND")
return()
endif()
+ _python_get_launcher (launcher INTERPRETER)
+
# validate ABI compatibility
if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI)
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
+ execute_process (COMMAND ${launcher} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
"import sys; sys.stdout.write(sys.abiflags)"
RESULT_VARIABLE result
OUTPUT_VARIABLE abi
@@ -472,6 +695,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}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND")
return()
endif()
@@ -479,24 +703,52 @@ function (_PYTHON_VALIDATE_INTERPRETER)
get_filename_component (python_name "${_${_PYTHON_PREFIX}_EXECUTABLE}" NAME)
- if (expected_version AND NOT python_name STREQUAL "python${expected_version}${abi}${CMAKE_EXECUTABLE_SUFFIX}")
- # executable found must have a specific version
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
- "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:2]]))"
- RESULT_VARIABLE result
- OUTPUT_VARIABLE version
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (result OR (_PVI_EXACT AND NOT version VERSION_EQUAL expected_version) OR (version VERSION_LESS expected_version))
- # interpreter not usable or has wrong major version
- set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND")
- return()
+ if (expected_version)
+ if (NOT python_name STREQUAL "python${expected_version}${abi}${CMAKE_EXECUTABLE_SUFFIX}")
+ # compute number of components for version
+ string (REGEX REPLACE "[^.]" "" dots "${expected_version}")
+ # add one dot because there is one dot less than there are components
+ string (LENGTH "${dots}." count)
+ if (count GREATER 3)
+ set (count 3)
+ endif()
+
+ # executable found must have a specific version
+ execute_process (COMMAND ${launcher} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
+ "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:${count}]]))"
+ RESULT_VARIABLE result
+ OUTPUT_VARIABLE version
+ ERROR_QUIET
+ 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}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND")
+ else()
+ if (_PVI_EXACT AND NOT version VERSION_EQUAL expected_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}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND")
+ else()
+ # check that version is OK
+ string(REGEX REPLACE "^([0-9]+)\\.?.*$" "\\1" major_version "${version}")
+ string(REGEX REPLACE "^([0-9]+)\\.?.*$" "\\1" expected_major_version "${expected_version}")
+ if (NOT major_version VERSION_EQUAL expected_major_version
+ OR NOT version VERSION_GREATER_EQUAL expected_version)
+ set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Wrong version for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"" PARENT_SCOPE)
+ set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND")
+ endif()
+ endif()
+ endif()
+ if (NOT _${_PYTHON_PREFIX}_EXECUTABLE)
+ return()
+ endif()
endif()
else()
if (NOT python_name STREQUAL "python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}${CMAKE_EXECUTABLE_SUFFIX}")
# executable found do not have version in name
# ensure major version is OK
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
+ execute_process (COMMAND ${launcher} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
"import sys; sys.stdout.write(str(sys.version_info[0]))"
RESULT_VARIABLE result
OUTPUT_VARIABLE version
@@ -504,16 +756,22 @@ function (_PYTHON_VALIDATE_INTERPRETER)
OUTPUT_STRIP_TRAILING_WHITESPACE)
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)
+ else()
+ set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Wrong major version for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"" PARENT_SCOPE)
+ endif()
set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND")
return()
endif()
endif()
endif()
- if (CMAKE_SIZEOF_VOID_P AND "Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+ if (CMAKE_SIZEOF_VOID_P AND ("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+ OR "Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
AND NOT CMAKE_CROSSCOMPILING)
# In this case, interpreter must have same architecture as environment
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
+ execute_process (COMMAND ${launcher} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
"import sys, struct; sys.stdout.write(str(struct.calcsize(\"P\")))"
RESULT_VARIABLE result
OUTPUT_VARIABLE size
@@ -521,6 +779,11 @@ function (_PYTHON_VALIDATE_INTERPRETER)
OUTPUT_STRIP_TRAILING_WHITESPACE)
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)
+ else()
+ set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Wrong architecture for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"" PARENT_SCOPE)
+ endif()
set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND")
return()
endif()
@@ -528,49 +791,68 @@ function (_PYTHON_VALIDATE_INTERPRETER)
endfunction()
-function (_PYTHON_VALIDATE_COMPILER expected_version)
+function (_PYTHON_VALIDATE_COMPILER)
if (NOT _${_PYTHON_PREFIX}_COMPILER)
return()
endif()
- cmake_parse_arguments (_PVC "EXACT;CHECK_EXISTS" "" "" ${ARGN})
+ cmake_parse_arguments (PARSE_ARGV 0 _PVC "EXACT;CHECK_EXISTS" "" "")
if (_PVC_UNPARSED_ARGUMENTS)
set (major_version FALSE)
- set (expected_version ${_PVC_UNPARSED_ARGUMENTS})
+ set (expected_version "${_PVC_UNPARSED_ARGUMENTS}")
else()
set (major_version TRUE)
- set (expected_version ${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR})
+ set (expected_version "${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}")
set (_PVC_EXACT TRUE)
endif()
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 PROPERTY VALUE "${_PYTHON_PREFIX}_COMPILER-NOTFOUND")
return()
endif()
+ _python_get_launcher (launcher COMPILER)
+
# retrieve python environment version from compiler
set (working_dir "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/PythonCompilerVersion.dir")
if (major_version)
# check only major version
file (WRITE "${working_dir}/version.py" "import sys; sys.stdout.write(str(sys.version_info[0]))")
else()
- file (WRITE "${working_dir}/version.py" "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:2]]))\n")
+ # compute number of components for version
+ string (REGEX REPLACE "[^.]" "" dots "${expected_version}")
+ # add one dot because there is one dot less than there are components
+ string (LENGTH "${dots}." count)
+ if (count GREATER 3)
+ set (count 3)
+ endif()
+ file (WRITE "${working_dir}/version.py" "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:${count}]]))\n")
endif()
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_COMPILER}" /target:exe /embed "${working_dir}/version.py"
+ execute_process (COMMAND ${launcher} "${_${_PYTHON_PREFIX}_COMPILER}"
+ ${_${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_ARCH_FLAGS}
+ /target:exe /embed "${working_dir}/version.py"
WORKING_DIRECTORY "${working_dir}"
OUTPUT_QUIET
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
- execute_process (COMMAND "${working_dir}/version"
+ get_filename_component (ir_dir "${_${_PYTHON_PREFIX}_COMPILER}" DIRECTORY)
+ execute_process (COMMAND "${CMAKE_COMMAND}" -E env "MONO_PATH=${ir_dir}"
+ ${${_PYTHON_PREFIX}_DOTNET_LAUNCHER} "${working_dir}/version.exe"
WORKING_DIRECTORY "${working_dir}"
RESULT_VARIABLE result
OUTPUT_VARIABLE version
ERROR_QUIET)
- file (REMOVE_RECURSE "${_${_PYTHON_PREFIX}_VERSION_DIR}")
-
- if (result OR (_PVC_EXACT AND NOT version VERSION_EQUAL expected_version) OR (version VERSION_LESS expected_version))
- # Compiler not usable or has wrong version
+ 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 PROPERTY VALUE "${_PYTHON_PREFIX}_COMPILER-NOTFOUND")
+ elseif ((_PVC_EXACT AND NOT version VERSION_EQUAL expected_version)
+ OR NOT version VERSION_GREATER_EQUAL expected_version)
+ # Compiler 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 PROPERTY VALUE "${_PYTHON_PREFIX}_COMPILER-NOTFOUND")
endif()
endfunction()
@@ -578,6 +860,7 @@ endfunction()
function (_PYTHON_VALIDATE_LIBRARY)
if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
+ unset (_${_PYTHON_PREFIX}_LIBRARY_DEBUG)
return()
endif()
@@ -590,6 +873,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}_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")
@@ -603,16 +887,21 @@ 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}_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND")
else()
if (expected_version)
- if ((_PVL_EXACT AND NOT lib_VERSION VERSION_EQUAL expected_version) OR (lib_VERSION VERSION_LESS expected_version))
+ # library have only major.minor information
+ string (REGEX MATCH "[0-9](\\.[0-9]+)?" version "${expected_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}_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND")
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}_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND")
endif()
endif()
@@ -643,6 +932,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}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND")
return()
endif()
@@ -652,16 +942,19 @@ 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}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND")
else()
if (expected_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}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND")
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}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND")
endif()
endif()
@@ -694,13 +987,30 @@ function (_PYTHON_SET_LIBRARY_DIRS _PYTHON_SLD_RESULT)
list (APPEND _PYTHON_DIRS "${_PYTHON_DIR}")
endif()
endforeach()
- if (_PYTHON_DIRS)
- list (REMOVE_DUPLICATES _PYTHON_DIRS)
- endif()
+ list (REMOVE_DUPLICATES _PYTHON_DIRS)
set (${_PYTHON_SLD_RESULT} ${_PYTHON_DIRS} PARENT_SCOPE)
endfunction()
+function (_PYTHON_SET_DEVELOPMENT_MODULE_FOUND module)
+ if ("Development.${module}" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+ string(TOUPPER "${module}" id)
+ set (module_found TRUE)
+
+ if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS
+ AND NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
+ set (module_found FALSE)
+ endif()
+ if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS
+ AND NOT _${_PYTHON_PREFIX}_INCLUDE_DIR)
+ set (module_found FALSE)
+ endif()
+
+ set (${_PYTHON_PREFIX}_Development.${module}_FOUND ${module_found} PARENT_SCOPE)
+ endif()
+endfunction()
+
+
# If major version is specified, it must be the same as internal major version
if (DEFINED ${_PYTHON_PREFIX}_FIND_VERSION_MAJOR
AND NOT ${_PYTHON_PREFIX}_FIND_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
@@ -714,26 +1024,49 @@ if (NOT ${_PYTHON_PREFIX}_FIND_COMPONENTS)
set (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter TRUE)
endif()
if ("NumPy" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
- list (APPEND ${_PYTHON_PREFIX}_FIND_COMPONENTS "Interpreter" "Development")
- list (REMOVE_DUPLICATES ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+ list (APPEND ${_PYTHON_PREFIX}_FIND_COMPONENTS "Interpreter" "Development.Module")
endif()
-foreach (_${_PYTHON_PREFIX}_COMPONENT IN ITEMS Interpreter Compiler Development NumPy)
+if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+ list (APPEND ${_PYTHON_PREFIX}_FIND_COMPONENTS "Development.Module" "Development.Embed")
+endif()
+list (REMOVE_DUPLICATES ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+foreach (_${_PYTHON_PREFIX}_COMPONENT IN ITEMS Interpreter Compiler Development Development.Module Development.Embed NumPy)
set (${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_FOUND FALSE)
endforeach()
-unset (_${_PYTHON_PREFIX}_FIND_VERSIONS)
+if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development)
+ set (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.Module TRUE)
+ set (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.Embed TRUE)
+endif()
+
+unset (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
+unset (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS)
+unset (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS)
+if ("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+ if (CMAKE_SYSTEM_NAME MATCHES "^(Windows.*|CYGWIN|MSYS)$")
+ list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS "LIBRARY")
+ endif()
+ list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS "INCLUDE_DIR")
+endif()
+if ("Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+ list (APPEND _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS "LIBRARY" "INCLUDE_DIR")
+endif()
+set (_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS ${_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS} ${_${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS})
+list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
# Set versions to search
## default: search any version
set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${_${_PYTHON_PREFIX}_VERSIONS})
+unset (_${_PYTHON_PREFIX}_FIND_VERSION_EXACT)
-if (${_PYTHON_PREFIX}_FIND_VERSION_COUNT GREATER 1)
+if (${_PYTHON_PREFIX}_FIND_VERSION_COUNT)
if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT)
+ set (_${_PYTHON_PREFIX}_FIND_VERSION_EXACT "EXACT")
set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}.${${_PYTHON_PREFIX}_FIND_VERSION_MINOR})
else()
unset (_${_PYTHON_PREFIX}_FIND_VERSIONS)
# add all compatible versions
foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_VERSIONS)
- if (_${_PYTHON_PREFIX}_VERSION VERSION_GREATER_EQUAL ${_PYTHON_PREFIX}_FIND_VERSION)
+ if (_${_PYTHON_PREFIX}_VERSION VERSION_GREATER_EQUAL "${${_PYTHON_PREFIX}_FIND_VERSION_MAJOR}.${${_PYTHON_PREFIX}_FIND_VERSION_MINOR}")
list (APPEND _${_PYTHON_PREFIX}_FIND_VERSIONS ${_${_PYTHON_PREFIX}_VERSION})
endif()
endforeach()
@@ -742,7 +1075,7 @@ endif()
# Set ABIs to search
## default: search any ABI
-if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR VERSION_LESS 3)
+if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR VERSION_LESS "3")
# ABI not supported
unset (_${_PYTHON_PREFIX}_FIND_ABI)
set (_${_PYTHON_PREFIX}_ABIFLAGS "")
@@ -761,6 +1094,7 @@ else()
_python_get_abiflags (_${_PYTHON_PREFIX}_ABIFLAGS)
endif()
endif()
+unset (${_PYTHON_PREFIX}_SOABI)
# Define lookup strategy
if (_${_PYTHON_PREFIX}_LOOKUP_POLICY STREQUAL "NEW")
@@ -789,15 +1123,75 @@ else()
endif()
# IronPython support
+unset (_${_PYTHON_PREFIX}_IRON_PYTHON_INTERPRETER_NAMES)
+unset (_${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_NAMES)
+unset (_${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_ARCH_FLAGS)
if (CMAKE_SIZEOF_VOID_P)
- # In this case, search only for 64bit or 32bit
- math (EXPR _${_PYTHON_PREFIX}_ARCH "${CMAKE_SIZEOF_VOID_P} * 8")
- set (_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES ipy${_${_PYTHON_PREFIX}_ARCH} ipy)
+ if (_${_PYTHON_PREFIX}_ARCH EQUAL "32")
+ set (_${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_ARCH_FLAGS "/platform:x86")
+ else()
+ set (_${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_ARCH_FLAGS "/platform:x64")
+ endif()
+endif()
+if (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ # Do not use wrapper script on Linux because it is buggy: -c interpreter option cannot be used
+ list (APPEND _${_PYTHON_PREFIX}_IRON_PYTHON_INTERPRETER_NAMES "ipy${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}" "ipy64" "ipy32" "ipy")
+ list (APPEND _${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_NAMES "ipyc")
+endif()
+list (APPEND _${_PYTHON_PREFIX}_IRON_PYTHON_INTERPRETER_NAMES "ipy.exe")
+list (APPEND _${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_NAMES "ipyc.exe")
+set (_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES net45 net40 bin)
+
+# PyPy support
+if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR EQUAL "3")
+ set (_${_PYTHON_PREFIX}_PYPY_NAMES pypy3)
+ set (_${_PYTHON_PREFIX}_PYPY_LIB_NAMES pypy3-c)
+ if (WIN32)
+ # special name for runtime part
+ list (APPEND _${_PYTHON_PREFIX}_PYPY_LIB_NAMES libpypy3-c)
+ endif()
+ set (_${_PYTHON_PREFIX}_PYPY_INCLUDE_PATH_SUFFIXES lib/pypy3)
+else()
+ set (_${_PYTHON_PREFIX}_PYPY_NAMES pypy)
+ set (_${_PYTHON_PREFIX}_PYPY_LIB_NAMES pypy-c)
+ if (WIN32)
+ # special name for runtime part
+ list (APPEND _${_PYTHON_PREFIX}_PYPY_LIB_NAMES libpypy-c)
+ endif()
+ set (_${_PYTHON_PREFIX}_PYPY_INCLUDE_PATH_SUFFIXES lib/pypy)
+endif()
+set (_${_PYTHON_PREFIX}_PYPY_EXECUTABLE_PATH_SUFFIXES bin)
+set (_${_PYTHON_PREFIX}_PYPY_LIBRARY_PATH_SUFFIXES lib libs bin)
+list (APPEND _${_PYTHON_PREFIX}_PYPY_INCLUDE_PATH_SUFFIXES include)
+
+# Python Implementations handling
+unset (_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS)
+if (DEFINED ${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS)
+ foreach (_${_PYTHON_PREFIX}_IMPLEMENTATION IN LISTS ${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS)
+ if (NOT _${_PYTHON_PREFIX}_IMPLEMENTATION MATCHES "^(CPython|IronPython|PyPy)$")
+ message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: ${_${_PYTHON_PREFIX}_IMPLEMENTATION}: invalid value for '${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS'. 'CPython', 'IronPython' or 'PyPy' expected. Value will be ignored.")
+ else()
+ list (APPEND _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS ${_${_PYTHON_PREFIX}_IMPLEMENTATION})
+ endif()
+ endforeach()
else()
- # architecture unknown, search for natural interpreter
- set (_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES ipy)
+ if (WIN32)
+ set (_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS CPython IronPython)
+ else()
+ set (_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS CPython)
+ endif()
endif()
-set (_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES net45 net40)
+
+# compute list of names for header file
+unset (_${_PYTHON_PREFIX}_INCLUDE_NAMES)
+foreach (_${_PYTHON_PREFIX}_IMPLEMENTATION IN LISTS _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS)
+ if (_${_PYTHON_PREFIX}_IMPLEMENTATION STREQUAL "CPython")
+ list (APPEND _${_PYTHON_PREFIX}_INCLUDE_NAMES "Python.h")
+ elseif (_${_PYTHON_PREFIX}_IMPLEMENTATION STREQUAL "PyPy")
+ list (APPEND _${_PYTHON_PREFIX}_INCLUDE_NAMES "PyPy.h")
+ endif()
+endforeach()
+
# Apple frameworks handling
_python_find_frameworks ()
@@ -850,8 +1244,8 @@ else()
set (_${_PYTHON_PREFIX}_FIND_REGISTRY "FIRST")
endif()
-# virtual environments handling
-if (DEFINED ENV{VIRTUAL_ENV})
+# virtual environments recognition
+if (DEFINED ENV{VIRTUAL_ENV} OR DEFINED ENV{CONDA_PREFIX})
if (DEFINED ${_PYTHON_PREFIX}_FIND_VIRTUALENV)
if (NOT ${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY|STANDARD)$")
message (AUTHOR_WARNING "Find${_PYTHON_PREFIX}: ${${_PYTHON_PREFIX}_FIND_VIRTUALENV}: invalid value for '${_PYTHON_PREFIX}_FIND_VIRTUALENV'. 'FIRST', 'ONLY' or 'STANDARD' expected. 'FIRST' will be used instead.")
@@ -869,31 +1263,107 @@ endif()
# Compute search signature
# This signature will be used to check validity of cached variables on new search
-set (_${_PYTHON_PREFIX}_SIGNATURE "${${_PYTHON_PREFIX}_ROOT_DIR}:${${_PYTHON_PREFIX}_FIND_STRATEGY}:${${_PYTHON_PREFIX}_FIND_VIRTUALENV}")
+set (_${_PYTHON_PREFIX}_SIGNATURE "${${_PYTHON_PREFIX}_ROOT_DIR}:${_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS}:${_${_PYTHON_PREFIX}_FIND_STRATEGY}:${${_PYTHON_PREFIX}_FIND_VIRTUALENV}")
if (NOT WIN32)
string (APPEND _${_PYTHON_PREFIX}_SIGNATURE ":${${_PYTHON_PREFIX}_USE_STATIC_LIBS}:")
endif()
if (CMAKE_HOST_APPLE)
- string (APPEND _${_PYTHON_PREFIX}_SIGNATURE ":${${_PYTHON_PREFIX}_FIND_FRAMEWORK}")
+ string (APPEND _${_PYTHON_PREFIX}_SIGNATURE ":${_${_PYTHON_PREFIX}_FIND_FRAMEWORK}")
endif()
if (CMAKE_HOST_WIN32)
- string (APPEND _${_PYTHON_PREFIX}_SIGNATURE ":${${_PYTHON_PREFIX}_FIND_REGISTRY}")
+ string (APPEND _${_PYTHON_PREFIX}_SIGNATURE ":${_${_PYTHON_PREFIX}_FIND_REGISTRY}")
endif()
+function (_PYTHON_CHECK_DEVELOPMENT_SIGNATURE module)
+ if ("Development.${module}" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+ string (TOUPPER "${module}" id)
+ set (signature "${_${_PYTHON_PREFIX}_SIGNATURE}:")
+ if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
+ list (APPEND signature "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}:")
+ endif()
+ if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
+ list (APPEND signature "${_${_PYTHON_PREFIX}_INCLUDE_DIR}:")
+ endif()
+ string (MD5 signature "${signature}")
+ if (signature STREQUAL _${_PYTHON_PREFIX}_DEVELOPMENT_${id}_SIGNATURE)
+ if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
+ _python_validate_library (${${_PYTHON_PREFIX}_FIND_VERSION}
+ ${_${_PYTHON_PREFIX}_FIND_VERSION_EXACT}
+ CHECK_EXISTS)
+ endif()
+ if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
+ _python_validate_include_dir (${${_PYTHON_PREFIX}_FIND_VERSION}
+ ${_${_PYTHON_PREFIX}_FIND_VERSION_EXACT}
+ CHECK_EXISTS)
+ endif()
+ else()
+ if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
+ unset (_${_PYTHON_PREFIX}_LIBRARY_RELEASE CACHE)
+ unset (_${_PYTHON_PREFIX}_LIBRARY_DEBUG CACHE)
+ endif()
+ if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
+ unset (_${_PYTHON_PREFIX}_INCLUDE_DIR CACHE)
+ endif()
+ endif()
+ if (("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS
+ AND NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
+ OR ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS
+ AND NOT _${_PYTHON_PREFIX}_INCLUDE_DIR))
+ unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
+ unset (_${_PYTHON_PREFIX}_DEVELOPMENT_${id}_SIGNATURE CACHE)
+ endif()
+ endif()
+endfunction()
+
+function (_PYTHON_COMPUTE_DEVELOPMENT_SIGNATURE module)
+ string (TOUPPER "${module}" id)
+ if (${_PYTHON_PREFIX}_Development.${module}_FOUND)
+ set (signature "${_${_PYTHON_PREFIX}_SIGNATURE}:")
+ if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
+ list (APPEND signature "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}:")
+ endif()
+ if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${id}_ARTIFACTS)
+ list (APPEND signature "${_${_PYTHON_PREFIX}_INCLUDE_DIR}:")
+ endif()
+ string (MD5 signature "${signature}")
+ set (_${_PYTHON_PREFIX}_DEVELOPMENT_${id}_SIGNATURE "${signature}" CACHE INTERNAL "")
+ else()
+ unset (_${_PYTHON_PREFIX}_DEVELOPMENT_${id}_SIGNATURE CACHE)
+ endif()
+endfunction()
+
unset (_${_PYTHON_PREFIX}_REQUIRED_VARS)
unset (_${_PYTHON_PREFIX}_CACHED_VARS)
+unset (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE)
+unset (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE)
+unset (_${_PYTHON_PREFIX}_Development_REASON_FAILURE)
+unset (_${_PYTHON_PREFIX}_NumPy_REASON_FAILURE)
+
+
+# preamble
+## For IronPython on platforms other than Windows, search for the .Net interpreter
+if ("IronPython" IN_LIST _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS
+ AND NOT WIN32)
+ find_program (${_PYTHON_PREFIX}_DOTNET_LAUNCHER
+ NAMES "mono")
+endif()
# first step, search for the interpreter
if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
- list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_EXECUTABLE)
+ list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_EXECUTABLE
+ _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES)
if (${_PYTHON_PREFIX}_FIND_REQUIRED_Interpreter)
list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_EXECUTABLE)
endif()
if (DEFINED ${_PYTHON_PREFIX}_EXECUTABLE
AND IS_ABSOLUTE "${${_PYTHON_PREFIX}_EXECUTABLE}")
+ if (NOT ${_PYTHON_PREFIX}_EXECUTABLE STREQUAL _${_PYTHON_PREFIX}_EXECUTABLE)
+ # invalidate cache properties
+ unset (_${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES CACHE)
+ endif()
set (_${_PYTHON_PREFIX}_EXECUTABLE "${${_PYTHON_PREFIX}_EXECUTABLE}" CACHE INTERNAL "")
elseif (DEFINED _${_PYTHON_PREFIX}_EXECUTABLE)
# compute interpreter signature and check validity of definition
@@ -907,7 +1377,10 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
endif()
else()
unset (_${_PYTHON_PREFIX}_EXECUTABLE CACHE)
+ endif()
+ if (NOT _${_PYTHON_PREFIX}_EXECUTABLE)
unset (_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE CACHE)
+ unset (_${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES CACHE)
endif()
endif()
@@ -915,25 +1388,14 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR)
if (_${_PYTHON_PREFIX}_FIND_STRATEGY STREQUAL "LOCATION")
- unset (_${_PYTHON_PREFIX}_NAMES)
- unset (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS)
- unset (_${_PYTHON_PREFIX}_REGISTRY_PATHS)
+ # build all executable names
+ _python_get_names (_${_PYTHON_PREFIX}_NAMES VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS} POSIX INTERPRETER)
+ _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS} INTERPRETER)
- foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
- # build all executable names
- _python_get_names (_${_PYTHON_PREFIX}_VERSION_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} POSIX EXECUTABLE)
- list (APPEND _${_PYTHON_PREFIX}_NAMES ${_${_PYTHON_PREFIX}_VERSION_NAMES})
-
- # Framework Paths
- _python_get_frameworks (_${_PYTHON_PREFIX}_VERSION_PATHS ${_${_PYTHON_PREFIX}_VERSION})
- list (APPEND _${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION_PATHS})
-
- # Registry Paths
- _python_get_registries (_${_PYTHON_PREFIX}_VERSION_PATHS ${_${_PYTHON_PREFIX}_VERSION})
- list (APPEND _${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_VERSION_PATHS}
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath])
- endforeach()
- list (APPEND _${_PYTHON_PREFIX}_NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR} python)
+ # Framework Paths
+ _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS})
+ # Registry Paths
+ _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS})
while (TRUE)
# Virtual environments handling
@@ -942,14 +1404,14 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
NAMES ${_${_PYTHON_PREFIX}_NAMES}
NAMES_PER_DIR
HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ENV VIRTUAL_ENV
- PATH_SUFFIXES bin Scripts
+ PATHS ENV VIRTUAL_ENV ENV CONDA_PREFIX
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_CMAKE_PATH
NO_CMAKE_ENVIRONMENT_PATH
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH)
- _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION})
+ _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION} ${_${_PYTHON_PREFIX}_FIND_VERSION_EXACT})
if (_${_PYTHON_PREFIX}_EXECUTABLE)
break()
endif()
@@ -965,12 +1427,12 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
NAMES_PER_DIR
HINTS ${_${_PYTHON_PREFIX}_HINTS}
PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
- PATH_SUFFIXES bin
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_CMAKE_PATH
NO_CMAKE_ENVIRONMENT_PATH
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH)
- _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION})
+ _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION} ${_${_PYTHON_PREFIX}_FIND_VERSION_EXACT})
if (_${_PYTHON_PREFIX}_EXECUTABLE)
break()
endif()
@@ -979,14 +1441,13 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST")
find_program (_${_PYTHON_PREFIX}_EXECUTABLE
NAMES ${_${_PYTHON_PREFIX}_NAMES}
- ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}
NAMES_PER_DIR
HINTS ${_${_PYTHON_PREFIX}_HINTS}
PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
- PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH)
- _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION})
+ _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION} ${_${_PYTHON_PREFIX}_FIND_VERSION_EXACT})
if (_${_PYTHON_PREFIX}_EXECUTABLE)
break()
endif()
@@ -995,23 +1456,21 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
# try using HINTS
find_program (_${_PYTHON_PREFIX}_EXECUTABLE
NAMES ${_${_PYTHON_PREFIX}_NAMES}
- ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}
NAMES_PER_DIR
HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH)
- _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION})
+ _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION} ${_${_PYTHON_PREFIX}_FIND_VERSION_EXACT})
if (_${_PYTHON_PREFIX}_EXECUTABLE)
break()
endif()
# try using standard paths
find_program (_${_PYTHON_PREFIX}_EXECUTABLE
NAMES ${_${_PYTHON_PREFIX}_NAMES}
- ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}
NAMES_PER_DIR
- PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES})
- _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION})
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES})
+ _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION} ${_${_PYTHON_PREFIX}_FIND_VERSION_EXACT})
if (_${_PYTHON_PREFIX}_EXECUTABLE)
break()
endif()
@@ -1022,9 +1481,9 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
NAMES ${_${_PYTHON_PREFIX}_NAMES}
NAMES_PER_DIR
PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
- PATH_SUFFIXES bin
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_DEFAULT_PATH)
- _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION})
+ _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION} ${_${_PYTHON_PREFIX}_FIND_VERSION_EXACT})
if (_${_PYTHON_PREFIX}_EXECUTABLE)
break()
endif()
@@ -1033,12 +1492,11 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
find_program (_${_PYTHON_PREFIX}_EXECUTABLE
NAMES ${_${_PYTHON_PREFIX}_NAMES}
- ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}
NAMES_PER_DIR
PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
- PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_DEFAULT_PATH)
- _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION})
+ _python_validate_interpreter (${${_PYTHON_PREFIX}_FIND_VERSION} ${_${_PYTHON_PREFIX}_FIND_VERSION_EXACT})
if (_${_PYTHON_PREFIX}_EXECUTABLE)
break()
endif()
@@ -1049,12 +1507,11 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
else()
# look-up for various versions and locations
foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
- _python_get_names (_${_PYTHON_PREFIX}_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} POSIX EXECUTABLE)
- list (APPEND _${_PYTHON_PREFIX}_NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}
- python)
+ _python_get_names (_${_PYTHON_PREFIX}_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} POSIX INTERPRETER)
+ _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_VERSION} INTERPRETER)
- _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION})
- _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_VERSION})
+ _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS VERSION ${_${_PYTHON_PREFIX}_VERSION})
+ _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS VERSION ${_${_PYTHON_PREFIX}_VERSION})
# Virtual environments handling
if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$")
@@ -1062,8 +1519,8 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
NAMES ${_${_PYTHON_PREFIX}_NAMES}
NAMES_PER_DIR
HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ENV VIRTUAL_ENV
- PATH_SUFFIXES bin Scripts
+ PATHS ENV VIRTUAL_ENV ENV CONDA_PREFIX
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_CMAKE_PATH
NO_CMAKE_ENVIRONMENT_PATH
NO_SYSTEM_ENVIRONMENT_PATH
@@ -1084,7 +1541,7 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
NAMES_PER_DIR
HINTS ${_${_PYTHON_PREFIX}_HINTS}
PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
- PATH_SUFFIXES bin
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_CMAKE_PATH
NO_CMAKE_ENVIRONMENT_PATH
NO_SYSTEM_ENVIRONMENT_PATH
@@ -1095,12 +1552,10 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST")
find_program (_${_PYTHON_PREFIX}_EXECUTABLE
NAMES ${_${_PYTHON_PREFIX}_NAMES}
- ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}
NAMES_PER_DIR
HINTS ${_${_PYTHON_PREFIX}_HINTS}
PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
- PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH)
endif()
@@ -1113,10 +1568,9 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
# try using HINTS
find_program (_${_PYTHON_PREFIX}_EXECUTABLE
NAMES ${_${_PYTHON_PREFIX}_NAMES}
- ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}
NAMES_PER_DIR
HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH)
_python_validate_interpreter (${_${_PYTHON_PREFIX}_VERSION} EXACT)
@@ -1129,15 +1583,9 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
# 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.
- if (CMAKE_HOST_WIN32)
- find_program (_${_PYTHON_PREFIX}_EXECUTABLE
- NAMES ${_${_PYTHON_PREFIX}_NAMES}
- python
- ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES})
- else()
- find_program (_${_PYTHON_PREFIX}_EXECUTABLE
- NAMES ${_${_PYTHON_PREFIX}_NAMES})
- endif()
+ find_program (_${_PYTHON_PREFIX}_EXECUTABLE
+ NAMES ${_${_PYTHON_PREFIX}_NAMES}
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES})
_python_validate_interpreter (${_${_PYTHON_PREFIX}_VERSION} EXACT)
if (_${_PYTHON_PREFIX}_EXECUTABLE)
break()
@@ -1149,7 +1597,7 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
NAMES ${_${_PYTHON_PREFIX}_NAMES}
NAMES_PER_DIR
PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
- PATH_SUFFIXES bin
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_DEFAULT_PATH)
endif()
@@ -1157,11 +1605,9 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
find_program (_${_PYTHON_PREFIX}_EXECUTABLE
NAMES ${_${_PYTHON_PREFIX}_NAMES}
- ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}
NAMES_PER_DIR
PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
- PATH_SUFFIXES bin ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_DEFAULT_PATH)
endif()
@@ -1179,20 +1625,20 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
# 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)
find_program (_${_PYTHON_PREFIX}_EXECUTABLE
- NAMES python${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}
- python
- ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES})
+ NAMES ${_${_PYTHON_PREFIX}_NAMES})
_python_validate_interpreter ()
endif()
endif()
endif()
set (${_PYTHON_PREFIX}_EXECUTABLE "${_${_PYTHON_PREFIX}_EXECUTABLE}")
+ _python_get_launcher (_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER INTERPRETER)
# retrieve exact version of executable found
if (_${_PYTHON_PREFIX}_EXECUTABLE)
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
+ execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
"import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]]))"
RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
OUTPUT_VARIABLE ${_PYTHON_PREFIX}_VERSION
@@ -1200,105 +1646,151 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
OUTPUT_STRIP_TRAILING_WHITESPACE)
if (NOT _${_PYTHON_PREFIX}_RESULT)
set (_${_PYTHON_PREFIX}_EXECUTABLE_USABLE TRUE)
- string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${${_PYTHON_PREFIX}_VERSION}")
- list (GET _${_PYTHON_PREFIX}_VERSIONS 0 ${_PYTHON_PREFIX}_VERSION_MAJOR)
- list (GET _${_PYTHON_PREFIX}_VERSIONS 1 ${_PYTHON_PREFIX}_VERSION_MINOR)
- list (GET _${_PYTHON_PREFIX}_VERSIONS 2 ${_PYTHON_PREFIX}_VERSION_PATCH)
else()
# 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}\"")
endif()
endif()
- if (_${_PYTHON_PREFIX}_EXECUTABLE AND _${_PYTHON_PREFIX}_EXECUTABLE_USABLE
- AND ${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
- set (${_PYTHON_PREFIX}_Interpreter_FOUND TRUE)
- # Use interpreter version and ABI for future searches to ensure consistency
- set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR})
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; sys.stdout.write(sys.abiflags)"
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE _${_PYTHON_PREFIX}_ABIFLAGS
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (_${_PYTHON_PREFIX}_RESULT)
- # assunme ABI is not supported
- set (_${_PYTHON_PREFIX}_ABIFLAGS "")
- endif()
- endif()
+ if (_${_PYTHON_PREFIX}_EXECUTABLE AND _${_PYTHON_PREFIX}_EXECUTABLE_USABLE)
+ if (_${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES)
+ set (${_PYTHON_PREFIX}_Interpreter_FOUND TRUE)
- if (${_PYTHON_PREFIX}_Interpreter_FOUND)
- # compute and save interpreter signature
- string (MD5 __${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_EXECUTABLE}")
- set (_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE "${__${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}" CACHE INTERNAL "")
-
- if (NOT CMAKE_SIZEOF_VOID_P)
- # determine interpreter architecture
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; print(sys.maxsize > 2**32)"
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE ${_PYTHON_PREFIX}_IS64BIT
- ERROR_VARIABLE ${_PYTHON_PREFIX}_IS64BIT)
- if (NOT _${_PYTHON_PREFIX}_RESULT)
- if (${_PYTHON_PREFIX}_IS64BIT)
- set (_${_PYTHON_PREFIX}_ARCH 64)
- set (_${_PYTHON_PREFIX}_ARCH2 64)
- else()
- set (_${_PYTHON_PREFIX}_ARCH 32)
- set (_${_PYTHON_PREFIX}_ARCH2 32)
+ list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 0 ${_PYTHON_PREFIX}_INTERPRETER_ID)
+
+ list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 1 ${_PYTHON_PREFIX}_VERSION_MAJOR)
+ list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 2 ${_PYTHON_PREFIX}_VERSION_MINOR)
+ list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 3 ${_PYTHON_PREFIX}_VERSION_PATCH)
+
+ list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 4 _${_PYTHON_PREFIX}_ARCH)
+ set (_${_PYTHON_PREFIX}_ARCH2 ${_${_PYTHON_PREFIX}_ARCH})
+
+ list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 5 _${_PYTHON_PREFIX}_ABIFLAGS)
+ list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 6 ${_PYTHON_PREFIX}_SOABI)
+
+ list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 7 ${_PYTHON_PREFIX}_STDLIB)
+ list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 8 ${_PYTHON_PREFIX}_STDARCH)
+ list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 9 ${_PYTHON_PREFIX}_SITELIB)
+ list (GET _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES 10 ${_PYTHON_PREFIX}_SITEARCH)
+ else()
+ string (REGEX MATCHALL "[0-9]+" _${_PYTHON_PREFIX}_VERSIONS "${${_PYTHON_PREFIX}_VERSION}")
+ list (GET _${_PYTHON_PREFIX}_VERSIONS 0 ${_PYTHON_PREFIX}_VERSION_MAJOR)
+ list (GET _${_PYTHON_PREFIX}_VERSIONS 1 ${_PYTHON_PREFIX}_VERSION_MINOR)
+ list (GET _${_PYTHON_PREFIX}_VERSIONS 2 ${_PYTHON_PREFIX}_VERSION_PATCH)
+
+ if (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
+ set (${_PYTHON_PREFIX}_Interpreter_FOUND TRUE)
+
+ # Use interpreter version and ABI for future searches to ensure consistency
+ set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR})
+ execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETR_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
+ "import sys; sys.stdout.write(sys.abiflags)"
+ RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
+ OUTPUT_VARIABLE _${_PYTHON_PREFIX}_ABIFLAGS
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if (_${_PYTHON_PREFIX}_RESULT)
+ # assunme ABI is not supported
+ set (_${_PYTHON_PREFIX}_ABIFLAGS "")
endif()
endif()
- endif()
- # retrieve interpreter identity
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -V
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE ${_PYTHON_PREFIX}_INTERPRETER_ID
- ERROR_VARIABLE ${_PYTHON_PREFIX}_INTERPRETER_ID)
- if (NOT _${_PYTHON_PREFIX}_RESULT)
- if (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "Anaconda")
- set (${_PYTHON_PREFIX}_INTERPRETER_ID "Anaconda")
- elseif (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "Enthought")
- set (${_PYTHON_PREFIX}_INTERPRETER_ID "Canopy")
- else()
- string (REGEX REPLACE "^([^ ]+).*" "\\1" ${_PYTHON_PREFIX}_INTERPRETER_ID "${${_PYTHON_PREFIX}_INTERPRETER_ID}")
- if (${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "Python")
- # try to get a more precise ID
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; print(sys.copyright)"
+ if (${_PYTHON_PREFIX}_Interpreter_FOUND)
+ unset (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE)
+
+ # compute and save interpreter signature
+ string (MD5 __${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_EXECUTABLE}")
+ set (_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE "${__${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}" CACHE INTERNAL "")
+
+ if (NOT CMAKE_SIZEOF_VOID_P)
+ # determine interpreter architecture
+ execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
+ "import sys; sys.stdout.write(str(sys.maxsize > 2**32))"
RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE ${_PYTHON_PREFIX}_COPYRIGHT
- ERROR_QUIET)
- if (${_PYTHON_PREFIX}_COPYRIGHT MATCHES "ActiveState")
- set (${_PYTHON_PREFIX}_INTERPRETER_ID "ActivePython")
+ OUTPUT_VARIABLE ${_PYTHON_PREFIX}_IS64BIT
+ ERROR_VARIABLE ${_PYTHON_PREFIX}_IS64BIT)
+ if (NOT _${_PYTHON_PREFIX}_RESULT)
+ if (${_PYTHON_PREFIX}_IS64BIT)
+ set (_${_PYTHON_PREFIX}_ARCH 64)
+ set (_${_PYTHON_PREFIX}_ARCH2 64)
+ else()
+ set (_${_PYTHON_PREFIX}_ARCH 32)
+ set (_${_PYTHON_PREFIX}_ARCH2 32)
+ endif()
endif()
endif()
- endif()
- else()
- set (${_PYTHON_PREFIX}_INTERPRETER_ID Python)
- endif()
- # retrieve various package installation directories
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c "import sys; from distutils import sysconfig;sys.stdout.write(';'.join([sysconfig.get_python_lib(plat_specific=False,standard_lib=True),sysconfig.get_python_lib(plat_specific=True,standard_lib=True),sysconfig.get_python_lib(plat_specific=False,standard_lib=False),sysconfig.get_python_lib(plat_specific=True,standard_lib=False)]))"
+ # retrieve interpreter identity
+ execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -V
+ RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
+ OUTPUT_VARIABLE ${_PYTHON_PREFIX}_INTERPRETER_ID
+ ERROR_VARIABLE ${_PYTHON_PREFIX}_INTERPRETER_ID)
+ if (NOT _${_PYTHON_PREFIX}_RESULT)
+ if (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "Anaconda")
+ set (${_PYTHON_PREFIX}_INTERPRETER_ID "Anaconda")
+ elseif (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "Enthought")
+ set (${_PYTHON_PREFIX}_INTERPRETER_ID "Canopy")
+ elseif (${_PYTHON_PREFIX}_INTERPRETER_ID MATCHES "PyPy ([0-9.]+)")
+ set (${_PYTHON_PREFIX}_INTERPRETER_ID "PyPy")
+ set (${_PYTHON_PREFIX}_PyPy_VERSION "${CMAKE_MATCH_1}")
+ else()
+ string (REGEX REPLACE "^([^ ]+).*" "\\1" ${_PYTHON_PREFIX}_INTERPRETER_ID "${${_PYTHON_PREFIX}_INTERPRETER_ID}")
+ if (${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "Python")
+ # try to get a more precise ID
+ execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
+ "import sys; sys.stdout.write(sys.copyright)"
+ RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
+ OUTPUT_VARIABLE ${_PYTHON_PREFIX}_COPYRIGHT
+ ERROR_QUIET)
+ if (${_PYTHON_PREFIX}_COPYRIGHT MATCHES "ActiveState")
+ set (${_PYTHON_PREFIX}_INTERPRETER_ID "ActivePython")
+ endif()
+ endif()
+ endif()
+ else()
+ set (${_PYTHON_PREFIX}_INTERPRETER_ID Python)
+ endif()
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE _${_PYTHON_PREFIX}_LIBPATHS
- ERROR_QUIET)
- if (NOT _${_PYTHON_PREFIX}_RESULT)
- list (GET _${_PYTHON_PREFIX}_LIBPATHS 0 ${_PYTHON_PREFIX}_STDLIB)
- list (GET _${_PYTHON_PREFIX}_LIBPATHS 1 ${_PYTHON_PREFIX}_STDARCH)
- list (GET _${_PYTHON_PREFIX}_LIBPATHS 2 ${_PYTHON_PREFIX}_SITELIB)
- list (GET _${_PYTHON_PREFIX}_LIBPATHS 3 ${_PYTHON_PREFIX}_SITEARCH)
- else()
- unset (${_PYTHON_PREFIX}_STDLIB)
- unset (${_PYTHON_PREFIX}_STDARCH)
- unset (${_PYTHON_PREFIX}_SITELIB)
- unset (${_PYTHON_PREFIX}_SITEARCH)
+ # retrieve various package installation directories
+ execute_process (COMMAND ${_${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
+ "import sys\ntry:\n from distutils import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_python_lib(plat_specific=False,standard_lib=True),sysconfig.get_python_lib(plat_specific=True,standard_lib=True),sysconfig.get_python_lib(plat_specific=False,standard_lib=False),sysconfig.get_python_lib(plat_specific=True,standard_lib=False)]))\nexcept Exception:\n import sysconfig\n sys.stdout.write(';'.join([sysconfig.get_path('stdlib'),sysconfig.get_path('platstdlib'),sysconfig.get_path('purelib'),sysconfig.get_path('platlib')]))"
+ RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
+ OUTPUT_VARIABLE _${_PYTHON_PREFIX}_LIBPATHS
+ ERROR_QUIET)
+ if (NOT _${_PYTHON_PREFIX}_RESULT)
+ list (GET _${_PYTHON_PREFIX}_LIBPATHS 0 ${_PYTHON_PREFIX}_STDLIB)
+ list (GET _${_PYTHON_PREFIX}_LIBPATHS 1 ${_PYTHON_PREFIX}_STDARCH)
+ list (GET _${_PYTHON_PREFIX}_LIBPATHS 2 ${_PYTHON_PREFIX}_SITELIB)
+ list (GET _${_PYTHON_PREFIX}_LIBPATHS 3 ${_PYTHON_PREFIX}_SITEARCH)
+ else()
+ unset (${_PYTHON_PREFIX}_STDLIB)
+ unset (${_PYTHON_PREFIX}_STDARCH)
+ unset (${_PYTHON_PREFIX}_SITELIB)
+ unset (${_PYTHON_PREFIX}_SITEARCH)
+ endif()
+
+ if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR VERSION_GREATER_EQUAL "3")
+ _python_get_config_var (${_PYTHON_PREFIX}_SOABI SOABI)
+ endif()
+
+ # store properties in the cache to speed-up future searches
+ set (_${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES
+ "${${_PYTHON_PREFIX}_INTERPRETER_ID};${${_PYTHON_PREFIX}_VERSION_MAJOR};${${_PYTHON_PREFIX}_VERSION_MINOR};${${_PYTHON_PREFIX}_VERSION_PATCH};${_${_PYTHON_PREFIX}_ARCH};${_${_PYTHON_PREFIX}_ABIFLAGS};${${_PYTHON_PREFIX}_SOABI};${${_PYTHON_PREFIX}_STDLIB};${${_PYTHON_PREFIX}_STDARCH};${${_PYTHON_PREFIX}_SITELIB};${${_PYTHON_PREFIX}_SITEARCH}" CACHE INTERNAL "${_PYTHON_PREFIX} Properties")
+ else()
+ unset (_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE CACHE)
+ unset (${_PYTHON_PREFIX}_INTERPRETER_ID)
+ endif()
endif()
- else()
- unset (_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE CACHE)
- unset (${_PYTHON_PREFIX}_INTERPRETER_ID)
+ endif()
+
+ if (${_PYTHON_PREFIX}_ARTIFACTS_INTERACTIVE)
+ set (${_PYTHON_PREFIX}_EXECUTABLE "${_${_PYTHON_PREFIX}_EXECUTABLE}" CACHE FILEPATH "${_PYTHON_PREFIX} Interpreter")
endif()
_python_mark_as_internal (_${_PYTHON_PREFIX}_EXECUTABLE
+ _${_PYTHON_PREFIX}_INTERPRETER_PROPERTIES
_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE)
endif()
@@ -1310,7 +1802,10 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_COMPILER)
endif()
- if (DEFINED ${_PYTHON_PREFIX}_COMPILER
+ if (NOT "IronPython" IN_LIST _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS)
+ unset (_${_PYTHON_PREFIX}_COMPILER CACHE)
+ unset (_${_PYTHON_PREFIX}_COMPILER_SIGNATURE CACHE)
+ elseif (DEFINED ${_PYTHON_PREFIX}_COMPILER
AND IS_ABSOLUTE "${${_PYTHON_PREFIX}_COMPILER}")
set (_${_PYTHON_PREFIX}_COMPILER "${${_PYTHON_PREFIX}_COMPILER}" CACHE INTERNAL "")
elseif (DEFINED _${_PYTHON_PREFIX}_COMPILER)
@@ -1329,7 +1824,8 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
endif()
endif()
- if (NOT _${_PYTHON_PREFIX}_COMPILER)
+ if ("IronPython" IN_LIST _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS
+ AND NOT _${_PYTHON_PREFIX}_COMPILER)
# IronPython specific artifacts
# If IronPython interpreter is found, use its path
unset (_${_PYTHON_PREFIX}_IRON_ROOT)
@@ -1338,46 +1834,104 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
endif()
if (_${_PYTHON_PREFIX}_FIND_STRATEGY STREQUAL "LOCATION")
- set (_${_PYTHON_PREFIX}_REGISTRY_PATHS)
-
- foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
- # Registry Paths
- list (APPEND _${_PYTHON_PREFIX}_REGISTRY_PATHS
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath])
- endforeach()
+ _python_get_names (_${_PYTHON_PREFIX}_COMPILER_NAMES
+ IMPLEMENTATIONS IronPython
+ VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS}
+ COMPILER)
+
+ _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES
+ IMPLEMENTATIONS IronPython
+ VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS}
+ COMPILER)
+
+ _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS
+ IMPLEMENTATIONS IronPython
+ VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS})
+ _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS
+ IMPLEMENTATIONS IronPython
+ VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS})
while (TRUE)
- if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST")
+ # Apple frameworks handling
+ if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST")
+ find_program (_${_PYTHON_PREFIX}_COMPILER
+ NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES}
+ NAMES_PER_DIR
+ HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS}
+ PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
+ NO_CMAKE_PATH
+ NO_CMAKE_ENVIRONMENT_PATH
+ NO_SYSTEM_ENVIRONMENT_PATH
+ NO_CMAKE_SYSTEM_PATH)
+ _python_validate_compiler (${${_PYTHON_PREFIX}_FIND_VERSION} ${_${_PYTHON_PREFIX}_FIND_VERSION_EXACT})
+ if (_${_PYTHON_PREFIX}_COMPILER)
+ break()
+ endif()
+ endif()
+ # Windows registry
+ if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST")
find_program (_${_PYTHON_PREFIX}_COMPILER
- NAMES ipyc
+ NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES}
+ NAMES_PER_DIR
HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS}
PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH)
- _python_validate_compiler (${${_PYTHON_PREFIX}_FIND_VERSION})
+ _python_validate_compiler (${${_PYTHON_PREFIX}_FIND_VERSION} ${_${_PYTHON_PREFIX}_FIND_VERSION_EXACT})
if (_${_PYTHON_PREFIX}_COMPILER)
break()
endif()
endif()
+ # try using HINTS
find_program (_${_PYTHON_PREFIX}_COMPILER
- NAMES ipyc
+ NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES}
+ NAMES_PER_DIR
HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS}
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH)
- _python_validate_compiler (${${_PYTHON_PREFIX}_FIND_VERSION})
+ _python_validate_compiler (${${_PYTHON_PREFIX}_FIND_VERSION} ${_${_PYTHON_PREFIX}_FIND_VERSION_EXACT})
if (_${_PYTHON_PREFIX}_COMPILER)
break()
endif()
- if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
+ # try using standard paths
+ find_program (_${_PYTHON_PREFIX}_COMPILER
+ NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES}
+ NAMES_PER_DIR
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES})
+ _python_validate_compiler (${${_PYTHON_PREFIX}_FIND_VERSION} ${_${_PYTHON_PREFIX}_FIND_VERSION_EXACT})
+ if (_${_PYTHON_PREFIX}_COMPILER)
+ break()
+ endif()
+
+ # Apple frameworks handling
+ if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST")
+ find_program (_${_PYTHON_PREFIX}_COMPILER
+ NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES}
+ NAMES_PER_DIR
+ PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
+ NO_DEFAULT_PATH)
+ _python_validate_compiler (${${_PYTHON_PREFIX}_FIND_VERSION} ${_${_PYTHON_PREFIX}_FIND_VERSION_EXACT})
+ 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
- NAMES ipyc
+ NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES}
+ NAMES_PER_DIR
PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_DEFAULT_PATH)
+ if (_${_PYTHON_PREFIX}_COMPILER)
+ break()
+ endif()
endif()
break()
@@ -1385,12 +1939,48 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
else()
# try using root dir and registry
foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
- if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST")
+ _python_get_names (_${_PYTHON_PREFIX}_COMPILER_NAMES
+ IMPLEMENTATIONS IronPython
+ VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS}
+ COMPILER)
+
+ _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES
+ IMPLEMENTATIONS IronPython
+ VERSION ${_${_PYTHON_PREFIX}_FIND_VERSION}
+ COMPILER)
+
+ _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS
+ IMPLEMENTATIONS IronPython
+ VERSION ${_${_PYTHON_PREFIX}_VERSION})
+ _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS
+ IMPLEMENTATIONS IronPython
+ VERSION ${_${_PYTHON_PREFIX}_VERSION})
+
+ # Apple frameworks handling
+ if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST")
+ find_program (_${_PYTHON_PREFIX}_COMPILER
+ NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES}
+ NAMES_PER_DIR
+ HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS}
+ PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
+ NO_CMAKE_PATH
+ NO_CMAKE_ENVIRONMENT_PATH
+ NO_SYSTEM_ENVIRONMENT_PATH
+ NO_CMAKE_SYSTEM_PATH)
+ _python_validate_compiler (${_${_PYTHON_PREFIX}_VERSION} EXACT)
+ if (_${_PYTHON_PREFIX}_COMPILER)
+ break()
+ endif()
+ endif()
+ # Windows registry
+ if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST")
find_program (_${_PYTHON_PREFIX}_COMPILER
- NAMES ipyc
+ NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES}
+ NAMES_PER_DIR
HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS}
- PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
+ PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH)
_python_validate_compiler (${_${_PYTHON_PREFIX}_VERSION} EXACT)
@@ -1399,10 +1989,12 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
endif()
endif()
+ # try using HINTS
find_program (_${_PYTHON_PREFIX}_COMPILER
- NAMES ipyc
+ NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES}
+ NAMES_PER_DIR
HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS}
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH)
_python_validate_compiler (${_${_PYTHON_PREFIX}_VERSION} EXACT)
@@ -1410,11 +2002,26 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
break()
endif()
- if (_${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
+ # Apple frameworks handling
+ if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST")
find_program (_${_PYTHON_PREFIX}_COMPILER
- NAMES ipyc
- PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath]
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES}
+ NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES}
+ NAMES_PER_DIR
+ PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
+ NO_DEFAULT_PATH)
+ _python_validate_compiler (${_${_PYTHON_PREFIX}_VERSION} EXACT)
+ 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
+ NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES}
+ NAMES_PER_DIR
+ PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_DEFAULT_PATH)
_python_validate_compiler (${_${_PYTHON_PREFIX}_VERSION} EXACT)
if (_${_PYTHON_PREFIX}_COMPILER)
@@ -1424,10 +2031,18 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
endforeach()
# no specific version found, re-try in standard paths
+ _python_get_names (_${_PYTHON_PREFIX}_COMPILER_NAMES
+ IMPLEMENTATIONS IronPython
+ VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS}
+ COMPILER)
+ _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES
+ IMPLEMENTATIONS IronPython
+ VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS}
+ COMPILER)
find_program (_${_PYTHON_PREFIX}_COMPILER
- NAMES ipyc
+ NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES}
HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS}
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_IRON_PYTHON_PATH_SUFFIXES})
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES})
endif()
endif()
@@ -1435,13 +2050,18 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
if (_${_PYTHON_PREFIX}_COMPILER)
# retrieve python environment version from compiler
+ _python_get_launcher (_${_PYTHON_PREFIX}_COMPILER_LAUNCHER COMPILER)
set (_${_PYTHON_PREFIX}_VERSION_DIR "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/PythonCompilerVersion.dir")
file (WRITE "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.py" "import sys; sys.stdout.write('.'.join([str(x) for x in sys.version_info[:3]]))\n")
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_COMPILER}" /target:exe /embed "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.py"
+ execute_process (COMMAND ${_${_PYTHON_PREFIX}_COMPILER_LAUNCHER} "${_${_PYTHON_PREFIX}_COMPILER}"
+ ${_${_PYTHON_PREFIX}_IRON_PYTHON_COMPILER_ARCH_FLAGS}
+ /target:exe /embed "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.py"
WORKING_DIRECTORY "${_${_PYTHON_PREFIX}_VERSION_DIR}"
OUTPUT_QUIET
ERROR_QUIET)
- execute_process (COMMAND "${_${_PYTHON_PREFIX}_VERSION_DIR}/version"
+ get_filename_component (_${_PYTHON_PREFIX}_IR_DIR "${_${_PYTHON_PREFIX}_COMPILER}" DIRECTORY)
+ execute_process (COMMAND "${CMAKE_COMMAND}" -E env "MONO_PATH=${_${_PYTHON_PREFIX}_IR_DIR}"
+ ${${_PYTHON_PREFIX}_DOTNET_LAUNCHER} "${_${_PYTHON_PREFIX}_VERSION_DIR}/version.exe"
WORKING_DIRECTORY "${_${_PYTHON_PREFIX}_VERSION_DIR}"
RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
OUTPUT_VARIABLE _${_PYTHON_PREFIX}_VERSION
@@ -1463,6 +2083,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}\"")
endif()
file (REMOVE_RECURSE "${_${_PYTHON_PREFIX}_VERSION_DIR}")
endif()
@@ -1470,17 +2091,19 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
if (_${_PYTHON_PREFIX}_COMPILER AND _${_PYTHON_PREFIX}_COMPILER_USABLE)
if (${_PYTHON_PREFIX}_Interpreter_FOUND)
# Compiler must be compatible with interpreter
- if (${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR} VERSION_EQUAL ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR})
+ if ("${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}" VERSION_EQUAL "${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}")
set (${_PYTHON_PREFIX}_Compiler_FOUND TRUE)
endif()
elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
set (${_PYTHON_PREFIX}_Compiler_FOUND TRUE)
- # Use compiler version for future searches to ensure consistency
- set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR})
+ # Use compiler version for future searches to ensure consistency
+ set (_${_PYTHON_PREFIX}_FIND_VERSIONS ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR})
endif()
endif()
if (${_PYTHON_PREFIX}_Compiler_FOUND)
+ unset (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE)
+
# compute and save compiler signature
string (MD5 __${_PYTHON_PREFIX}_COMPILER_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_COMPILER}")
set (_${_PYTHON_PREFIX}_COMPILER_SIGNATURE "${__${_PYTHON_PREFIX}_COMPILER_SIGNATURE}" CACHE INTERNAL "")
@@ -1491,50 +2114,61 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
unset (${_PYTHON_PREFIX}_COMPILER_ID)
endif()
+ if (${_PYTHON_PREFIX}_ARTIFACTS_INTERACTIVE)
+ set (${_PYTHON_PREFIX}_COMPILER "${_${_PYTHON_PREFIX}_COMPILER}" CACHE FILEPATH "${_PYTHON_PREFIX} Compiler")
+ endif()
+
_python_mark_as_internal (_${_PYTHON_PREFIX}_COMPILER
_${_PYTHON_PREFIX}_COMPILER_SIGNATURE)
endif()
-
# third step, search for the development artifacts
+if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.Module)
+ if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS)
+ list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_LIBRARIES)
+ endif()
+ if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS)
+ list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_INCLUDE_DIRS)
+ endif()
+endif()
+if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development.Embed)
+ if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS)
+ list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_LIBRARIES)
+ endif()
+ if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_EMBED_ARTIFACTS)
+ list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_INCLUDE_DIRS)
+ endif()
+endif()
+list (REMOVE_DUPLICATES _${_PYTHON_PREFIX}_REQUIRED_VARS)
## Development environment is not compatible with IronPython interpreter
-if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
- AND NOT ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython")
+if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+ OR "Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
+ AND ((${_PYTHON_PREFIX}_Interpreter_FOUND
+ AND NOT ${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "IronPython")
+ OR NOT ${_PYTHON_PREFIX}_Interpreter_FOUND))
+ if (${_PYTHON_PREFIX}_Interpreter_FOUND)
+ # reduce possible implementations to the interpreter one
+ if (${_PYTHON_PREFIX}_INTERPRETER_ID STREQUAL "PyPy")
+ set (_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS "PyPy")
+ else()
+ set (_${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS "CPython")
+ endif()
+ else()
+ list (REMOVE_ITEM _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS "IronPython")
+ endif()
+ if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_LIBRARY_RELEASE
_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE
_${_PYTHON_PREFIX}_LIBRARY_DEBUG
- _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG
- _${_PYTHON_PREFIX}_INCLUDE_DIR)
- if (${_PYTHON_PREFIX}_FIND_REQUIRED_Development)
- list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_LIBRARIES
- ${_PYTHON_PREFIX}_INCLUDE_DIRS)
+ _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)
endif()
-
- if (DEFINED _${_PYTHON_PREFIX}_LIBRARY_RELEASE OR DEFINED _${_PYTHON_PREFIX}_INCLUDE_DIR)
- # compute development signature and check validity of definition
- string (MD5 __${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}:${_${_PYTHON_PREFIX}_INCLUDE_DIR}")
- if (WIN32 AND NOT DEFINED _${_PYTHON_PREFIX}_LIBRARY_DEBUG)
- set (_${_PYTHON_PREFIX}_LIBRARY_DEBUG "${_PYTHON_PREFIX}_LIBRARY_DEBUG-NOTFOUND" CACHE INTERNAL "")
- endif()
- if (NOT DEFINED _${_PYTHON_PREFIX}_INCLUDE_DIR)
- set (_${_PYTHON_PREFIX}_INCLUDE_DIR "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND" CACHE INTERNAL "")
- endif()
- if (__${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE STREQUAL _${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE)
- # check version validity
- if (${_PYTHON_PREFIX}_FIND_VERSION_EXACT)
- _python_validate_library (${${_PYTHON_PREFIX}_FIND_VERSION} EXACT CHECK_EXISTS)
- _python_validate_include_dir (${${_PYTHON_PREFIX}_FIND_VERSION} EXACT CHECK_EXISTS)
- else()
- _python_validate_library (${${_PYTHON_PREFIX}_FIND_VERSION} CHECK_EXISTS)
- _python_validate_include_dir (${${_PYTHON_PREFIX}_FIND_VERSION} CHECK_EXISTS)
- endif()
- else()
- unset (_${_PYTHON_PREFIX}_LIBRARY_RELEASE CACHE)
- unset (_${_PYTHON_PREFIX}_LIBRARY_DEBUG CACHE)
- unset (_${_PYTHON_PREFIX}_INCLUDE_DIR CACHE)
- unset (_${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE CACHE)
- endif()
+ if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
+ list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_INCLUDE_DIR)
endif()
+
+ _python_check_development_signature (Module)
+ _python_check_development_signature (Embed)
+
if (DEFINED ${_PYTHON_PREFIX}_LIBRARY
AND IS_ABSOLUTE "${${_PYTHON_PREFIX}_LIBRARY}")
set (_${_PYTHON_PREFIX}_LIBRARY_RELEASE "${${_PYTHON_PREFIX}_LIBRARY}" CACHE INTERNAL "")
@@ -1561,25 +2195,18 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
# if python interpreter is found, use it to look-up for artifacts
# to ensure consistency between interpreter and development environments.
# If not, try to locate a compatible config tool
- if (NOT ${_PYTHON_PREFIX}_Interpreter_FOUND OR CMAKE_CROSSCOMPILING)
+ if ((NOT ${_PYTHON_PREFIX}_Interpreter_FOUND OR CMAKE_CROSSCOMPILING)
+ AND "CPython" IN_LIST _${_PYTHON_PREFIX}_FIND_IMPLEMENTATIONS)
set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR)
unset (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS)
if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$")
- set (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS ENV VIRTUAL_ENV)
+ set (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS ENV VIRTUAL_ENV ENV CONDA_PREFIX)
endif()
- unset (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS)
if (_${_PYTHON_PREFIX}_FIND_STRATEGY STREQUAL "LOCATION")
- set (_${_PYTHON_PREFIX}_CONFIG_NAMES)
-
- foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
- _python_get_names (_${_PYTHON_PREFIX}_VERSION_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} POSIX CONFIG)
- list (APPEND _${_PYTHON_PREFIX}_CONFIG_NAMES ${_${_PYTHON_PREFIX}_VERSION_NAMES})
-
+ _python_get_names (_${_PYTHON_PREFIX}_CONFIG_NAMES VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS} POSIX CONFIG)
# Framework Paths
- _python_get_frameworks (_${_PYTHON_PREFIX}_VERSION_PATHS ${_${_PYTHON_PREFIX}_VERSION})
- list (APPEND _${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION_PATHS})
- endforeach()
+ _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS})
# Apple frameworks handling
if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST")
@@ -1663,7 +2290,7 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
_python_get_names (_${_PYTHON_PREFIX}_CONFIG_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} POSIX CONFIG)
# Framework Paths
- _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION})
+ _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS VERSION ${_${_PYTHON_PREFIX}_VERSION})
# Apple frameworks handling
if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST")
@@ -1756,140 +2383,61 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
endif()
endif()
- if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
- if ((${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT CMAKE_CROSSCOMPILING) OR _${_PYTHON_PREFIX}_CONFIG)
- # retrieve root install directory
- _python_get_config_var (_${_PYTHON_PREFIX}_PREFIX PREFIX)
-
- # enforce current ABI
- _python_get_config_var (_${_PYTHON_PREFIX}_ABIFLAGS ABIFLAGS)
-
- set (_${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_PREFIX}")
-
- # retrieve library
- ## compute some paths and artifact names
- if (_${_PYTHON_PREFIX}_CONFIG)
- string (REGEX REPLACE "^.+python([0-9.]+)[a-z]*-config" "\\1" _${_PYTHON_PREFIX}_VERSION "${_${_PYTHON_PREFIX}_CONFIG}")
- else()
- set (_${_PYTHON_PREFIX}_VERSION "${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}")
- endif()
- _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_VERSION} LIBRARY)
- _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} WIN32 POSIX LIBRARY)
-
- _python_get_config_var (_${_PYTHON_PREFIX}_CONFIGDIR CONFIGDIR)
- list (APPEND _${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_CONFIGDIR}")
-
- list (APPEND _${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR)
-
- find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
- NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
- NAMES_PER_DIR
- HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
- NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- endif()
-
- # Rely on HINTS and standard paths if interpreter or config tool failed to locate artifacts
+ if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
- set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR)
+ if ((${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT CMAKE_CROSSCOMPILING) OR _${_PYTHON_PREFIX}_CONFIG)
+ # retrieve root install directory
+ _python_get_config_var (_${_PYTHON_PREFIX}_PREFIX PREFIX)
- unset (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS)
- if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$")
- set (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS ENV VIRTUAL_ENV)
- endif()
+ # enforce current ABI
+ _python_get_config_var (_${_PYTHON_PREFIX}_ABIFLAGS ABIFLAGS)
- if (_${_PYTHON_PREFIX}_FIND_STRATEGY STREQUAL "LOCATION")
- unset (_${_PYTHON_PREFIX}_LIB_NAMES)
- unset (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG)
- unset (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS)
- unset (_${_PYTHON_PREFIX}_REGISTRY_PATHS)
- unset (_${_PYTHON_PREFIX}_PATH_SUFFIXES)
-
- foreach (_${_PYTHON_PREFIX}_LIB_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
- # library names
- _python_get_names (_${_PYTHON_PREFIX}_VERSION_NAMES VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} WIN32 POSIX LIBRARY)
- list (APPEND _${_PYTHON_PREFIX}_LIB_NAMES ${_${_PYTHON_PREFIX}_VERSION_NAMES})
- _python_get_names (_${_PYTHON_PREFIX}_VERSION_NAMES VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} WIN32 DEBUG)
- list (APPEND _${_PYTHON_PREFIX}_LIB_NAMES_DEBUG ${_${_PYTHON_PREFIX}_VERSION_NAMES})
-
- # Framework Paths
- _python_get_frameworks (_${_PYTHON_PREFIX}_VERSION_PATHS ${_${_PYTHON_PREFIX}_LIB_VERSION})
- list (APPEND _${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION_PATHS})
-
- # Registry Paths
- _python_get_registries (_${_PYTHON_PREFIX}_VERSION_PATHS ${_${_PYTHON_PREFIX}_LIB_VERSION})
- list (APPEND _${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_VERSION_PATHS})
-
- # Paths suffixes
- _python_get_path_suffixes (_${_PYTHON_PREFIX}_VERSION_PATHS VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} LIBRARY)
- list (APPEND _${_PYTHON_PREFIX}_PATH_SUFFIXES ${_${_PYTHON_PREFIX}_VERSION_PATHS})
- endforeach()
+ set (_${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_PREFIX}")
- if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST")
- find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
- NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
- NAMES_PER_DIR
- HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
- ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
- NO_CMAKE_PATH
- NO_CMAKE_ENVIRONMENT_PATH
- NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
+ # retrieve library
+ ## compute some paths and artifact names
+ if (_${_PYTHON_PREFIX}_CONFIG)
+ string (REGEX REPLACE "^.+python([0-9.]+)[a-z]*-config" "\\1" _${_PYTHON_PREFIX}_VERSION "${_${_PYTHON_PREFIX}_CONFIG}")
+ else()
+ set (_${_PYTHON_PREFIX}_VERSION "${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}")
endif()
+ _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_VERSION} LIBRARY)
+ _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} WIN32 POSIX LIBRARY)
- if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST")
- find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
- NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
- NAMES_PER_DIR
- HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
- ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
- NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- endif()
+ _python_get_config_var (_${_PYTHON_PREFIX}_CONFIGDIR CONFIGDIR)
+ list (APPEND _${_PYTHON_PREFIX}_HINTS "${_${_PYTHON_PREFIX}_CONFIGDIR}")
+
+ list (APPEND _${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR)
- # search in HINTS locations
find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
NAMES_PER_DIR
HINTS ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH)
+ endif()
- if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST")
- set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS})
- else()
- unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS)
- endif()
+ # Rely on HINTS and standard paths if interpreter or config tool failed to locate artifacts
+ if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
+ set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR)
- if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
- set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS})
- else()
- unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS)
+ unset (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS)
+ if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$")
+ set (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS ENV VIRTUAL_ENV ENV CONDA_PREFIX)
endif()
- # search in all default paths
- find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
- NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
- NAMES_PER_DIR
- PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
- ${__${_PYTHON_PREFIX}_REGISTRY_PATHS}
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES})
- else()
- foreach (_${_PYTHON_PREFIX}_LIB_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
- _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} WIN32 POSIX LIBRARY)
- _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} WIN32 DEBUG)
-
- _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_LIB_VERSION})
- _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_LIB_VERSION})
+ if (_${_PYTHON_PREFIX}_FIND_STRATEGY STREQUAL "LOCATION")
+ # library names
+ _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS} WIN32 POSIX LIBRARY)
+ _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS} WIN32 DEBUG)
+ # Paths suffixes
+ _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS} LIBRARY)
- _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} LIBRARY)
+ # Framework Paths
+ _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS VERSION ${_${_PYTHON_PREFIX}_LIB_FIND_VERSIONS})
+ # Registry Paths
+ _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS} )
if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST")
find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
@@ -1927,182 +2475,282 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH)
- if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST")
- set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS})
- else()
- unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS)
- endif()
+ if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST")
+ set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS})
+ else()
+ unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS)
+ endif()
- if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
- set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS})
- else()
- unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS)
- endif()
+ if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
+ set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS})
+ else()
+ unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS)
+ endif()
- # search in all default paths
- find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
+ # search in all default paths
+ find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
NAMES_PER_DIR
PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
${__${_PYTHON_PREFIX}_REGISTRY_PATHS}
PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES})
+ else()
+ foreach (_${_PYTHON_PREFIX}_LIB_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
+ _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} WIN32 POSIX LIBRARY)
+ _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} WIN32 DEBUG)
+
+ _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION})
+ _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION})
+
+ _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_LIB_VERSION} LIBRARY)
+
+ if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST")
+ find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
+ NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
+ NAMES_PER_DIR
+ HINTS ${_${_PYTHON_PREFIX}_HINTS}
+ PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
+ ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
+ NO_CMAKE_PATH
+ NO_CMAKE_ENVIRONMENT_PATH
+ NO_SYSTEM_ENVIRONMENT_PATH
+ NO_CMAKE_SYSTEM_PATH)
+ endif()
- if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE)
- break()
- endif()
- endforeach()
+ if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST")
+ find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
+ NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
+ NAMES_PER_DIR
+ HINTS ${_${_PYTHON_PREFIX}_HINTS}
+ PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
+ ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
+ NO_SYSTEM_ENVIRONMENT_PATH
+ NO_CMAKE_SYSTEM_PATH)
+ endif()
+
+ # search in HINTS locations
+ find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
+ NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
+ NAMES_PER_DIR
+ HINTS ${_${_PYTHON_PREFIX}_HINTS}
+ PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
+ NO_SYSTEM_ENVIRONMENT_PATH
+ NO_CMAKE_SYSTEM_PATH)
+
+ if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST")
+ set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS})
+ else()
+ unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS)
+ endif()
+
+ if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
+ set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS})
+ else()
+ unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS)
+ endif()
+
+ # search in all default paths
+ find_library (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
+ NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
+ NAMES_PER_DIR
+ PATHS ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
+ ${__${_PYTHON_PREFIX}_REGISTRY_PATHS}
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES})
+
+ if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE)
+ break()
+ endif()
+ endforeach()
+ endif()
endif()
endif()
- endif()
- # finalize library version information
- _python_get_version (LIBRARY PREFIX _${_PYTHON_PREFIX}_)
+ # finalize library version information
+ _python_get_version (LIBRARY PREFIX _${_PYTHON_PREFIX}_)
+ if (_${_PYTHON_PREFIX}_VERSION EQUAL "${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}")
+ # not able to extract full version from library name
+ if (${_PYTHON_PREFIX}_Interpreter_FOUND)
+ # update from interpreter
+ set (_${_PYTHON_PREFIX}_VERSION ${${_PYTHON_PREFIX}_VERSION})
+ set (_${_PYTHON_PREFIX}_VERSION_MAJOR ${${_PYTHON_PREFIX}_VERSION_MAJOR})
+ set (_${_PYTHON_PREFIX}_VERSION_MINOR ${${_PYTHON_PREFIX}_VERSION_MINOR})
+ set (_${_PYTHON_PREFIX}_VERSION_PATCH ${${_PYTHON_PREFIX}_VERSION_PATCH})
+ endif()
+ endif()
- set (${_PYTHON_PREFIX}_LIBRARY_RELEASE "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}")
+ set (${_PYTHON_PREFIX}_LIBRARY_RELEASE "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}")
- if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE AND NOT EXISTS "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}")
- set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND")
- endif()
+ 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}_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND")
+ endif()
- set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR)
-
- if (WIN32 AND _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
- # search for debug library
- # use release library location as a hint
- _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG VERSION ${_${_PYTHON_PREFIX}_VERSION} WIN32 DEBUG)
- get_filename_component (_${_PYTHON_PREFIX}_PATH "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY)
- find_library (_${_PYTHON_PREFIX}_LIBRARY_DEBUG
- NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG}
- NAMES_PER_DIR
- HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS}
- NO_DEFAULT_PATH)
- endif()
-
- # retrieve runtime libraries
- if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE)
- _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} WIN32 POSIX LIBRARY)
- get_filename_component (_${_PYTHON_PREFIX}_PATH "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY)
- get_filename_component (_${_PYTHON_PREFIX}_PATH2 "${_${_PYTHON_PREFIX}_PATH}" DIRECTORY)
- _python_find_runtime_library (_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE
- NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
- NAMES_PER_DIR
- HINTS "${_${_PYTHON_PREFIX}_PATH}" "${_${_PYTHON_PREFIX}_PATH2}" ${_${_PYTHON_PREFIX}_HINTS}
- PATH_SUFFIXES bin)
- endif()
- if (_${_PYTHON_PREFIX}_LIBRARY_DEBUG)
- _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG VERSION ${_${_PYTHON_PREFIX}_VERSION} WIN32 DEBUG)
- get_filename_component (_${_PYTHON_PREFIX}_PATH "${_${_PYTHON_PREFIX}_LIBRARY_DEBUG}" DIRECTORY)
- get_filename_component (_${_PYTHON_PREFIX}_PATH2 "${_${_PYTHON_PREFIX}_PATH}" DIRECTORY)
- _python_find_runtime_library (_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG
- NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG}
- NAMES_PER_DIR
- HINTS "${_${_PYTHON_PREFIX}_PATH}" "${_${_PYTHON_PREFIX}_PATH2}" ${_${_PYTHON_PREFIX}_HINTS}
- PATH_SUFFIXES bin)
- endif()
-
- # Don't search for include dir if no library was founded
- if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE AND NOT _${_PYTHON_PREFIX}_INCLUDE_DIR)
- if ((${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT CMAKE_CROSSCOMPILING) OR _${_PYTHON_PREFIX}_CONFIG)
- _python_get_config_var (_${_PYTHON_PREFIX}_INCLUDE_DIRS INCLUDES)
+ set (_${_PYTHON_PREFIX}_HINTS "${${_PYTHON_PREFIX}_ROOT_DIR}" ENV ${_PYTHON_PREFIX}_ROOT_DIR)
- find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR
- NAMES Python.h
- HINTS ${_${_PYTHON_PREFIX}_INCLUDE_DIRS}
- NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
+ if (WIN32 AND _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
+ # search for debug library
+ # use release library location as a hint
+ _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG VERSION ${_${_PYTHON_PREFIX}_VERSION} WIN32 DEBUG)
+ get_filename_component (_${_PYTHON_PREFIX}_PATH "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY)
+ find_library (_${_PYTHON_PREFIX}_LIBRARY_DEBUG
+ NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG}
+ NAMES_PER_DIR
+ HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS}
+ NO_DEFAULT_PATH)
endif()
- # Rely on HINTS and standard paths if interpreter or config tool failed to locate artifacts
- if (NOT _${_PYTHON_PREFIX}_INCLUDE_DIR)
- unset (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS)
- if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$")
- set (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS ENV VIRTUAL_ENV)
- endif()
- unset (_${_PYTHON_PREFIX}_INCLUDE_HINTS)
-
- # Use the library's install prefix as a hint
- if (${_${_PYTHON_PREFIX}_LIBRARY_RELEASE} MATCHES "^(.+/Frameworks/Python.framework/Versions/[0-9.]+)")
- list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}")
- elseif (${_${_PYTHON_PREFIX}_LIBRARY_RELEASE} MATCHES "^(.+)/lib(64|32)?/python[0-9.]+/config")
- list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}")
- elseif (DEFINED CMAKE_LIBRARY_ARCHITECTURE AND ${_${_PYTHON_PREFIX}_LIBRARY_RELEASE} MATCHES "^(.+)/lib/${CMAKE_LIBRARY_ARCHITECTURE}")
- list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}")
- else()
- # assume library is in a directory under root
- get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY)
- get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${_${_PYTHON_PREFIX}_PREFIX}" DIRECTORY)
- list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${_${_PYTHON_PREFIX}_PREFIX}")
+ # retrieve runtime libraries
+ if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE)
+ _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES VERSION ${_${_PYTHON_PREFIX}_VERSION} WIN32 POSIX LIBRARY)
+ get_filename_component (_${_PYTHON_PREFIX}_PATH "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY)
+ get_filename_component (_${_PYTHON_PREFIX}_PATH2 "${_${_PYTHON_PREFIX}_PATH}" DIRECTORY)
+ _python_find_runtime_library (_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE
+ NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES}
+ NAMES_PER_DIR
+ HINTS "${_${_PYTHON_PREFIX}_PATH}"
+ "${_${_PYTHON_PREFIX}_PATH2}" ${_${_PYTHON_PREFIX}_HINTS}
+ PATH_SUFFIXES bin)
+ endif()
+ if (_${_PYTHON_PREFIX}_LIBRARY_DEBUG)
+ _python_get_names (_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG VERSION ${_${_PYTHON_PREFIX}_VERSION} WIN32 DEBUG)
+ get_filename_component (_${_PYTHON_PREFIX}_PATH "${_${_PYTHON_PREFIX}_LIBRARY_DEBUG}" DIRECTORY)
+ get_filename_component (_${_PYTHON_PREFIX}_PATH2 "${_${_PYTHON_PREFIX}_PATH}" DIRECTORY)
+ _python_find_runtime_library (_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG
+ NAMES ${_${_PYTHON_PREFIX}_LIB_NAMES_DEBUG}
+ NAMES_PER_DIR
+ HINTS "${_${_PYTHON_PREFIX}_PATH}"
+ "${_${_PYTHON_PREFIX}_PATH2}" ${_${_PYTHON_PREFIX}_HINTS}
+ PATH_SUFFIXES bin)
+ endif()
+ endif()
+
+ 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
+ AND NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
+ # Don't search for include dir if no library was founded
+ break()
endif()
- _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION})
- _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_VERSION})
- _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_VERSION} INCLUDE)
+ if ((${_PYTHON_PREFIX}_Interpreter_FOUND AND NOT CMAKE_CROSSCOMPILING) OR _${_PYTHON_PREFIX}_CONFIG)
+ _python_get_config_var (_${_PYTHON_PREFIX}_INCLUDE_DIRS INCLUDES)
- if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST")
find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR
- NAMES Python.h
- HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
- ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
- NO_CMAKE_PATH
- NO_CMAKE_ENVIRONMENT_PATH
+ NAMES ${_${_PYTHON_PREFIX}_INCLUDE_NAMES}
+ HINTS ${_${_PYTHON_PREFIX}_INCLUDE_DIRS}
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH)
endif()
- if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST")
+ # Rely on HINTS and standard paths if interpreter or config tool failed to locate artifacts
+ if (NOT _${_PYTHON_PREFIX}_INCLUDE_DIR)
+ unset (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS)
+ if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$")
+ set (_${_PYTHON_PREFIX}_VIRTUALENV_PATHS ENV VIRTUAL_ENV ENV CONDA_PREFIX)
+ endif()
+ unset (_${_PYTHON_PREFIX}_INCLUDE_HINTS)
+
+ if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE)
+ # Use the library's install prefix as a hint
+ if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "^(.+/Frameworks/Python.framework/Versions/[0-9.]+)")
+ list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}")
+ elseif (_${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "^(.+)/lib(64|32)?/python[0-9.]+/config")
+ list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}")
+ elseif (DEFINED CMAKE_LIBRARY_ARCHITECTURE AND ${_${_PYTHON_PREFIX}_LIBRARY_RELEASE} MATCHES "^(.+)/lib/${CMAKE_LIBRARY_ARCHITECTURE}")
+ list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${CMAKE_MATCH_1}")
+ else()
+ # assume library is in a directory under root
+ get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" DIRECTORY)
+ get_filename_component (_${_PYTHON_PREFIX}_PREFIX "${_${_PYTHON_PREFIX}_PREFIX}" DIRECTORY)
+ list (APPEND _${_PYTHON_PREFIX}_INCLUDE_HINTS "${_${_PYTHON_PREFIX}_PREFIX}")
+ endif()
+ endif()
+
+ _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS VERSION ${_${_PYTHON_PREFIX}_VERSION})
+ _python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS VERSION ${_${_PYTHON_PREFIX}_VERSION})
+ _python_get_path_suffixes (_${_PYTHON_PREFIX}_PATH_SUFFIXES VERSION ${_${_PYTHON_PREFIX}_VERSION} INCLUDE)
+
+ if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST")
+ find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR
+ NAMES ${_${_PYTHON_PREFIX}_INCLUDE_NAMES}
+ HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS}
+ PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
+ ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
+ NO_CMAKE_PATH
+ NO_CMAKE_ENVIRONMENT_PATH
+ NO_SYSTEM_ENVIRONMENT_PATH
+ NO_CMAKE_SYSTEM_PATH)
+ endif()
+
+ if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST")
+ find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR
+ NAMES ${_${_PYTHON_PREFIX}_INCLUDE_NAMES}
+ HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS}
+ PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
+ ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
+ NO_SYSTEM_ENVIRONMENT_PATH
+ NO_CMAKE_SYSTEM_PATH)
+ endif()
+
+ if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST")
+ set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS})
+ else()
+ unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS)
+ endif()
+
+ if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
+ set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS})
+ else()
+ unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS)
+ endif()
+
find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR
- NAMES Python.h
+ NAMES ${_${_PYTHON_PREFIX}_INCLUDE_NAMES}
HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS}
PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
- ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
+ ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
+ ${__${_PYTHON_PREFIX}_REGISTRY_PATHS}
PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH)
endif()
- if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST")
- set (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS})
- else()
- unset (__${_PYTHON_PREFIX}_FRAMEWORK_PATHS)
- endif()
-
- if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
- set (__${_PYTHON_PREFIX}_REGISTRY_PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS})
- else()
- unset (__${_PYTHON_PREFIX}_REGISTRY_PATHS)
- endif()
-
+ # search header file in standard locations
find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR
- NAMES Python.h
- HINTS ${_${_PYTHON_PREFIX}_INCLUDE_HINTS} ${_${_PYTHON_PREFIX}_HINTS}
- PATHS ${_${_PYTHON_PREFIX}_VIRTUALENV_PATHS}
- ${__${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
- ${__${_PYTHON_PREFIX}_REGISTRY_PATHS}
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
- NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- endif()
-
- # search header file in standard locations
- find_path (_${_PYTHON_PREFIX}_INCLUDE_DIR
- NAMES Python.h)
- endif()
+ NAMES ${_${_PYTHON_PREFIX}_INCLUDE_NAMES})
- set (${_PYTHON_PREFIX}_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}")
+ break()
+ endwhile()
- if (_${_PYTHON_PREFIX}_INCLUDE_DIR AND NOT EXISTS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}")
- set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND")
- endif()
+ set (${_PYTHON_PREFIX}_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}")
- if (_${_PYTHON_PREFIX}_INCLUDE_DIR)
- # retrieve version from header file
- _python_get_version (INCLUDE PREFIX _${_PYTHON_PREFIX}_INC_)
+ 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}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND")
+ endif()
- # update versioning
- if (_${_PYTHON_PREFIX}_INC_VERSION VERSION_EQUAL ${_${_PYTHON_PREFIX}_VERSION})
- set (_${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_INC_VERSION_PATCH})
+ if (_${_PYTHON_PREFIX}_INCLUDE_DIR)
+ # retrieve version from header file
+ _python_get_version (INCLUDE PREFIX _${_PYTHON_PREFIX}_INC_)
+
+ if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE)
+ if ("${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_INC_VERSION_MINOR}"
+ VERSION_EQUAL _${_PYTHON_PREFIX}_VERSION)
+ # update versioning
+ set (_${_PYTHON_PREFIX}_VERSION ${_${_PYTHON_PREFIX}_INC_VERSION})
+ set (_${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_INC_VERSION_PATCH})
+ endif()
+ else()
+ set (_${_PYTHON_PREFIX}_VERSION ${_${_PYTHON_PREFIX}_INC_VERSION})
+ set (_${_PYTHON_PREFIX}_VERSION_MAJOR ${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR})
+ set (_${_PYTHON_PREFIX}_VERSION_MINOR ${_${_PYTHON_PREFIX}_INC_VERSION_MINOR})
+ set (_${_PYTHON_PREFIX}_VERSION_PATCH ${_${_PYTHON_PREFIX}_INC_VERSION_PATCH})
+ endif()
endif()
endif()
@@ -2115,82 +2763,125 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
endif()
# define public variables
- set (${_PYTHON_PREFIX}_LIBRARY_DEBUG "${_${_PYTHON_PREFIX}_LIBRARY_DEBUG}")
- _python_select_library_configurations (${_PYTHON_PREFIX})
+ if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
+ set (${_PYTHON_PREFIX}_LIBRARY_DEBUG "${_${_PYTHON_PREFIX}_LIBRARY_DEBUG}")
+ _python_select_library_configurations (${_PYTHON_PREFIX})
- set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE "${_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}")
- set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG "${_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}")
+ set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE "${_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}")
+ set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG "${_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}")
- if (_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE)
- set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}")
- elseif (_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)
- set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}")
- else()
- set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${_PYTHON_PREFIX}_RUNTIME_LIBRARY-NOTFOUND")
- endif()
-
- _python_set_library_dirs (${_PYTHON_PREFIX}_LIBRARY_DIRS
- _${_PYTHON_PREFIX}_LIBRARY_RELEASE _${_PYTHON_PREFIX}_LIBRARY_DEBUG)
- if (UNIX)
- if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$")
- set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DIRS ${${_PYTHON_PREFIX}_LIBRARY_DIRS})
+ if (_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE)
+ set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}")
+ elseif (_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)
+ set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG}")
+ else()
+ set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY "${_PYTHON_PREFIX}_RUNTIME_LIBRARY-NOTFOUND")
endif()
- else()
+
+ _python_set_library_dirs (${_PYTHON_PREFIX}_LIBRARY_DIRS
+ _${_PYTHON_PREFIX}_LIBRARY_RELEASE
+ _${_PYTHON_PREFIX}_LIBRARY_DEBUG)
+ if (UNIX)
+ if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$")
+ set (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DIRS ${${_PYTHON_PREFIX}_LIBRARY_DIRS})
+ endif()
+ else()
_python_set_library_dirs (${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DIRS
- _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)
+ _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE
+ _${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG)
+ endif()
endif()
- if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE AND _${_PYTHON_PREFIX}_INCLUDE_DIR)
+ if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE OR _${_PYTHON_PREFIX}_INCLUDE_DIR)
if (${_PYTHON_PREFIX}_Interpreter_FOUND OR ${_PYTHON_PREFIX}_Compiler_FOUND)
# development environment must be compatible with interpreter/compiler
- if (${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR} VERSION_EQUAL ${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}
- AND ${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_INC_VERSION_MINOR} VERSION_EQUAL ${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR})
- set (${_PYTHON_PREFIX}_Development_FOUND TRUE)
+ if ("${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}" VERSION_EQUAL "${${_PYTHON_PREFIX}_VERSION_MAJOR}.${${_PYTHON_PREFIX}_VERSION_MINOR}"
+ AND "${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_INC_VERSION_MINOR}" VERSION_EQUAL "${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}")
+ _python_set_development_module_found (Module)
+ _python_set_development_module_found (Embed)
endif()
elseif (${_PYTHON_PREFIX}_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR
- AND ${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_INC_VERSION_MINOR} VERSION_EQUAL ${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR})
- set (${_PYTHON_PREFIX}_Development_FOUND TRUE)
+ AND "${_${_PYTHON_PREFIX}_INC_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_INC_VERSION_MINOR}" VERSION_EQUAL "${_${_PYTHON_PREFIX}_VERSION_MAJOR}.${_${_PYTHON_PREFIX}_VERSION_MINOR}")
+ _python_set_development_module_found (Module)
+ _python_set_development_module_found (Embed)
endif()
if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND
(NOT _${_PYTHON_PREFIX}_ABI IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS
OR NOT _${_PYTHON_PREFIX}_INC_ABI IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS))
- set (${_PYTHON_PREFIX}_Development_FOUND FALSE)
+ set (${_PYTHON_PREFIX}_Development.Module_FOUND FALSE)
+ set (${_PYTHON_PREFIX}_Development.Embed_FOUND FALSE)
endif()
endif()
- if (${_PYTHON_PREFIX}_Development_FOUND)
- # compute and save development signature
- string (MD5 __${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}:${_${_PYTHON_PREFIX}_INCLUDE_DIR}")
- set (_${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE "${__${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE}" CACHE INTERNAL "")
- else()
- unset (_${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE CACHE)
+ if (( ${_PYTHON_PREFIX}_Development.Module_FOUND
+ AND ${_PYTHON_PREFIX}_Development.Embed_FOUND)
+ OR (NOT "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)
endif()
+ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+ AND ${_PYTHON_PREFIX}_Development.Module_FOUND
+ AND ${_PYTHON_PREFIX}_Development.Embed_FOUND)
+ set (${_PYTHON_PREFIX}_Development_FOUND TRUE)
+ endif()
+
+ if ((${_PYTHON_PREFIX}_Development.Module_FOUND
+ OR ${_PYTHON_PREFIX}_Development.Embed_FOUND)
+ AND EXISTS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}/PyPy.h")
+ # retrieve PyPy version
+ file (STRINGS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}/patchlevel.h" ${_PYTHON_PREFIX}_PyPy_VERSION
+ REGEX "^#define[ \t]+PYPY_VERSION[ \t]+\"[^\"]+\"")
+ string (REGEX REPLACE "^#define[ \t]+PYPY_VERSION[ \t]+\"([^\"]+)\".*" "\\1"
+ ${_PYTHON_PREFIX}_PyPy_VERSION "${${_PYTHON_PREFIX}_PyPy_VERSION}")
+ endif()
+
+ if (_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR VERSION_GREATER_EQUAL "3"
+ AND NOT DEFINED ${_PYTHON_PREFIX}_SOABI)
+ _python_get_config_var (${_PYTHON_PREFIX}_SOABI SOABI)
+ endif()
+
+ _python_compute_development_signature (Module)
+ _python_compute_development_signature (Embed)
+
# Restore the original find library ordering
if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES)
set (CMAKE_FIND_LIBRARY_SUFFIXES ${_${_PYTHON_PREFIX}_CMAKE_FIND_LIBRARY_SUFFIXES})
endif()
+ if (${_PYTHON_PREFIX}_ARTIFACTS_INTERACTIVE)
+ if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
+ set (${_PYTHON_PREFIX}_LIBRARY "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}" CACHE FILEPATH "${_PYTHON_PREFIX} Library")
+ endif()
+ if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
+ set (${_PYTHON_PREFIX}_INCLUDE_DIR "${_${_PYTHON_PREFIX}_INCLUDE_DIR}" CACHE FILEPATH "${_PYTHON_PREFIX} Include Directory")
+ endif()
+ endif()
+
_python_mark_as_internal (_${_PYTHON_PREFIX}_LIBRARY_RELEASE
_${_PYTHON_PREFIX}_LIBRARY_DEBUG
_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE
_${_PYTHON_PREFIX}_RUNTIME_LIBRARY_DEBUG
_${_PYTHON_PREFIX}_INCLUDE_DIR
- _${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE)
+ _${_PYTHON_PREFIX}_CONFIG
+ _${_PYTHON_PREFIX}_DEVELOPMENT_MODULE_SIGNATURE
+ _${_PYTHON_PREFIX}_DEVELOPMENT_EMBED_SIGNATURE)
endif()
+if (${_PYTHON_PREFIX}_FIND_REQUIRED_NumPy)
+ list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_NumPy_INCLUDE_DIRS)
+endif()
if ("NumPy" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_Interpreter_FOUND)
list (APPEND _${_PYTHON_PREFIX}_CACHED_VARS _${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR)
- if (${_PYTHON_PREFIX}_FIND_REQUIRED_NumPy)
- list (APPEND _${_PYTHON_PREFIX}_REQUIRED_VARS ${_PYTHON_PREFIX}_NumPy_INCLUDE_DIRS)
- endif()
if (DEFINED ${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR
AND IS_ABSOLUTE "${${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}")
set (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR "${${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}" CACHE INTERNAL "")
elseif (DEFINED _${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR)
# compute numpy signature. Depends on interpreter and development signatures
- string (MD5 __${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}:${_${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE}:${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}")
+ string (MD5 __${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}:${_${_PYTHON_PREFIX}_DEVELOPMENT_MODULE_SIGNATURE}:${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}")
if (NOT __${_PYTHON_PREFIX}_NUMPY_SIGNATURE STREQUAL _${_PYTHON_PREFIX}_NUMPY_SIGNATURE
OR NOT EXISTS "${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}")
unset (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR CACHE)
@@ -2199,13 +2890,12 @@ if ("NumPy" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_Inte
endif()
if (NOT _${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR)
- execute_process(
- COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c
- "from __future__ import print_function\ntry: import numpy; print(numpy.get_include(), end='')\nexcept:pass\n"
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE _${_PYTHON_PREFIX}_NumPy_PATH
- ERROR_QUIET
- OUTPUT_STRIP_TRAILING_WHITESPACE)
+ execute_process(COMMAND ${${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
+ "import sys\ntry: import numpy; sys.stdout.write(numpy.get_include())\nexcept:pass\n"
+ RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
+ OUTPUT_VARIABLE _${_PYTHON_PREFIX}_NumPy_PATH
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
if (NOT _${_PYTHON_PREFIX}_RESULT)
find_path (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR
@@ -2218,35 +2908,41 @@ 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_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR-NOTFOUND")
endif()
if (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR)
- execute_process (
- COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c
- "from __future__ import print_function\ntry: import numpy; print(numpy.__version__, end='')\nexcept:pass\n"
- RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
- OUTPUT_VARIABLE _${_PYTHON_PREFIX}_NumPy_VERSION)
+ execute_process (COMMAND ${${_PYTHON_PREFIX}_INTERPRETER_LAUNCHER} "${_${_PYTHON_PREFIX}_EXECUTABLE}" -c
+ "import sys\ntry: import numpy; sys.stdout.write(numpy.__version__)\nexcept:pass\n"
+ RESULT_VARIABLE _${_PYTHON_PREFIX}_RESULT
+ OUTPUT_VARIABLE _${_PYTHON_PREFIX}_NumPy_VERSION)
if (NOT _${_PYTHON_PREFIX}_RESULT)
set (${_PYTHON_PREFIX}_NumPy_VERSION "${_${_PYTHON_PREFIX}_NumPy_VERSION}")
else()
unset (${_PYTHON_PREFIX}_NumPy_VERSION)
endif()
- # final step: set NumPy founded only if Development component is founded as well
- set(${_PYTHON_PREFIX}_NumPy_FOUND ${${_PYTHON_PREFIX}_Development_FOUND})
+ # final step: set NumPy founded only if Development.Module component is founded as well
+ set(${_PYTHON_PREFIX}_NumPy_FOUND ${${_PYTHON_PREFIX}_Development.Module_FOUND})
else()
set (${_PYTHON_PREFIX}_NumPy_FOUND FALSE)
endif()
if (${_PYTHON_PREFIX}_NumPy_FOUND)
+ unset (_${_PYTHON_PREFIX}_NumPy_REASON_FAILURE)
+
# compute and save numpy signature
- string (MD5 __${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}:${_${_PYTHON_PREFIX}_DEVELOPMENT_SIGNATURE}:${${_PYTHON_PREFIX}_NumPyINCLUDE_DIR}")
+ string (MD5 __${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}:${_${_PYTHON_PREFIX}_DEVELOPMENT_MODULE_SIGNATURE}:${${_PYTHON_PREFIX}_NumPyINCLUDE_DIR}")
set (_${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${__${_PYTHON_PREFIX}_NUMPY_SIGNATURE}" CACHE INTERNAL "")
else()
unset (_${_PYTHON_PREFIX}_NUMPY_SIGNATURE CACHE)
endif()
+ if (${_PYTHON_PREFIX}_ARTIFACTS_INTERACTIVE)
+ set (${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR "${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}" CACHE FILEPATH "${_PYTHON_PREFIX} NumPy Include Directory")
+ endif()
+
_python_mark_as_internal (_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR
_${_PYTHON_PREFIX}_NUMPY_SIGNATURE)
endif()
@@ -2257,11 +2953,20 @@ if (${_PYTHON_PREFIX}_VERSION_MAJOR AND
_python_display_failure ("Could NOT find ${_PYTHON_PREFIX}: Found unsuitable major version \"${${_PYTHON_PREFIX}_VERSION_MAJOR}\", but required major version is exact version \"${_${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR}\"")
endif()
+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)
+ endif()
+endforeach()
+
include (${CMAKE_CURRENT_LIST_DIR}/../FindPackageHandleStandardArgs.cmake)
find_package_handle_standard_args (${_PYTHON_PREFIX}
REQUIRED_VARS ${_${_PYTHON_PREFIX}_REQUIRED_VARS}
VERSION_VAR ${_PYTHON_PREFIX}_VERSION
- HANDLE_COMPONENTS)
+ HANDLE_COMPONENTS
+ REASON_FAILURE_MESSAGE "${_${_PYTHON_PREFIX}_REASON_FAILURE}")
# Create imported targets and helper functions
if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT")
@@ -2281,8 +2986,10 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT")
PROPERTY IMPORTED_LOCATION "${${_PYTHON_PREFIX}_COMPILER}")
endif()
- if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
- AND ${_PYTHON_PREFIX}_Development_FOUND)
+ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+ AND ${_PYTHON_PREFIX}_Development.Module_FOUND)
+ OR ("Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+ AND ${_PYTHON_PREFIX}_Development.Embed_FOUND))
macro (__PYTHON_IMPORT_LIBRARY __name)
if (${_PYTHON_PREFIX}_LIBRARY_RELEASE MATCHES "${CMAKE_SHARED_LIBRARY_SUFFIX}$"
@@ -2314,8 +3021,8 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT")
else()
set_target_properties (${__name}
PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C"
- IMPORTED_IMPLIB "${${_PYTHON_PREFIX}_LIBRARY}"
- IMPORTED_LOCATION "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY}")
+ IMPORTED_IMPLIB "${${_PYTHON_PREFIX}_LIBRARIES}"
+ IMPORTED_LOCATION "${${_PYTHON_PREFIX}_RUNTIME_LIBRARY_RELEASE}")
endif()
else()
if (${_PYTHON_PREFIX}_LIBRARY_RELEASE AND ${_PYTHON_PREFIX}_LIBRARY_DEBUG)
@@ -2329,7 +3036,7 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT")
else()
set_target_properties (${__name}
PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C"
- IMPORTED_LOCATION "${${_PYTHON_PREFIX}_LIBRARY}")
+ IMPORTED_LOCATION "${${_PYTHON_PREFIX}_LIBRARY_RELEASE}")
endif()
endif()
@@ -2343,31 +3050,35 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT")
endif()
endmacro()
- __python_import_library (${_PYTHON_PREFIX}::Python)
-
- if (CMAKE_SYSTEM_NAME MATCHES "^(Windows.*|CYGWIN|MSYS)$")
- # On Windows/CYGWIN/MSYS, Python::Module is the same as Python::Python
- # but ALIAS cannot be used because the imported library is not GLOBAL.
- __python_import_library (${_PYTHON_PREFIX}::Module)
- else()
- if (NOT TARGET ${_PYTHON_PREFIX}::Module )
- add_library (${_PYTHON_PREFIX}::Module INTERFACE IMPORTED)
- endif()
- set_property (TARGET ${_PYTHON_PREFIX}::Module
- PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_INCLUDE_DIRS}")
+ if (${_PYTHON_PREFIX}_Development.Embed_FOUND)
+ __python_import_library (${_PYTHON_PREFIX}::Python)
+ endif()
- # When available, enforce shared library generation with undefined symbols
- if (APPLE)
- set_property (TARGET ${_PYTHON_PREFIX}::Module
- PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-undefined,dynamic_lookup")
- endif()
- if (CMAKE_SYSTEM_NAME STREQUAL "SunOS")
- set_property (TARGET ${_PYTHON_PREFIX}::Module
- PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-z,nodefs")
- endif()
- if (CMAKE_SYSTEM_NAME STREQUAL "AIX")
+ if (${_PYTHON_PREFIX}_Development.Module_FOUND)
+ if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_MODULE_ARTIFACTS)
+ # On Windows/CYGWIN/MSYS, Python::Module is the same as Python::Python
+ # but ALIAS cannot be used because the imported library is not GLOBAL.
+ __python_import_library (${_PYTHON_PREFIX}::Module)
+ else()
+ if (NOT TARGET ${_PYTHON_PREFIX}::Module)
+ add_library (${_PYTHON_PREFIX}::Module INTERFACE IMPORTED)
+ endif()
set_property (TARGET ${_PYTHON_PREFIX}::Module
- PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-b,erok")
+ PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${${_PYTHON_PREFIX}_INCLUDE_DIRS}")
+
+ # When available, enforce shared library generation with undefined symbols
+ if (APPLE)
+ set_property (TARGET ${_PYTHON_PREFIX}::Module
+ PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-undefined,dynamic_lookup")
+ endif()
+ if (CMAKE_SYSTEM_NAME STREQUAL "SunOS")
+ set_property (TARGET ${_PYTHON_PREFIX}::Module
+ PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-z,nodefs")
+ endif()
+ if (CMAKE_SYSTEM_NAME STREQUAL "AIX")
+ set_property (TARGET ${_PYTHON_PREFIX}::Module
+ PROPERTY INTERFACE_LINK_OPTIONS "LINKER:-b,erok")
+ endif()
endif()
endif()
@@ -2376,16 +3087,31 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT")
# It is used to build modules for python.
#
function (__${_PYTHON_PREFIX}_ADD_LIBRARY prefix name)
- cmake_parse_arguments (PARSE_ARGV 2 PYTHON_ADD_LIBRARY
- "STATIC;SHARED;MODULE" "" "")
+ cmake_parse_arguments (PARSE_ARGV 2 PYTHON_ADD_LIBRARY "STATIC;SHARED;MODULE;WITH_SOABI" "" "")
- unset (type)
- if (NOT (PYTHON_ADD_LIBRARY_STATIC
- OR PYTHON_ADD_LIBRARY_SHARED
- OR PYTHON_ADD_LIBRARY_MODULE))
+ if (prefix STREQUAL "Python2" AND PYTHON_ADD_LIBRARY_WITH_SOABI)
+ message (AUTHOR_WARNING "FindPython2: Option `WITH_SOABI` is not supported for Python2 and will be ignored.")
+ unset (PYTHON_ADD_LIBRARY_WITH_SOABI)
+ endif()
+
+ if (PYTHON_ADD_LIBRARY_STATIC)
+ set (type STATIC)
+ elseif (PYTHON_ADD_LIBRARY_SHARED)
+ set (type SHARED)
+ else()
set (type MODULE)
endif()
- add_library (${name} ${type} ${ARGN})
+
+ if (type STREQUAL "MODULE" AND NOT TARGET ${prefix}::Module)
+ message (SEND_ERROR "${prefix}_ADD_LIBRARY: dependent target '${prefix}::Module' is not defined.\n Did you miss to request COMPONENT 'Development.Module'?")
+ return()
+ endif()
+ if (NOT type STREQUAL "MODULE" AND NOT TARGET ${prefix}::Python)
+ message (SEND_ERROR "${prefix}_ADD_LIBRARY: dependent target '${prefix}::Python' is not defined.\n Did you miss to request COMPONENT 'Development.Embed'?")
+ return()
+ endif()
+
+ add_library (${name} ${type} ${PYTHON_ADD_LIBRARY_UNPARSED_ARGUMENTS})
get_property (type TARGET ${name} PROPERTY TYPE)
@@ -2396,7 +3122,18 @@ if(_${_PYTHON_PREFIX}_CMAKE_ROLE STREQUAL "PROJECT")
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
set_property (TARGET ${name} PROPERTY SUFFIX ".pyd")
endif()
+
+ if (PYTHON_ADD_LIBRARY_WITH_SOABI AND ${prefix}_SOABI)
+ get_property (suffix TARGET ${name} PROPERTY SUFFIX)
+ if (NOT suffix)
+ set (suffix "${CMAKE_SHARED_MODULE_SUFFIX}")
+ endif()
+ set_property (TARGET ${name} PROPERTY SUFFIX ".${${prefix}_SOABI}${suffix}")
+ endif()
else()
+ if (PYTHON_ADD_LIBRARY_WITH_SOABI)
+ message (AUTHOR_WARNING "Find${prefix}: Option `WITH_SOABI` is only supported for `MODULE` library type.")
+ endif()
target_link_libraries (${name} PRIVATE ${prefix}::Python)
endif()
endfunction()
@@ -2427,5 +3164,3 @@ if (DEFINED _${_PYTHON_PREFIX}_CMAKE_FIND_FRAMEWORK)
else()
unset (CMAKE_FIND_FRAMEWORK)
endif()
-
-unset (_${_PYTHON_PREFIX}_CONFIG CACHE)
diff --git a/Modules/FindPython2.cmake b/Modules/FindPython2.cmake
index 3cc7d56..84c0c73 100644
--- a/Modules/FindPython2.cmake
+++ b/Modules/FindPython2.cmake
@@ -13,13 +13,24 @@ The following components are supported:
* ``Interpreter``: search for Python 2 interpreter
* ``Compiler``: search for Python 2 compiler. Only offered by IronPython.
* ``Development``: search for development artifacts (include directories and
- libraries)
+ libraries). This component includes two sub-components which can be specified
+ independently:
+
+ * ``Development.Module``: search for artifacts for Python 2 module
+ developments.
+ * ``Development.Embed``: search for artifacts for Python 2 embedding
+ developments.
+
* ``NumPy``: search for NumPy include directories.
If no ``COMPONENTS`` are specified, ``Interpreter`` is assumed.
+If component ``Development`` is specified, it implies sub-components
+``Development.Module`` and ``Development.Embed``.
+
To ensure consistent versions between components ``Interpreter``, ``Compiler``,
-``Development`` and ``NumPy``, specify all components at the same time::
+``Development`` (or one of its sub-components) and ``NumPy``, specify all
+components at the same time::
find_package (Python2 COMPONENTS Interpreter Development)
@@ -31,10 +42,11 @@ for you.
.. note::
- If components ``Interpreter`` and ``Development`` are both specified, this
- module search only for interpreter with same platform architecture as the one
- defined by ``CMake`` configuration. This contraint does not apply if only
- ``Interpreter`` component is specified.
+ If components ``Interpreter`` and ``Development`` (or one of its
+ sub-components) are both specified, this module search only for interpreter
+ with same platform architecture as the one defined by ``CMake``
+ configuration. This contraint does not apply if only ``Interpreter``
+ component is specified.
Imported Targets
^^^^^^^^^^^^^^^^
@@ -46,12 +58,12 @@ This module defines the following :ref:`Imported Targets <Imported Targets>`
Python 2 interpreter. Target defined if component ``Interpreter`` is found.
``Python2::Compiler``
Python 2 compiler. Target defined if component ``Compiler`` is found.
-``Python2::Python``
- Python 2 library for Python embedding. Target defined if component
- ``Development`` is found.
``Python2::Module``
Python 2 library for Python module. Target defined if component
- ``Development`` is found.
+ ``Development.Module`` is found.
+``Python2::Python``
+ Python 2 library for Python embedding. Target defined if component
+ ``Development.Embed`` is found.
``Python2::NumPy``
NumPy library for Python 2. Target defined if component ``NumPy`` is found.
@@ -74,26 +86,31 @@ This module will set the following variables in your project
* Anaconda
* Canopy
* IronPython
+ * PyPy
``Python2_STDLIB``
Standard platform independent installation directory.
Information returned by
- ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)``.
+ ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)``
+ or else ``sysconfig.get_path('stdlib')``.
``Python2_STDARCH``
Standard platform dependent installation directory.
Information returned by
- ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)``.
+ ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)``
+ or else ``sysconfig.get_path('platstdlib')``.
``Python2_SITELIB``
Third-party platform independent installation directory.
Information returned by
- ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)``.
+ ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)``
+ or else ``sysconfig.get_path('purelib')``.
``Python2_SITEARCH``
Third-party platform dependent installation directory.
Information returned by
- ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``.
+ ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``
+ or else ``sysconfig.get_path('platlib')``.
``Python2_Compiler_FOUND``
System has the Python 2 compiler.
``Python2_COMPILER``
@@ -101,8 +118,14 @@ This module will set the following variables in your project
``Python2_COMPILER_ID``
A short string unique to the compiler. Possible values include:
* IronPython
+``Python2_DOTNET_LAUNCHER``
+ The ``.Net`` interpreter. Only used by ``IronPython`` implementation.
``Python2_Development_FOUND``
System has the Python 2 development artifacts.
+``Python2_Development.Module_FOUND``
+ System has the Python 2 development artifacts for Python module.
+``Python2_Development.Embed_FOUND``
+ System has the Python 2 development artifacts for Python embedding.
``Python2_INCLUDE_DIRS``
The Python 2 include directories.
``Python2_LIBRARIES``
@@ -119,6 +142,8 @@ This module will set the following variables in your project
Python 2 minor version.
``Python2_VERSION_PATCH``
Python 2 patch version.
+``Python2_PyPy_VERSION``
+ Python 2 PyPy version.
``Python2_NumPy_FOUND``
System has the NumPy.
``Python2_NumPy_INCLUDE_DIRS``
@@ -140,8 +165,7 @@ Hints
``Python2_FIND_STRATEGY``
This variable defines how lookup will be done.
- The ``Python2_FIND_STRATEGY`` variable can be set to empty or one of the
- following:
+ The ``Python2_FIND_STRATEGY`` variable can be set to one of the following:
* ``VERSION``: Try to find the most recent version in all specified
locations.
@@ -154,8 +178,7 @@ Hints
``Python2_FIND_REGISTRY``
On Windows the ``Python2_FIND_REGISTRY`` variable determine the order
of preference between registry and environment variables.
- the ``Python2_FIND_REGISTRY`` variable can be set to empty or one of the
- following:
+ the ``Python2_FIND_REGISTRY`` variable can be set to one of the following:
* ``FIRST``: Try to use registry before environment variables.
This is the default.
@@ -165,8 +188,8 @@ Hints
``Python2_FIND_FRAMEWORK``
On macOS the ``Python2_FIND_FRAMEWORK`` variable determine the order of
preference between Apple-style and unix-style package components.
- This variable can be set to empty or take same values as
- :variable:`CMAKE_FIND_FRAMEWORK` variable.
+ This variable can take same values as :variable:`CMAKE_FIND_FRAMEWORK`
+ variable.
.. note::
@@ -176,11 +199,11 @@ Hints
variable will be used, if any.
``Python2_FIND_VIRTUALENV``
- This variable defines the handling of virtual environments. It is meaningfull
- only when a virtual environment is active (i.e. the ``activate`` script has
- been evaluated). In this case, it takes precedence over
- ``Python2_FIND_REGISTRY`` and ``CMAKE_FIND_FRAMEWORK`` variables.
- The ``Python2_FIND_VIRTUALENV`` variable can be set to empty or one of the
+ This variable defines the handling of virtual environments managed by
+ ``virtualenv`` or ``conda``. It is meaningful only when a virtual environment
+ is active (i.e. the ``activate`` script has been evaluated). In this case, it
+ takes precedence over ``Python2_FIND_REGISTRY`` and ``CMAKE_FIND_FRAMEWORK``
+ variables. The ``Python2_FIND_VIRTUALENV`` variable can be set to one of the
following:
* ``FIRST``: The virtual environment is used before any other standard
@@ -188,8 +211,9 @@ Hints
* ``ONLY``: Only the virtual environment is used to look-up for the
interpreter.
* ``STANDARD``: The virtual environment is not used to look-up for the
- interpreter. In this case, variable ``Python2_FIND_REGISTRY`` (Windows)
- or ``CMAKE_FIND_FRAMEWORK`` (macOS) can be set with value ``LAST`` or
+ interpreter but environment variable ``PATH`` is always considered.
+ In this case, variable ``Python2_FIND_REGISTRY`` (Windows) or
+ ``CMAKE_FIND_FRAMEWORK`` (macOS) can be set with value ``LAST`` or
``NEVER`` to select preferably the interpreter from the virtual
environment.
@@ -199,6 +223,39 @@ Hints
recommended to also include the component ``Interpreter`` to get expected
result.
+``Python2_FIND_IMPLEMENTATIONS``
+ This variable defines, in an ordered list, the different implementations
+ which will be searched. The ``Python2_FIND_IMPLEMENTATIONS`` variable can
+ hold the following values:
+
+ * ``CPython``: this is the standard implementation. Various products, like
+ ``Anaconda`` or ``ActivePython``, rely on this implementation.
+ * ``IronPython``: This implementation use the ``CSharp`` language for
+ ``.NET Framework`` on top of the `Dynamic Language Runtime` (``DLR``).
+ See `IronPython <http://ironpython.net>`_.
+ * ``PyPy``: This implementation use ``RPython`` language and
+ ``RPython translation toolchain`` to produce the python interpreter.
+ See `PyPy <https://www.pypy.org>`_.
+
+ The default value is:
+
+ * Windows platform: ``CPython``, ``IronPython``
+ * Other platforms: ``CPython``
+
+ .. note::
+
+ This hint has the lowest priority of all hints, so even if, for example,
+ you specify ``IronPython`` first and ``CPython`` in second, a python
+ product based on ``CPython`` can be selected because, for example with
+ ``Python2_FIND_STRATEGY=LOCATION``, each location will be search first for
+ ``IronPython`` and second for ``CPython``.
+
+ .. note::
+
+ When ``IronPython`` is specified, on platforms other than ``Windows``, the
+ ``.Net`` interpreter (i.e. ``mono`` command) is expected to be available
+ through the ``PATH`` variable.
+
Artifacts Specification
^^^^^^^^^^^^^^^^^^^^^^^
@@ -211,6 +268,9 @@ setting the following variables:
``Python2_COMPILER``
The path to the compiler.
+``Python2_DOTNET_LAUNCHER``
+ The ``.Net`` interpreter. Only used by ``IronPython`` implementation.
+
``Python2_LIBRARY``
The path to the library. It will be used to compute the
variables ``Python2_LIBRARIES``, ``Python2_LIBRAY_DIRS`` and
@@ -237,16 +297,33 @@ setting the following variables:
If more than one artifact is specified, it is the user's responsability to
ensure the consistency of the various artifacts.
+By default, this module supports multiple calls in different directories of a
+project with different version/component requirements while providing correct
+and consistent results for each call. To support this behavior, ``CMake`` cache
+is not used in the traditional way which can be problematic for interactive
+specification. So, to enable also interactive specification, module behavior
+can be controled with the following variable:
+
+``Python2_ARTIFACTS_INTERACTIVE``
+ Selects the behavior of the module. This is a boolean variable:
+
+ * If set to ``TRUE``: Create CMake cache entries for the above artifact
+ specification variables so that users can edit them interactively.
+ This disables support for multiple version/component requirements.
+ * If set to ``FALSE`` or undefined: Enable multiple version/component
+ requirements.
+
Commands
^^^^^^^^
-This module defines the command ``Python_add_library`` (when
+This module defines the command ``Python2_add_library`` (when
:prop_gbl:`CMAKE_ROLE` is ``PROJECT``), which has the same semantics as
:command:`add_library` and adds a dependency to target ``Python2::Python`` or,
when library type is ``MODULE``, to target ``Python2::Module`` and takes care
of Python module naming rules::
- Python2_add_library (my_module MODULE src1.cpp)
+ Python2_add_library (<name> [STATIC | SHARED | MODULE]
+ <source1> [<source2> ...])
If library type is not specified, ``MODULE`` is assumed.
#]=======================================================================]
diff --git a/Modules/FindPython3.cmake b/Modules/FindPython3.cmake
index 066d0df..f142c07 100644
--- a/Modules/FindPython3.cmake
+++ b/Modules/FindPython3.cmake
@@ -13,13 +13,24 @@ The following components are supported:
* ``Interpreter``: search for Python 3 interpreter
* ``Compiler``: search for Python 3 compiler. Only offered by IronPython.
* ``Development``: search for development artifacts (include directories and
- libraries)
+ libraries). This component includes two sub-components which can be specified
+ independently:
+
+ * ``Development.Module``: search for artifacts for Python 3 module
+ developments.
+ * ``Development.Embed``: search for artifacts for Python 3 embedding
+ developments.
+
* ``NumPy``: search for NumPy include directories.
If no ``COMPONENTS`` are specified, ``Interpreter`` is assumed.
+If component ``Development`` is specified, it implies sub-components
+``Development.Module`` and ``Development.Embed``.
+
To ensure consistent versions between components ``Interpreter``, ``Compiler``,
-``Development`` and ``NumPy``, specify all components at the same time::
+``Development`` (or one of its sub-components) and ``NumPy``, specify all
+components at the same time::
find_package (Python3 COMPONENTS Interpreter Development)
@@ -31,10 +42,11 @@ for you.
.. note::
- If components ``Interpreter`` and ``Development`` are both specified, this
- module search only for interpreter with same platform architecture as the one
- defined by ``CMake`` configuration. This contraint does not apply if only
- ``Interpreter`` component is specified.
+ If components ``Interpreter`` and ``Development`` (or one of its
+ sub-components) are both specified, this module search only for interpreter
+ with same platform architecture as the one defined by ``CMake``
+ configuration. This contraint does not apply if only ``Interpreter``
+ component is specified.
Imported Targets
^^^^^^^^^^^^^^^^
@@ -46,12 +58,12 @@ This module defines the following :ref:`Imported Targets <Imported Targets>`
Python 3 interpreter. Target defined if component ``Interpreter`` is found.
``Python3::Compiler``
Python 3 compiler. Target defined if component ``Compiler`` is found.
-``Python3::Python``
- Python 3 library for Python embedding. Target defined if component
- ``Development`` is found.
``Python3::Module``
Python 3 library for Python module. Target defined if component
- ``Development`` is found.
+ ``Development.Module`` is found.
+``Python3::Python``
+ Python 3 library for Python embedding. Target defined if component
+ ``Development.Embed`` is found.
``Python3::NumPy``
NumPy library for Python 3. Target defined if component ``NumPy`` is found.
@@ -74,26 +86,40 @@ This module will set the following variables in your project
* Anaconda
* Canopy
* IronPython
+ * PyPy
``Python3_STDLIB``
Standard platform independent installation directory.
Information returned by
- ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)``.
+ ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=True)``
+ or else ``sysconfig.get_path('stdlib')``.
``Python3_STDARCH``
Standard platform dependent installation directory.
Information returned by
- ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)``.
+ ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=True)``
+ or else ``sysconfig.get_path('platstdlib')``.
``Python3_SITELIB``
Third-party platform independent installation directory.
Information returned by
- ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)``.
+ ``distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False)``
+ or else ``sysconfig.get_path('purelib')``.
``Python3_SITEARCH``
Third-party platform dependent installation directory.
Information returned by
- ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``.
+ ``distutils.sysconfig.get_python_lib(plat_specific=True,standard_lib=False)``
+ or else ``sysconfig.get_path('platlib')``.
+``Python3_SOABI``
+ Extension suffix for modules.
+
+ Information returned by
+ ``distutils.sysconfig.get_config_var('SOABI')`` or computed from
+ ``distutils.sysconfig.get_config_var('EXT_SUFFIX')`` or
+ ``python3-config --extension-suffix``. If package ``distutils.sysconfig`` is
+ not available, ``sysconfig.get_config_var('SOABI')`` or
+ ``sysconfig.get_config_var('EXT_SUFFIX')`` are used.
``Python3_Compiler_FOUND``
System has the Python 3 compiler.
``Python3_COMPILER``
@@ -101,8 +127,14 @@ This module will set the following variables in your project
``Python3_COMPILER_ID``
A short string unique to the compiler. Possible values include:
* IronPython
+``Python3_DOTNET_LAUNCHER``
+ The ``.Net`` interpreter. Only used by ``IronPython`` implementation.
``Python3_Development_FOUND``
System has the Python 3 development artifacts.
+``Python3_Development.Module_FOUND``
+ System has the Python 3 development artifacts for Python module.
+``Python3_Development.Embed_FOUND``
+ System has the Python 3 development artifacts for Python embedding.
``Python3_INCLUDE_DIRS``
The Python 3 include directories.
``Python3_LIBRARIES``
@@ -119,6 +151,8 @@ This module will set the following variables in your project
Python 3 minor version.
``Python3_VERSION_PATCH``
Python 3 patch version.
+``Python3_PyPy_VERSION``
+ Python 3 PyPy version.
``Python3_NumPy_FOUND``
System has the NumPy.
``Python3_NumPy_INCLUDE_DIRS``
@@ -181,8 +215,7 @@ Hints
``Python3_FIND_STRATEGY``
This variable defines how lookup will be done.
- The ``Python3_FIND_STRATEGY`` variable can be set to empty or one of the
- following:
+ The ``Python3_FIND_STRATEGY`` variable can be set to one of the following:
* ``VERSION``: Try to find the most recent version in all specified
locations.
@@ -195,8 +228,7 @@ Hints
``Python3_FIND_REGISTRY``
On Windows the ``Python3_FIND_REGISTRY`` variable determine the order
of preference between registry and environment variables.
- The ``Python3_FIND_REGISTRY`` variable can be set to empty or one of the
- following:
+ The ``Python3_FIND_REGISTRY`` variable can be set to one of the following:
* ``FIRST``: Try to use registry before environment variables.
This is the default.
@@ -206,8 +238,8 @@ Hints
``Python3_FIND_FRAMEWORK``
On macOS the ``Python3_FIND_FRAMEWORK`` variable determine the order of
preference between Apple-style and unix-style package components.
- This variable can be set to empty or take same values as
- :variable:`CMAKE_FIND_FRAMEWORK` variable.
+ This variable can take same values as :variable:`CMAKE_FIND_FRAMEWORK`
+ variable.
.. note::
@@ -217,11 +249,11 @@ Hints
variable will be used, if any.
``Python3_FIND_VIRTUALENV``
- This variable defines the handling of virtual environments. It is meaningfull
- only when a virtual environment is active (i.e. the ``activate`` script has
- been evaluated). In this case, it takes precedence over
- ``Python3_FIND_REGISTRY`` and ``CMAKE_FIND_FRAMEWORK`` variables.
- The ``Python3_FIND_VIRTUALENV`` variable can be set to empty or one of the
+ This variable defines the handling of virtual environments managed by
+ ``virtualenv`` or ``conda``. It is meaningful only when a virtual environment
+ is active (i.e. the ``activate`` script has been evaluated). In this case, it
+ takes precedence over ``Python3_FIND_REGISTRY`` and ``CMAKE_FIND_FRAMEWORK``
+ variables. The ``Python3_FIND_VIRTUALENV`` variable can be set to one of the
following:
* ``FIRST``: The virtual environment is used before any other standard
@@ -229,8 +261,9 @@ Hints
* ``ONLY``: Only the virtual environment is used to look-up for the
interpreter.
* ``STANDARD``: The virtual environment is not used to look-up for the
- interpreter. In this case, variable ``Python3_FIND_REGISTRY`` (Windows)
- or ``CMAKE_FIND_FRAMEWORK`` (macOS) can be set with value ``LAST`` or
+ interpreter but environment variable ``PATH`` is always considered.
+ In this case, variable ``Python3_FIND_REGISTRY`` (Windows) or
+ ``CMAKE_FIND_FRAMEWORK`` (macOS) can be set with value ``LAST`` or
``NEVER`` to select preferably the interpreter from the virtual
environment.
@@ -240,6 +273,39 @@ Hints
recommended to also include the component ``Interpreter`` to get expected
result.
+``Python3_FIND_IMPLEMENTATIONS``
+ This variable defines, in an ordered list, the different implementations
+ which will be searched. The ``Python3_FIND_IMPLEMENTATIONS`` variable can
+ hold the following values:
+
+ * ``CPython``: this is the standard implementation. Various products, like
+ ``Anaconda`` or ``ActivePython``, rely on this implementation.
+ * ``IronPython``: This implementation use the ``CSharp`` language for
+ ``.NET Framework`` on top of the `Dynamic Language Runtime` (``DLR``).
+ See `IronPython <http://ironpython.net>`_.
+ * ``PyPy``: This implementation use ``RPython`` language and
+ ``RPython translation toolchain`` to produce the python interpreter.
+ See `PyPy <https://www.pypy.org>`_.
+
+ The default value is:
+
+ * Windows platform: ``CPython``, ``IronPython``
+ * Other platforms: ``CPython``
+
+ .. note::
+
+ This hint has the lowest priority of all hints, so even if, for example,
+ you specify ``IronPython`` first and ``CPython`` in second, a python
+ product based on ``CPython`` can be selected because, for example with
+ ``Python3_FIND_STRATEGY=LOCATION``, each location will be search first for
+ ``IronPython`` and second for ``CPython``.
+
+ .. note::
+
+ When ``IronPython`` is specified, on platforms other than ``Windows``, the
+ ``.Net`` interpreter (i.e. ``mono`` command) is expected to be available
+ through the ``PATH`` variable.
+
Artifacts Specification
^^^^^^^^^^^^^^^^^^^^^^^
@@ -252,6 +318,9 @@ setting the following variables:
``Python3_COMPILER``
The path to the compiler.
+``Python3_DOTNET_LAUNCHER``
+ The ``.Net`` interpreter. Only used by ``IronPython`` implementation.
+
``Python3_LIBRARY``
The path to the library. It will be used to compute the
variables ``Python3_LIBRARIES``, ``Python3_LIBRAY_DIRS`` and
@@ -278,18 +347,38 @@ setting the following variables:
If more than one artifact is specified, it is the user's responsability to
ensure the consistency of the various artifacts.
+By default, this module supports multiple calls in different directories of a
+project with different version/component requirements while providing correct
+and consistent results for each call. To support this behavior, ``CMake`` cache
+is not used in the traditional way which can be problematic for interactive
+specification. So, to enable also interactive specification, module behavior
+can be controled with the following variable:
+
+``Python3_ARTIFACTS_INTERACTIVE``
+ Selects the behavior of the module. This is a boolean variable:
+
+ * If set to ``TRUE``: Create CMake cache entries for the above artifact
+ specification variables so that users can edit them interactively.
+ This disables support for multiple version/component requirements.
+ * If set to ``FALSE`` or undefined: Enable multiple version/component
+ requirements.
+
Commands
^^^^^^^^
-This module defines the command ``Python_add_library`` (when
+This module defines the command ``Python3_add_library`` (when
:prop_gbl:`CMAKE_ROLE` is ``PROJECT``), which has the same semantics as
:command:`add_library` and adds a dependency to target ``Python3::Python`` or,
when library type is ``MODULE``, to target ``Python3::Module`` and takes care
of Python module naming rules::
- Python3_add_library (my_module MODULE src1.cpp)
+ Python3_add_library (<name> [STATIC | SHARED | MODULE [WITH_SOABI]]
+ <source1> [<source2> ...])
+
+If the library type is not specified, ``MODULE`` is assumed.
-If library type is not specified, ``MODULE`` is assumed.
+For ``MODULE`` library type, if option ``WITH_SOABI`` is specified, the
+module suffix will include the ``Python3_SOABI`` value, if any.
#]=======================================================================]
diff --git a/Modules/FindRuby.cmake b/Modules/FindRuby.cmake
index 7e01fbc..1bdee60 100644
--- a/Modules/FindRuby.cmake
+++ b/Modules/FindRuby.cmake
@@ -8,288 +8,505 @@ FindRuby
Find Ruby
This module finds if Ruby is installed and determines where the
-include files and libraries are. Ruby 1.8, 1.9, 2.0 and 2.1 are
+include files and libraries are. Ruby 1.8 through 2.7 are
supported.
The minimum required version of Ruby can be specified using the
-standard syntax, e.g. find_package(Ruby 1.8)
+standard syntax, e.g.
-It also determines what the name of the library is. This code sets
-the following variables:
+.. code-block:: cmake
-``RUBY_EXECUTABLE``
+ find_package(Ruby 2.5.1 EXACT REQUIRED)
+ # OR
+ find_package(Ruby 2.4)
+
+It also determines what the name of the library is.
+
+Virtual environments such as RVM are handled as well, by passing
+the argument ``Ruby_FIND_VIRTUALENV``
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module will set the following variables in your project:
+
+``Ruby_FOUND``
+ set to true if ruby was found successfully
+``Ruby_EXECUTABLE``
full path to the ruby binary
-``RUBY_INCLUDE_DIRS``
+``Ruby_INCLUDE_DIRS``
include dirs to be used when using the ruby library
-``RUBY_LIBRARY``
- full path to the ruby library
-``RUBY_VERSION``
+``Ruby_LIBRARIES``
+ libraries needed to use ruby from C.
+``Ruby_VERSION``
the version of ruby which was found, e.g. "1.8.7"
-``RUBY_FOUND``
- set to true if ruby ws found successfully
+``Ruby_VERSION_MAJOR``
+ Ruby major version.
+``Ruby_VERSION_MINOR``
+ Ruby minor version.
+``Ruby_VERSION_PATCH``
+ Ruby patch version.
+
Also:
-``RUBY_INCLUDE_PATH``
- same as RUBY_INCLUDE_DIRS, only provided for compatibility reasons, don't use it
+``Ruby_INCLUDE_PATH``
+ same as Ruby_INCLUDE_DIRS, only provided for compatibility reasons, don't use it
+
+Hints
+^^^^^
+
+``Ruby_ROOT_DIR``
+ Define the root directory of a Ruby installation.
+
+``Ruby_FIND_VIRTUALENV``
+ This variable defines the handling of virtual environments managed by
+ ``rvm``. It is meaningful only when a virtual environment
+ is active (i.e. the ``rvm`` script has been evaluated or at least the
+ ``MY_RUBY_HOME`` environment variable is set).
+ The ``Ruby_FIND_VIRTUALENV`` variable can be set to empty or
+ one of the following:
+
+ * ``FIRST``: The virtual environment is used before any other standard
+ paths to look-up for the interpreter. This is the default.
+ * ``ONLY``: Only the virtual environment is used to look-up for the
+ interpreter.
+ * ``STANDARD``: The virtual environment is not used to look-up for the
+ interpreter (assuming it isn't still in the PATH...)
+
#]=======================================================================]
-# RUBY_ARCHDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"archdir"@:>@)'`
-# RUBY_SITEARCHDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"sitearchdir"@:>@)'`
-# RUBY_SITEDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"sitelibdir"@:>@)'`
-# RUBY_LIBDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"libdir"@:>@)'`
-# RUBY_LIBRUBYARG=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"LIBRUBYARG_SHARED"@:>@)'`
+# Backwards compatibility
+# Define camel case versions of input variables
+foreach(UPPER
+ RUBY_EXECUTABLE
+ RUBY_LIBRARY
+ RUBY_INCLUDE_DIR
+ RUBY_CONFIG_INCLUDE_DIR
+ )
+ if (DEFINED ${UPPER})
+ string(REPLACE "RUBY_" "Ruby_" Camel ${UPPER})
+ if (NOT DEFINED ${Camel})
+ set(${Camel} ${${UPPER}})
+ endif()
+ endif()
+endforeach()
+
+# Ruby_ARCHDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"archdir"@:>@)'`
+# Ruby_SITEARCHDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"sitearchdir"@:>@)'`
+# Ruby_SITEDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"sitelibdir"@:>@)'`
+# Ruby_LIBDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"libdir"@:>@)'`
+# Ruby_LIBRUBYARG=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"LIBRUBYARG_SHARED"@:>@)'`
# uncomment the following line to get debug output for this file
-# set(_RUBY_DEBUG_OUTPUT TRUE)
+# set(_Ruby_DEBUG_OUTPUT TRUE)
# Determine the list of possible names of the ruby executable depending
# on which version of ruby is required
-set(_RUBY_POSSIBLE_EXECUTABLE_NAMES ruby)
-
-# if 1.9 is required, don't look for ruby18 and ruby1.8, default to version 1.8
-if(DEFINED Ruby_FIND_VERSION_MAJOR AND DEFINED Ruby_FIND_VERSION_MINOR)
- set(Ruby_FIND_VERSION_SHORT_NODOT "${Ruby_FIND_VERSION_MAJOR}${RUBY_FIND_VERSION_MINOR}")
- # we can't construct that if only major version is given
- set(_RUBY_POSSIBLE_EXECUTABLE_NAMES
- ruby${Ruby_FIND_VERSION_MAJOR}.${Ruby_FIND_VERSION_MINOR}
- ruby${Ruby_FIND_VERSION_MAJOR}${Ruby_FIND_VERSION_MINOR}
- ${_RUBY_POSSIBLE_EXECUTABLE_NAMES})
-else()
- set(Ruby_FIND_VERSION_SHORT_NODOT "18")
+set(_Ruby_POSSIBLE_EXECUTABLE_NAMES ruby)
+
+# If not specified, allow everything as far back as 1.8.0
+if(NOT DEFINED Ruby_FIND_VERSION_MAJOR)
+ set(Ruby_FIND_VERSION "1.8.0")
+ set(Ruby_FIND_VERSION_MAJOR 1)
+ set(Ruby_FIND_VERSION_MINOR 8)
+ set(Ruby_FIND_VERSION_PATCH 0)
+endif()
+
+if(_Ruby_DEBUG_OUTPUT)
+ message("Ruby_FIND_VERSION=${Ruby_FIND_VERSION}")
+ message("Ruby_FIND_VERSION_MAJOR=${Ruby_FIND_VERSION_MAJOR}")
+ message("Ruby_FIND_VERSION_MINOR=${Ruby_FIND_VERSION_MINOR}")
+ message("Ruby_FIND_VERSION_PATCH=${Ruby_FIND_VERSION_PATCH}")
endif()
+set(Ruby_FIND_VERSION_SHORT_NODOT "${Ruby_FIND_VERSION_MAJOR}${Ruby_FIND_VERSION_MINOR}")
+
+# Set name of possible executables, ignoring the minor
+# Eg:
+# 2.1.1 => from ruby27 to ruby21 included
+# 2.1 => from ruby27 to ruby21 included
+# 2 => from ruby26 to ruby20 included
+# empty => from ruby27 to ruby18 included
if(NOT Ruby_FIND_VERSION_EXACT)
- list(APPEND _RUBY_POSSIBLE_EXECUTABLE_NAMES ruby2.4 ruby24)
- list(APPEND _RUBY_POSSIBLE_EXECUTABLE_NAMES ruby2.3 ruby23)
- list(APPEND _RUBY_POSSIBLE_EXECUTABLE_NAMES ruby2.2 ruby22)
- list(APPEND _RUBY_POSSIBLE_EXECUTABLE_NAMES ruby2.1 ruby21)
- list(APPEND _RUBY_POSSIBLE_EXECUTABLE_NAMES ruby2.0 ruby20)
- list(APPEND _RUBY_POSSIBLE_EXECUTABLE_NAMES ruby1.9 ruby19)
-
- # if we want a version below 1.9, also look for ruby 1.8
- if("${Ruby_FIND_VERSION_SHORT_NODOT}" VERSION_LESS "19")
- list(APPEND _RUBY_POSSIBLE_EXECUTABLE_NAMES ruby1.8 ruby18)
+
+ foreach(_ruby_version RANGE 27 18 -1)
+ string(SUBSTRING "${_ruby_version}" 0 1 _ruby_major_version)
+ string(SUBSTRING "${_ruby_version}" 1 1 _ruby_minor_version)
+
+ if(NOT "${_ruby_major_version}${_ruby_minor_version}" VERSION_LESS ${Ruby_FIND_VERSION_SHORT_NODOT})
+ # Append both rubyX.Y and rubyXY (eg: ruby2.7 ruby27)
+ list(APPEND _Ruby_POSSIBLE_EXECUTABLE_NAMES ruby${_ruby_major_version}.${_ruby_minor_version} ruby${_ruby_major_version}${_ruby_minor_version})
+ else()
+ break()
+ endif()
+
+ endforeach()
+
+ list(REMOVE_DUPLICATES _Ruby_POSSIBLE_EXECUTABLE_NAMES)
+endif()
+
+# virtual environments handling (eg RVM)
+if (DEFINED ENV{MY_RUBY_HOME})
+ if(_Ruby_DEBUG_OUTPUT)
+ message("My ruby home is defined: $ENV{MY_RUBY_HOME}")
+ endif()
+
+ if (DEFINED Ruby_FIND_VIRTUALENV)
+ if (NOT Ruby_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY|STANDARD)$")
+ message (AUTHOR_WARNING "FindRuby: ${Ruby_FIND_VIRTUALENV}: invalid value for 'Ruby_FIND_VIRTUALENV'. 'FIRST', 'ONLY' or 'STANDARD' expected. 'FIRST' will be used instead.")
+ set (_Ruby_FIND_VIRTUALENV "FIRST")
+ else()
+ set (_Ruby_FIND_VIRTUALENV ${Ruby_FIND_VIRTUALENV})
+ endif()
+ else()
+ set (_Ruby_FIND_VIRTUALENV FIRST)
endif()
+else()
+ if (DEFINED Ruby_FIND_VIRTUALENV)
+ message("Environment variable MY_RUBY_HOME isn't set, defaulting back to Ruby_FIND_VIRTUALENV=STANDARD")
+ endif()
+ set (_Ruby_FIND_VIRTUALENV STANDARD)
+endif()
- list(REMOVE_DUPLICATES _RUBY_POSSIBLE_EXECUTABLE_NAMES)
+if(_Ruby_DEBUG_OUTPUT)
+ message("_Ruby_POSSIBLE_EXECUTABLE_NAMES=${_Ruby_POSSIBLE_EXECUTABLE_NAMES}")
+ message("_Ruby_FIND_VIRTUALENV=${_Ruby_FIND_VIRTUALENV}")
endif()
-find_program(RUBY_EXECUTABLE NAMES ${_RUBY_POSSIBLE_EXECUTABLE_NAMES})
+function (_RUBY_VALIDATE_INTERPRETER)
+ if (NOT Ruby_EXECUTABLE)
+ return()
+ endif()
-if(RUBY_EXECUTABLE AND NOT RUBY_VERSION_MAJOR)
+ cmake_parse_arguments (PARSE_ARGV 0 _RVI "EXACT;CHECK_EXISTS" "" "")
+ if (_RVI_UNPARSED_ARGUMENTS)
+ set (expected_version ${_RVI_UNPARSED_ARGUMENTS})
+ else()
+ unset (expected_version)
+ endif()
+
+ if (_RVI_CHECK_EXISTS AND NOT EXISTS "${Ruby_EXECUTABLE}")
+ # interpreter does not exist anymore
+ set (_Ruby_Interpreter_REASON_FAILURE "Cannot find the interpreter \"${Ruby_EXECUTABLE}\"")
+ set_property (CACHE Ruby_EXECUTABLE PROPERTY VALUE "Ruby_EXECUTABLE-NOTFOUND")
+ return()
+ endif()
+
+ # Check the version it returns
+ # executable found must have a specific version
+ execute_process (COMMAND "${Ruby_EXECUTABLE}" -e "puts RUBY_VERSION"
+ RESULT_VARIABLE result
+ OUTPUT_VARIABLE version
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if (result OR (_RVI_EXACT AND NOT version VERSION_EQUAL expected_version) OR (version VERSION_LESS expected_version))
+ # interpreter not usable or has wrong major version
+ if (result)
+ set (_Ruby_Interpreter_REASON_FAILURE "Cannot use the interpreter \"${Ruby_EXECUTABLE}\"")
+ else()
+ set (_Ruby_Interpreter_REASON_FAILURE "Wrong major version for the interpreter \"${Ruby_EXECUTABLE}\"")
+ endif()
+ set_property (CACHE Ruby_EXECUTABLE PROPERTY VALUE "Ruby_EXECUTABLE-NOTFOUND")
+ return()
+ endif()
+
+endfunction()
+
+while(1)
+ # Virtual environments handling
+ if(_Ruby_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$")
+ if(_Ruby_DEBUG_OUTPUT)
+ message("Inside Matches")
+ endif()
+ find_program (Ruby_EXECUTABLE
+ NAMES ${_Ruby_POSSIBLE_EXECUTABLE_NAMES}
+ NAMES_PER_DIR
+ PATHS ENV MY_RUBY_HOME
+ PATH_SUFFIXES bin Scripts
+ NO_CMAKE_PATH
+ NO_CMAKE_ENVIRONMENT_PATH
+ NO_SYSTEM_ENVIRONMENT_PATH
+ NO_CMAKE_SYSTEM_PATH)
+
+ if(_Ruby_DEBUG_OUTPUT)
+ message("Ruby_EXECUTABLE=${Ruby_EXECUTABLE}")
+ endif()
+
+ _RUBY_VALIDATE_INTERPRETER (${Ruby_FIND_VERSION}})
+ if(Ruby_EXECUTABLE)
+ break()
+ endif()
+ if(NOT _Ruby_FIND_VIRTUALENV STREQUAL "ONLY")
+ break()
+ endif()
+ elseif(_Ruby_DEBUG_OUTPUT)
+ message("_Ruby_FIND_VIRTUALENV doesn't match: ${_Ruby_FIND_VIRTUALENV}")
+ endif()
+
+ # try using standard paths
+ find_program (Ruby_EXECUTABLE
+ NAMES ${_Ruby_POSSIBLE_EXECUTABLE_NAMES}
+ NAMES_PER_DIR)
+ _RUBY_VALIDATE_INTERPRETER (${Ruby_FIND_VERSION})
+ if (Ruby_EXECUTABLE)
+ break()
+ endif()
+
+ break()
+endwhile()
+
+if(Ruby_EXECUTABLE AND NOT Ruby_VERSION_MAJOR)
function(_RUBY_CONFIG_VAR RBVAR OUTVAR)
- execute_process(COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "print RbConfig::CONFIG['${RBVAR}']"
- RESULT_VARIABLE _RUBY_SUCCESS
- OUTPUT_VARIABLE _RUBY_OUTPUT
+ execute_process(COMMAND ${Ruby_EXECUTABLE} -r rbconfig -e "print RbConfig::CONFIG['${RBVAR}']"
+ RESULT_VARIABLE _Ruby_SUCCESS
+ OUTPUT_VARIABLE _Ruby_OUTPUT
ERROR_QUIET)
- if(_RUBY_SUCCESS OR _RUBY_OUTPUT STREQUAL "")
- execute_process(COMMAND ${RUBY_EXECUTABLE} -r rbconfig -e "print Config::CONFIG['${RBVAR}']"
- RESULT_VARIABLE _RUBY_SUCCESS
- OUTPUT_VARIABLE _RUBY_OUTPUT
+ if(_Ruby_SUCCESS OR _Ruby_OUTPUT STREQUAL "")
+ execute_process(COMMAND ${Ruby_EXECUTABLE} -r rbconfig -e "print Config::CONFIG['${RBVAR}']"
+ RESULT_VARIABLE _Ruby_SUCCESS
+ OUTPUT_VARIABLE _Ruby_OUTPUT
ERROR_QUIET)
endif()
- set(${OUTVAR} "${_RUBY_OUTPUT}" PARENT_SCOPE)
+ set(${OUTVAR} "${_Ruby_OUTPUT}" PARENT_SCOPE)
endfunction()
# query the ruby version
- _RUBY_CONFIG_VAR("MAJOR" RUBY_VERSION_MAJOR)
- _RUBY_CONFIG_VAR("MINOR" RUBY_VERSION_MINOR)
- _RUBY_CONFIG_VAR("TEENY" RUBY_VERSION_PATCH)
+ _RUBY_CONFIG_VAR("MAJOR" Ruby_VERSION_MAJOR)
+ _RUBY_CONFIG_VAR("MINOR" Ruby_VERSION_MINOR)
+ _RUBY_CONFIG_VAR("TEENY" Ruby_VERSION_PATCH)
# query the different directories
- _RUBY_CONFIG_VAR("archdir" RUBY_ARCH_DIR)
- _RUBY_CONFIG_VAR("arch" RUBY_ARCH)
- _RUBY_CONFIG_VAR("rubyhdrdir" RUBY_HDR_DIR)
- _RUBY_CONFIG_VAR("rubyarchhdrdir" RUBY_ARCHHDR_DIR)
- _RUBY_CONFIG_VAR("libdir" RUBY_POSSIBLE_LIB_DIR)
- _RUBY_CONFIG_VAR("rubylibdir" RUBY_RUBY_LIB_DIR)
+ _RUBY_CONFIG_VAR("archdir" Ruby_ARCH_DIR)
+ _RUBY_CONFIG_VAR("arch" Ruby_ARCH)
+ _RUBY_CONFIG_VAR("rubyhdrdir" Ruby_HDR_DIR)
+ _RUBY_CONFIG_VAR("rubyarchhdrdir" Ruby_ARCHHDR_DIR)
+ _RUBY_CONFIG_VAR("libdir" Ruby_POSSIBLE_LIB_DIR)
+ _RUBY_CONFIG_VAR("rubylibdir" Ruby_RUBY_LIB_DIR)
# site_ruby
- _RUBY_CONFIG_VAR("sitearchdir" RUBY_SITEARCH_DIR)
- _RUBY_CONFIG_VAR("sitelibdir" RUBY_SITELIB_DIR)
+ _RUBY_CONFIG_VAR("sitearchdir" Ruby_SITEARCH_DIR)
+ _RUBY_CONFIG_VAR("sitelibdir" Ruby_SITELIB_DIR)
# vendor_ruby available ?
- execute_process(COMMAND ${RUBY_EXECUTABLE} -r vendor-specific -e "print 'true'"
- OUTPUT_VARIABLE RUBY_HAS_VENDOR_RUBY ERROR_QUIET)
+ execute_process(COMMAND ${Ruby_EXECUTABLE} -r vendor-specific -e "print 'true'"
+ OUTPUT_VARIABLE Ruby_HAS_VENDOR_RUBY ERROR_QUIET)
- if(RUBY_HAS_VENDOR_RUBY)
- _RUBY_CONFIG_VAR("vendorlibdir" RUBY_VENDORLIB_DIR)
- _RUBY_CONFIG_VAR("vendorarchdir" RUBY_VENDORARCH_DIR)
+ if(Ruby_HAS_VENDOR_RUBY)
+ _RUBY_CONFIG_VAR("vendorlibdir" Ruby_VENDORLIB_DIR)
+ _RUBY_CONFIG_VAR("vendorarchdir" Ruby_VENDORARCH_DIR)
endif()
# save the results in the cache so we don't have to run ruby the next time again
- set(RUBY_VERSION_MAJOR ${RUBY_VERSION_MAJOR} CACHE PATH "The Ruby major version" FORCE)
- set(RUBY_VERSION_MINOR ${RUBY_VERSION_MINOR} CACHE PATH "The Ruby minor version" FORCE)
- set(RUBY_VERSION_PATCH ${RUBY_VERSION_PATCH} CACHE PATH "The Ruby patch version" FORCE)
- set(RUBY_ARCH_DIR ${RUBY_ARCH_DIR} CACHE PATH "The Ruby arch dir" FORCE)
- set(RUBY_HDR_DIR ${RUBY_HDR_DIR} CACHE PATH "The Ruby header dir (1.9+)" FORCE)
- set(RUBY_ARCHHDR_DIR ${RUBY_ARCHHDR_DIR} CACHE PATH "The Ruby arch header dir (2.0+)" FORCE)
- set(RUBY_POSSIBLE_LIB_DIR ${RUBY_POSSIBLE_LIB_DIR} CACHE PATH "The Ruby lib dir" FORCE)
- set(RUBY_RUBY_LIB_DIR ${RUBY_RUBY_LIB_DIR} CACHE PATH "The Ruby ruby-lib dir" FORCE)
- set(RUBY_SITEARCH_DIR ${RUBY_SITEARCH_DIR} CACHE PATH "The Ruby site arch dir" FORCE)
- set(RUBY_SITELIB_DIR ${RUBY_SITELIB_DIR} CACHE PATH "The Ruby site lib dir" FORCE)
- set(RUBY_HAS_VENDOR_RUBY ${RUBY_HAS_VENDOR_RUBY} CACHE BOOL "Vendor Ruby is available" FORCE)
- set(RUBY_VENDORARCH_DIR ${RUBY_VENDORARCH_DIR} CACHE PATH "The Ruby vendor arch dir" FORCE)
- set(RUBY_VENDORLIB_DIR ${RUBY_VENDORLIB_DIR} CACHE PATH "The Ruby vendor lib dir" FORCE)
+ set(Ruby_VERSION_MAJOR ${Ruby_VERSION_MAJOR} CACHE PATH "The Ruby major version" FORCE)
+ set(Ruby_VERSION_MINOR ${Ruby_VERSION_MINOR} CACHE PATH "The Ruby minor version" FORCE)
+ set(Ruby_VERSION_PATCH ${Ruby_VERSION_PATCH} CACHE PATH "The Ruby patch version" FORCE)
+ set(Ruby_ARCH_DIR ${Ruby_ARCH_DIR} CACHE PATH "The Ruby arch dir" FORCE)
+ set(Ruby_HDR_DIR ${Ruby_HDR_DIR} CACHE PATH "The Ruby header dir (1.9+)" FORCE)
+ set(Ruby_ARCHHDR_DIR ${Ruby_ARCHHDR_DIR} CACHE PATH "The Ruby arch header dir (2.0+)" FORCE)
+ set(Ruby_POSSIBLE_LIB_DIR ${Ruby_POSSIBLE_LIB_DIR} CACHE PATH "The Ruby lib dir" FORCE)
+ set(Ruby_RUBY_LIB_DIR ${Ruby_RUBY_LIB_DIR} CACHE PATH "The Ruby ruby-lib dir" FORCE)
+ set(Ruby_SITEARCH_DIR ${Ruby_SITEARCH_DIR} CACHE PATH "The Ruby site arch dir" FORCE)
+ set(Ruby_SITELIB_DIR ${Ruby_SITELIB_DIR} CACHE PATH "The Ruby site lib dir" FORCE)
+ set(Ruby_HAS_VENDOR_RUBY ${Ruby_HAS_VENDOR_RUBY} CACHE BOOL "Vendor Ruby is available" FORCE)
+ set(Ruby_VENDORARCH_DIR ${Ruby_VENDORARCH_DIR} CACHE PATH "The Ruby vendor arch dir" FORCE)
+ set(Ruby_VENDORLIB_DIR ${Ruby_VENDORLIB_DIR} CACHE PATH "The Ruby vendor lib dir" FORCE)
mark_as_advanced(
- RUBY_ARCH_DIR
- RUBY_ARCH
- RUBY_HDR_DIR
- RUBY_ARCHHDR_DIR
- RUBY_POSSIBLE_LIB_DIR
- RUBY_RUBY_LIB_DIR
- RUBY_SITEARCH_DIR
- RUBY_SITELIB_DIR
- RUBY_HAS_VENDOR_RUBY
- RUBY_VENDORARCH_DIR
- RUBY_VENDORLIB_DIR
- RUBY_VERSION_MAJOR
- RUBY_VERSION_MINOR
- RUBY_VERSION_PATCH
+ Ruby_ARCH_DIR
+ Ruby_ARCH
+ Ruby_HDR_DIR
+ Ruby_ARCHHDR_DIR
+ Ruby_POSSIBLE_LIB_DIR
+ Ruby_RUBY_LIB_DIR
+ Ruby_SITEARCH_DIR
+ Ruby_SITELIB_DIR
+ Ruby_HAS_VENDOR_RUBY
+ Ruby_VENDORARCH_DIR
+ Ruby_VENDORLIB_DIR
+ Ruby_VERSION_MAJOR
+ Ruby_VERSION_MINOR
+ Ruby_VERSION_PATCH
)
endif()
-# In case RUBY_EXECUTABLE could not be executed (e.g. cross compiling)
+# In case Ruby_EXECUTABLE could not be executed (e.g. cross compiling)
# try to detect which version we found. This is not too good.
-if(RUBY_EXECUTABLE AND NOT RUBY_VERSION_MAJOR)
+if(Ruby_EXECUTABLE AND NOT Ruby_VERSION_MAJOR)
# by default assume 1.8.0
- set(RUBY_VERSION_MAJOR 1)
- set(RUBY_VERSION_MINOR 8)
- set(RUBY_VERSION_PATCH 0)
+ set(Ruby_VERSION_MAJOR 1)
+ set(Ruby_VERSION_MINOR 8)
+ set(Ruby_VERSION_PATCH 0)
# check whether we found 1.9.x
- if(${RUBY_EXECUTABLE} MATCHES "ruby1\\.?9")
- set(RUBY_VERSION_MAJOR 1)
- set(RUBY_VERSION_MINOR 9)
+ if(${Ruby_EXECUTABLE} MATCHES "ruby1\\.?9")
+ set(Ruby_VERSION_MAJOR 1)
+ set(Ruby_VERSION_MINOR 9)
endif()
# check whether we found 2.0.x
- if(${RUBY_EXECUTABLE} MATCHES "ruby2\\.?0")
- set(RUBY_VERSION_MAJOR 2)
- set(RUBY_VERSION_MINOR 0)
+ if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?0")
+ set(Ruby_VERSION_MAJOR 2)
+ set(Ruby_VERSION_MINOR 0)
endif()
# check whether we found 2.1.x
- if(${RUBY_EXECUTABLE} MATCHES "ruby2\\.?1")
- set(RUBY_VERSION_MAJOR 2)
- set(RUBY_VERSION_MINOR 1)
+ 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)
+ 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)
+ 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)
+ 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()
endif()
-if(RUBY_VERSION_MAJOR)
- set(RUBY_VERSION "${RUBY_VERSION_MAJOR}.${RUBY_VERSION_MINOR}.${RUBY_VERSION_PATCH}")
- set(_RUBY_VERSION_SHORT "${RUBY_VERSION_MAJOR}.${RUBY_VERSION_MINOR}")
- set(_RUBY_VERSION_SHORT_NODOT "${RUBY_VERSION_MAJOR}${RUBY_VERSION_MINOR}")
- set(_RUBY_NODOT_VERSION "${RUBY_VERSION_MAJOR}${RUBY_VERSION_MINOR}${RUBY_VERSION_PATCH}")
+if(Ruby_VERSION_MAJOR)
+ set(Ruby_VERSION "${Ruby_VERSION_MAJOR}.${Ruby_VERSION_MINOR}.${Ruby_VERSION_PATCH}")
+ set(_Ruby_VERSION_SHORT "${Ruby_VERSION_MAJOR}.${Ruby_VERSION_MINOR}")
+ set(_Ruby_VERSION_SHORT_NODOT "${Ruby_VERSION_MAJOR}${Ruby_VERSION_MINOR}")
+ set(_Ruby_NODOT_VERSION "${Ruby_VERSION_MAJOR}${Ruby_VERSION_MINOR}${Ruby_VERSION_PATCH}")
endif()
-find_path(RUBY_INCLUDE_DIR
+# FIXME: Currently we require both the interpreter and development components to be found
+# in order to use either. See issue #20474.
+find_path(Ruby_INCLUDE_DIR
NAMES ruby.h
HINTS
- ${RUBY_HDR_DIR}
- ${RUBY_ARCH_DIR}
- /usr/lib/ruby/${_RUBY_VERSION_SHORT}/i586-linux-gnu/
+ ${Ruby_HDR_DIR}
+ ${Ruby_ARCH_DIR}
+ /usr/lib/ruby/${_Ruby_VERSION_SHORT}/i586-linux-gnu/
)
-set(RUBY_INCLUDE_DIRS ${RUBY_INCLUDE_DIR} )
+set(Ruby_INCLUDE_DIRS ${Ruby_INCLUDE_DIR})
# if ruby > 1.8 is required or if ruby > 1.8 was found, search for the config.h dir
-if( "${Ruby_FIND_VERSION_SHORT_NODOT}" GREATER 18 OR "${_RUBY_VERSION_SHORT_NODOT}" GREATER 18 OR RUBY_HDR_DIR)
- find_path(RUBY_CONFIG_INCLUDE_DIR
+if( Ruby_FIND_VERSION VERSION_GREATER_EQUAL "1.9" OR Ruby_VERSION VERSION_GREATER_EQUAL "1.9" OR Ruby_HDR_DIR)
+ find_path(Ruby_CONFIG_INCLUDE_DIR
NAMES ruby/config.h config.h
HINTS
- ${RUBY_HDR_DIR}/${RUBY_ARCH}
- ${RUBY_ARCH_DIR}
- ${RUBY_ARCHHDR_DIR}
+ ${Ruby_HDR_DIR}/${Ruby_ARCH}
+ ${Ruby_ARCH_DIR}
+ ${Ruby_ARCHHDR_DIR}
)
- set(RUBY_INCLUDE_DIRS ${RUBY_INCLUDE_DIRS} ${RUBY_CONFIG_INCLUDE_DIR} )
+ set(Ruby_INCLUDE_DIRS ${Ruby_INCLUDE_DIRS} ${Ruby_CONFIG_INCLUDE_DIR} )
endif()
# Determine the list of possible names for the ruby library
-set(_RUBY_POSSIBLE_LIB_NAMES ruby ruby-static ruby${_RUBY_VERSION_SHORT} ruby${_RUBY_VERSION_SHORT_NODOT} ruby-${_RUBY_VERSION_SHORT} ruby-${RUBY_VERSION})
+set(_Ruby_POSSIBLE_LIB_NAMES ruby ruby-static ruby${_Ruby_VERSION_SHORT} ruby${_Ruby_VERSION_SHORT_NODOT} ruby-${_Ruby_VERSION_SHORT} ruby-${Ruby_VERSION})
if(WIN32)
- set( _RUBY_MSVC_RUNTIME "" )
- if( MSVC_VERSION EQUAL 1200 )
- set( _RUBY_MSVC_RUNTIME "60" )
- endif()
- if( MSVC_VERSION EQUAL 1300 )
- set( _RUBY_MSVC_RUNTIME "70" )
- endif()
- if( MSVC_VERSION EQUAL 1310 )
- set( _RUBY_MSVC_RUNTIME "71" )
- endif()
- if( MSVC_VERSION EQUAL 1400 )
- set( _RUBY_MSVC_RUNTIME "80" )
- endif()
- if( MSVC_VERSION EQUAL 1500 )
- set( _RUBY_MSVC_RUNTIME "90" )
+ if(MSVC_TOOLSET_VERSION)
+ set(_Ruby_MSVC_RUNTIME "${MSVC_TOOLSET_VERSION}")
+ else()
+ set(_Ruby_MSVC_RUNTIME "")
endif()
- set(_RUBY_ARCH_PREFIX "")
+ set(_Ruby_ARCH_PREFIX "")
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
- set(_RUBY_ARCH_PREFIX "x64-")
+ set(_Ruby_ARCH_PREFIX "x64-")
endif()
- list(APPEND _RUBY_POSSIBLE_LIB_NAMES
- "${_RUBY_ARCH_PREFIX}msvcr${_RUBY_MSVC_RUNTIME}-ruby${_RUBY_NODOT_VERSION}"
- "${_RUBY_ARCH_PREFIX}msvcr${_RUBY_MSVC_RUNTIME}-ruby${_RUBY_NODOT_VERSION}-static"
- "${_RUBY_ARCH_PREFIX}msvcrt-ruby${_RUBY_NODOT_VERSION}"
- "${_RUBY_ARCH_PREFIX}msvcrt-ruby${_RUBY_NODOT_VERSION}-static" )
+ list(APPEND _Ruby_POSSIBLE_LIB_NAMES
+ "${_Ruby_ARCH_PREFIX}msvcr${_Ruby_MSVC_RUNTIME}-ruby${_Ruby_NODOT_VERSION}"
+ "${_Ruby_ARCH_PREFIX}msvcr${_Ruby_MSVC_RUNTIME}-ruby${_Ruby_NODOT_VERSION}-static"
+ "${_Ruby_ARCH_PREFIX}msvcrt-ruby${_Ruby_NODOT_VERSION}"
+ "${_Ruby_ARCH_PREFIX}msvcrt-ruby${_Ruby_NODOT_VERSION}-static" )
endif()
-find_library(RUBY_LIBRARY NAMES ${_RUBY_POSSIBLE_LIB_NAMES} HINTS ${RUBY_POSSIBLE_LIB_DIR} )
+find_library(Ruby_LIBRARY NAMES ${_Ruby_POSSIBLE_LIB_NAMES} HINTS ${Ruby_POSSIBLE_LIB_DIR} )
-include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
-set(_RUBY_REQUIRED_VARS RUBY_EXECUTABLE RUBY_INCLUDE_DIR RUBY_LIBRARY)
-if(_RUBY_VERSION_SHORT_NODOT GREATER 18)
- list(APPEND _RUBY_REQUIRED_VARS RUBY_CONFIG_INCLUDE_DIR)
+set(_Ruby_REQUIRED_VARS Ruby_EXECUTABLE Ruby_INCLUDE_DIR Ruby_LIBRARY)
+if(_Ruby_VERSION_SHORT_NODOT GREATER 18)
+ list(APPEND _Ruby_REQUIRED_VARS Ruby_CONFIG_INCLUDE_DIR)
endif()
-if(_RUBY_DEBUG_OUTPUT)
+if(_Ruby_DEBUG_OUTPUT)
message(STATUS "--------FindRuby.cmake debug------------")
- message(STATUS "_RUBY_POSSIBLE_EXECUTABLE_NAMES: ${_RUBY_POSSIBLE_EXECUTABLE_NAMES}")
- message(STATUS "_RUBY_POSSIBLE_LIB_NAMES: ${_RUBY_POSSIBLE_LIB_NAMES}")
- message(STATUS "RUBY_ARCH_DIR: ${RUBY_ARCH_DIR}")
- message(STATUS "RUBY_HDR_DIR: ${RUBY_HDR_DIR}")
- message(STATUS "RUBY_POSSIBLE_LIB_DIR: ${RUBY_POSSIBLE_LIB_DIR}")
- message(STATUS "Found RUBY_VERSION: \"${RUBY_VERSION}\" , short: \"${_RUBY_VERSION_SHORT}\", nodot: \"${_RUBY_VERSION_SHORT_NODOT}\"")
- message(STATUS "_RUBY_REQUIRED_VARS: ${_RUBY_REQUIRED_VARS}")
- message(STATUS "RUBY_EXECUTABLE: ${RUBY_EXECUTABLE}")
- message(STATUS "RUBY_LIBRARY: ${RUBY_LIBRARY}")
- message(STATUS "RUBY_INCLUDE_DIR: ${RUBY_INCLUDE_DIR}")
- message(STATUS "RUBY_CONFIG_INCLUDE_DIR: ${RUBY_CONFIG_INCLUDE_DIR}")
+ message(STATUS "_Ruby_POSSIBLE_EXECUTABLE_NAMES: ${_Ruby_POSSIBLE_EXECUTABLE_NAMES}")
+ message(STATUS "_Ruby_POSSIBLE_LIB_NAMES: ${_Ruby_POSSIBLE_LIB_NAMES}")
+ message(STATUS "Ruby_ARCH_DIR: ${Ruby_ARCH_DIR}")
+ message(STATUS "Ruby_HDR_DIR: ${Ruby_HDR_DIR}")
+ message(STATUS "Ruby_POSSIBLE_LIB_DIR: ${Ruby_POSSIBLE_LIB_DIR}")
+ message(STATUS "Found Ruby_VERSION: \"${Ruby_VERSION}\" , short: \"${_Ruby_VERSION_SHORT}\", nodot: \"${_Ruby_VERSION_SHORT_NODOT}\"")
+ message(STATUS "_Ruby_REQUIRED_VARS: ${_Ruby_REQUIRED_VARS}")
+ message(STATUS "Ruby_EXECUTABLE: ${Ruby_EXECUTABLE}")
+ message(STATUS "Ruby_LIBRARY: ${Ruby_LIBRARY}")
+ message(STATUS "Ruby_INCLUDE_DIR: ${Ruby_INCLUDE_DIR}")
+ message(STATUS "Ruby_CONFIG_INCLUDE_DIR: ${Ruby_CONFIG_INCLUDE_DIR}")
message(STATUS "--------------------")
endif()
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(Ruby REQUIRED_VARS ${_RUBY_REQUIRED_VARS}
- VERSION_VAR RUBY_VERSION )
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Ruby REQUIRED_VARS ${_Ruby_REQUIRED_VARS}
+ VERSION_VAR Ruby_VERSION )
+
+if(Ruby_FOUND)
+ set(Ruby_LIBRARIES ${Ruby_LIBRARY})
+endif()
mark_as_advanced(
- RUBY_EXECUTABLE
- RUBY_LIBRARY
- RUBY_INCLUDE_DIR
- RUBY_CONFIG_INCLUDE_DIR
+ Ruby_EXECUTABLE
+ Ruby_LIBRARY
+ Ruby_INCLUDE_DIR
+ Ruby_CONFIG_INCLUDE_DIR
)
-# Set some variables for compatibility with previous version of this file
-set(RUBY_POSSIBLE_LIB_PATH ${RUBY_POSSIBLE_LIB_DIR})
-set(RUBY_RUBY_LIB_PATH ${RUBY_RUBY_LIB_DIR})
-set(RUBY_INCLUDE_PATH ${RUBY_INCLUDE_DIRS})
+# Set some variables for compatibility with previous version of this file (no need to provide a CamelCase version of that...)
+set(RUBY_POSSIBLE_LIB_PATH ${Ruby_POSSIBLE_LIB_DIR})
+set(RUBY_RUBY_LIB_PATH ${Ruby_RUBY_LIB_DIR})
+set(RUBY_INCLUDE_PATH ${Ruby_INCLUDE_DIRS})
+
+# Backwards compatibility
+# Define upper case versions of output variables
+foreach(Camel
+ Ruby_EXECUTABLE
+ Ruby_INCLUDE_DIRS
+ Ruby_LIBRARY
+ Ruby_VERSION
+ Ruby_VERSION_MAJOR
+ Ruby_VERSION_MINOR
+ Ruby_VERSION_PATCH
+ Ruby_INCLUDE_PATH
+
+ Ruby_ARCH_DIR
+ Ruby_ARCH
+ Ruby_HDR_DIR
+ Ruby_ARCHHDR_DIR
+ Ruby_POSSIBLE_LIB_DIR
+ Ruby_RUBY_LIB_DIR
+ Ruby_SITEARCH_DIR
+ Ruby_SITELIB_DIR
+ Ruby_HAS_VENDOR_RUBY
+ Ruby_VENDORARCH_DIR
+
+ )
+ string(TOUPPER ${Camel} UPPER)
+ set(${UPPER} ${${Camel}})
+endforeach()
diff --git a/Modules/FindSWIG.cmake b/Modules/FindSWIG.cmake
index ae6ae56..2fded49 100644
--- a/Modules/FindSWIG.cmake
+++ b/Modules/FindSWIG.cmake
@@ -5,25 +5,49 @@
FindSWIG
--------
-Find Simplified Wrapper and Interface Generator (SWIG)
+Find the Simplified Wrapper and Interface Generator (SWIG_) executable.
-This module finds an installed SWIG. It sets the following variables:
-
-::
-
- SWIG_FOUND - set to "True" if SWIG is found
- SWIG_DIR - the directory where swig is installed
- SWIG_EXECUTABLE - the path to the swig executable
- SWIG_VERSION - the version number of the swig executable
+This module finds an installed SWIG and determines its version. If a
+``COMPONENTS`` or ``OPTIONAL_COMPONENTS`` argument is given to ``find_package``,
+it will also determine supported target languages. The module sents the
+following variables:
+``SWIG_FOUND``
+ Whether SWIG and any required components were found on the system.
+``SWIG_EXECUTABLE``
+ Path to the SWIG executable.
+``SWIG_DIR``
+ Path to the installed SWIG ``Lib`` directory (result of ``swig -swiglib``).
+``SWIG_VERSION``
+ SWIG executable version (result of ``swig -version``).
+``SWIG_<lang>_FOUND``
+ If ``COMPONENTS`` or ``OPTIONAL_COMPONENTS`` are requested, each available
+ target language ``<lang>`` (lowercase) will be set to TRUE.
-The minimum required version of SWIG can be specified using the
-standard syntax, e.g. :command:`find_package(SWIG 1.1)`
+Any ``COMPONENTS`` given to ``find_package`` should be the names of supported
+target languages as provided to the LANGUAGE argument of ``swig_add_library``,
+such as ``python`` or ``perl5``. Language names *must* be lowercase.
All information is collected from the ``SWIG_EXECUTABLE``, so the version
to be found can be changed from the command line by means of setting
-``SWIG_EXECUTABLE``
+``SWIG_EXECUTABLE``.
+
+Example usage requiring SWIG 4.0 or higher and Python language support, with
+optional Fortran support:
+
+.. code-block:: cmake
+
+ find_package(SWIG 4.0 COMPONENTS python OPTIONAL_COMPONENTS fortran)
+ if(SWIG_FOUND)
+ message("SWIG found: ${SWIG_EXECUTABLE}")
+ if(NOT SWIG_fortran_FOUND)
+ message(WARNING "SWIG Fortran bindings cannot be generated")
+ endif()
+ endif()
+
+.. _`SWIG`: http://swig.org
+
#]=======================================================================]
find_program(SWIG_EXECUTABLE NAMES swig4.0 swig3.0 swig2.0 swig)
@@ -58,10 +82,29 @@ if(SWIG_EXECUTABLE)
endif()
endif()
endif()
+
+ if(SWIG_FIND_COMPONENTS)
+ execute_process(COMMAND ${SWIG_EXECUTABLE} -help
+ OUTPUT_VARIABLE SWIG_swighelp_output
+ ERROR_VARIABLE SWIG_swighelp_error
+ RESULT_VARIABLE SWIG_swighelp_result)
+ if(SWIG_swighelp_result)
+ message(SEND_ERROR "Command \"${SWIG_EXECUTABLE} -help\" failed with output:\n${SWIG_swiglib_error}")
+ else()
+ string(REPLACE "\n" ";" SWIG_swighelp_output "${SWIG_swighelp_output}")
+ foreach(SWIG_line IN LISTS SWIG_swighelp_output)
+ if(SWIG_line MATCHES "-([A-Za-z0-9_]+) +- *Generate.*wrappers")
+ set(SWIG_${CMAKE_MATCH_1}_FOUND TRUE)
+ endif()
+ endforeach()
+ endif()
+ endif()
endif()
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(SWIG REQUIRED_VARS SWIG_EXECUTABLE SWIG_DIR
- VERSION_VAR SWIG_VERSION )
+find_package_handle_standard_args(
+ SWIG HANDLE_COMPONENTS
+ REQUIRED_VARS SWIG_EXECUTABLE SWIG_DIR
+ VERSION_VAR SWIG_VERSION)
mark_as_advanced(SWIG_DIR SWIG_VERSION SWIG_EXECUTABLE)
diff --git a/Modules/FindSquish.cmake b/Modules/FindSquish.cmake
index 7d49505..16f5ab8 100644
--- a/Modules/FindSquish.cmake
+++ b/Modules/FindSquish.cmake
@@ -9,8 +9,7 @@ FindSquish
-This module can be used to find Squish. Currently Squish versions 3
-and 4 are supported.
+This module can be used to find Squish.
::
@@ -39,12 +38,12 @@ and 4 are supported.
-It provides the function squish_v4_add_test() for adding a squish test
-to cmake using Squish 4.x:
+It provides the function squish_add_test() for adding a squish test
+to cmake using Squish >= 4.x:
::
- squish_v4_add_test(cmakeTestName
+ squish_add_test(cmakeTestName
AUT targetName SUITE suiteName TEST squishTestName
[SETTINGSGROUP group] [PRE_COMMAND command] [POST_COMMAND command] )
@@ -78,9 +77,9 @@ The arguments have the following meaning:
::
enable_testing()
- find_package(Squish 4.0)
+ find_package(Squish 6.5)
if (SQUISH_FOUND)
- squish_v4_add_test(myTestName
+ squish_add_test(myTestName
AUT myApp
SUITE ${CMAKE_SOURCE_DIR}/tests/mySuite
TEST someSquishTest
@@ -105,19 +104,12 @@ provided:
::
enable_testing()
- find_package(Squish)
+ find_package(Squish 3.0)
if (SQUISH_FOUND)
squish_v3_add_test(myTestName myApplication testCase envVars testWrapper)
endif ()
-
-macro SQUISH_ADD_TEST(testName applicationUnderTest testCase envVars
-testWrapper)
-
-::
-
- This is deprecated. Use SQUISH_V3_ADD_TEST() if you are using Squish 3.x instead.
#]=======================================================================]
set(SQUISH_INSTALL_DIR_STRING "Directory containing the bin, doc, and lib directories for Squish; this should be the root of the installation directory.")
@@ -137,7 +129,8 @@ if(NOT SQUISH_INSTALL_DIR)
string(REPLACE "//" "/" SQUISH_INSTALL_DIR_SEARCH "${SQUISH_INSTALL_DIR_SEARCH}")
# Look for an installation
- find_path(SQUISH_INSTALL_DIR bin/squishrunner
+ find_path(SQUISH_INSTALL_DIR
+ NAMES bin/squishrunner bin/squishrunner.exe
HINTS
# Look for an environment variable SQUISH_INSTALL_DIR.
ENV SQUISH_INSTALL_DIR
@@ -169,9 +162,9 @@ endif()
set(SQUISH_VERSION)
-set(SQUISH_VERSION_MAJOR )
-set(SQUISH_VERSION_MINOR )
-set(SQUISH_VERSION_PATCH )
+set(SQUISH_VERSION_MAJOR)
+set(SQUISH_VERSION_MINOR)
+set(SQUISH_VERSION_PATCH)
# record if executables are set
if(SQUISH_CLIENT_EXECUTABLE)
@@ -203,8 +196,8 @@ find_package_handle_standard_args(Squish REQUIRED_VARS SQUISH_INSTALL_DIR SQUI
set(_SQUISH_MODULE_DIR "${CMAKE_CURRENT_LIST_DIR}")
-macro(SQUISH_V3_ADD_TEST testName testAUT testCase envVars testWraper)
- if("${SQUISH_VERSION_MAJOR}" STREQUAL "4")
+macro(squish_v3_add_test testName testAUT testCase envVars testWraper)
+ if("${SQUISH_VERSION_MAJOR}" STRGREATER "3")
message(STATUS "Using squish_v3_add_test(), but SQUISH_VERSION_MAJOR is ${SQUISH_VERSION_MAJOR}.\nThis may not work.")
endif()
@@ -227,16 +220,9 @@ macro(SQUISH_V3_ADD_TEST testName testAUT testCase envVars testWraper)
endmacro()
-macro(SQUISH_ADD_TEST)
- message(STATUS "Using squish_add_test() is deprecated, use squish_v3_add_test() instead.")
- squish_v3_add_test(${ARGV})
-endmacro()
-
-
-function(SQUISH_V4_ADD_TEST testName)
-
- if(NOT "${SQUISH_VERSION_MAJOR}" STREQUAL "4")
- message(STATUS "Using squish_v4_add_test(), but SQUISH_VERSION_MAJOR is ${SQUISH_VERSION_MAJOR}.\nThis may not work.")
+function(squish_v4_add_test testName)
+ if(NOT "${SQUISH_VERSION_MAJOR}" STRGREATER "3")
+ message(STATUS "Using squish_add_test(), but SQUISH_VERSION_MAJOR is ${SQUISH_VERSION_MAJOR}.\nThis may not work.")
endif()
set(oneValueArgs AUT SUITE TEST SETTINGSGROUP PRE_COMMAND POST_COMMAND)
@@ -259,10 +245,6 @@ function(SQUISH_V4_ADD_TEST testName)
message(FATAL_ERROR "Required argument TEST not given for SQUISH_ADD_TEST()")
endif()
- get_target_property(testAUTLocation ${_SQUISH_AUT} LOCATION)
- get_filename_component(testAUTDir ${testAUTLocation} PATH)
- get_filename_component(testAUTName ${testAUTLocation} NAME)
-
get_filename_component(absTestSuite "${_SQUISH_SUITE}" ABSOLUTE)
if(NOT EXISTS "${absTestSuite}")
message(FATAL_ERROR "Could not find squish test suite ${_SQUISH_SUITE} (checked ${absTestSuite})")
@@ -277,11 +259,11 @@ function(SQUISH_V4_ADD_TEST testName)
set(_SQUISH_SETTINGSGROUP "CTest_$ENV{LOGNAME}")
endif()
- add_test(${testName}
- ${CMAKE_COMMAND} -V -VV
+ add_test(NAME ${testName}
+ COMMAND ${CMAKE_COMMAND} -V -VV
"-Dsquish_version:STRING=4"
- "-Dsquish_aut:STRING=${testAUTName}"
- "-Dsquish_aut_dir:STRING=${testAUTDir}"
+ "-Dsquish_aut:STRING=$<TARGET_FILE_BASE_NAME:${_SQUISH_AUT}>"
+ "-Dsquish_aut_dir:STRING=$<TARGET_FILE_DIR:${_SQUISH_AUT}>"
"-Dsquish_server_executable:STRING=${SQUISH_SERVER_EXECUTABLE}"
"-Dsquish_client_executable:STRING=${SQUISH_CLIENT_EXECUTABLE}"
"-Dsquish_libqtdir:STRING=${QT_LIBRARY_DIR}"
@@ -299,3 +281,11 @@ function(SQUISH_V4_ADD_TEST testName)
PROPERTIES FAIL_REGULAR_EXPRESSION "FAIL;FAILED;ERROR;FATAL"
)
endfunction()
+
+macro(squish_add_test)
+ if("${SQUISH_VERSION_MAJOR}" STRGREATER "3")
+ squish_v4_add_test(${ARGV})
+ else()
+ squish_v3_add_test(${ARGV})
+ endif()
+endmacro()
diff --git a/Modules/FindTCL.cmake b/Modules/FindTCL.cmake
index be47c39..960265f 100644
--- a/Modules/FindTCL.cmake
+++ b/Modules/FindTCL.cmake
@@ -224,12 +224,14 @@ find_path(TK_INCLUDE_PATH
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(TCL DEFAULT_MSG TCL_LIBRARY TCL_INCLUDE_PATH)
+set(FPHSA_NAME_MISMATCHED 1)
set(TCLTK_FIND_REQUIRED ${TCL_FIND_REQUIRED})
set(TCLTK_FIND_QUIETLY ${TCL_FIND_QUIETLY})
FIND_PACKAGE_HANDLE_STANDARD_ARGS(TCLTK DEFAULT_MSG TCL_LIBRARY TCL_INCLUDE_PATH TK_LIBRARY TK_INCLUDE_PATH)
set(TK_FIND_REQUIRED ${TCL_FIND_REQUIRED})
set(TK_FIND_QUIETLY ${TCL_FIND_QUIETLY})
FIND_PACKAGE_HANDLE_STANDARD_ARGS(TK DEFAULT_MSG TK_LIBRARY TK_INCLUDE_PATH)
+unset(FPHSA_NAME_MISMATCHED)
mark_as_advanced(
TCL_INCLUDE_PATH
diff --git a/Modules/FindThreads.cmake b/Modules/FindThreads.cmake
index b0c91b2..f97e5c8 100644
--- a/Modules/FindThreads.cmake
+++ b/Modules/FindThreads.cmake
@@ -7,31 +7,44 @@ FindThreads
This module determines the thread library of the system.
-The following variables are set
+Imported Targets
+^^^^^^^^^^^^^^^^
-::
+This module defines the following :prop_tgt:`IMPORTED` target:
- CMAKE_THREAD_LIBS_INIT - the thread library
- CMAKE_USE_WIN32_THREADS_INIT - using WIN32 threads?
- CMAKE_USE_PTHREADS_INIT - are we using pthreads
- CMAKE_HP_PTHREADS_INIT - are we using hp pthreads
+``Threads::Threads``
+ The thread library, if found.
-The following import target is created
+Result Variables
+^^^^^^^^^^^^^^^^
-::
+The following variables are set:
- Threads::Threads
+``Threads_FOUND``
+ If a supported thread library was found.
+``CMAKE_THREAD_LIBS_INIT``
+ The thread library to use. This may be empty if the thread functions
+ are provided by the system libraries and no special flags are needed
+ to use them.
+``CMAKE_USE_WIN32_THREADS_INIT``
+ If the found thread library is the win32 one.
+``CMAKE_USE_PTHREADS_INIT``
+ If the found thread library is pthread compatible.
+``CMAKE_HP_PTHREADS_INIT``
+ If the found thread library is the HP thread library.
-If the use of the -pthread compiler and linker flag is preferred then the
-caller can set
+Variables Affecting Behavior
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-::
+.. variable:: THREADS_PREFER_PTHREAD_FLAG
- THREADS_PREFER_PTHREAD_FLAG
+ If the use of the -pthread compiler and linker flag is preferred then
+ the caller can set this variable to TRUE. The compiler flag can only be
+ used with the imported target. Use of both the imported target as well
+ as this switch is highly recommended for new code.
-The compiler flag can only be used with the imported
-target. Use of both the imported target as well as this switch is highly
-recommended for new code.
+ This variable has no effect if the system libraries provide the
+ thread functions, i.e. when ``CMAKE_THREAD_LIBS_INIT`` will be empty.
#]=======================================================================]
include (CheckLibraryExists)
@@ -63,6 +76,7 @@ int main(void)
pthread_t thread;
pthread_create(&thread, NULL, test_func, NULL);
pthread_detach(thread);
+ pthread_cancel(thread);
pthread_join(thread, NULL);
pthread_atfork(NULL, NULL, NULL);
pthread_exit(NULL);
@@ -90,7 +104,7 @@ macro(_check_pthreads_flag)
if(NOT Threads_FOUND)
# If we did not found -lpthread, -lpthread, or -lthread, look for -pthread
if(NOT DEFINED THREADS_HAVE_PTHREAD_ARG)
- message(STATUS "Check if compiler accepts -pthread")
+ message(CHECK_START "Check if compiler accepts -pthread")
if(CMAKE_C_COMPILER_LOADED)
set(_threads_src ${CMAKE_CURRENT_LIST_DIR}/CheckForPthreads.c)
elseif(CMAKE_CXX_COMPILER_LOADED)
@@ -106,9 +120,9 @@ macro(_check_pthreads_flag)
if(THREADS_HAVE_PTHREAD_ARG)
set(Threads_FOUND TRUE)
- message(STATUS "Check if compiler accepts -pthread - yes")
+ message(CHECK_PASS "yes")
else()
- message(STATUS "Check if compiler accepts -pthread - no")
+ message(CHECK_FAIL "no")
file(APPEND
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if compiler accepts -pthread failed with the following output:\n${OUTPUT}\n\n")
diff --git a/Modules/FindVulkan.cmake b/Modules/FindVulkan.cmake
index 55da55f..4b999b6 100644
--- a/Modules/FindVulkan.cmake
+++ b/Modules/FindVulkan.cmake
@@ -28,40 +28,46 @@ The module will also define two cache variables::
Vulkan_INCLUDE_DIR - the Vulkan include directory
Vulkan_LIBRARY - the path to the Vulkan library
+Hints
+^^^^^
+
+The ``VULKAN_SDK`` environment variable optionally specifies the
+location of the Vulkan SDK root directory for the given
+architecture. It is typically set by sourcing the toplevel
+``setup-env.sh`` script of the Vulkan SDK directory into the shell
+environment.
+
#]=======================================================================]
if(WIN32)
find_path(Vulkan_INCLUDE_DIR
NAMES vulkan/vulkan.h
- PATHS
+ HINTS
"$ENV{VULKAN_SDK}/Include"
)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
find_library(Vulkan_LIBRARY
NAMES vulkan-1
- PATHS
+ HINTS
"$ENV{VULKAN_SDK}/Lib"
"$ENV{VULKAN_SDK}/Bin"
- )
+ )
elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
find_library(Vulkan_LIBRARY
NAMES vulkan-1
- PATHS
+ HINTS
"$ENV{VULKAN_SDK}/Lib32"
"$ENV{VULKAN_SDK}/Bin32"
- NO_SYSTEM_ENVIRONMENT_PATH
- )
+ )
endif()
else()
- find_path(Vulkan_INCLUDE_DIR
- NAMES vulkan/vulkan.h
- PATHS
- "$ENV{VULKAN_SDK}/include")
- find_library(Vulkan_LIBRARY
- NAMES vulkan
- PATHS
- "$ENV{VULKAN_SDK}/lib")
+ find_path(Vulkan_INCLUDE_DIR
+ NAMES vulkan/vulkan.h
+ HINTS "$ENV{VULKAN_SDK}/include")
+ find_library(Vulkan_LIBRARY
+ NAMES vulkan
+ HINTS "$ENV{VULKAN_SDK}/lib")
endif()
set(Vulkan_LIBRARIES ${Vulkan_LIBRARY})
diff --git a/Modules/FindX11.cmake b/Modules/FindX11.cmake
index b28dd12..aa83575 100644
--- a/Modules/FindX11.cmake
+++ b/Modules/FindX11.cmake
@@ -25,6 +25,10 @@ and also the following more fine grained variables and targets:
X11_Xaccessrules_INCLUDE_PATH,
X11_Xaccessstr_INCLUDE_PATH, X11_Xaccess_FOUND
X11_Xau_INCLUDE_PATH, X11_Xau_LIB, X11_Xau_FOUND, X11::Xau
+ X11_xcb_INCLUDE_PATH, X11_xcb_LIB, X11_xcb_FOUND, X11::xcb
+ X11_X11_xcb_INCLUDE_PATH, X11_X11_xcb_LIB, X11_X11_xcb_FOUND, X11::X11_xcb
+ X11_xcb_icccm_INCLUDE_PATH, X11_xcb_icccm_LIB, X11_xcb_icccm_FOUND, X11::xcb_icccm
+ X11_xcb_xkb_INCLUDE_PATH, X11_xcb_xkb_LIB, X11_xcb_xkb_FOUND, X11::xcb_xkb
X11_Xcomposite_INCLUDE_PATH, X11_Xcomposite_LIB, X11_Xcomposite_FOUND, X11::Xcomposite
X11_Xcursor_INCLUDE_PATH, X11_Xcursor_LIB, X11_Xcursor_FOUND, X11::Xcursor
X11_Xdamage_INCLUDE_PATH, X11_Xdamage_LIB, X11_Xdamage_FOUND, X11::Xdamage
@@ -38,6 +42,8 @@ and also the following more fine grained variables and targets:
X11_Xinerama_INCLUDE_PATH, X11_Xinerama_LIB, X11_Xinerama_FOUND, X11::Xinerama
X11_Xkb_INCLUDE_PATH,
X11_Xkblib_INCLUDE_PATH, X11_Xkb_FOUND, X11::Xkb
+ X11_xkbcommon_INCLUDE_PATH, X11_xkbcommon_LIB, X11_xkbcommon_FOUND, X11::xkbcommon
+ X11_xkbcommon_X11_INCLUDE_PATH,X11_xkbcommon_X11_LIB,X11_xkbcommon_X11_FOUND,X11::xkbcommon_X11
X11_xkbfile_INCLUDE_PATH, X11_xkbfile_LIB, X11_xkbfile_FOUND, X11::xkbfile
X11_Xmu_INCLUDE_PATH, X11_Xmu_LIB, X11_Xmu_FOUND, X11::Xmu
X11_Xpm_INCLUDE_PATH, X11_Xpm_LIB, X11_Xpm_FOUND, X11::Xpm
@@ -94,6 +100,9 @@ if (UNIX)
find_path(X11_Xaccessrules_INCLUDE_PATH X11/extensions/XKBrules.h ${X11_INC_SEARCH_PATH})
find_path(X11_Xaccessstr_INCLUDE_PATH X11/extensions/XKBstr.h ${X11_INC_SEARCH_PATH})
find_path(X11_Xau_INCLUDE_PATH X11/Xauth.h ${X11_INC_SEARCH_PATH})
+ find_path(X11_xcb_INCLUDE_PATH xcb/xcb.h ${X11_INC_SEARCH_PATH})
+ find_path(X11_X11_xcb_INCLUDE_PATH X11/Xlib-xcb.h ${X11_INC_SEARCH_PATH})
+ find_path(X11_xcb_icccm_INCLUDE_PATH xcb/xcb_icccm.h ${X11_INC_SEARCH_PATH})
find_path(X11_Xcomposite_INCLUDE_PATH X11/extensions/Xcomposite.h ${X11_INC_SEARCH_PATH})
find_path(X11_Xcursor_INCLUDE_PATH X11/Xcursor/Xcursor.h ${X11_INC_SEARCH_PATH})
find_path(X11_Xdamage_INCLUDE_PATH X11/extensions/Xdamage.h ${X11_INC_SEARCH_PATH})
@@ -107,6 +116,8 @@ if (UNIX)
find_path(X11_Xi_INCLUDE_PATH X11/extensions/XInput.h ${X11_INC_SEARCH_PATH})
find_path(X11_Xinerama_INCLUDE_PATH X11/extensions/Xinerama.h ${X11_INC_SEARCH_PATH})
find_path(X11_Xkb_INCLUDE_PATH X11/extensions/XKB.h ${X11_INC_SEARCH_PATH})
+ find_path(X11_xkbcommon_INCLUDE_PATH xkbcommon/xkbcommon.h ${X11_INC_SEARCH_PATH})
+ find_path(X11_xkbcommon_X11_INCLUDE_PATH xkbcommon/xkbcommon-x11.h ${X11_INC_SEARCH_PATH})
find_path(X11_Xkblib_INCLUDE_PATH X11/XKBlib.h ${X11_INC_SEARCH_PATH})
find_path(X11_xkbfile_INCLUDE_PATH X11/extensions/XKBfile.h ${X11_INC_SEARCH_PATH})
find_path(X11_Xmu_INCLUDE_PATH X11/Xmu/Xmu.h ${X11_INC_SEARCH_PATH})
@@ -137,6 +148,10 @@ if (UNIX)
find_library(X11_ICE_LIB ICE ${X11_LIB_SEARCH_PATH})
find_library(X11_SM_LIB SM ${X11_LIB_SEARCH_PATH})
find_library(X11_Xau_LIB Xau ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_LIB xcb ${X11_LIB_SEARCH_PATH})
+ find_library(X11_X11_xcb_LIB X11-xcb ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_icccm_LIB xcb-icccm ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_xkb_LIB xcb-xkb ${X11_LIB_SEARCH_PATH})
find_library(X11_Xcomposite_LIB Xcomposite ${X11_LIB_SEARCH_PATH})
find_library(X11_Xcursor_LIB Xcursor ${X11_LIB_SEARCH_PATH})
find_library(X11_Xdamage_LIB Xdamage ${X11_LIB_SEARCH_PATH})
@@ -146,6 +161,8 @@ if (UNIX)
find_library(X11_Xft_LIB Xft ${X11_LIB_SEARCH_PATH})
find_library(X11_Xi_LIB Xi ${X11_LIB_SEARCH_PATH})
find_library(X11_Xinerama_LIB Xinerama ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xkbcommon_LIB xkbcommon ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xkbcommon_X11_LIB xkbcommon-x11 ${X11_LIB_SEARCH_PATH})
find_library(X11_xkbfile_LIB xkbfile ${X11_LIB_SEARCH_PATH})
find_library(X11_Xmu_LIB Xmu ${X11_LIB_SEARCH_PATH})
find_library(X11_Xpm_LIB Xpm ${X11_LIB_SEARCH_PATH})
@@ -221,6 +238,22 @@ if (UNIX)
set(X11_Xau_FOUND TRUE)
endif ()
+ if (X11_xcb_LIB AND X11_xcb_INCLUDE_PATH)
+ set(X11_xcb_FOUND TRUE)
+ endif ()
+
+ if (X11_X11_xcb_LIB AND X11_X11_xcb_INCLUDE_PATH)
+ set(X11_X11_xcb_FOUND TRUE)
+ endif ()
+
+ if (X11_xcb_icccm_LIB AND X11_xcb_icccm_INCLUDE_PATH)
+ set(X11_xcb_icccm_FOUND TRUE)
+ endif ()
+
+ if (X11_xcb_xkb_LIB)
+ set(X11_xcb_xkb_FOUND TRUE)
+ endif ()
+
if (X11_Xdmcp_INCLUDE_PATH AND X11_Xdmcp_LIB)
set(X11_Xdmcp_FOUND TRUE)
list(APPEND X11_INCLUDE_DIR ${X11_Xdmcp_INCLUDE_PATH})
@@ -326,6 +359,14 @@ if (UNIX)
list(APPEND X11_INCLUDE_DIR ${X11_Xkb_INCLUDE_PATH} )
endif ()
+ if (X11_xkbcommon_INCLUDE_PATH AND X11_xkbcommon_LIB)
+ set(X11_xkbcommon_FOUND TRUE)
+ endif ()
+
+ if (X11_xkbcommon_X11_INCLUDE_PATH AND X11_xkbcommon_X11_LIB)
+ set(X11_xkbcommon_X11_FOUND TRUE)
+ endif ()
+
if (X11_xkbfile_INCLUDE_PATH AND X11_xkbfile_LIB AND X11_Xlib_INCLUDE_PATH)
set(X11_xkbfile_FOUND TRUE)
# Backwards compatibility.
@@ -478,6 +519,35 @@ if (UNIX)
INTERFACE_INCLUDE_DIRECTORIES "${X11_Xau_INCLUDE_PATH}")
endif ()
+ if (X11_xcb_FOUND AND NOT TARGET X11::xcb)
+ add_library(X11::xcb UNKNOWN IMPORTED)
+ set_target_properties(X11::xcb PROPERTIES
+ IMPORTED_LOCATION "${X11_xcb_LIB}"
+ INTERFACE_INCLUDE_DIRECTORIES "${X11_xcb_INCLUDE_PATH}")
+ endif ()
+
+ if (X11_X11_xcb_FOUND AND NOT TARGET X11::X11_xcb)
+ add_library(X11::X11_xcb UNKNOWN IMPORTED)
+ set_target_properties(X11::X11_xcb PROPERTIES
+ IMPORTED_LOCATION "${X11_X11_xcb_LIB}"
+ INTERFACE_INCLUDE_DIRECTORIES "${X11_X11_xcb_INCLUDE_PATH}"
+ INTERFACE_LINK_LIBRARIES "X11::xcb;X11::X11")
+ endif ()
+
+ if (X11_xcb_icccm_FOUND AND NOT TARGET X11::xcb_icccm)
+ add_library(X11::xcb_icccm UNKNOWN IMPORTED)
+ set_target_properties(X11::xcb_icccm PROPERTIES
+ IMPORTED_LOCATION "${X11_xcb_icccm_LIB}"
+ INTERFACE_LINK_LIBRARIES "X11::xcb")
+ endif ()
+
+ if (X11_xcb_xkb_FOUND AND NOT TARGET X11::xcb_xkb)
+ add_library(X11::xcb_xkb UNKNOWN IMPORTED)
+ set_target_properties(X11::xcb_xkb PROPERTIES
+ IMPORTED_LOCATION "${X11_xcb_xkb_LIB}"
+ INTERFACE_LINK_LIBRARIES "X11::xcb")
+ endif ()
+
if (X11_Xcomposite_FOUND AND NOT TARGET X11::Xcomposite)
add_library(X11::Xcomposite UNKNOWN IMPORTED)
set_target_properties(X11::Xcomposite PROPERTIES
@@ -572,6 +642,21 @@ if (UNIX)
INTERFACE_LINK_LIBRARIES "X11::X11")
endif ()
+ if (X11_xkbcommon_FOUND AND NOT TARGET X11::xkbcommon)
+ add_library(X11::xkbcommon UNKNOWN IMPORTED)
+ set_target_properties(X11::xkbcommon PROPERTIES
+ IMPORTED_LOCATION "${X11_xkbcommon_LIB}"
+ INTERFACE_INCLUDE_DIRECTORIES "${X11_xkbcommon_INCLUDE_PATH}")
+ endif ()
+
+ if (X11_xkbcommon_X11_FOUND AND NOT TARGET X11::xkbcommon_X11)
+ add_library(X11::xkbcommon_X11 UNKNOWN IMPORTED)
+ set_target_properties(X11::xkbcommon_X11 PROPERTIES
+ IMPORTED_LOCATION "${X11_xkbcommon_X11_LIB}"
+ INTERFACE_INCLUDE_DIRECTORIES "${X11_xkbcommon_X11_INCLUDE_PATH}"
+ INTERFACE_LINK_LIBRARIES "X11::X11;X11::xkbcommon")
+ endif ()
+
if (X11_xkbfile_FOUND AND NOT TARGET X11::xkbfile)
add_library(X11::xkbfile UNKNOWN IMPORTED)
set_target_properties(X11::xkbfile PROPERTIES
@@ -668,6 +753,11 @@ if (UNIX)
X11_Xext_LIB
X11_Xau_LIB
X11_Xau_INCLUDE_PATH
+ X11_xcb_LIB
+ X11_xcb_INCLUDE_PATH
+ X11_xcb_xkb_LIB
+ X11_X11_xcb_LIB
+ X11_X11_xcb_INCLUDE_PATH
X11_Xlib_INCLUDE_PATH
X11_Xutil_INCLUDE_PATH
X11_Xcomposite_INCLUDE_PATH
@@ -704,6 +794,10 @@ if (UNIX)
X11_Xdmcp_INCLUDE_PATH
X11_Xkb_INCLUDE_PATH
X11_Xkblib_INCLUDE_PATH
+ X11_xkbcommon_INCLUDE_PATH
+ X11_xkbcommon_LIB
+ X11_xkbcommon_X11_INCLUDE_PATH
+ X11_xkbcommon_X11_LIB
X11_xkbfile_INCLUDE_PATH
X11_xkbfile_LIB
X11_Xmu_INCLUDE_PATH
diff --git a/Modules/FortranCInterface.cmake b/Modules/FortranCInterface.cmake
index 893a96f..547346b 100644
--- a/Modules/FortranCInterface.cmake
+++ b/Modules/FortranCInterface.cmake
@@ -341,7 +341,7 @@ function(FortranCInterface_VERIFY)
# Build the verification project if not yet built.
if(NOT DEFINED FortranCInterface_VERIFIED_${lang})
set(_desc "Verifying Fortran/${lang} Compiler Compatibility")
- message(STATUS "${_desc}")
+ message(CHECK_START "${_desc}")
# Build a sample project which reports symbols.
set(CMAKE_TRY_COMPILE_CONFIGURATION Release)
@@ -363,12 +363,12 @@ function(FortranCInterface_VERIFY)
# Report results.
if(FortranCInterface_VERIFY_${lang}_COMPILED)
- message(STATUS "${_desc} - Success")
+ message(CHECK_PASS "Success")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"${_desc} passed with the following output:\n${_output}\n\n")
set(FortranCInterface_VERIFIED_${lang} 1 CACHE INTERNAL "Fortran/${lang} compatibility")
else()
- message(STATUS "${_desc} - Failed")
+ message(CHECK_FAIL "Failed")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"${_desc} failed with the following output:\n${_output}\n\n")
set(FortranCInterface_VERIFIED_${lang} 0 CACHE INTERNAL "Fortran/${lang} compatibility")
diff --git a/Modules/FortranCInterface/CMakeLists.txt b/Modules/FortranCInterface/CMakeLists.txt
index 381080b..13e4498 100644
--- a/Modules/FortranCInterface/CMakeLists.txt
+++ b/Modules/FortranCInterface/CMakeLists.txt
@@ -101,3 +101,7 @@ set_property(TARGET symbols PROPERTY POSITION_INDEPENDENT_CODE 1)
# Require symbols through Fortran.
add_executable(FortranCInterface main.F call_sub.f ${call_mod})
target_link_libraries(FortranCInterface PUBLIC symbols)
+
+file(GENERATE OUTPUT exe-$<CONFIG>.cmake CONTENT [[
+set(FortranCInterface_EXE "$<TARGET_FILE:FortranCInterface>")
+]])
diff --git a/Modules/FortranCInterface/Detect.cmake b/Modules/FortranCInterface/Detect.cmake
index 7789785..c75067b 100644
--- a/Modules/FortranCInterface/Detect.cmake
+++ b/Modules/FortranCInterface/Detect.cmake
@@ -15,7 +15,7 @@ if(${FortranCInterface_BINARY_DIR}/Input.cmake
OR ${CMAKE_CURRENT_LIST_FILE}
IS_NEWER_THAN ${FortranCInterface_BINARY_DIR}/Output.cmake
)
- message(STATUS "Detecting Fortran/C Interface")
+ message(CHECK_START "Detecting Fortran/C Interface")
else()
return()
endif()
@@ -43,17 +43,11 @@ set(FortranCInterface_COMPILED ${FortranCInterface_COMPILED})
unset(FortranCInterface_COMPILED CACHE)
# Locate the sample project executable.
+set(FortranCInterface_EXE)
if(FortranCInterface_COMPILED)
- find_program(FortranCInterface_EXE
- NAMES FortranCInterface${CMAKE_EXECUTABLE_SUFFIX}
- PATHS ${FortranCInterface_BINARY_DIR} ${FortranCInterface_BINARY_DIR}/Release
- NO_DEFAULT_PATH
- )
- set(FortranCInterface_EXE ${FortranCInterface_EXE})
- unset(FortranCInterface_EXE CACHE)
+ include(${FortranCInterface_BINARY_DIR}/exe-Release.cmake OPTIONAL)
else()
set(_result "Failed to compile")
- set(FortranCInterface_EXE)
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Fortran/C interface test project failed with the following output:\n"
"${FortranCInterface_OUTPUT}\n")
@@ -172,7 +166,9 @@ if(FortranCInterface_GLOBAL_FOUND)
else()
set(_result "Found GLOBAL but not MODULE mangling")
endif()
+ set(_result_type CHECK_PASS)
elseif(NOT _result)
set(_result "Failed to recognize symbols")
+ set(_result_type CHECK_FAIL)
endif()
-message(STATUS "Detecting Fortran/C Interface - ${_result}")
+message(${_result_type} "${_result}")
diff --git a/Modules/GNUInstallDirs.cmake b/Modules/GNUInstallDirs.cmake
index f95e6e2..9ef22b9 100644
--- a/Modules/GNUInstallDirs.cmake
+++ b/Modules/GNUInstallDirs.cmake
@@ -221,6 +221,11 @@ if(NOT DEFINED CMAKE_INSTALL_LIBDIR OR (_libdir_set
# default one. When CMAKE_INSTALL_PREFIX changes, the value is
# updated to the new default, unless the user explicitly changed it.
endif()
+ if (NOT DEFINED CMAKE_SYSTEM_NAME OR NOT DEFINED CMAKE_SIZEOF_VOID_P)
+ message(AUTHOR_WARNING
+ "Unable to determine default CMAKE_INSTALL_LIBDIR directory because no target architecture is known. "
+ "Please enable at least one language before including GNUInstallDirs.")
+ endif()
if(CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU)$"
AND NOT CMAKE_CROSSCOMPILING
AND NOT EXISTS "/etc/arch-release")
@@ -235,16 +240,10 @@ if(NOT DEFINED CMAKE_INSTALL_LIBDIR OR (_libdir_set
endif()
endif()
else() # not debian, rely on CMAKE_SIZEOF_VOID_P:
- if(NOT DEFINED CMAKE_SIZEOF_VOID_P)
- message(AUTHOR_WARNING
- "Unable to determine default CMAKE_INSTALL_LIBDIR directory because no target architecture is known. "
- "Please enable at least one language before including GNUInstallDirs.")
- else()
- if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
- set(_LIBDIR_DEFAULT "lib64")
- if(DEFINED _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX)
- set(__LAST_LIBDIR_DEFAULT "lib64")
- endif()
+ if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
+ set(_LIBDIR_DEFAULT "lib64")
+ if(DEFINED _GNUInstallDirs_LAST_CMAKE_INSTALL_PREFIX)
+ set(__LAST_LIBDIR_DEFAULT "lib64")
endif()
endif()
endif()
diff --git a/Modules/GoogleTest.cmake b/Modules/GoogleTest.cmake
index a5bb863..975ce6c 100644
--- a/Modules/GoogleTest.cmake
+++ b/Modules/GoogleTest.cmake
@@ -151,6 +151,8 @@ same as the Google Test name (i.e. ``suite.testcase``); see also
[PROPERTIES name1 value1...]
[TEST_LIST var]
[DISCOVERY_TIMEOUT seconds]
+ [XML_OUTPUT_DIR dir]
+ [DISCOVERY_MODE <POST_BUILD|PRE_TEST>]
)
``gtest_discover_tests`` sets up a post-build command on the test executable
@@ -236,6 +238,29 @@ same as the Google Test name (i.e. ``suite.testcase``); see also
problem. The ambiguous behavior of the ``TIMEOUT`` keyword in 3.10.1
and 3.10.2 has not been preserved.
+ ``XML_OUTPUT_DIR dir``
+ If specified, the parameter is passed along with ``--gtest_output=xml:``
+ to test executable. The actual file name is the same as the test target,
+ including prefix and suffix. This should be used instead of
+ ``EXTRA_ARGS --gtest_output=xml`` to avoid race conditions writing the
+ XML result output when using parallel test execution.
+
+ ``DISCOVERY_MODE``
+ Provides greater control over when ``gtest_discover_tests``performs test
+ discovery. By default, ``POST_BUILD`` sets up a post-build command
+ to perform test discovery at build time. In certain scenarios, like
+ cross-compiling, this ``POST_BUILD`` behavior is not desirable.
+ By contrast, ``PRE_TEST`` delays test discovery until just prior to test
+ execution. This way test discovery occurs in the target environment
+ where the test has a better chance at finding appropriate runtime
+ dependencies.
+
+ ``DISCOVERY_MODE`` defaults to the value of the
+ ``CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE`` variable if it is not
+ passed when calling ``gtest_discover_tests``. This provides a mechanism
+ for globally selecting a preferred test discovery behavior without having
+ to modify each call site.
+
#]=======================================================================]
# Save project's policies
@@ -368,11 +393,12 @@ function(gtest_add_tests)
endfunction()
#------------------------------------------------------------------------------
+
function(gtest_discover_tests TARGET)
cmake_parse_arguments(
""
"NO_PRETTY_TYPES;NO_PRETTY_VALUES"
- "TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST;DISCOVERY_TIMEOUT"
+ "TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST;DISCOVERY_TIMEOUT;XML_OUTPUT_DIR;DISCOVERY_MODE"
"EXTRA_ARGS;PROPERTIES"
${ARGN}
)
@@ -386,6 +412,12 @@ function(gtest_discover_tests TARGET)
if(NOT _DISCOVERY_TIMEOUT)
set(_DISCOVERY_TIMEOUT 5)
endif()
+ if(NOT _DISCOVERY_MODE)
+ if(NOT CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE)
+ set(CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE "POST_BUILD")
+ endif()
+ set(_DISCOVERY_MODE ${CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE})
+ endif()
get_property(
has_counter
@@ -417,34 +449,86 @@ function(gtest_discover_tests TARGET)
TARGET ${TARGET}
PROPERTY CROSSCOMPILING_EMULATOR
)
- add_custom_command(
- TARGET ${TARGET} POST_BUILD
- BYPRODUCTS "${ctest_tests_file}"
- COMMAND "${CMAKE_COMMAND}"
- -D "TEST_TARGET=${TARGET}"
- -D "TEST_EXECUTABLE=$<TARGET_FILE:${TARGET}>"
- -D "TEST_EXECUTOR=${crosscompiling_emulator}"
- -D "TEST_WORKING_DIR=${_WORKING_DIRECTORY}"
- -D "TEST_EXTRA_ARGS=${_EXTRA_ARGS}"
- -D "TEST_PROPERTIES=${_PROPERTIES}"
- -D "TEST_PREFIX=${_TEST_PREFIX}"
- -D "TEST_SUFFIX=${_TEST_SUFFIX}"
- -D "NO_PRETTY_TYPES=${_NO_PRETTY_TYPES}"
- -D "NO_PRETTY_VALUES=${_NO_PRETTY_VALUES}"
- -D "TEST_LIST=${_TEST_LIST}"
- -D "CTEST_FILE=${ctest_tests_file}"
- -D "TEST_DISCOVERY_TIMEOUT=${_DISCOVERY_TIMEOUT}"
- -P "${_GOOGLETEST_DISCOVER_TESTS_SCRIPT}"
- VERBATIM
- )
- file(WRITE "${ctest_include_file}"
- "if(EXISTS \"${ctest_tests_file}\")\n"
- " include(\"${ctest_tests_file}\")\n"
- "else()\n"
- " add_test(${TARGET}_NOT_BUILT ${TARGET}_NOT_BUILT)\n"
- "endif()\n"
- )
+ if(_DISCOVERY_MODE STREQUAL "POST_BUILD")
+ add_custom_command(
+ TARGET ${TARGET} POST_BUILD
+ BYPRODUCTS "${ctest_tests_file}"
+ COMMAND "${CMAKE_COMMAND}"
+ -D "TEST_TARGET=${TARGET}"
+ -D "TEST_EXECUTABLE=$<TARGET_FILE:${TARGET}>"
+ -D "TEST_EXECUTOR=${crosscompiling_emulator}"
+ -D "TEST_WORKING_DIR=${_WORKING_DIRECTORY}"
+ -D "TEST_EXTRA_ARGS=${_EXTRA_ARGS}"
+ -D "TEST_PROPERTIES=${_PROPERTIES}"
+ -D "TEST_PREFIX=${_TEST_PREFIX}"
+ -D "TEST_SUFFIX=${_TEST_SUFFIX}"
+ -D "NO_PRETTY_TYPES=${_NO_PRETTY_TYPES}"
+ -D "NO_PRETTY_VALUES=${_NO_PRETTY_VALUES}"
+ -D "TEST_LIST=${_TEST_LIST}"
+ -D "CTEST_FILE=${ctest_tests_file}"
+ -D "TEST_DISCOVERY_TIMEOUT=${_DISCOVERY_TIMEOUT}"
+ -D "TEST_XML_OUTPUT_DIR=${_XML_OUTPUT_DIR}"
+ -P "${_GOOGLETEST_DISCOVER_TESTS_SCRIPT}"
+ VERBATIM
+ )
+
+ file(WRITE "${ctest_include_file}"
+ "if(EXISTS \"${ctest_tests_file}\")\n"
+ " include(\"${ctest_tests_file}\")\n"
+ "else()\n"
+ " add_test(${TARGET}_NOT_BUILT ${TARGET}_NOT_BUILT)\n"
+ "endif()\n"
+ )
+ elseif(_DISCOVERY_MODE STREQUAL "PRE_TEST")
+
+ get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL
+ PROPERTY GENERATOR_IS_MULTI_CONFIG
+ )
+
+ if(GENERATOR_IS_MULTI_CONFIG)
+ set(ctest_tests_file "${ctest_file_base}_tests-$<CONFIG>.cmake")
+ endif()
+
+ string(CONCAT ctest_include_content
+ "if(EXISTS \"$<TARGET_FILE:${TARGET}>\")" "\n"
+ " if(\"$<TARGET_FILE:${TARGET}>\" IS_NEWER_THAN \"${ctest_tests_file}\")" "\n"
+ " include(GoogleTestAddTests)" "\n"
+ " gtest_discover_tests_impl(" "\n"
+ " TEST_EXECUTABLE" " [==[" "$<TARGET_FILE:${TARGET}>" "]==]" "\n"
+ " TEST_EXECUTOR" " [==[" "${crosscompiling_emulator}" "]==]" "\n"
+ " TEST_WORKING_DIR" " [==[" "${_WORKING_DIRECTORY}" "]==]" "\n"
+ " TEST_EXTRA_ARGS" " [==[" "${_EXTRA_ARGS}" "]==]" "\n"
+ " TEST_PROPERTIES" " [==[" "${_PROPERTIES}" "]==]" "\n"
+ " TEST_PREFIX" " [==[" "${_TEST_PREFIX}" "]==]" "\n"
+ " TEST_SUFFIX" " [==[" "${_TEST_SUFFIX}" "]==]" "\n"
+ " NO_PRETTY_TYPES" " [==[" "${_NO_PRETTY_TYPES}" "]==]" "\n"
+ " NO_PRETTY_VALUES" " [==[" "${_NO_PRETTY_VALUES}" "]==]" "\n"
+ " TEST_LIST" " [==[" "${_TEST_LIST}" "]==]" "\n"
+ " CTEST_FILE" " [==[" "${ctest_tests_file}" "]==]" "\n"
+ " TEST_DISCOVERY_TIMEOUT" " [==[" "${_DISCOVERY_TIMEOUT}" "]==]" "\n"
+ " TEST_XML_OUTPUT_DIR" " [==[" "${_XML_OUTPUT_DIR}" "]==]" "\n"
+ " )" "\n"
+ " endif()" "\n"
+ " include(\"${ctest_tests_file}\")" "\n"
+ "else()" "\n"
+ " add_test(${TARGET}_NOT_BUILT ${TARGET}_NOT_BUILT)" "\n"
+ "endif()" "\n"
+ )
+
+ if(GENERATOR_IS_MULTI_CONFIG)
+ foreach(_config ${CMAKE_CONFIGURATION_TYPES})
+ file(GENERATE OUTPUT "${ctest_file_base}_include-${_config}.cmake" CONTENT "${ctest_include_content}" CONDITION $<CONFIG:${_config}>)
+ endforeach()
+ file(WRITE "${ctest_include_file}" "include(\"${ctest_file_base}_include-\${CTEST_CONFIGURATION_TYPE}.cmake\")")
+ else()
+ file(GENERATE OUTPUT "${ctest_file_base}_include.cmake" CONTENT "${ctest_include_content}")
+ file(WRITE "${ctest_include_file}" "include(\"${ctest_file_base}_include.cmake\")")
+ endif()
+
+ else()
+ message(SEND_ERROR "Unknown DISCOVERY_MODE: ${_DISCOVERY_MODE}")
+ endif()
# Add discovered tests to directory TEST_INCLUDE_FILES
set_property(DIRECTORY
diff --git a/Modules/GoogleTestAddTests.cmake b/Modules/GoogleTestAddTests.cmake
index 4abbbec..4af62ed 100644
--- a/Modules/GoogleTestAddTests.cmake
+++ b/Modules/GoogleTestAddTests.cmake
@@ -1,106 +1,188 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
-set(prefix "${TEST_PREFIX}")
-set(suffix "${TEST_SUFFIX}")
-set(extra_args ${TEST_EXTRA_ARGS})
-set(properties ${TEST_PROPERTIES})
-set(script)
-set(suite)
-set(tests)
-
-function(add_command NAME)
+cmake_minimum_required(VERSION ${CMAKE_VERSION})
+
+# Overwrite possibly existing ${_CTEST_FILE} with empty file
+set(flush_tests_MODE WRITE)
+
+# Flushes script to ${_CTEST_FILE}
+macro(flush_script)
+ file(${flush_tests_MODE} "${_CTEST_FILE}" "${script}")
+ set(flush_tests_MODE APPEND)
+
+ set(script "")
+endmacro()
+
+# Flushes tests_buffer to tests
+macro(flush_tests_buffer)
+ list(APPEND tests "${tests_buffer}")
+ set(tests_buffer "")
+endmacro()
+
+macro(add_command NAME)
set(_args "")
foreach(_arg ${ARGN})
if(_arg MATCHES "[^-./:a-zA-Z0-9_]")
- set(_args "${_args} [==[${_arg}]==]")
+ string(APPEND _args " [==[${_arg}]==]")
else()
- set(_args "${_args} ${_arg}")
+ string(APPEND _args " ${_arg}")
endif()
endforeach()
- set(script "${script}${NAME}(${_args})\n" PARENT_SCOPE)
-endfunction()
+ string(APPEND script "${NAME}(${_args})\n")
+ string(LENGTH "${script}" _script_len)
+ if(${_script_len} GREATER "50000")
+ flush_script()
+ endif()
+ # Unsets macro local variables to prevent leakage outside of this macro.
+ unset(_args)
+ unset(_script_len)
+endmacro()
+
+function(gtest_discover_tests_impl)
-# Run test executable to get list of available tests
-if(NOT EXISTS "${TEST_EXECUTABLE}")
- message(FATAL_ERROR
- "Specified test executable does not exist.\n"
- " Path: '${TEST_EXECUTABLE}'"
+ cmake_parse_arguments(
+ ""
+ ""
+ "NO_PRETTY_TYPES;NO_PRETTY_VALUES;TEST_EXECUTABLE;TEST_EXECUTOR;TEST_WORKING_DIR;TEST_PREFIX;TEST_SUFFIX;TEST_LIST;CTEST_FILE;TEST_DISCOVERY_TIMEOUT;TEST_XML_OUTPUT_DIR"
+ "TEST_EXTRA_ARGS;TEST_PROPERTIES"
+ ${ARGN}
)
-endif()
-execute_process(
- COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" --gtest_list_tests
- WORKING_DIRECTORY "${TEST_WORKING_DIR}"
- TIMEOUT ${TEST_DISCOVERY_TIMEOUT}
- OUTPUT_VARIABLE output
- RESULT_VARIABLE result
-)
-if(NOT ${result} EQUAL 0)
- string(REPLACE "\n" "\n " output "${output}")
- message(FATAL_ERROR
- "Error running test executable.\n"
- " Path: '${TEST_EXECUTABLE}'\n"
- " Result: ${result}\n"
- " Output:\n"
- " ${output}\n"
+
+ set(prefix "${_TEST_PREFIX}")
+ set(suffix "${_TEST_SUFFIX}")
+ set(extra_args ${_TEST_EXTRA_ARGS})
+ set(properties ${_TEST_PROPERTIES})
+ set(script)
+ set(suite)
+ set(tests)
+ set(tests_buffer)
+
+ # Run test executable to get list of available tests
+ if(NOT EXISTS "${_TEST_EXECUTABLE}")
+ message(FATAL_ERROR
+ "Specified test executable does not exist.\n"
+ " Path: '${_TEST_EXECUTABLE}'"
+ )
+ endif()
+ execute_process(
+ COMMAND ${_TEST_EXECUTOR} "${_TEST_EXECUTABLE}" --gtest_list_tests
+ WORKING_DIRECTORY "${_TEST_WORKING_DIR}"
+ TIMEOUT ${_TEST_DISCOVERY_TIMEOUT}
+ OUTPUT_VARIABLE output
+ RESULT_VARIABLE result
)
-endif()
+ if(NOT ${result} EQUAL 0)
+ string(REPLACE "\n" "\n " output "${output}")
+ message(FATAL_ERROR
+ "Error running test executable.\n"
+ " Path: '${_TEST_EXECUTABLE}'\n"
+ " Result: ${result}\n"
+ " Output:\n"
+ " ${output}\n"
+ )
+ endif()
-string(REPLACE "\n" ";" output "${output}")
-
-# Parse output
-foreach(line ${output})
- # Skip header
- if(NOT line MATCHES "gtest_main\\.cc")
- # Do we have a module name or a test name?
- if(NOT line MATCHES "^ ")
- # Module; remove trailing '.' to get just the name...
- string(REGEX REPLACE "\\.( *#.*)?" "" suite "${line}")
- if(line MATCHES "#" AND NOT NO_PRETTY_TYPES)
- string(REGEX REPLACE "/[0-9]\\.+ +#.*= +" "/" pretty_suite "${line}")
- else()
- set(pretty_suite "${suite}")
- endif()
- string(REGEX REPLACE "^DISABLED_" "" pretty_suite "${pretty_suite}")
- else()
- # Test name; strip spaces and comments to get just the name...
- string(REGEX REPLACE " +" "" test "${line}")
- if(test MATCHES "#" AND NOT NO_PRETTY_VALUES)
- string(REGEX REPLACE "/[0-9]+#GetParam..=" "/" pretty_test "${test}")
+ # Preserve semicolon in test-parameters
+ string(REPLACE [[;]] [[\;]] output "${output}")
+ string(REPLACE "\n" ";" output "${output}")
+
+ # Parse output
+ foreach(line ${output})
+ # Skip header
+ if(NOT line MATCHES "gtest_main\\.cc")
+ # Do we have a module name or a test name?
+ if(NOT line MATCHES "^ ")
+ # Module; remove trailing '.' to get just the name...
+ string(REGEX REPLACE "\\.( *#.*)?" "" suite "${line}")
+ if(line MATCHES "#" AND NOT _NO_PRETTY_TYPES)
+ string(REGEX REPLACE "/[0-9]\\.+ +#.*= +" "/" pretty_suite "${line}")
+ else()
+ set(pretty_suite "${suite}")
+ endif()
+ string(REGEX REPLACE "^DISABLED_" "" pretty_suite "${pretty_suite}")
else()
- string(REGEX REPLACE "#.*" "" pretty_test "${test}")
- endif()
- string(REGEX REPLACE "^DISABLED_" "" pretty_test "${pretty_test}")
- string(REGEX REPLACE "#.*" "" test "${test}")
- # ...and add to script
- add_command(add_test
- "${prefix}${pretty_suite}.${pretty_test}${suffix}"
- ${TEST_EXECUTOR}
- "${TEST_EXECUTABLE}"
- "--gtest_filter=${suite}.${test}"
- "--gtest_also_run_disabled_tests"
- ${extra_args}
- )
- if(suite MATCHES "^DISABLED" OR test MATCHES "^DISABLED")
+ # Test name; strip spaces and comments to get just the name...
+ string(REGEX REPLACE " +" "" test "${line}")
+ if(test MATCHES "#" AND NOT _NO_PRETTY_VALUES)
+ string(REGEX REPLACE "/[0-9]+#GetParam..=" "/" pretty_test "${test}")
+ else()
+ string(REGEX REPLACE "#.*" "" pretty_test "${test}")
+ endif()
+ string(REGEX REPLACE "^DISABLED_" "" pretty_test "${pretty_test}")
+ string(REGEX REPLACE "#.*" "" test "${test}")
+ if(NOT "${_TEST_XML_OUTPUT_DIR}" STREQUAL "")
+ set(TEST_XML_OUTPUT_PARAM "--gtest_output=xml:${_TEST_XML_OUTPUT_DIR}/${prefix}${pretty_suite}.${pretty_test}${suffix}.xml")
+ else()
+ unset(TEST_XML_OUTPUT_PARAM)
+ endif()
+
+ # sanitize test name for further processing downstream
+ set(testname "${prefix}${pretty_suite}.${pretty_test}${suffix}")
+ # escape \
+ string(REPLACE [[\]] [[\\]] testname "${testname}")
+ # escape ;
+ string(REPLACE [[;]] [[\;]] testname "${testname}")
+ # escape $
+ string(REPLACE [[$]] [[\$]] testname "${testname}")
+
+ # ...and add to script
+ add_command(add_test
+ "${testname}"
+ ${_TEST_EXECUTOR}
+ "${_TEST_EXECUTABLE}"
+ "--gtest_filter=${suite}.${test}"
+ "--gtest_also_run_disabled_tests"
+ ${TEST_XML_OUTPUT_PARAM}
+ ${extra_args}
+ )
+ if(suite MATCHES "^DISABLED" OR test MATCHES "^DISABLED")
+ add_command(set_tests_properties
+ "${testname}"
+ PROPERTIES DISABLED TRUE
+ )
+ endif()
add_command(set_tests_properties
- "${prefix}${pretty_suite}.${pretty_test}${suffix}"
- PROPERTIES DISABLED TRUE
+ "${testname}"
+ PROPERTIES
+ WORKING_DIRECTORY "${_TEST_WORKING_DIR}"
+ SKIP_REGULAR_EXPRESSION "\\\\[ SKIPPED \\\\]"
+ ${properties}
)
+ list(APPEND tests_buffer "${testname}")
+ list(LENGTH tests_buffer tests_buffer_length)
+ if(${tests_buffer_length} GREATER "250")
+ flush_tests_buffer()
+ endif()
endif()
- add_command(set_tests_properties
- "${prefix}${pretty_suite}.${pretty_test}${suffix}"
- PROPERTIES
- WORKING_DIRECTORY "${TEST_WORKING_DIR}"
- ${properties}
- )
- list(APPEND tests "${prefix}${pretty_suite}.${pretty_test}${suffix}")
endif()
- endif()
-endforeach()
+ endforeach()
+
-# Create a list of all discovered tests, which users may use to e.g. set
-# properties on the tests
-add_command(set ${TEST_LIST} ${tests})
+ # Create a list of all discovered tests, which users may use to e.g. set
+ # properties on the tests
+ flush_tests_buffer()
+ add_command(set ${_TEST_LIST} ${tests})
-# Write CTest script
-file(WRITE "${CTEST_FILE}" "${script}")
+ # Write CTest script
+ flush_script()
+
+endfunction()
+
+if(CMAKE_SCRIPT_MODE_FILE)
+ gtest_discover_tests_impl(
+ NO_PRETTY_TYPES ${NO_PRETTY_TYPES}
+ NO_PRETTY_VALUES ${NO_PRETTY_VALUES}
+ TEST_EXECUTABLE ${TEST_EXECUTABLE}
+ TEST_EXECUTOR ${TEST_EXECUTOR}
+ TEST_WORKING_DIR ${TEST_WORKING_DIR}
+ TEST_PREFIX ${TEST_PREFIX}
+ TEST_SUFFIX ${TEST_SUFFIX}
+ TEST_LIST ${TEST_LIST}
+ CTEST_FILE ${CTEST_FILE}
+ TEST_DISCOVERY_TIMEOUT ${TEST_DISCOVERY_TIMEOUT}
+ TEST_XML_OUTPUT_DIR ${TEST_XML_OUTPUT_DIR}
+ TEST_EXTRA_ARGS ${TEST_EXTRA_ARGS}
+ TEST_PROPERTIES ${TEST_PROPERTIES}
+ )
+endif()
diff --git a/Modules/Internal/CPack/CPackDeb.cmake b/Modules/Internal/CPack/CPackDeb.cmake
index 97906ca..14bb104 100644
--- a/Modules/Internal/CPack/CPackDeb.cmake
+++ b/Modules/Internal/CPack/CPackDeb.cmake
@@ -554,8 +554,8 @@ function(cpack_deb_prepare_package_vars)
)
# Homepage: (optional)
- if(NOT CPACK_DEBIAN_PACKAGE_HOMEPAGE AND CMAKE_PROJECT_HOMEPAGE_URL)
- set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "${CMAKE_PROJECT_HOMEPAGE_URL}")
+ if(NOT CPACK_DEBIAN_PACKAGE_HOMEPAGE AND CPACK_PACKAGE_HOMEPAGE_URL)
+ set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "${CPACK_PACKAGE_HOMEPAGE_URL}")
endif()
# Section: (recommended)
diff --git a/Modules/Internal/CPack/CPackFreeBSD.cmake b/Modules/Internal/CPack/CPackFreeBSD.cmake
index 16f906c..ae40532 100644
--- a/Modules/Internal/CPack/CPackFreeBSD.cmake
+++ b/Modules/Internal/CPack/CPackFreeBSD.cmake
@@ -68,7 +68,7 @@ _cpack_freebsd_fallback_var("CPACK_FREEBSD_PACKAGE_DESCRIPTION"
# There's really only one homepage for a project, so
# re-use the Debian setting if it's there.
_cpack_freebsd_fallback_var("CPACK_FREEBSD_PACKAGE_WWW"
- "CMAKE_PROJECT_HOMEPAGE_URL"
+ "CPACK_PACKAGE_HOMEPAGE_URL"
"CPACK_DEBIAN_PACKAGE_HOMEPAGE"
"_cpack_freebsd_fallback_www"
)
diff --git a/Modules/Internal/CPack/CPackNuGet.cmake b/Modules/Internal/CPack/CPackNuGet.cmake
index 82053b2..20eed2e 100644
--- a/Modules/Internal/CPack/CPackNuGet.cmake
+++ b/Modules/Internal/CPack/CPackNuGet.cmake
@@ -230,31 +230,22 @@ function(_cpack_nuget_render_spec)
foreach(_dep IN LISTS _deps)
_cpack_nuget_debug(" checking dependency `${_dep}`")
- string(MAKE_C_IDENTIFIER "${_dep}" _dep_id)
-
- _cpack_nuget_variable_fallback(_ver DEPENDENCIES_${_dep_id}_VERSION)
+ _cpack_nuget_variable_fallback(_ver DEPENDENCIES_${_dep}_VERSION)
if(NOT _ver)
- string(TOUPPER "${_dep_id}" _dep_id)
- _cpack_nuget_variable_fallback(_ver DEPENDENCIES_${_dep_id}_VERSION)
+ string(TOUPPER "${_dep}" _dep_upper)
+ _cpack_nuget_variable_fallback(_ver DEPENDENCIES_${_dep_upper}_VERSION)
endif()
if(_ver)
_cpack_nuget_debug(" got `${_dep}` dependency version ${_ver}")
- list(APPEND _collected_deps "<dependency id=\"${_dep}\" version=\"${_ver}\" />")
+ string(CONCAT _collected_deps "${_collected_deps}" " <dependency id=\"${_dep}\" version=\"${_ver}\" />\n")
endif()
endforeach()
# Render deps into the variable
if(_collected_deps)
- set(_CPACK_NUGET_DEPENDENCIES_TAG "<dependencies>\n")
- foreach(_line IN LISTS _collected_deps)
- string(
- APPEND _CPACK_NUGET_DEPENDENCIES_TAG
- " ${_line}\n"
- )
- endforeach()
- string(APPEND _CPACK_NUGET_DEPENDENCIES_TAG " </dependencies>")
+ string(CONCAT _CPACK_NUGET_DEPENDENCIES_TAG "<dependencies>\n" "${_collected_deps}" " </dependencies>")
endif()
# Render the spec file
@@ -296,7 +287,11 @@ if(CPACK_NUGET_ORDINAL_MONOLITIC)
execute_process(
COMMAND "${NUGET_EXECUTABLE}" pack ${CPACK_NUGET_PACK_ADDITIONAL_OPTIONS}
WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}"
+ RESULT_VARIABLE _nuget_result
)
+ if(NOT _nuget_result EQUAL 0)
+ message(FATAL_ERROR "Nuget pack failed")
+ endif()
elseif(CPACK_NUGET_ALL_IN_ONE)
# This variable `CPACK_NUGET_ALL_IN_ONE` set by C++ code:
@@ -309,7 +304,11 @@ elseif(CPACK_NUGET_ALL_IN_ONE)
execute_process(
COMMAND "${NUGET_EXECUTABLE}" pack ${CPACK_NUGET_PACK_ADDITIONAL_OPTIONS}
WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}"
+ RESULT_VARIABLE _nuget_result
)
+ if(NOT _nuget_result EQUAL 0)
+ message(FATAL_ERROR "Nuget pack failed")
+ endif()
else()
# Is there any grouped component?
@@ -331,7 +330,11 @@ else()
execute_process(
COMMAND "${NUGET_EXECUTABLE}" pack ${CPACK_NUGET_PACK_ADDITIONAL_OPTIONS}
WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}"
+ RESULT_VARIABLE _nuget_result
)
+ if(NOT _nuget_result EQUAL 0)
+ message(FATAL_ERROR "Nuget pack failed")
+ endif()
endforeach()
endif()
# Is there any single component package needed?
@@ -350,7 +353,11 @@ else()
execute_process(
COMMAND "${NUGET_EXECUTABLE}" pack ${CPACK_NUGET_PACK_ADDITIONAL_OPTIONS}
WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}"
+ RESULT_VARIABLE _nuget_result
)
+ if(NOT _nuget_result EQUAL 0)
+ message(FATAL_ERROR "Nuget pack failed")
+ endif()
endforeach()
endif()
endif()
diff --git a/Modules/Internal/CPack/CPackRPM.cmake b/Modules/Internal/CPack/CPackRPM.cmake
index ffb24e2..08bbc68 100644
--- a/Modules/Internal/CPack/CPackRPM.cmake
+++ b/Modules/Internal/CPack/CPackRPM.cmake
@@ -844,8 +844,8 @@ function(cpack_rpm_generate_package)
endif()
endif()
- if(NOT CPACK_RPM_PACKAGE_URL AND CMAKE_PROJECT_HOMEPAGE_URL)
- set(CPACK_RPM_PACKAGE_URL "${CMAKE_PROJECT_HOMEPAGE_URL}")
+ if(NOT CPACK_RPM_PACKAGE_URL AND CPACK_PACKAGE_HOMEPAGE_URL)
+ set(CPACK_RPM_PACKAGE_URL "${CPACK_PACKAGE_HOMEPAGE_URL}")
endif()
# CPACK_RPM_PACKAGE_NAME (mandatory)
@@ -1099,16 +1099,18 @@ function(cpack_rpm_generate_package)
# CPACK_RPM_POST_INSTALL_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_POST_INSTALL_SCRIPT_FILE)
# CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_POST_UNINSTALL_SCRIPT_FILE)
- # May be used to embed a post (un)installation script in the spec file.
+ # CPACK_RPM_POST_TRANS_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_POST_TRANS_SCRIPT_FILE)
+ # May be used to embed a post installation/uninstallation/transaction script in the spec file.
# The referred script file(s) will be read and directly
- # put after the %post or %postun section
+ # put after the %post or %postun or %posttrans section
# ----------------------------------------------------------------
# CPACK_RPM_PRE_INSTALL_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_PRE_INSTALL_SCRIPT_FILE)
# CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_PRE_UNINSTALL_SCRIPT_FILE)
- # May be used to embed a pre (un)installation script in the spec file.
+ # CPACK_RPM_PRE_TRANS_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_PRE_TRANS_SCRIPT_FILE)
+ # May be used to embed a pre installation/uninstallation/transaction script in the spec file.
# The referred script file(s) will be read and directly
- # put after the %pre or %preun section
- foreach(RPM_SCRIPT_FILE_TYPE_ "INSTALL" "UNINSTALL")
+ # put after the %pre or %preun or %pretrans section
+ foreach(RPM_SCRIPT_FILE_TYPE_ "INSTALL" "UNINSTALL" "TRANS")
foreach(RPM_SCRIPT_FILE_TIME_ "PRE" "POST")
set("CPACK_RPM_${RPM_SCRIPT_FILE_TIME_}_${RPM_SCRIPT_FILE_TYPE_}_READ_FILE"
"${CPACK_RPM_${RPM_SCRIPT_FILE_TIME_}_${RPM_SCRIPT_FILE_TYPE_}_SCRIPT_FILE}")
@@ -1727,12 +1729,18 @@ mv %_topdir/tmpBBroot $RPM_BUILD_ROOT
\@RPM_SYMLINK_POSTINSTALL\@
\@CPACK_RPM_SPEC_POSTINSTALL\@
+%posttrans
+\@CPACK_RPM_SPEC_POSTTRANS\@
+
%postun
\@CPACK_RPM_SPEC_POSTUNINSTALL\@
%pre
\@CPACK_RPM_SPEC_PREINSTALL\@
+%pretrans
+\@CPACK_RPM_SPEC_PRETRANS\@
+
%preun
\@CPACK_RPM_SPEC_PREUNINSTALL\@
diff --git a/Modules/Internal/CPack/NSIS.template.in b/Modules/Internal/CPack/NSIS.template.in
index f75ae78..6009ce0 100644
--- a/Modules/Internal/CPack/NSIS.template.in
+++ b/Modules/Internal/CPack/NSIS.template.in
@@ -41,6 +41,7 @@
RequestExecutionLevel admin
@CPACK_NSIS_DEFINES@
+@CPACK_NSIS_MANIFEST_DPI_AWARE_CODE@
!include Sections.nsh
@@ -524,14 +525,6 @@ FunctionEnd
!endif
;--------------------------------
-; Installation types
-@CPACK_NSIS_INSTALLATION_TYPES@
-
-;--------------------------------
-; Component sections
-@CPACK_NSIS_COMPONENT_SECTIONS@
-
-;--------------------------------
; Define some macro setting for the gui
@CPACK_NSIS_INSTALLER_MUI_ICON_CODE@
@CPACK_NSIS_INSTALLER_ICON_CODE@
@@ -542,6 +535,8 @@ FunctionEnd
;--------------------------------
;Pages
+ @CPACK_NSIS_INSTALLER_WELCOME_TITLE_CODE@
+ @CPACK_NSIS_INSTALLER_WELCOME_TITLE_3LINES_CODE@
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_LICENSE "@CPACK_RESOURCE_FILE_LICENSE@"
@@ -557,6 +552,8 @@ FunctionEnd
@CPACK_NSIS_PAGE_COMPONENTS@
!insertmacro MUI_PAGE_INSTFILES
+ @CPACK_NSIS_INSTALLER_FINISH_TITLE_CODE@
+ @CPACK_NSIS_INSTALLER_FINISH_TITLE_3LINES_CODE@
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_CONFIRM
@@ -617,7 +614,6 @@ FunctionEnd
!insertmacro MUI_LANGUAGE "Ukrainian"
!insertmacro MUI_LANGUAGE "Welsh"
-
;--------------------------------
;Reserve Files
@@ -628,6 +624,17 @@ FunctionEnd
ReserveFile "NSIS.InstallOptions.ini"
!insertmacro MUI_RESERVEFILE_INSTALLOPTIONS
+ ; for UserInfo::GetName and UserInfo::GetAccountType
+ ReserveFile /plugin 'UserInfo.dll'
+
+;--------------------------------
+; Installation types
+@CPACK_NSIS_INSTALLATION_TYPES@
+
+;--------------------------------
+; Component sections
+@CPACK_NSIS_COMPONENT_SECTIONS@
+
;--------------------------------
;Installer Sections
@@ -642,7 +649,7 @@ Section "-Core installation"
WriteRegStr SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" "" $INSTDIR
;Create uninstaller
- WriteUninstaller "$INSTDIR\Uninstall.exe"
+ WriteUninstaller "$INSTDIR\@CPACK_NSIS_UNINSTALL_NAME@.exe"
Push "DisplayName"
Push "@CPACK_NSIS_DISPLAY_NAME@"
Call ConditionalAddToRegisty
@@ -653,7 +660,7 @@ Section "-Core installation"
Push "@CPACK_PACKAGE_VENDOR@"
Call ConditionalAddToRegisty
Push "UninstallString"
- Push "$INSTDIR\Uninstall.exe"
+ Push "$INSTDIR\@CPACK_NSIS_UNINSTALL_NAME@.exe"
Call ConditionalAddToRegisty
Push "NoRepair"
Push "1"
@@ -690,7 +697,7 @@ Section "-Core installation"
CreateDirectory "$SMPROGRAMS\$STARTMENU_FOLDER"
@CPACK_NSIS_CREATE_ICONS@
@CPACK_NSIS_CREATE_ICONS_EXTRA@
- CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\Uninstall.exe"
+ CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\@CPACK_NSIS_UNINSTALL_NAME@.exe"
;Read a value from an InstallOptions INI file
!insertmacro MUI_INSTALLOPTIONS_READ $DO_NOT_ADD_TO_PATH "NSIS.InstallOptions.ini" "Field 2" "State"
@@ -829,7 +836,7 @@ Section "Uninstall"
!endif
;Remove the uninstaller itself.
- Delete "$INSTDIR\Uninstall.exe"
+ Delete "$INSTDIR\@CPACK_NSIS_UNINSTALL_NAME@.exe"
DeleteRegKey SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@"
;Remove the installation directory if it is empty.
diff --git a/Modules/Internal/FeatureTesting.cmake b/Modules/Internal/FeatureTesting.cmake
index 75be473..72d96b3 100644
--- a/Modules/Internal/FeatureTesting.cmake
+++ b/Modules/Internal/FeatureTesting.cmake
@@ -89,6 +89,16 @@ macro(_record_compiler_features_cxx std)
unset(lang_level_has_features)
endmacro()
+macro(_record_compiler_features_cuda std)
+ list(APPEND CMAKE_CUDA${std}_COMPILE_FEATURES cuda_std_${std})
+
+ get_property(lang_level_has_features GLOBAL PROPERTY CMAKE_CUDA${std}_KNOWN_FEATURES)
+ if(lang_level_has_features)
+ _record_compiler_features(CUDA "${CMAKE_CUDA${std}_STANDARD_COMPILE_OPTION}" CMAKE_CUDA${std}_COMPILE_FEATURES)
+ endif()
+ unset(lang_level_has_features)
+endmacro()
+
macro(_has_compiler_features lang level compile_flags feature_list)
# presume all known features are supported
get_property(known_features GLOBAL PROPERTY CMAKE_${lang}${level}_KNOWN_FEATURES)
@@ -103,3 +113,7 @@ macro(_has_compiler_features_cxx std)
list(APPEND CMAKE_CXX${std}_COMPILE_FEATURES cxx_std_${std})
_has_compiler_features(CXX ${std} "${CMAKE_CXX${std}_STANDARD_COMPILE_OPTION}" CMAKE_CXX${std}_COMPILE_FEATURES)
endmacro()
+macro(_has_compiler_features_cuda std)
+ list(APPEND CMAKE_CUDA${std}_COMPILE_FEATURES cuda_std_${std})
+ _has_compiler_features(CUDA ${std} "${CMAKE_CUDA${std}_STANDARD_COMPILE_OPTION}" CMAKE_CUDA${std}_COMPILE_FEATURES)
+endmacro()
diff --git a/Modules/Platform/AIX-GNU.cmake b/Modules/Platform/AIX-GNU.cmake
index 61d213a..5a532c7 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>/objects.exp <OBJECTS>"
- "<CMAKE_${lang}_COMPILER> <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> -Wl,-bE:<OBJECT_DIR>/objects.exp <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>"
+ "\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <OBJECT_DIR>/exports.exp <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 . <OBJECTS>"
+ "\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <TARGET_IMPLIB> -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 2a67c4f..2a8c159 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>/objects.exp${_OBJECTS}"
- "<CMAKE_${lang}_COMPILER> <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> -Wl,-bE:<OBJECT_DIR>/objects.exp <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>"
+ "\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <OBJECT_DIR>/exports.exp <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 . <OBJECTS>"
+ "\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <TARGET_IMPLIB> -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 4f67ef5..891bce7 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>] [--] <objects>...'
+usage='usage: ExportImportList -o <out-file> [-l <lib>] [-n] [--] <objects>...'
die() {
echo "$@" 1>&2; exit 1
@@ -14,10 +14,12 @@ die() {
# Process command-line arguments.
out=''
lib=''
+no_objects=''
while test "$#" != 0; do
case "$1" in
-l) shift; lib="$1" ;;
-o) shift; out="$1" ;;
+ -n) no_objects='1' ;;
--) shift; break ;;
-*) die "$usage" ;;
*) break ;;
@@ -26,23 +28,28 @@ while test "$#" != 0; do
done
test -n "$out" || die "$usage"
-# Collect symbols exported from all object files.
+# Build a temporary file that atomically replaces the output later.
out_tmp="$out.tmp$$"
trap 'rm -f "$out_tmp"' EXIT INT TERM
-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)]
+> "$out_tmp"
+
+# 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)]
+ }
}
- }
- '
-done > "$out_tmp"
+ '
+ done >> "$out_tmp"
+fi
# Generate the export/import file.
{
diff --git a/Modules/Platform/Android-Clang.cmake b/Modules/Platform/Android-Clang.cmake
index 847178f..759448b 100644
--- a/Modules/Platform/Android-Clang.cmake
+++ b/Modules/Platform/Android-Clang.cmake
@@ -24,6 +24,14 @@ if(CMAKE_SYSTEM_VERSION EQUAL 1)
return()
endif()
+# Natively compiling on an Android host doesn't use the NDK cross-compilation
+# tools.
+if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Android")
+ macro(__android_compiler_clang lang)
+ endmacro()
+ return()
+endif()
+
include(Platform/Android-Common)
# The NDK toolchain configuration files at:
diff --git a/Modules/Platform/Android-Common.cmake b/Modules/Platform/Android-Common.cmake
index 1affcd0..581fde4 100644
--- a/Modules/Platform/Android-Common.cmake
+++ b/Modules/Platform/Android-Common.cmake
@@ -73,7 +73,7 @@ if(CMAKE_ANDROID_STL_TYPE)
macro(__android_stl lang)
# FIXME: Add a way to add project-wide language-specific compile-only flags.
set(CMAKE_CXX_COMPILE_OBJECT
- "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE> -nostdinc++")
+ "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE> -nostdinc++")
string(APPEND CMAKE_${lang}_STANDARD_LIBRARIES " -nostdlib++")
endmacro()
else()
diff --git a/Modules/Platform/Android-Determine.cmake b/Modules/Platform/Android-Determine.cmake
index e7c1b48..2225897 100644
--- a/Modules/Platform/Android-Determine.cmake
+++ b/Modules/Platform/Android-Determine.cmake
@@ -18,6 +18,12 @@ if(CMAKE_SYSTEM_VERSION EQUAL 1)
return()
endif()
+# Natively compiling on an Android host doesn't use the NDK cross-compilation
+# tools.
+if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Android")
+ return()
+endif()
+
cmake_policy(PUSH)
cmake_policy(SET CMP0057 NEW) # if IN_LIST
diff --git a/Modules/Platform/Android-Initialize.cmake b/Modules/Platform/Android-Initialize.cmake
index a5d2820..b90dd7a 100644
--- a/Modules/Platform/Android-Initialize.cmake
+++ b/Modules/Platform/Android-Initialize.cmake
@@ -24,6 +24,12 @@ if(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED)
return()
endif()
+# Natively compiling on an Android host doesn't use the NDK cross-compilation
+# tools.
+if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Android")
+ return()
+endif()
+
if(NOT CMAKE_SYSROOT)
if(CMAKE_ANDROID_NDK)
set(CMAKE_SYSROOT "${CMAKE_ANDROID_NDK}/platforms/android-${CMAKE_SYSTEM_VERSION}/arch-${CMAKE_ANDROID_ARCH}")
diff --git a/Modules/Platform/Android.cmake b/Modules/Platform/Android.cmake
index f08f841..8ffa1b2 100644
--- a/Modules/Platform/Android.cmake
+++ b/Modules/Platform/Android.cmake
@@ -2,6 +2,11 @@ include(Platform/Linux)
set(ANDROID 1)
+# Natively compiling on an Android host doesn't need these flags to be reset.
+if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Android")
+ return()
+endif()
+
# Conventionally Android does not use versioned soname
# But in modern versions it is acceptable
if(NOT DEFINED CMAKE_PLATFORM_NO_VERSIONED_SONAME)
diff --git a/Modules/Platform/Android/Determine-Compiler.cmake b/Modules/Platform/Android/Determine-Compiler.cmake
index 5c6b97b..f9c2d89 100644
--- a/Modules/Platform/Android/Determine-Compiler.cmake
+++ b/Modules/Platform/Android/Determine-Compiler.cmake
@@ -31,6 +31,16 @@ elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
set(_ANDROID_HOST_EXT "")
elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
set(_ANDROID_HOST_EXT ".exe")
+elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Android")
+ # Natively compiling on an Android host doesn't use the NDK cross-compilation
+ # tools.
+ macro(__android_determine_compiler lang)
+ # Do nothing
+ endmacro()
+ if(NOT CMAKE_CXX_COMPILER_NAMES)
+ set(CMAKE_CXX_COMPILER_NAMES c++)
+ endif()
+ return()
else()
message(FATAL_ERROR "Android: Builds hosted on '${CMAKE_HOST_SYSTEM_NAME}' not supported.")
endif()
diff --git a/Modules/Platform/Apple-GNU.cmake b/Modules/Platform/Apple-GNU.cmake
index 0eb8168..9572736 100644
--- a/Modules/Platform/Apple-GNU.cmake
+++ b/Modules/Platform/Apple-GNU.cmake
@@ -19,17 +19,17 @@ endmacro()
macro(cmake_gnu_set_sysroot_flag lang)
if(NOT DEFINED CMAKE_${lang}_SYSROOT_FLAG)
set(_doc "${lang} compiler has -isysroot")
- message(STATUS "Checking whether ${_doc}")
+ message(CHECK_START "Checking whether ${_doc}")
execute_process(
COMMAND ${CMAKE_${lang}_COMPILER} "-v" "--help"
OUTPUT_VARIABLE _gcc_help
ERROR_VARIABLE _gcc_help
)
if("${_gcc_help}" MATCHES "isysroot")
- message(STATUS "Checking whether ${_doc} - yes")
+ message(CHECK_PASS "yes")
set(CMAKE_${lang}_SYSROOT_FLAG "-isysroot")
else()
- message(STATUS "Checking whether ${_doc} - no")
+ message(CHECK_FAIL "no")
set(CMAKE_${lang}_SYSROOT_FLAG "")
endif()
set(CMAKE_${lang}_SYSROOT_FLAG_CODE "set(CMAKE_${lang}_SYSROOT_FLAG \"${CMAKE_${lang}_SYSROOT_FLAG}\")")
@@ -39,17 +39,17 @@ endmacro()
macro(cmake_gnu_set_osx_deployment_target_flag lang)
if(NOT DEFINED CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG)
set(_doc "${lang} compiler supports OSX deployment target flag")
- message(STATUS "Checking whether ${_doc}")
+ message(CHECK_START "Checking whether ${_doc}")
execute_process(
COMMAND ${CMAKE_${lang}_COMPILER} "-v" "--help"
OUTPUT_VARIABLE _gcc_help
ERROR_VARIABLE _gcc_help
)
if("${_gcc_help}" MATCHES "macosx-version-min")
- message(STATUS "Checking whether ${_doc} - yes")
+ message(CHECK_PASS "yes")
set(CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG "-mmacosx-version-min=")
else()
- message(STATUS "Checking whether ${_doc} - no")
+ message(CHECK_FAIL "no")
set(CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG "")
endif()
set(CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG_CODE "set(CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG \"${CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG}\")")
diff --git a/Modules/Platform/BlueGeneL.cmake b/Modules/Platform/BlueGeneL.cmake
index 082e46c..0ed9975 100644
--- a/Modules/Platform/BlueGeneL.cmake
+++ b/Modules/Platform/BlueGeneL.cmake
@@ -23,18 +23,18 @@ include(Platform/UnixPaths)
if(CMAKE_COMPILER_IS_GNUCC)
set(CMAKE_C_LINK_EXECUTABLE
- "<CMAKE_C_COMPILER> -Wl,-relax <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Wl,-lgcc,-lc -lnss_files -lnss_dns -lresolv")
+ "<CMAKE_C_COMPILER> -Wl,-relax <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Wl,-lgcc,-lc -lnss_files -lnss_dns -lresolv")
else()
# when using IBM xlc we probably don't want to link to -lgcc
set(CMAKE_C_LINK_EXECUTABLE
- "<CMAKE_C_COMPILER> -Wl,-relax <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Wl,-lc -lnss_files -lnss_dns -lresolv")
+ "<CMAKE_C_COMPILER> -Wl,-relax <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Wl,-lc -lnss_files -lnss_dns -lresolv")
endif()
if(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_LINK_EXECUTABLE
- "<CMAKE_CXX_COMPILER> -Wl,-relax <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Wl,-lstdc++,-lgcc,-lc -lnss_files -lnss_dns -lresolv")
+ "<CMAKE_CXX_COMPILER> -Wl,-relax <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Wl,-lstdc++,-lgcc,-lc -lnss_files -lnss_dns -lresolv")
else()
# when using the IBM xlC we probably don't want to link to -lgcc
set(CMAKE_CXX_LINK_EXECUTABLE
- "<CMAKE_CXX_COMPILER> -Wl,-relax <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Wl,-lstdc++,-lc -lnss_files -lnss_dns -lresolv")
+ "<CMAKE_CXX_COMPILER> -Wl,-relax <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Wl,-lstdc++,-lc -lnss_files -lnss_dns -lresolv")
endif()
diff --git a/Modules/Platform/BlueGeneP-base.cmake b/Modules/Platform/BlueGeneP-base.cmake
index fe95b42..7095dd8 100644
--- a/Modules/Platform/BlueGeneP-base.cmake
+++ b/Modules/Platform/BlueGeneP-base.cmake
@@ -97,7 +97,7 @@ macro(__BlueGeneP_set_dynamic_flags compiler_id lang)
set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG_SEP ":") # : or empty
set(BGP_${lang}_DEFAULT_EXE_FLAGS
- "<FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
+ "<FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
set(CMAKE_${lang}_LINK_EXECUTABLE
"<CMAKE_${lang}_COMPILER> -Wl,-relax ${BGP_${lang}_DYNAMIC_EXE_FLAGS} ${BGP_${lang}_DEFAULT_EXE_FLAGS}")
endmacro()
@@ -108,7 +108,7 @@ endmacro()
#
macro(__BlueGeneP_set_static_flags compiler_id lang)
set(BGP_${lang}_DEFAULT_EXE_FLAGS
- "<FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
+ "<FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
set(CMAKE_${lang}_LINK_EXECUTABLE
"<CMAKE_${lang}_COMPILER> -Wl,-relax ${BGP_${lang}_DEFAULT_EXE_FLAGS}")
endmacro()
diff --git a/Modules/Platform/BlueGeneQ-base.cmake b/Modules/Platform/BlueGeneQ-base.cmake
index 5e56d8e..94cb0a8 100644
--- a/Modules/Platform/BlueGeneQ-base.cmake
+++ b/Modules/Platform/BlueGeneQ-base.cmake
@@ -101,7 +101,7 @@ macro(__BlueGeneQ_common_setup compiler_id lang)
foreach(dir ${CMAKE_SYSTEM_INCLUDE_PATH})
string(APPEND BGQ_SYSTEM_INCLUDES " -I${dir}")
endforeach()
- set(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER> <DEFINES> ${BGQ_SYSTEM_INCLUDES} <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
+ set(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER> <DEFINES> ${BGQ_SYSTEM_INCLUDES} <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
set(CMAKE_CXX_COMPILE_OBJECT "<CMAKE_CXX_COMPILER> <DEFINES> ${BGQ_SYSTEM_INCLUDES} <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
#
@@ -146,7 +146,7 @@ macro(__BlueGeneQ_setup_dynamic compiler_id lang)
# For dynamic executables, need to provide special BG/Q arguments.
set(BGQ_${lang}_DEFAULT_EXE_FLAGS
- "<FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
+ "<FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
set(CMAKE_${lang}_LINK_EXECUTABLE
"<CMAKE_${lang}_COMPILER> -Wl,-relax ${BGQ_${lang}_DYNAMIC_EXE_FLAGS} ${BGQ_${lang}_DEFAULT_EXE_FLAGS}")
endmacro()
@@ -160,7 +160,7 @@ macro(__BlueGeneQ_setup_static compiler_id lang)
# For static executables, use default link settings.
set(BGQ_${lang}_DEFAULT_EXE_FLAGS
- "<FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
+ "<FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
set(CMAKE_${lang}_LINK_EXECUTABLE
"<CMAKE_${lang}_COMPILER> -Wl,-relax ${BGQ_${lang}_DEFAULT_EXE_FLAGS}")
endmacro()
diff --git a/Modules/Platform/CYGWIN-GNU.cmake b/Modules/Platform/CYGWIN-GNU.cmake
index ca90712..4fa14ce 100644
--- a/Modules/Platform/CYGWIN-GNU.cmake
+++ b/Modules/Platform/CYGWIN-GNU.cmake
@@ -22,7 +22,7 @@ macro(__cygwin_compiler_gnu lang)
set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
"<CMAKE_${lang}_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <OBJECTS> <LINK_LIBRARIES>")
set(CMAKE_${lang}_LINK_EXECUTABLE
- "<CMAKE_${lang}_COMPILER> <FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>")
+ "<CMAKE_${lang}_COMPILER> <FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>")
# No -fPIC on cygwin
set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "")
diff --git a/Modules/Platform/DOS-OpenWatcom-C.cmake b/Modules/Platform/DOS-OpenWatcom-C.cmake
new file mode 100644
index 0000000..cf71c84
--- /dev/null
+++ b/Modules/Platform/DOS-OpenWatcom-C.cmake
@@ -0,0 +1 @@
+include(Platform/DOS-OpenWatcom)
diff --git a/Modules/Platform/DOS-OpenWatcom-CXX.cmake b/Modules/Platform/DOS-OpenWatcom-CXX.cmake
new file mode 100644
index 0000000..cf71c84
--- /dev/null
+++ b/Modules/Platform/DOS-OpenWatcom-CXX.cmake
@@ -0,0 +1 @@
+include(Platform/DOS-OpenWatcom)
diff --git a/Modules/Platform/DOS-OpenWatcom.cmake b/Modules/Platform/DOS-OpenWatcom.cmake
new file mode 100644
index 0000000..54c452e
--- /dev/null
+++ b/Modules/Platform/DOS-OpenWatcom.cmake
@@ -0,0 +1,28 @@
+
+# This module is shared by multiple languages; use include blocker.
+include_guard()
+
+set(CMAKE_BUILD_TYPE_INIT Debug)
+
+if(DEFINED CMAKE_SYSTEM_PROCESSOR AND CMAKE_SYSTEM_PROCESSOR STREQUAL "I86")
+ string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " system dos")
+ string(APPEND CMAKE_SHARED_LINKER_FLAGS_INIT " system dos")
+ string(APPEND CMAKE_MODULE_LINKER_FLAGS_INIT " system dos")
+else()
+ string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " system dos4g")
+ string(APPEND CMAKE_SHARED_LINKER_FLAGS_INIT " system dos4g")
+ string(APPEND CMAKE_MODULE_LINKER_FLAGS_INIT " system dos4g")
+endif()
+
+set(CMAKE_C_COMPILE_OPTIONS_DLL "-bd") # Note: This variable is a ';' separated list
+set(CMAKE_SHARED_LIBRARY_C_FLAGS "-bd") # ... while this is a space separated string.
+
+string(APPEND CMAKE_C_FLAGS_INIT " -bt=dos")
+string(APPEND CMAKE_CXX_FLAGS_INIT " -bt=dos -xs")
+
+if(NOT CMAKE_C_STANDARD_INCLUDE_DIRECTORIES)
+ set(CMAKE_C_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/h)
+endif()
+if(NOT CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES)
+ set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/h)
+endif()
diff --git a/Modules/Platform/DOS.cmake b/Modules/Platform/DOS.cmake
new file mode 100644
index 0000000..fc95936
--- /dev/null
+++ b/Modules/Platform/DOS.cmake
@@ -0,0 +1,14 @@
+set(DOS 1)
+
+set(CMAKE_STATIC_LIBRARY_PREFIX "")
+set(CMAKE_STATIC_LIBRARY_SUFFIX ".lib")
+set(CMAKE_SHARED_LIBRARY_PREFIX "")
+set(CMAKE_SHARED_LIBRARY_SUFFIX ".dll")
+set(CMAKE_IMPORT_LIBRARY_PREFIX "")
+set(CMAKE_IMPORT_LIBRARY_SUFFIX ".lib")
+set(CMAKE_EXECUTABLE_SUFFIX ".exe")
+set(CMAKE_LINK_LIBRARY_SUFFIX ".lib")
+set(CMAKE_DL_LIBS "")
+
+set(CMAKE_FIND_LIBRARY_PREFIXES "")
+set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib")
diff --git a/Modules/Platform/Darwin-Initialize.cmake b/Modules/Platform/Darwin-Initialize.cmake
index 2d797f6..80e9a40 100644
--- a/Modules/Platform/Darwin-Initialize.cmake
+++ b/Modules/Platform/Darwin-Initialize.cmake
@@ -122,7 +122,162 @@ endforeach()
set(CMAKE_OSX_SYSROOT "${_CMAKE_OSX_SYSROOT_DEFAULT}" CACHE ${_CMAKE_OSX_SYSROOT_TYPE}
"The product will be built against the headers and libraries located inside the indicated SDK.")
-# Transform the cached value to something we can use.
+# Resolves the SDK name into a path
+function(_apple_resolve_sdk_path sdk_name ret)
+ execute_process(
+ COMMAND xcrun -sdk ${sdk_name} --show-sdk-path
+ OUTPUT_VARIABLE _stdout
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_VARIABLE _stderr
+ RESULT_VARIABLE _failed
+ )
+ set(${ret} "${_stdout}" PARENT_SCOPE)
+endfunction()
+
+function(_apple_resolve_supported_archs_for_sdk_from_system_lib sdk_path ret ret_failed)
+ # Detect the supported SDK architectures by inspecting the main libSystem library.
+ set(common_lib_prefix "${sdk_path}/usr/lib/libSystem")
+ set(system_lib_dylib_path "${common_lib_prefix}.dylib")
+ set(system_lib_tbd_path "${common_lib_prefix}.tbd")
+
+ # Newer SDKs ship text based dylib stub files which contain the architectures supported by the
+ # library in text form.
+ if(EXISTS "${system_lib_tbd_path}")
+ file(STRINGS "${system_lib_tbd_path}" tbd_lines REGEX "^archs: +\\[.+\\]")
+ if(NOT tbd_lines)
+ set(${ret_failed} TRUE PARENT_SCOPE)
+ return()
+ endif()
+
+ # The tbd architectures line looks like the following:
+ # archs: [ armv7, armv7s, arm64, arm64e ]
+ list(GET tbd_lines 0 first_arch_line)
+ string(REGEX REPLACE
+ "archs: +\\[ (.+) \\]" "\\1" arches_comma_separated "${first_arch_line}")
+ string(STRIP "${arches_comma_separated}" arches_comma_separated)
+ string(REPLACE "," ";" arch_list "${arches_comma_separated}")
+ string(REPLACE " " "" arch_list "${arch_list}")
+ if(NOT arch_list)
+ set(${ret_failed} TRUE PARENT_SCOPE)
+ return()
+ endif()
+ set(${ret} "${arch_list}" PARENT_SCOPE)
+ elseif(EXISTS "${system_lib_dylib_path}")
+ # Old SDKs (Xcode < 7) ship dylib files, use lipo to inspect the supported architectures.
+ # Can't use -archs because the option is not available in older Xcode versions.
+ execute_process(
+ COMMAND lipo -info ${system_lib_dylib_path}
+ OUTPUT_VARIABLE lipo_output
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_VARIABLE _stderr
+ RESULT_VARIABLE _failed
+ )
+ if(_failed OR NOT lipo_output OR NOT lipo_output MATCHES "(Non-fat file:|Architectures in the fat file:)")
+ set(${ret_failed} TRUE PARENT_SCOPE)
+ return()
+ endif()
+
+ # The lipo output looks like the following:
+ # Non-fat file: <path> is architecture: i386
+ # Architectures in the fat file: <path> are: i386 x86_64
+ string(REGEX REPLACE
+ "^(.+)is architecture:(.+)" "\\2" arches_space_separated "${lipo_output}")
+ string(REGEX REPLACE
+ "^(.+)are:(.+)" "\\2" arches_space_separated "${arches_space_separated}")
+
+ # Need to clean up the arches, with Xcode 4.6.3 the output of lipo -info contains some
+ # additional info, e.g.
+ # Architectures in the fat file: <path> are: armv7 (cputype (12) cpusubtype (11))
+ string(REGEX REPLACE
+ "\\(.+\\)" "" arches_space_separated "${arches_space_separated}")
+
+ # The output is space separated.
+ string(STRIP "${arches_space_separated}" arches_space_separated)
+ string(REPLACE " " ";" arch_list "${arches_space_separated}")
+
+ if(NOT arch_list)
+ set(${ret_failed} TRUE PARENT_SCOPE)
+ return()
+ endif()
+ set(${ret} "${arch_list}" PARENT_SCOPE)
+ else()
+ # This shouldn't happen, but keep it for safety.
+ message(WARNING "No way to find architectures for given sdk_path '${sdk_path}'")
+ set(${ret_failed} TRUE PARENT_SCOPE)
+ endif()
+endfunction()
+
+# Handle multi-arch sysroots. Do this before CMAKE_OSX_SYSROOT is
+# transformed into a path, so that we know the sysroot name.
+function(_apple_resolve_multi_arch_sysroots)
+ if(DEFINED CMAKE_APPLE_ARCH_SYSROOTS)
+ return() # Already cached
+ endif()
+
+ list(LENGTH CMAKE_OSX_ARCHITECTURES _num_archs)
+ if(NOT (_num_archs GREATER 1))
+ return() # Only apply to multi-arch
+ endif()
+
+ if(CMAKE_OSX_SYSROOT STREQUAL "macosx")
+ # macOS doesn't have a simulator sdk / sysroot, so there is no need to handle per-sdk arches.
+ return()
+ endif()
+
+ if(IS_DIRECTORY "${CMAKE_OSX_SYSROOT}")
+ if(NOT CMAKE_OSX_SYSROOT STREQUAL _CMAKE_OSX_SYSROOT_DEFAULT)
+ message(WARNING "Can not resolve multi-arch sysroots with CMAKE_OSX_SYSROOT set to path (${CMAKE_OSX_SYSROOT})")
+ endif()
+ return()
+ endif()
+
+ string(REPLACE "os" "simulator" _simulator_sdk ${CMAKE_OSX_SYSROOT})
+ set(_sdks "${CMAKE_OSX_SYSROOT};${_simulator_sdk}")
+ foreach(sdk ${_sdks})
+ _apple_resolve_sdk_path(${sdk} _sdk_path)
+ if(NOT IS_DIRECTORY "${_sdk_path}")
+ message(WARNING "Failed to resolve SDK path for '${sdk}'")
+ continue()
+ endif()
+
+ _apple_resolve_supported_archs_for_sdk_from_system_lib(${_sdk_path} _sdk_archs _failed)
+
+ if(_failed)
+ # Failure to extract supported architectures for an SDK means that the installed SDK is old
+ # and does not provide such information (SDKs that come with Xcode >= 10.x started providing
+ # the information). In such a case, return early, and handle multi-arch builds the old way
+ # (no per-sdk arches).
+ return()
+ endif()
+
+ set(_sdk_archs_${sdk} ${_sdk_archs})
+ set(_sdk_path_${sdk} ${_sdk_path})
+ endforeach()
+
+ foreach(arch ${CMAKE_OSX_ARCHITECTURES})
+ set(_arch_sysroot "")
+ foreach(sdk ${_sdks})
+ list(FIND _sdk_archs_${sdk} ${arch} arch_index)
+ if(NOT arch_index EQUAL -1)
+ set(_arch_sysroot ${_sdk_path_${sdk}})
+ break()
+ endif()
+ endforeach()
+ if(_arch_sysroot)
+ list(APPEND _arch_sysroots ${_arch_sysroot})
+ else()
+ message(WARNING "No SDK found for architecture '${arch}'")
+ list(APPEND _arch_sysroots "${arch}-SDK-NOTFOUND")
+ endif()
+ endforeach()
+
+ set(CMAKE_APPLE_ARCH_SYSROOTS "${_arch_sysroots}" CACHE INTERNAL
+ "Architecture dependent sysroots, one per CMAKE_OSX_ARCHITECTURES")
+endfunction()
+
+_apple_resolve_multi_arch_sysroots()
+
+# Transform CMAKE_OSX_SYSROOT to absolute path
set(_CMAKE_OSX_SYSROOT_PATH "")
if(CMAKE_OSX_SYSROOT)
if("x${CMAKE_OSX_SYSROOT}" MATCHES "/")
@@ -134,16 +289,9 @@ if(CMAKE_OSX_SYSROOT)
endif()
set(_CMAKE_OSX_SYSROOT_PATH "${CMAKE_OSX_SYSROOT}")
else()
- # Transform the sdk name into a path.
- execute_process(
- COMMAND xcodebuild -sdk ${CMAKE_OSX_SYSROOT} -version Path
- OUTPUT_VARIABLE _stdout
- OUTPUT_STRIP_TRAILING_WHITESPACE
- ERROR_VARIABLE _stderr
- RESULT_VARIABLE _failed
- )
- if(NOT _failed AND IS_DIRECTORY "${_stdout}")
- set(_CMAKE_OSX_SYSROOT_PATH "${_stdout}")
+ _apple_resolve_sdk_path(${CMAKE_OSX_SYSROOT} _sdk_path)
+ if(IS_DIRECTORY "${_sdk_path}")
+ set(_CMAKE_OSX_SYSROOT_PATH "${_sdk_path}")
# For non-Xcode generators use the path.
if(NOT "${CMAKE_GENERATOR}" MATCHES "Xcode")
set(CMAKE_OSX_SYSROOT "${_CMAKE_OSX_SYSROOT_PATH}")
diff --git a/Modules/Platform/Darwin.cmake b/Modules/Platform/Darwin.cmake
index e5a57b5..0a4d4e1 100644
--- a/Modules/Platform/Darwin.cmake
+++ b/Modules/Platform/Darwin.cmake
@@ -210,7 +210,7 @@ unset(_apps_paths)
include(Platform/UnixPaths)
if(_CMAKE_OSX_SYSROOT_PATH AND EXISTS ${_CMAKE_OSX_SYSROOT_PATH}/usr/include)
list(APPEND CMAKE_SYSTEM_PREFIX_PATH ${_CMAKE_OSX_SYSROOT_PATH}/usr)
- foreach(lang C CXX OBJC OBJCXX)
+ foreach(lang C CXX OBJC OBJCXX Swift)
list(APPEND _CMAKE_${lang}_IMPLICIT_INCLUDE_DIRECTORIES_INIT ${_CMAKE_OSX_SYSROOT_PATH}/usr/include)
endforeach()
endif()
diff --git a/Modules/Platform/Generic-SDCC-C.cmake b/Modules/Platform/Generic-SDCC-C.cmake
index aef4abf..c3fd186 100644
--- a/Modules/Platform/Generic-SDCC-C.cmake
+++ b/Modules/Platform/Generic-SDCC-C.cmake
@@ -1,4 +1,3 @@
-
# This file implements basic support for sdcc (http://sdcc.sourceforge.net/)
# a free C compiler for 8 and 16 bit microcontrollers.
# To use it either a toolchain file is required or cmake has to be run like this:
@@ -19,22 +18,26 @@ set(CMAKE_DL_LIBS "")
set(CMAKE_C_OUTPUT_EXTENSION ".rel")
-# find sdcclib as CMAKE_AR
-# since cmake may already have searched for "ar", sdcclib has to
-# be searched with a different variable name (SDCCLIB_EXECUTABLE)
-# and must then be forced into the cache
+# find sdar/sdcclib as CMAKE_AR
+# since cmake may already have searched for "ar", sdar has to
+# be searched with a different variable name (SDCCAR_EXECUTABLE)
+# and must then be forced into the cache.
+# sdcclib has been deprecated in SDCC 3.2.0 and removed in 3.8.6
+# so we first look for sdar
get_filename_component(SDCC_LOCATION "${CMAKE_C_COMPILER}" PATH)
-find_program(SDCCLIB_EXECUTABLE sdcclib PATHS "${SDCC_LOCATION}" NO_DEFAULT_PATH)
-find_program(SDCCLIB_EXECUTABLE sdcclib)
-set(CMAKE_AR "${SDCCLIB_EXECUTABLE}" CACHE FILEPATH "The sdcc librarian" FORCE)
-
-# CMAKE_C_FLAGS_INIT and CMAKE_EXE_LINKER_FLAGS_INIT should be set in a CMAKE_SYSTEM_PROCESSOR file
-if(NOT DEFINED CMAKE_C_FLAGS_INIT)
- string(APPEND CMAKE_C_FLAGS_INIT " -mmcs51 --model-small")
+find_program(SDCCAR_EXECUTABLE sdar NAMES sdcclib PATHS "${SDCC_LOCATION}" NO_DEFAULT_PATH)
+find_program(SDCCAR_EXECUTABLE sdar NAMES sdcclib)
+# for compatibility, in case SDCCLIB_EXECUTABLE is set, we use it
+if(DEFINED SDCCLIB_EXECUTABLE)
+ set(CMAKE_AR "${SDCCLIB_EXECUTABLE}" CACHE FILEPATH "The sdcc librarian" FORCE)
+else()
+ set(CMAKE_AR "${SDCCAR_EXECUTABLE}" CACHE FILEPATH "The sdcc librarian" FORCE)
endif()
-if(NOT DEFINED CMAKE_EXE_LINKER_FLAGS_INIT)
- set (CMAKE_EXE_LINKER_FLAGS_INIT --model-small)
+if("${SDCCAR_EXECUTABLE}" MATCHES "sdcclib")
+ set(CMAKE_AR_OPTIONS "-a")
+else()
+ set(CMAKE_AR_OPTIONS "-rc")
endif()
set(CMAKE_C_LINKER_WRAPPER_FLAG "-Wl" ",")
@@ -45,10 +48,10 @@ set(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o
# link object files to an executable
set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <FLAGS> <OBJECTS> -o <TARGET> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>")
-# needs sdcc 2.7.0 + sddclib from cvs
+# needs sdcc + sdar/sdcclib
set(CMAKE_C_CREATE_STATIC_LIBRARY
"\"${CMAKE_COMMAND}\" -E remove <TARGET>"
- "<CMAKE_AR> -a <TARGET> <LINK_FLAGS> <OBJECTS> ")
+ "<CMAKE_AR> ${CMAKE_AR_OPTIONS} <TARGET> <LINK_FLAGS> <OBJECTS> ")
# not supported by sdcc
set(CMAKE_C_CREATE_SHARED_LIBRARY "")
diff --git a/Modules/Platform/HP-UX-HP-C.cmake b/Modules/Platform/HP-UX-HP-C.cmake
index 7610383..57ba2eb 100644
--- a/Modules/Platform/HP-UX-HP-C.cmake
+++ b/Modules/Platform/HP-UX-HP-C.cmake
@@ -3,4 +3,4 @@ __hpux_compiler_hp(C)
set(CMAKE_C_CREATE_PREPROCESSED_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
set(CMAKE_C_CREATE_ASSEMBLY_SOURCE "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
-set(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER> <DEFINES> -Aa -Ae <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
+set(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER> <DEFINES> -Aa -Ae <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
diff --git a/Modules/Platform/Linux-OpenWatcom-C.cmake b/Modules/Platform/Linux-OpenWatcom-C.cmake
new file mode 100644
index 0000000..383349a
--- /dev/null
+++ b/Modules/Platform/Linux-OpenWatcom-C.cmake
@@ -0,0 +1 @@
+include(Platform/Linux-OpenWatcom)
diff --git a/Modules/Platform/Linux-OpenWatcom-CXX.cmake b/Modules/Platform/Linux-OpenWatcom-CXX.cmake
new file mode 100644
index 0000000..383349a
--- /dev/null
+++ b/Modules/Platform/Linux-OpenWatcom-CXX.cmake
@@ -0,0 +1 @@
+include(Platform/Linux-OpenWatcom)
diff --git a/Modules/Platform/Linux-OpenWatcom.cmake b/Modules/Platform/Linux-OpenWatcom.cmake
new file mode 100644
index 0000000..5b4e995
--- /dev/null
+++ b/Modules/Platform/Linux-OpenWatcom.cmake
@@ -0,0 +1,25 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+# This module is shared by multiple languages; use include blocker.
+include_guard()
+
+set(CMAKE_BUILD_TYPE_INIT Debug)
+
+string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " system linux opt noextension")
+string(APPEND CMAKE_MODULE_LINKER_FLAGS_INIT " system linux")
+string(APPEND CMAKE_SHARED_LINKER_FLAGS_INIT " system linux")
+
+# single/multi-threaded /-bm
+# default is setup for single-threaded libraries
+string(APPEND CMAKE_C_FLAGS_INIT " -bt=linux")
+string(APPEND CMAKE_CXX_FLAGS_INIT " -bt=linux -xs")
+
+if(CMAKE_CROSSCOMPILING)
+ if(NOT CMAKE_C_STANDARD_INCLUDE_DIRECTORIES)
+ set(CMAKE_C_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/lh)
+ endif()
+ if(NOT CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES)
+ set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/lh)
+ endif()
+endif()
diff --git a/Modules/Platform/Linux-como.cmake b/Modules/Platform/Linux-como.cmake
index d1550d2..f6db34c 100644
--- a/Modules/Platform/Linux-como.cmake
+++ b/Modules/Platform/Linux-como.cmake
@@ -11,7 +11,7 @@ set(CMAKE_CXX_CREATE_STATIC_LIBRARY
set(CMAKE_CXX_LINK_EXECUTABLE
"<CMAKE_CXX_COMPILER> --prelink_objects <OBJECTS>"
- "<CMAKE_CXX_COMPILER> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
+ "<CMAKE_CXX_COMPILER> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "")
set(CMAKE_SHARED_LIBRARY_C_FLAGS "")
diff --git a/Modules/Platform/OS2-OpenWatcom-C.cmake b/Modules/Platform/OS2-OpenWatcom-C.cmake
new file mode 100644
index 0000000..21a4d9e
--- /dev/null
+++ b/Modules/Platform/OS2-OpenWatcom-C.cmake
@@ -0,0 +1 @@
+include(Platform/OS2-OpenWatcom)
diff --git a/Modules/Platform/OS2-OpenWatcom-CXX.cmake b/Modules/Platform/OS2-OpenWatcom-CXX.cmake
new file mode 100644
index 0000000..21a4d9e
--- /dev/null
+++ b/Modules/Platform/OS2-OpenWatcom-CXX.cmake
@@ -0,0 +1 @@
+include(Platform/OS2-OpenWatcom)
diff --git a/Modules/Platform/OS2-OpenWatcom.cmake b/Modules/Platform/OS2-OpenWatcom.cmake
new file mode 100644
index 0000000..998fb9f
--- /dev/null
+++ b/Modules/Platform/OS2-OpenWatcom.cmake
@@ -0,0 +1,35 @@
+# This module is shared by multiple languages; use include blocker.
+include_guard()
+
+set(CMAKE_BUILD_TYPE_INIT Debug)
+
+if(DEFINED CMAKE_SYSTEM_PROCESSOR AND CMAKE_SYSTEM_PROCESSOR STREQUAL "I86")
+ string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " system os2")
+ string(APPEND CMAKE_SHARED_LINKER_FLAGS_INIT " system os2_dll")
+ string(APPEND CMAKE_MODULE_LINKER_FLAGS_INIT " system os2_dll")
+else()
+ string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " system os2v2")
+ string(APPEND CMAKE_SHARED_LINKER_FLAGS_INIT " system os2v2_dll")
+ string(APPEND CMAKE_MODULE_LINKER_FLAGS_INIT " system os2v2_dll")
+endif()
+
+set(CMAKE_C_COMPILE_OPTIONS_DLL "-bd") # Note: This variable is a ';' separated list
+set(CMAKE_SHARED_LIBRARY_C_FLAGS "-bd") # ... while this is a space separated string.
+
+string(APPEND CMAKE_C_FLAGS_INIT " -bt=os2")
+string(APPEND CMAKE_CXX_FLAGS_INIT " -bt=os2 -xs")
+
+if(NOT CMAKE_C_STANDARD_INCLUDE_DIRECTORIES)
+ if(DEFINED CMAKE_SYSTEM_PROCESSOR AND CMAKE_SYSTEM_PROCESSOR STREQUAL "I86")
+ set(CMAKE_C_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/h $ENV{WATCOM}/h/os21x)
+ else()
+ set(CMAKE_C_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/h $ENV{WATCOM}/h/os2)
+ endif()
+endif()
+if(NOT CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES)
+ if(DEFINED CMAKE_SYSTEM_PROCESSOR AND CMAKE_SYSTEM_PROCESSOR STREQUAL "I86")
+ set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/h $ENV{WATCOM}/h/os21x)
+ else()
+ set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/h $ENV{WATCOM}/h/os2)
+ endif()
+endif()
diff --git a/Modules/Platform/OS2.cmake b/Modules/Platform/OS2.cmake
new file mode 100644
index 0000000..a9df66d
--- /dev/null
+++ b/Modules/Platform/OS2.cmake
@@ -0,0 +1,14 @@
+set(OS2 1)
+
+set(CMAKE_STATIC_LIBRARY_PREFIX "")
+set(CMAKE_STATIC_LIBRARY_SUFFIX ".lib")
+set(CMAKE_SHARED_LIBRARY_PREFIX "")
+set(CMAKE_SHARED_LIBRARY_SUFFIX ".dll")
+set(CMAKE_IMPORT_LIBRARY_PREFIX "")
+set(CMAKE_IMPORT_LIBRARY_SUFFIX ".lib")
+set(CMAKE_EXECUTABLE_SUFFIX ".exe")
+set(CMAKE_LINK_LIBRARY_SUFFIX ".lib")
+set(CMAKE_DL_LIBS "")
+
+set(CMAKE_FIND_LIBRARY_PREFIXES "")
+set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib")
diff --git a/Modules/Platform/UnixPaths.cmake b/Modules/Platform/UnixPaths.cmake
index 97f744d..98c83aa 100644
--- a/Modules/Platform/UnixPaths.cmake
+++ b/Modules/Platform/UnixPaths.cmake
@@ -86,6 +86,10 @@ set(_CMAKE_CUDA_IMPLICIT_INCLUDE_DIRECTORIES_INIT
unset(_cmake_sysroot_compile)
+if(CMAKE_COMPILER_SYSROOT)
+ list(PREPEND CMAKE_SYSTEM_PREFIX_PATH "${CMAKE_COMPILER_SYSROOT}")
+endif()
+
# Enable use of lib32 and lib64 search path variants by default.
set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB32_PATHS TRUE)
set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS TRUE)
diff --git a/Modules/Platform/Windows-Apple-Swift.cmake b/Modules/Platform/Windows-Apple-Swift.cmake
new file mode 100644
index 0000000..1177755
--- /dev/null
+++ b/Modules/Platform/Windows-Apple-Swift.cmake
@@ -0,0 +1 @@
+set(CMAKE_Swift_IMPLIB_LINKER_FLAGS "-Xlinker -implib:<TARGET_IMPLIB>")
diff --git a/Modules/Platform/Windows-Clang-ASM.cmake b/Modules/Platform/Windows-Clang-ASM.cmake
new file mode 100644
index 0000000..345d77d
--- /dev/null
+++ b/Modules/Platform/Windows-Clang-ASM.cmake
@@ -0,0 +1,2 @@
+include(Platform/Windows-Clang)
+__windows_compiler_clang(ASM)
diff --git a/Modules/Platform/Windows-Clang.cmake b/Modules/Platform/Windows-Clang.cmake
index 02864c6..dff8166 100644
--- a/Modules/Platform/Windows-Clang.cmake
+++ b/Modules/Platform/Windows-Clang.cmake
@@ -21,10 +21,12 @@ macro(__windows_compiler_clang_gnu lang)
set(CMAKE_SHARED_LIBRARY_SUFFIX ".dll")
set(CMAKE_SHARED_MODULE_SUFFIX ".dll")
set(CMAKE_STATIC_LIBRARY_SUFFIX ".lib")
- set(CMAKE_DEPFILE_FLAGS_${lang} "-MD -MT <OBJECT> -MF <DEPFILE>")
+ if(NOT "${lang}" STREQUAL "ASM")
+ set(CMAKE_DEPFILE_FLAGS_${lang} "-MD -MT <OBJECT> -MF <DEPFILE>")
+ endif()
set(CMAKE_FIND_LIBRARY_PREFIXES "lib" "")
- set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll" ".dll.a" ".a" ".lib")
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll.a" ".a" ".lib")
set(CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS 1)
set (CMAKE_LINK_DEF_FILE_FLAG "-Xlinker /DEF:")
@@ -53,36 +55,38 @@ macro(__windows_compiler_clang_gnu lang)
# Create archiving rules to support large object file lists for static libraries.
set(CMAKE_${lang}_ARCHIVE_CREATE "<CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>")
- set(CMAKE_${lang}_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
+ set(CMAKE_${lang}_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
set(CMAKE_${lang}_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")
set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
"<CMAKE_${lang}_COMPILER> -fuse-ld=lld-link -nostartfiles -nostdlib <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> -o <TARGET> ${CMAKE_GNULD_IMAGE_VERSION} -Xlinker /implib:<TARGET_IMPLIB> -Xlinker /pdb:<TARGET_PDB> -Xlinker /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <OBJECTS> <LINK_LIBRARIES>")
set(CMAKE_${lang}_CREATE_SHARED_MODULE ${CMAKE_${lang}_CREATE_SHARED_LIBRARY})
set(CMAKE_${lang}_LINK_EXECUTABLE
- "<CMAKE_${lang}_COMPILER> -fuse-ld=lld-link -nostartfiles -nostdlib <FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -Xlinker /implib:<TARGET_IMPLIB> -Xlinker /pdb:<TARGET_PDB> -Xlinker /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>")
+ "<CMAKE_${lang}_COMPILER> -fuse-ld=lld-link -nostartfiles -nostdlib <FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -Xlinker /implib:<TARGET_IMPLIB> -Xlinker /pdb:<TARGET_PDB> -Xlinker /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>")
- set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded -Xclang -flto-visibility-public-std -D_MT -Xclang --dependent-lib=libcmt)
- set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL -D_DLL -D_MT -Xclang --dependent-lib=msvcrt)
- set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug -D_DEBUG -Xclang -flto-visibility-public-std -D_MT -Xclang --dependent-lib=libcmtd)
- set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL -D_DEBUG -D_DLL -D_MT -Xclang --dependent-lib=msvcrtd)
+ if(NOT "${lang}" STREQUAL "ASM")
+ set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded -Xclang -flto-visibility-public-std -D_MT -Xclang --dependent-lib=libcmt)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL -D_DLL -D_MT -Xclang --dependent-lib=msvcrt)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug -D_DEBUG -Xclang -flto-visibility-public-std -D_MT -Xclang --dependent-lib=libcmtd)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL -D_DEBUG -D_DLL -D_MT -Xclang --dependent-lib=msvcrtd)
- if(CMAKE_MSVC_RUNTIME_LIBRARY_DEFAULT)
- set(__ADDED_FLAGS "")
- set(__ADDED_FLAGS_DEBUG "")
- else()
- set(__ADDED_FLAGS_DEBUG "-D_DEBUG -D_DLL -D_MT -Xclang --dependent-lib=msvcrtd")
- set(__ADDED_FLAGS "-D_DLL -D_MT -Xclang --dependent-lib=msvcrt")
- endif()
+ if(CMAKE_MSVC_RUNTIME_LIBRARY_DEFAULT)
+ set(__ADDED_FLAGS "")
+ set(__ADDED_FLAGS_DEBUG "")
+ else()
+ set(__ADDED_FLAGS_DEBUG "-D_DEBUG -D_DLL -D_MT -Xclang --dependent-lib=msvcrtd")
+ set(__ADDED_FLAGS "-D_DLL -D_MT -Xclang --dependent-lib=msvcrt")
+ endif()
- string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT " -g -Xclang -gcodeview -O0 ${__ADDED_FLAGS_DEBUG}")
- string(APPEND CMAKE_${lang}_FLAGS_MINSIZEREL_INIT " -Os -DNDEBUG ${__ADDED_FLAGS}")
- string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT " -O3 -DNDEBUG ${__ADDED_FLAGS}")
- string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT " -O2 -g -DNDEBUG -Xclang -gcodeview ${__ADDED_FLAGS}")
+ string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT " -g -Xclang -gcodeview -O0 ${__ADDED_FLAGS_DEBUG}")
+ string(APPEND CMAKE_${lang}_FLAGS_MINSIZEREL_INIT " -Os -DNDEBUG ${__ADDED_FLAGS}")
+ string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT " -O3 -DNDEBUG ${__ADDED_FLAGS}")
+ string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT " -O2 -g -DNDEBUG -Xclang -gcodeview ${__ADDED_FLAGS}")
+ endif()
set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ")
set(CMAKE_PCH_EXTENSION .pch)
set(CMAKE_PCH_PROLOGUE "#pragma clang system_header")
- set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Xclang -include-pch -Xclang <PCH_FILE>)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Xclang -include-pch -Xclang <PCH_FILE> -Xclang -include -Xclang <PCH_HEADER>)
set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Xclang -emit-pch -Xclang -include -Xclang <PCH_HEADER>)
unset(__ADDED_FLAGS)
@@ -129,6 +133,24 @@ if("x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC"
if ( "x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC" OR "x${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC" )
include(Platform/Windows-MSVC)
+ # Feed the preprocessed rc file to llvm-rc
+ if(CMAKE_RC_COMPILER_INIT MATCHES "llvm-rc")
+ if(DEFINED CMAKE_C_COMPILER_ID)
+ set(CMAKE_RC_PREPROCESSOR CMAKE_C_COMPILER)
+ elseif(DEFINED CMAKE_CXX_COMPILER_ID)
+ set(CMAKE_RC_PREPROCESSOR CMAKE_CXX_COMPILER)
+ endif()
+ if(DEFINED CMAKE_RC_PREPROCESSOR)
+ set(CMAKE_DEPFILE_FLAGS_RC "-clang:-MD -clang:-MF -clang:<DEPFILE>")
+ set(CMAKE_RC_COMPILE_OBJECT "${CMAKE_COMMAND} -E cmake_llvm_rc <SOURCE> <OBJECT>.pp <${CMAKE_RC_PREPROCESSOR}> <DEFINES> -DRC_INVOKED <INCLUDES> <FLAGS> -E <SOURCE> -- <CMAKE_RC_COMPILER> <DEFINES> -I <SOURCE_DIR> <INCLUDES> /fo <OBJECT> <OBJECT>.pp")
+ if(CMAKE_GENERATOR STREQUAL "Ninja")
+ set(CMAKE_NINJA_CMCLDEPS_RC 0)
+ set(CMAKE_NINJA_DEP_TYPE_RC gcc)
+ endif()
+ unset(CMAKE_RC_PREPROCESSOR)
+ endif()
+ endif()
+
macro(__windows_compiler_clang lang)
set(_COMPILE_${lang} "${_COMPILE_${lang}_MSVC}")
__windows_compiler_msvc(${lang})
diff --git a/Modules/Platform/Windows-Embarcadero.cmake b/Modules/Platform/Windows-Embarcadero.cmake
index 370b56e..0c24739 100644
--- a/Modules/Platform/Windows-Embarcadero.cmake
+++ b/Modules/Platform/Windows-Embarcadero.cmake
@@ -122,7 +122,7 @@ macro(__embarcadero_language lang)
# Precompile Headers
if (EMBARCADERO)
set(CMAKE_PCH_EXTENSION .pch)
- set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Xclang -include-pch -Xclang <PCH_FILE>)
+ set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Xclang -include-pch -Xclang <PCH_FILE> -Xclang -include -Xclang <PCH_HEADER>)
set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Xclang -emit-pch -Xclang -include -Xclang <PCH_HEADER>)
endif()
diff --git a/Modules/Platform/Windows-GNU-ASM.cmake b/Modules/Platform/Windows-GNU-ASM.cmake
new file mode 100644
index 0000000..8600892
--- /dev/null
+++ b/Modules/Platform/Windows-GNU-ASM.cmake
@@ -0,0 +1,2 @@
+include(Platform/Windows-GNU)
+__windows_compiler_gnu(ASM)
diff --git a/Modules/Platform/Windows-GNU.cmake b/Modules/Platform/Windows-GNU.cmake
index 6bf245c..a2e3811 100644
--- a/Modules/Platform/Windows-GNU.cmake
+++ b/Modules/Platform/Windows-GNU.cmake
@@ -25,7 +25,7 @@ endif()
if(MINGW)
set(CMAKE_FIND_LIBRARY_PREFIXES "lib" "")
- set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll" ".dll.a" ".a" ".lib")
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll.a" ".a" ".lib")
set(CMAKE_C_STANDARD_LIBRARIES_INIT "-lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32")
set(CMAKE_CXX_STANDARD_LIBRARIES_INIT "${CMAKE_C_STANDARD_LIBRARIES_INIT}")
endif()
@@ -47,16 +47,12 @@ if("${_help}" MATCHES "GNU ld .* 2\\.1[1-6]")
set(__WINDOWS_GNU_LD_RESPONSE 0)
endif()
-if(NOT CMAKE_GENERATOR_RC AND CMAKE_GENERATOR MATCHES "Unix Makefiles")
- set(CMAKE_GENERATOR_RC windres)
-endif()
-
macro(__windows_compiler_gnu lang)
if(MSYS OR MINGW)
# Create archiving rules to support large object file lists for static libraries.
set(CMAKE_${lang}_ARCHIVE_CREATE "<CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>")
- set(CMAKE_${lang}_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
+ set(CMAKE_${lang}_ARCHIVE_APPEND "<CMAKE_AR> q <TARGET> <LINK_FLAGS> <OBJECTS>")
set(CMAKE_${lang}_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")
# Initialize C link type selection flags. These flags are used when
@@ -108,7 +104,7 @@ macro(__windows_compiler_gnu lang)
set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
"<CMAKE_${lang}_COMPILER> <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <OBJECTS> <LINK_LIBRARIES>")
set(CMAKE_${lang}_LINK_EXECUTABLE
- "<CMAKE_${lang}_COMPILER> <FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>")
+ "<CMAKE_${lang}_COMPILER> <FLAGS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -Wl,--out-implib,<TARGET_IMPLIB> ${CMAKE_GNULD_IMAGE_VERSION} <LINK_LIBRARIES>")
list(APPEND CMAKE_${lang}_ABI_FILES "Platform/Windows-GNU-${lang}-ABI")
@@ -124,7 +120,7 @@ macro(__windows_compiler_gnu lang)
string(REPLACE "<OBJECTS>" "-Wl,--whole-archive <OBJECT_DIR>/objects.a -Wl,--no-whole-archive"
CMAKE_${lang}_${rule} "${CMAKE_${lang}_${rule}}")
set(CMAKE_${lang}_${rule}
- "<CMAKE_COMMAND> -E remove -f <OBJECT_DIR>/objects.a"
+ "<CMAKE_COMMAND> -E rm -f <OBJECT_DIR>/objects.a"
"<CMAKE_AR> cr <OBJECT_DIR>/objects.a <OBJECTS>"
"${CMAKE_${lang}_${rule}}"
)
@@ -132,7 +128,7 @@ macro(__windows_compiler_gnu lang)
endif()
if(NOT CMAKE_RC_COMPILER_INIT AND NOT CMAKE_GENERATOR_RC)
- set(CMAKE_RC_COMPILER_INIT windres)
+ set(CMAKE_RC_COMPILER_INIT ${_CMAKE_TOOLCHAIN_PREFIX}windres)
endif()
enable_language(RC)
diff --git a/Modules/Platform/Windows-Intel.cmake b/Modules/Platform/Windows-Intel.cmake
index 96b1760..5d8f7fc 100644
--- a/Modules/Platform/Windows-Intel.cmake
+++ b/Modules/Platform/Windows-Intel.cmake
@@ -11,7 +11,7 @@ set(__WINDOWS_INTEL 1)
include(Platform/Windows-MSVC)
macro(__windows_compiler_intel lang)
__windows_compiler_msvc(${lang})
- string(REPLACE "<CMAKE_LINKER> /lib" "xilib" CMAKE_${lang}_CREATE_STATIC_LIBRARY "${CMAKE_${lang}_CREATE_STATIC_LIBRARY}")
+ string(REPLACE "<CMAKE_AR>" "xilib" CMAKE_${lang}_CREATE_STATIC_LIBRARY "${CMAKE_${lang}_CREATE_STATIC_LIBRARY}")
foreach(rule CREATE_SHARED_LIBRARY CREATE_SHARED_MODULE LINK_EXECUTABLE)
string(REPLACE "<CMAKE_LINKER>" "xilink" CMAKE_${lang}_${rule} "${CMAKE_${lang}_${rule}}")
endforeach()
diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake
index e0f33bd..2476a33 100644
--- a/Modules/Platform/Windows-MSVC.cmake
+++ b/Modules/Platform/Windows-MSVC.cmake
@@ -217,7 +217,7 @@ elseif(WINDOWS_PHONE OR WINDOWS_STORE)
else()
set(_PLATFORM_DEFINES "/DWIN32")
- if(_MSVC_C_ARCHITECTURE_FAMILY STREQUAL "ARM" OR _MSVC_CXX_ARCHITECTURE_FAMILY STREQUAL "ARM" OR _MSVC_C_ARCHITECTURE_FAMILY STREQUAL "ARM64" OR _MSVC_CXX_ARCHITECTURE_FAMILY STREQUAL "ARM64")
+ if(_MSVC_C_ARCHITECTURE_FAMILY STREQUAL "ARM" OR _MSVC_CXX_ARCHITECTURE_FAMILY STREQUAL "ARM")
set(CMAKE_C_STANDARD_LIBRARIES_INIT "kernel32.lib user32.lib")
elseif(MSVC_VERSION GREATER 1310)
if(CMAKE_VS_PLATFORM_TOOLSET MATCHES "v[0-9]+_clang_.*")
@@ -316,7 +316,7 @@ macro(__windows_compiler_msvc lang)
"${_CMAKE_VS_LINK_DLL}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /dll /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <LINK_FLAGS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
set(CMAKE_${lang}_CREATE_SHARED_MODULE ${CMAKE_${lang}_CREATE_SHARED_LIBRARY})
- set(CMAKE_${lang}_CREATE_STATIC_LIBRARY "<CMAKE_LINKER> /lib ${CMAKE_CL_NOLOGO} <LINK_FLAGS> /out:<TARGET> <OBJECTS> ")
+ set(CMAKE_${lang}_CREATE_STATIC_LIBRARY "<CMAKE_AR> ${CMAKE_CL_NOLOGO} <LINK_FLAGS> /out:<TARGET> <OBJECTS> ")
set(CMAKE_${lang}_COMPILE_OBJECT
"<CMAKE_${lang}_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO}${_COMPILE_${lang}} <DEFINES> <INCLUDES> <FLAGS> /Fo<OBJECT> /Fd<TARGET_COMPILE_PDB>${_FS_${lang}} -c <SOURCE>${CMAKE_END_TEMP_FILE}")
diff --git a/Modules/Platform/Windows-NVIDIA-CUDA.cmake b/Modules/Platform/Windows-NVIDIA-CUDA.cmake
index 94d77b9..f425cf8 100644
--- a/Modules/Platform/Windows-NVIDIA-CUDA.cmake
+++ b/Modules/Platform/Windows-NVIDIA-CUDA.cmake
@@ -1,11 +1,11 @@
include(Platform/Windows-MSVC)
set(CMAKE_CUDA_COMPILE_PTX_COMPILATION
- "<CMAKE_CUDA_COMPILER> ${CMAKE_CUDA_HOST_FLAGS} <DEFINES> <INCLUDES> <FLAGS> -x cu -ptx <SOURCE> -o <OBJECT> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS")
+ "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <DEFINES> <INCLUDES> <FLAGS> ${_CMAKE_COMPILE_AS_CUDA_FLAG} -ptx <SOURCE> -o <OBJECT> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS")
set(CMAKE_CUDA_COMPILE_SEPARABLE_COMPILATION
- "<CMAKE_CUDA_COMPILER> ${CMAKE_CUDA_HOST_FLAGS} <DEFINES> <INCLUDES> <FLAGS> -x cu -dc <SOURCE> -o <OBJECT> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS")
+ "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <DEFINES> <INCLUDES> <FLAGS> ${_CMAKE_COMPILE_AS_CUDA_FLAG} -dc <SOURCE> -o <OBJECT> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS")
set(CMAKE_CUDA_COMPILE_WHOLE_COMPILATION
- "<CMAKE_CUDA_COMPILER> ${CMAKE_CUDA_HOST_FLAGS} <DEFINES> <INCLUDES> <FLAGS> -x cu -c <SOURCE> -o <OBJECT> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS")
+ "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <DEFINES> <INCLUDES> <FLAGS> ${_CMAKE_COMPILE_AS_CUDA_FLAG} -c <SOURCE> -o <OBJECT> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS")
set(__IMPLICT_LINKS )
foreach(dir ${CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES})
@@ -23,18 +23,13 @@ set(CMAKE_CUDA_CREATE_SHARED_LIBRARY
"${_CMAKE_VS_LINK_DLL}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /dll /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <LINK_FLAGS> <LINK_LIBRARIES>${__IMPLICT_LINKS} ${CMAKE_END_TEMP_FILE}")
set(CMAKE_CUDA_CREATE_SHARED_MODULE ${CMAKE_CUDA_CREATE_SHARED_LIBRARY})
-set(CMAKE_CUDA_CREATE_STATIC_LIBRARY "<CMAKE_LINKER> /lib ${CMAKE_CL_NOLOGO} <LINK_FLAGS> /out:<TARGET> <OBJECTS> ")
+set(CMAKE_CUDA_CREATE_STATIC_LIBRARY "<CMAKE_AR> ${CMAKE_CL_NOLOGO} <LINK_FLAGS> /out:<TARGET> <OBJECTS> ")
set(CMAKE_CUDA_LINKER_SUPPORTS_PDB ON)
set(CMAKE_CUDA_LINK_EXECUTABLE
"${_CMAKE_VS_LINK_EXE}<CMAKE_LINKER> ${CMAKE_CL_NOLOGO} <OBJECTS> ${CMAKE_START_TEMP_FILE} /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <LINK_FLAGS> <LINK_LIBRARIES>${__IMPLICT_LINKS} ${CMAKE_END_TEMP_FILE}")
unset(_CMAKE_VS_LINK_EXE)
unset(_CMAKE_VS_LINK_EXE)
-if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "8.0.0")
- set(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS "-Wno-deprecated-gpu-targets")
-else()
- set(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS "")
-endif()
# Add implicit host link directories that contain device libraries
# to the device link line.
@@ -51,11 +46,9 @@ endforeach()
unset(__IMPLICT_DLINK_DIRS)
set(CMAKE_CUDA_DEVICE_LINK_LIBRARY
- "<CMAKE_CUDA_COMPILER> <LANGUAGE_COMPILE_FLAGS> ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS${__IMPLICT_DLINK_FLAGS}")
+ "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS${__IMPLICT_DLINK_FLAGS}")
set(CMAKE_CUDA_DEVICE_LINK_EXECUTABLE
- "<CMAKE_CUDA_COMPILER> <FLAGS> ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS${__IMPLICT_DLINK_FLAGS}")
-
-unset(_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS)
+ "<CMAKE_CUDA_COMPILER> ${_CMAKE_CUDA_EXTRA_FLAGS} <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> ${_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS} -shared -dlink <OBJECTS> -o <TARGET> <LINK_LIBRARIES> -Xcompiler=-Fd<TARGET_COMPILE_PDB>,-FS${__IMPLICT_DLINK_FLAGS}")
unset(__IMPLICT_DLINK_FLAGS)
string(REPLACE "/D" "-D" _PLATFORM_DEFINES_CUDA "${_PLATFORM_DEFINES}${_PLATFORM_DEFINES_CXX}")
@@ -76,6 +69,11 @@ else()
endif()
unset(_cmp0092)
+set(CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT "STATIC")
+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 "")
+
string(APPEND CMAKE_CUDA_FLAGS_INIT " ${PLATFORM_DEFINES_CUDA} -D_WINDOWS -Xcompiler=\"${_W3}${_FLAGS_CXX}\"")
string(APPEND CMAKE_CUDA_FLAGS_DEBUG_INIT " -Xcompiler=\"${_MDd}-Zi -Ob0 -Od ${_RTC1}\"")
string(APPEND CMAKE_CUDA_FLAGS_RELEASE_INIT " -Xcompiler=\"${_MD}-O2 -Ob2\" -DNDEBUG")
diff --git a/Modules/Platform/Windows-OpenWatcom.cmake b/Modules/Platform/Windows-OpenWatcom.cmake
index 76cd28b..70055da 100644
--- a/Modules/Platform/Windows-OpenWatcom.cmake
+++ b/Modules/Platform/Windows-OpenWatcom.cmake
@@ -1,129 +1,32 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
-
# This module is shared by multiple languages; use include blocker.
-if(__WINDOWS_OPENWATCOM)
- return()
-endif()
-set(__WINDOWS_OPENWATCOM 1)
-
-set(CMAKE_LIBRARY_PATH_FLAG "libpath ")
-set(CMAKE_LINK_LIBRARY_FLAG "library ")
-set(CMAKE_LINK_LIBRARY_FILE_FLAG "library ")
+include_guard()
-if(CMAKE_VERBOSE_MAKEFILE)
- set(CMAKE_WCL_QUIET)
- set(CMAKE_WLINK_QUIET)
- set(CMAKE_LIB_QUIET)
-else()
- set(CMAKE_WCL_QUIET "-zq")
- set(CMAKE_WLINK_QUIET "option quiet")
- set(CMAKE_LIB_QUIET "-q")
-endif()
+set(CMAKE_BUILD_TYPE_INIT Debug)
-string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " ")
set(CMAKE_CREATE_WIN32_EXE "system nt_win" )
set(CMAKE_CREATE_CONSOLE_EXE "system nt" )
string(APPEND CMAKE_SHARED_LINKER_FLAGS_INIT " system nt_dll")
string(APPEND CMAKE_MODULE_LINKER_FLAGS_INIT " system nt_dll")
-foreach(type SHARED MODULE EXE)
- string(APPEND CMAKE_${type}_LINKER_FLAGS_DEBUG_INIT " debug all opt map")
- string(APPEND CMAKE_${type}_LINKER_FLAGS_RELWITHDEBINFO_INIT " debug all opt map")
-endforeach()
set(CMAKE_C_COMPILE_OPTIONS_DLL "-bd") # Note: This variable is a ';' separated list
set(CMAKE_SHARED_LIBRARY_C_FLAGS "-bd") # ... while this is a space separated string.
set(CMAKE_RC_COMPILER "rc" )
-set(CMAKE_BUILD_TYPE_INIT Debug)
-
# single/multi-threaded /-bm
# static/DLL run-time libraries /-br
# default is setup for multi-threaded + DLL run-time libraries
-string(APPEND CMAKE_C_FLAGS_INIT " -bt=nt -w3 -dWIN32 -br -bm")
-string(APPEND CMAKE_CXX_FLAGS_INIT " -bt=nt -xs -w3 -dWIN32 -br -bm")
-foreach(lang C CXX)
- string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT " -d2")
- string(APPEND CMAKE_${lang}_FLAGS_MINSIZEREL_INIT " -s -os -d0 -dNDEBUG")
- string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT " -s -ot -d0 -dNDEBUG")
- string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT " -s -ot -d1 -dNDEBUG")
-endforeach()
-
-foreach(type CREATE_SHARED_LIBRARY CREATE_SHARED_MODULE LINK_EXECUTABLE)
- set(CMAKE_C_${type}_USE_WATCOM_QUOTE 1)
- set(CMAKE_CXX_${type}_USE_WATCOM_QUOTE 1)
-endforeach()
-
-set(CMAKE_C_CREATE_IMPORT_LIBRARY
- "wlib -c -q -n -b <TARGET_IMPLIB> +<TARGET_QUOTED>")
-set(CMAKE_CXX_CREATE_IMPORT_LIBRARY ${CMAKE_C_CREATE_IMPORT_LIBRARY})
-
-set(CMAKE_C_LINK_EXECUTABLE
- "wlink ${CMAKE_START_TEMP_FILE} ${CMAKE_WLINK_QUIET} name <TARGET> <LINK_FLAGS> file {<OBJECTS>} <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
-
-
-set(CMAKE_CXX_LINK_EXECUTABLE ${CMAKE_C_LINK_EXECUTABLE})
-
-# compile a C++ file into an object file
-set(CMAKE_CXX_COMPILE_OBJECT
- "<CMAKE_CXX_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_WCL_QUIET} -d+ <DEFINES> <INCLUDES> <FLAGS> -fo<OBJECT> -c -cc++ <SOURCE>${CMAKE_END_TEMP_FILE}")
-
-# compile a C file into an object file
-set(CMAKE_C_COMPILE_OBJECT
- "<CMAKE_C_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_WCL_QUIET} -d+ <DEFINES> <INCLUDES> <FLAGS> -fo<OBJECT> -c -cc <SOURCE>${CMAKE_END_TEMP_FILE}")
-
-# preprocess a C source file
-set(CMAKE_C_CREATE_PREPROCESSED_SOURCE
- "<CMAKE_C_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_WCL_QUIET} -d+ <DEFINES> <INCLUDES> <FLAGS> -fo<PREPROCESSED_SOURCE> -pl -cc <SOURCE>${CMAKE_END_TEMP_FILE}")
-
-# preprocess a C++ source file
-set(CMAKE_CXX_CREATE_PREPROCESSED_SOURCE
- "<CMAKE_CXX_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_WCL_QUIET} -d+ <DEFINES> <INCLUDES> <FLAGS> -fo<PREPROCESSED_SOURCE> -pl -cc++ <SOURCE>${CMAKE_END_TEMP_FILE}")
-
-set(CMAKE_CXX_CREATE_SHARED_LIBRARY
- "wlink ${CMAKE_START_TEMP_FILE} ${CMAKE_WLINK_QUIET} name <TARGET> <LINK_FLAGS> option implib=<TARGET_IMPLIB> file {<OBJECTS>} <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
-string(REPLACE " option implib=<TARGET_IMPLIB>" ""
- CMAKE_CXX_CREATE_SHARED_MODULE "${CMAKE_CXX_CREATE_SHARED_LIBRARY}")
-
-# create a C shared library
-set(CMAKE_C_CREATE_SHARED_LIBRARY ${CMAKE_CXX_CREATE_SHARED_LIBRARY})
-
-# create a C shared module
-set(CMAKE_C_CREATE_SHARED_MODULE ${CMAKE_CXX_CREATE_SHARED_MODULE})
-
-# create a C++ static library
-set(CMAKE_CXX_CREATE_STATIC_LIBRARY "wlib ${CMAKE_LIB_QUIET} -c -n -b <TARGET_QUOTED> <LINK_FLAGS> <OBJECTS> ")
-
-# create a C static library
-set(CMAKE_C_CREATE_STATIC_LIBRARY ${CMAKE_CXX_CREATE_STATIC_LIBRARY})
+string(APPEND CMAKE_C_FLAGS_INIT " -bt=nt -dWIN32 -br -bm")
+string(APPEND CMAKE_CXX_FLAGS_INIT " -bt=nt -xs -dWIN32 -br -bm")
-if(NOT _CMAKE_WATCOM_VERSION)
- set(_CMAKE_WATCOM_VERSION 1)
- if(CMAKE_C_COMPILER_VERSION)
- set(_compiler_version ${CMAKE_C_COMPILER_VERSION})
- set(_compiler_id ${CMAKE_C_COMPILER_ID})
- else()
- set(_compiler_version ${CMAKE_CXX_COMPILER_VERSION})
- set(_compiler_id ${CMAKE_CXX_COMPILER_ID})
+if(CMAKE_CROSSCOMPILING)
+ if(NOT CMAKE_C_STANDARD_INCLUDE_DIRECTORIES)
+ set(CMAKE_C_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/h $ENV{WATCOM}/h/nt)
endif()
- set(WATCOM16)
- set(WATCOM17)
- set(WATCOM18)
- set(WATCOM19)
- if("${_compiler_id}" STREQUAL "OpenWatcom")
- if("${_compiler_version}" VERSION_LESS 1.7)
- set(WATCOM16 1)
- endif()
- if("${_compiler_version}" VERSION_EQUAL 1.7)
- set(WATCOM17 1)
- endif()
- if("${_compiler_version}" VERSION_EQUAL 1.8)
- set(WATCOM18 1)
- endif()
- if("${_compiler_version}" VERSION_EQUAL 1.9)
- set(WATCOM19 1)
- endif()
+ if(NOT CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES)
+ set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES $ENV{WATCOM}/h $ENV{WATCOM}/h/nt)
endif()
endif()
diff --git a/Modules/Platform/Windows-PGI.cmake b/Modules/Platform/Windows-PGI.cmake
index ad77e8a..8166240 100644
--- a/Modules/Platform/Windows-PGI.cmake
+++ b/Modules/Platform/Windows-PGI.cmake
@@ -9,9 +9,10 @@ endif()
set(__WINDOWS_COMPILER_PGI 1)
# PGI on Windows doesn't support parallel compile processes
-if(NOT DEFINED CMAKE_JOB_POOL_LINK OR NOT DEFINED CMAKE_JOB_POOL_COMPILE)
+if(NOT DEFINED CMAKE_JOB_POOL_LINK OR NOT DEFINED CMAKE_JOB_POOL_COMPILE OR NOT DEFINED CMAKE_JOB_POOL_PRECOMPILE_HEADER)
set(CMAKE_JOB_POOL_LINK PGITaskPool)
set(CMAKE_JOB_POOL_COMPILE PGITaskPool)
+ set(CMAKE_JOB_POOL_PRECOMPILE_HEADER PGITaskPool)
get_property(_pgijp GLOBAL PROPERTY JOB_POOLS)
if(NOT _pgijp MATCHES "PGITaskPool=")
set_property(GLOBAL APPEND PROPERTY JOB_POOLS PGITaskPool=1)
diff --git a/Modules/Platform/Windows-df.cmake b/Modules/Platform/Windows-df.cmake
index f948914..8b824bc 100644
--- a/Modules/Platform/Windows-df.cmake
+++ b/Modules/Platform/Windows-df.cmake
@@ -13,7 +13,7 @@ endif()
set(CMAKE_Fortran_MODDIR_FLAG "-module:")
set(CMAKE_Fortran_CREATE_SHARED_LIBRARY
- "link ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} /out:<TARGET> /dll <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
+ "link ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} /out:<TARGET> /dll <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
set(CMAKE_Fortran_CREATE_SHARED_MODULE ${CMAKE_Fortran_CREATE_SHARED_LIBRARY})
@@ -22,7 +22,7 @@ set(CMAKE_Fortran_CREATE_STATIC_LIBRARY "lib ${CMAKE_CL_NOLOGO} <LINK_FLAGS> /o
# compile a C++ file into an object file
set(CMAKE_Fortran_COMPILE_OBJECT
- "<CMAKE_Fortran_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO} /object:<OBJECT> <FLAGS> /compile_only <SOURCE>${CMAKE_END_TEMP_FILE}")
+ "<CMAKE_Fortran_COMPILER> ${CMAKE_START_TEMP_FILE} ${CMAKE_CL_NOLOGO} /object:<OBJECT> <FLAGS> /compile_only <SOURCE>${CMAKE_END_TEMP_FILE}")
set(CMAKE_Fortran_LINK_EXECUTABLE
"<CMAKE_Fortran_COMPILER> ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} <FLAGS> /exe:<TARGET> <OBJECTS> /link <CMAKE_Fortran_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}")
diff --git a/Modules/Platform/WindowsPhone-Clang-ASM.cmake b/Modules/Platform/WindowsPhone-Clang-ASM.cmake
new file mode 100644
index 0000000..94f4ca7
--- /dev/null
+++ b/Modules/Platform/WindowsPhone-Clang-ASM.cmake
@@ -0,0 +1 @@
+include(Platform/Windows-Clang-ASM)
diff --git a/Modules/Platform/WindowsPhone-GNU-ASM.cmake b/Modules/Platform/WindowsPhone-GNU-ASM.cmake
new file mode 100644
index 0000000..140eea7
--- /dev/null
+++ b/Modules/Platform/WindowsPhone-GNU-ASM.cmake
@@ -0,0 +1 @@
+include(Platform/Windows-GNU-ASM)
diff --git a/Modules/Platform/WindowsStore-Clang-ASM.cmake b/Modules/Platform/WindowsStore-Clang-ASM.cmake
new file mode 100644
index 0000000..94f4ca7
--- /dev/null
+++ b/Modules/Platform/WindowsStore-Clang-ASM.cmake
@@ -0,0 +1 @@
+include(Platform/Windows-Clang-ASM)
diff --git a/Modules/Platform/WindowsStore-GNU-ASM.cmake b/Modules/Platform/WindowsStore-GNU-ASM.cmake
new file mode 100644
index 0000000..140eea7
--- /dev/null
+++ b/Modules/Platform/WindowsStore-GNU-ASM.cmake
@@ -0,0 +1 @@
+include(Platform/Windows-GNU-ASM)
diff --git a/Modules/Platform/eCos.cmake b/Modules/Platform/eCos.cmake
index e1279ef..25db028 100644
--- a/Modules/Platform/eCos.cmake
+++ b/Modules/Platform/eCos.cmake
@@ -52,8 +52,8 @@ include_directories(${ECOS_SYSTEM_CONFIG_HEADER_PATH})
add_definitions(-D__ECOS__=1 -D__ECOS=1)
# special link commands for eCos executables
-set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -nostdlib -nostartfiles -L${ECOS_LIBTARGET_DIRECTORY} -Ttarget.ld <LINK_LIBRARIES>")
-set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -nostdlib -nostartfiles -L${ECOS_LIBTARGET_DIRECTORY} -Ttarget.ld <LINK_LIBRARIES>")
+set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -nostdlib -nostartfiles -L${ECOS_LIBTARGET_DIRECTORY} -Ttarget.ld <LINK_LIBRARIES>")
+set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -nostdlib -nostartfiles -L${ECOS_LIBTARGET_DIRECTORY} -Ttarget.ld <LINK_LIBRARIES>")
# eCos doesn't support shared libs
set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS FALSE)
diff --git a/Modules/Platform/gas.cmake b/Modules/Platform/gas.cmake
index 7c659f2..8484076 100644
--- a/Modules/Platform/gas.cmake
+++ b/Modules/Platform/gas.cmake
@@ -11,7 +11,7 @@ set(CMAKE_ASM${ASM_DIALECT}_CREATE_STATIC_LIBRARY
"<CMAKE_RANLIB> <TARGET> ")
set(CMAKE_ASM${ASM_DIALECT}_LINK_EXECUTABLE
- "<CMAKE_LINKER> <FLAGS> <CMAKE_ASM${ASM_DIALECT}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
+ "<CMAKE_LINKER> <FLAGS> <CMAKE_ASM${ASM_DIALECT}_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
# to be done
set(CMAKE_ASM${ASM_DIALECT}_CREATE_SHARED_LIBRARY)
diff --git a/Modules/Qt4Macros.cmake b/Modules/Qt4Macros.cmake
index 33cacf1..cb6ae43 100644
--- a/Modules/Qt4Macros.cmake
+++ b/Modules/Qt4Macros.cmake
@@ -436,7 +436,7 @@ macro(QT4_CREATE_TRANSLATION _qm_files)
if(_my_sources)
# make a .pro file to call lupdate on, so we don't make our commands too
# long for some systems
- get_filename_component(_ts_name ${_ts_file} NAME_WE)
+ get_filename_component(_ts_name ${_ts_file} NAME)
set(_ts_pro ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_ts_name}_lupdate.pro)
set(_pro_srcs)
foreach(_pro_src ${_my_sources})
@@ -463,13 +463,15 @@ endmacro()
macro(QT4_ADD_TRANSLATION _qm_files)
foreach (_current_FILE ${ARGN})
get_filename_component(_abs_FILE ${_current_FILE} ABSOLUTE)
- get_filename_component(qm ${_abs_FILE} NAME_WE)
- get_property(output_location SOURCE ${_abs_FILE} PROPERTY OUTPUT_LOCATION)
+ get_filename_component(qm ${_abs_FILE} NAME)
+ # everything before the last dot has to be considered the file name (including other dots)
+ string(REGEX REPLACE "\\.[^.]*$" "" FILE_NAME ${qm})
+ get_source_file_property(output_location ${_abs_FILE} OUTPUT_LOCATION)
if(output_location)
file(MAKE_DIRECTORY "${output_location}")
- set(qm "${output_location}/${qm}.qm")
+ set(qm "${output_location}/${FILE_NAME}.qm")
else()
- set(qm "${CMAKE_CURRENT_BINARY_DIR}/${qm}.qm")
+ set(qm "${CMAKE_CURRENT_BINARY_DIR}/${FILE_NAME}.qm")
endif()
add_custom_command(OUTPUT ${qm}
diff --git a/Modules/Squish4RunTestCase.bat b/Modules/Squish4RunTestCase.bat
index ad1cc8c..5bd815a 100755
--- a/Modules/Squish4RunTestCase.bat
+++ b/Modules/Squish4RunTestCase.bat
@@ -12,7 +12,7 @@ echo "Adding AUT... %SQUISHSERVER% --config addAUT %AUT% %AUTDIR%"
%SQUISHSERVER% --config addAUT "%AUT%" "%AUTDIR%"
echo "Starting the squish server... %SQUISHSERVER%"
-start /B %SQUISHSERVER%
+start /B "Squish Server" %SQUISHSERVER%
echo "Running the test case...%SQUISHRUNNER% --testsuite %TESTSUITE% --testcase %TESTCASE%"
%SQUISHRUNNER% --testsuite "%TESTSUITE%" --testcase "%TESTCASE%"
diff --git a/Modules/TestBigEndian.cmake b/Modules/TestBigEndian.cmake
index 0c6e188..8a769b7 100644
--- a/Modules/TestBigEndian.cmake
+++ b/Modules/TestBigEndian.cmake
@@ -19,8 +19,8 @@ include(CheckTypeSize)
macro(TEST_BIG_ENDIAN VARIABLE)
if(NOT DEFINED HAVE_${VARIABLE})
- message(STATUS "Check if the system is big endian")
- message(STATUS "Searching 16 bit integer")
+ message(CHECK_START "Check if the system is big endian")
+ message(CHECK_START "Searching 16 bit integer")
if(CMAKE_C_COMPILER_LOADED)
set(_test_language "C")
@@ -32,19 +32,19 @@ macro(TEST_BIG_ENDIAN VARIABLE)
CHECK_TYPE_SIZE("unsigned short" CMAKE_SIZEOF_UNSIGNED_SHORT LANGUAGE ${_test_language})
if(CMAKE_SIZEOF_UNSIGNED_SHORT EQUAL 2)
- message(STATUS "Using unsigned short")
+ message(CHECK_PASS "Using unsigned short")
set(CMAKE_16BIT_TYPE "unsigned short")
else()
CHECK_TYPE_SIZE("unsigned int" CMAKE_SIZEOF_UNSIGNED_INT LANGUAGE ${_test_language})
if(CMAKE_SIZEOF_UNSIGNED_INT)
- message(STATUS "Using unsigned int")
+ message(CHECK_PASS "Using unsigned int")
set(CMAKE_16BIT_TYPE "unsigned int")
else()
CHECK_TYPE_SIZE("unsigned long" CMAKE_SIZEOF_UNSIGNED_LONG LANGUAGE ${_test_language})
if(CMAKE_SIZEOF_UNSIGNED_LONG)
- message(STATUS "Using unsigned long")
+ message(CHECK_PASS "Using unsigned long")
set(CMAKE_16BIT_TYPE "unsigned long")
else()
message(FATAL_ERROR "no suitable type found")
@@ -95,15 +95,16 @@ macro(TEST_BIG_ENDIAN VARIABLE)
if(CMAKE_TEST_ENDIANESS_STRINGS_LE)
set(${VARIABLE} 0 CACHE INTERNAL "Result of TEST_BIG_ENDIAN" FORCE)
- message(STATUS "Check if the system is big endian - little endian")
+ message(CHECK_PASS "little endian")
endif()
if(CMAKE_TEST_ENDIANESS_STRINGS_BE)
set(${VARIABLE} 1 CACHE INTERNAL "Result of TEST_BIG_ENDIAN" FORCE)
- message(STATUS "Check if the system is big endian - big endian")
+ message(CHECK_PASS "big endian")
endif()
if(NOT CMAKE_TEST_ENDIANESS_STRINGS_BE AND NOT CMAKE_TEST_ENDIANESS_STRINGS_LE)
+ message(CHECK_FAIL "TEST_BIG_ENDIAN found no result!")
message(SEND_ERROR "TEST_BIG_ENDIAN found no result!")
endif()
@@ -111,7 +112,7 @@ macro(TEST_BIG_ENDIAN VARIABLE)
"Determining if the system is big endian passed with the following output:\n${OUTPUT}\nTestEndianess.c:\n${TEST_ENDIANESS_FILE_CONTENT}\n\n")
else()
- message(STATUS "Check if the system is big endian - failed")
+ message(CHECK_FAIL "failed")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the system is big endian failed with the following output:\n${OUTPUT}\nTestEndianess.c:\n${TEST_ENDIANESS_FILE_CONTENT}\n\n")
set(${VARIABLE})
diff --git a/Modules/TestCXXAcceptsFlag.cmake b/Modules/TestCXXAcceptsFlag.cmake
index 92a362e..ce505f3 100644
--- a/Modules/TestCXXAcceptsFlag.cmake
+++ b/Modules/TestCXXAcceptsFlag.cmake
@@ -23,19 +23,19 @@ Check if the CXX compiler accepts a flag.
macro(CHECK_CXX_ACCEPTS_FLAG FLAGS VARIABLE)
if(NOT DEFINED ${VARIABLE})
- message(STATUS "Checking to see if CXX compiler accepts flag ${FLAGS}")
+ message(CHECK_START "Checking to see if CXX compiler accepts flag ${FLAGS}")
try_compile(${VARIABLE}
${CMAKE_BINARY_DIR}
${CMAKE_ROOT}/Modules/DummyCXXFile.cxx
CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${FLAGS}
OUTPUT_VARIABLE OUTPUT)
if(${VARIABLE})
- message(STATUS "Checking to see if CXX compiler accepts flag ${FLAGS} - yes")
+ message(CHECK_PASS "yes")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the CXX compiler accepts the flag ${FLAGS} passed with "
"the following output:\n${OUTPUT}\n\n")
else()
- message(STATUS "Checking to see if CXX compiler accepts flag ${FLAGS} - no")
+ message(CHECK_FAIL "no")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if the CXX compiler accepts the flag ${FLAGS} failed with "
"the following output:\n${OUTPUT}\n\n")
diff --git a/Modules/TestForANSIForScope.cmake b/Modules/TestForANSIForScope.cmake
index 272e4ec..0f2dc01 100644
--- a/Modules/TestForANSIForScope.cmake
+++ b/Modules/TestForANSIForScope.cmake
@@ -16,19 +16,19 @@ for-init-statement to the loop body.
#]=======================================================================]
if(NOT DEFINED CMAKE_ANSI_FOR_SCOPE)
- message(STATUS "Check for ANSI scope")
+ message(CHECK_START "Check for ANSI scope")
try_compile(CMAKE_ANSI_FOR_SCOPE ${CMAKE_BINARY_DIR}
${CMAKE_ROOT}/Modules/TestForAnsiForScope.cxx
OUTPUT_VARIABLE OUTPUT)
if (CMAKE_ANSI_FOR_SCOPE)
- message(STATUS "Check for ANSI scope - found")
+ message(CHECK_PASS "found")
set (CMAKE_NO_ANSI_FOR_SCOPE 0 CACHE INTERNAL
"Does the compiler support ansi for scope.")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the CXX compiler understands ansi for scopes passed with "
"the following output:\n${OUTPUT}\n\n")
else ()
- message(STATUS "Check for ANSI scope - not found")
+ message(CHECK_FAIL "not found")
set (CMAKE_NO_ANSI_FOR_SCOPE 1 CACHE INTERNAL
"Does the compiler support ansi for scope.")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
diff --git a/Modules/TestForSSTREAM.cmake b/Modules/TestForSSTREAM.cmake
index e70df00..545b7ec 100644
--- a/Modules/TestForSSTREAM.cmake
+++ b/Modules/TestForSSTREAM.cmake
@@ -15,19 +15,19 @@ check if the compiler supports the standard ANSI sstream header
#]=======================================================================]
if(NOT DEFINED CMAKE_HAS_ANSI_STRING_STREAM)
- message(STATUS "Check for sstream")
+ message(CHECK_START "Check for sstream")
try_compile(CMAKE_HAS_ANSI_STRING_STREAM ${CMAKE_BINARY_DIR}
${CMAKE_ROOT}/Modules/TestForSSTREAM.cxx
OUTPUT_VARIABLE OUTPUT)
if (CMAKE_HAS_ANSI_STRING_STREAM)
- message(STATUS "Check for sstream - found")
+ message(CHECK_PASS "found")
set (CMAKE_NO_ANSI_STRING_STREAM 0 CACHE INTERNAL
"Does the compiler support sstream")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the CXX compiler has sstream passed with "
"the following output:\n${OUTPUT}\n\n")
else ()
- message(STATUS "Check for sstream - not found")
+ message(CHECK_FAIL "not found")
set (CMAKE_NO_ANSI_STRING_STREAM 1 CACHE INTERNAL
"Does the compiler support sstream")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
diff --git a/Modules/TestForSTDNamespace.cmake b/Modules/TestForSTDNamespace.cmake
index 703e631..d101c83 100644
--- a/Modules/TestForSTDNamespace.cmake
+++ b/Modules/TestForSTDNamespace.cmake
@@ -15,19 +15,19 @@ check if the compiler supports std:: on stl classes
#]=======================================================================]
if(NOT DEFINED CMAKE_STD_NAMESPACE)
- message(STATUS "Check for STD namespace")
+ message(CHECK_START "Check for STD namespace")
try_compile(CMAKE_STD_NAMESPACE ${CMAKE_BINARY_DIR}
${CMAKE_ROOT}/Modules/TestForSTDNamespace.cxx
OUTPUT_VARIABLE OUTPUT)
if (CMAKE_STD_NAMESPACE)
- message(STATUS "Check for STD namespace - found")
+ message(CHECK_PASS "found")
set (CMAKE_NO_STD_NAMESPACE 0 CACHE INTERNAL
"Does the compiler support std::.")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if the CXX compiler has std namespace passed with "
"the following output:\n${OUTPUT}\n\n")
else ()
- message(STATUS "Check for STD namespace - not found")
+ message(CHECK_FAIL "not found")
set (CMAKE_NO_STD_NAMESPACE 1 CACHE INTERNAL
"Does the compiler support std::.")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
diff --git a/Modules/UseEcos.cmake b/Modules/UseEcos.cmake
index 60324b1..83c9b20 100644
--- a/Modules/UseEcos.cmake
+++ b/Modules/UseEcos.cmake
@@ -185,11 +185,11 @@ macro(ECOS_ADD_EXECUTABLE _exe_NAME )
# when using nmake makefiles, the custom buildtype suppresses the default cl.exe flags
# and the rules for creating objects are adjusted for gcc
set(CMAKE_BUILD_TYPE CUSTOM_ECOS_BUILD)
- set(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
+ set(CMAKE_C_COMPILE_OBJECT "<CMAKE_C_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
set(CMAKE_CXX_COMPILE_OBJECT "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
# special link commands for ecos-executables
- set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> <CMAKE_CXX_LINK_FLAGS> <OBJECTS> -o <TARGET> ${_ecos_EXTRA_LIBS} -nostdlib -nostartfiles -L${CMAKE_CURRENT_BINARY_DIR}/ecos/install/lib -Ttarget.ld ${ECOS_LD_MCPU}")
- set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <CMAKE_C_LINK_FLAGS> <OBJECTS> -o <TARGET> ${_ecos_EXTRA_LIBS} -nostdlib -nostartfiles -L${CMAKE_CURRENT_BINARY_DIR}/ecos/install/lib -Ttarget.ld ${ECOS_LD_MCPU}")
+ set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> <CMAKE_CXX_LINK_FLAGS> <OBJECTS> -o <TARGET> ${_ecos_EXTRA_LIBS} -nostdlib -nostartfiles -L${CMAKE_CURRENT_BINARY_DIR}/ecos/install/lib -Ttarget.ld ${ECOS_LD_MCPU}")
+ set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <CMAKE_C_LINK_FLAGS> <OBJECTS> -o <TARGET> ${_ecos_EXTRA_LIBS} -nostdlib -nostartfiles -L${CMAKE_CURRENT_BINARY_DIR}/ecos/install/lib -Ttarget.ld ${ECOS_LD_MCPU}")
# some strict compiler flags
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wstrict-prototypes")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Woverloaded-virtual -fno-rtti -Wctor-dtor-privacy -fno-strict-aliasing -fno-exceptions")
diff --git a/Modules/UseJava.cmake b/Modules/UseJava.cmake
index 0798488..db3fb95 100644
--- a/Modules/UseJava.cmake
+++ b/Modules/UseJava.cmake
@@ -377,7 +377,9 @@ function (__java_copy_file src dest comment)
ARGS ${src}
${dest}
DEPENDS ${src}
- COMMENT ${comment})
+ COMMENT ${comment}
+ VERBATIM
+ )
endfunction ()
function(__java_lcat VAR)
@@ -405,9 +407,14 @@ endfunction()
# define helper scripts
set(_JAVA_EXPORT_TARGETS_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/javaTargets.cmake.in)
-set(_JAVA_CLASS_FILELIST_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/UseJavaClassFilelist.cmake)
set(_JAVA_SYMLINK_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/UseJavaSymlinks.cmake)
+if (CMAKE_HOST_WIN32 AND NOT CYGWIN AND CMAKE_HOST_SYSTEM_NAME MATCHES "Windows")
+ set(_UseJava_PATH_SEP "$<SEMICOLON>")
+else ()
+ set(_UseJava_PATH_SEP ":")
+endif()
+
function(add_jar _TARGET_NAME)
cmake_parse_arguments(_add_jar
@@ -497,14 +504,8 @@ function(add_jar _TARGET_NAME)
${CMAKE_JAVA_LIBRARY_OUTPUT_PATH}
)
- if (CMAKE_HOST_WIN32 AND NOT CYGWIN AND CMAKE_HOST_SYSTEM_NAME MATCHES "Windows")
- set(CMAKE_JAVA_INCLUDE_FLAG_SEP ";")
- else ()
- set(CMAKE_JAVA_INCLUDE_FLAG_SEP ":")
- endif()
-
foreach (JAVA_INCLUDE_DIR IN LISTS CMAKE_JAVA_INCLUDE_PATH)
- string(APPEND CMAKE_JAVA_INCLUDE_PATH_FINAL "${CMAKE_JAVA_INCLUDE_FLAG_SEP}${JAVA_INCLUDE_DIR}")
+ string(APPEND CMAKE_JAVA_INCLUDE_PATH_FINAL "${_UseJava_PATH_SEP}${JAVA_INCLUDE_DIR}")
endforeach()
set(CMAKE_JAVA_CLASS_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_TARGET_NAME}.dir")
@@ -576,7 +577,7 @@ function(add_jar _TARGET_NAME)
if (TARGET ${_JAVA_INCLUDE_JAR})
get_target_property(_JAVA_JAR_PATH ${_JAVA_INCLUDE_JAR} JAR_FILE)
if (_JAVA_JAR_PATH)
- string(APPEND CMAKE_JAVA_INCLUDE_PATH_FINAL "${CMAKE_JAVA_INCLUDE_FLAG_SEP}${_JAVA_JAR_PATH}")
+ string(APPEND CMAKE_JAVA_INCLUDE_PATH_FINAL "${_UseJava_PATH_SEP}${_JAVA_JAR_PATH}")
list(APPEND CMAKE_JAVA_INCLUDE_PATH ${_JAVA_JAR_PATH})
list(APPEND _JAVA_DEPENDS ${_JAVA_INCLUDE_JAR})
list(APPEND _JAVA_COMPILE_DEPENDS ${_JAVA_JAR_PATH})
@@ -584,7 +585,7 @@ function(add_jar _TARGET_NAME)
message(SEND_ERROR "add_jar: INCLUDE_JARS target ${_JAVA_INCLUDE_JAR} is not a jar")
endif ()
else ()
- string(APPEND CMAKE_JAVA_INCLUDE_PATH_FINAL "${CMAKE_JAVA_INCLUDE_FLAG_SEP}${_JAVA_INCLUDE_JAR}")
+ string(APPEND CMAKE_JAVA_INCLUDE_PATH_FINAL "${_UseJava_PATH_SEP}${_JAVA_INCLUDE_JAR}")
list(APPEND CMAKE_JAVA_INCLUDE_PATH "${_JAVA_INCLUDE_JAR}")
list(APPEND _JAVA_DEPENDS "${_JAVA_INCLUDE_JAR}")
list(APPEND _JAVA_COMPILE_DEPENDS "${_JAVA_INCLUDE_JAR}")
@@ -598,7 +599,10 @@ function(add_jar _TARGET_NAME)
# Create the list of files to compile.
set(_JAVA_SOURCES_FILE ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_sources)
string(REPLACE ";" "\"\n\"" _JAVA_COMPILE_STRING "\"${_JAVA_COMPILE_FILES}\"")
- file(WRITE ${_JAVA_SOURCES_FILE} ${_JAVA_COMPILE_STRING})
+ set(CMAKE_CONFIGURABLE_FILE_CONTENT "${_JAVA_COMPILE_STRING}")
+ configure_file("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in"
+ "${_JAVA_SOURCES_FILE}" @ONLY)
+ unset(CMAKE_CONFIGURABLE_FILE_CONTENT)
list (APPEND _JAVA_SOURCES_FILELISTS "@${_JAVA_SOURCES_FILE}")
endif()
if (_JAVA_COMPILE_FILELISTS)
@@ -611,6 +615,10 @@ function(add_jar _TARGET_NAME)
add_custom_command(
# NOTE: this command generates an artificial dependency file
OUTPUT ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_compiled_${_TARGET_NAME}
+ COMMAND ${CMAKE_COMMAND}
+ -DCMAKE_JAVA_CLASS_OUTPUT_PATH=${CMAKE_JAVA_CLASS_OUTPUT_PATH}
+ -DCMAKE_JAR_CLASSES_PREFIX=${CMAKE_JAR_CLASSES_PREFIX}
+ -P ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/UseJava/ClearClassFiles.cmake
COMMAND ${Java_JAVAC_EXECUTABLE}
${CMAKE_JAVA_COMPILE_FLAGS}
-classpath "${CMAKE_JAVA_INCLUDE_PATH_FINAL}"
@@ -618,18 +626,20 @@ function(add_jar _TARGET_NAME)
${_GENERATE_NATIVE_HEADERS}
${_JAVA_SOURCES_FILELISTS}
COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_compiled_${_TARGET_NAME}
- DEPENDS ${_JAVA_COMPILE_FILES} ${_JAVA_COMPILE_FILELISTS} ${_JAVA_COMPILE_DEPENDS}
+ DEPENDS ${_JAVA_COMPILE_FILES} ${_JAVA_COMPILE_FILELISTS} ${_JAVA_COMPILE_DEPENDS} ${_JAVA_SOURCES_FILE}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Building Java objects for ${_TARGET_NAME}.jar"
+ VERBATIM
)
add_custom_command(
OUTPUT ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist
COMMAND ${CMAKE_COMMAND}
-DCMAKE_JAVA_CLASS_OUTPUT_PATH=${CMAKE_JAVA_CLASS_OUTPUT_PATH}
- -DCMAKE_JAR_CLASSES_PREFIX="${CMAKE_JAR_CLASSES_PREFIX}"
- -P ${_JAVA_CLASS_FILELIST_SCRIPT}
+ -DCMAKE_JAR_CLASSES_PREFIX=${CMAKE_JAR_CLASSES_PREFIX}
+ -P ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/UseJavaClassFilelist.cmake
DEPENDS ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_compiled_${_TARGET_NAME}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ VERBATIM
)
else ()
# create an empty java_class_filelist
@@ -660,6 +670,7 @@ function(add_jar _TARGET_NAME)
DEPENDS ${_JAVA_RESOURCE_FILES} ${_JAVA_DEPENDS} ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist
WORKING_DIRECTORY ${CMAKE_JAVA_CLASS_OUTPUT_PATH}
COMMENT "Creating Java archive ${_JAVA_TARGET_OUTPUT_NAME}"
+ VERBATIM
)
else ()
add_custom_command(
@@ -675,6 +686,7 @@ function(add_jar _TARGET_NAME)
WORKING_DIRECTORY ${CMAKE_JAVA_CLASS_OUTPUT_PATH}
DEPENDS ${_JAVA_RESOURCE_FILES} ${_JAVA_DEPENDS} ${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist
COMMENT "Creating Java archive ${_JAVA_TARGET_OUTPUT_NAME}"
+ VERBATIM
)
endif ()
@@ -1190,55 +1202,40 @@ function(create_javadoc _target)
set(_javadoc_options -d ${_javadoc_builddir})
if (_javadoc_sourcepath)
- set(_start TRUE)
- foreach(_path IN LISTS _javadoc_sourcepath)
- if (_start)
- set(_sourcepath ${_path})
- set(_start FALSE)
- else ()
- set(_sourcepath ${_sourcepath}:${_path})
- endif ()
- endforeach()
- set(_javadoc_options ${_javadoc_options} -sourcepath ${_sourcepath})
+ list(JOIN _javadoc_sourcepath "${_UseJava_PATH_SEP}" _javadoc_sourcepath)
+ list(APPEND _javadoc_options -sourcepath "\"${_javadoc_sourcepath}\"")
endif ()
if (_javadoc_classpath)
- set(_start TRUE)
- foreach(_path IN LISTS _javadoc_classpath)
- if (_start)
- set(_classpath ${_path})
- set(_start FALSE)
- else ()
- set(_classpath ${_classpath}:${_path})
- endif ()
- endforeach()
- set(_javadoc_options ${_javadoc_options} -classpath "${_classpath}")
+ list(JOIN _javadoc_classpath "${_UseJava_PATH_SEP}" _javadoc_classpath)
+ list(APPEND _javadoc_options -classpath "\"${_javadoc_classpath}\"")
endif ()
if (_javadoc_doctitle)
- set(_javadoc_options ${_javadoc_options} -doctitle '${_javadoc_doctitle}')
+ list(APPEND _javadoc_options -doctitle '${_javadoc_doctitle}')
endif ()
if (_javadoc_windowtitle)
- set(_javadoc_options ${_javadoc_options} -windowtitle '${_javadoc_windowtitle}')
+ list(APPEND _javadoc_options -windowtitle '${_javadoc_windowtitle}')
endif ()
if (_javadoc_author)
- set(_javadoc_options ${_javadoc_options} -author)
+ list(APPEND _javadoc_options -author)
endif ()
if (_javadoc_use)
- set(_javadoc_options ${_javadoc_options} -use)
+ list(APPEND _javadoc_options -use)
endif ()
if (_javadoc_version)
- set(_javadoc_options ${_javadoc_options} -version)
+ list(APPEND _javadoc_options -version)
endif ()
add_custom_target(${_target}_javadoc ALL
- COMMAND ${Java_JAVADOC_EXECUTABLE} ${_javadoc_options}
- ${_javadoc_files}
- ${_javadoc_packages}
+ COMMAND ${Java_JAVADOC_EXECUTABLE}
+ ${_javadoc_options}
+ ${_javadoc_files}
+ ${_javadoc_packages}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
@@ -1274,11 +1271,6 @@ function (create_javah)
endif()
set (_output_files)
- if (WIN32 AND NOT CYGWIN AND CMAKE_HOST_SYSTEM_NAME MATCHES "Windows")
- set(_classpath_sep "$<SEMICOLON>")
- else ()
- set(_classpath_sep ":")
- endif()
# handle javah options
set (_javah_options)
@@ -1304,7 +1296,7 @@ function (create_javah)
message(SEND_ERROR "create_javah: CLASSPATH entry ${_path} does not exist.")
endif()
endforeach()
- string (REPLACE ";" "${_classpath_sep}" _classpath "${_classpath}")
+ string (REPLACE ";" "${_UseJava_PATH_SEP}" _classpath "${_classpath}")
list (APPEND _javah_options -classpath "${_classpath}")
endif()
diff --git a/Modules/UseJava/ClearClassFiles.cmake b/Modules/UseJava/ClearClassFiles.cmake
new file mode 100644
index 0000000..f3115c6
--- /dev/null
+++ b/Modules/UseJava/ClearClassFiles.cmake
@@ -0,0 +1,17 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+# This script deletes compiled Java class files.
+
+if(CMAKE_JAVA_CLASS_OUTPUT_PATH)
+ if(EXISTS "${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist")
+ file(STRINGS "${CMAKE_JAVA_CLASS_OUTPUT_PATH}/java_class_filelist" classes)
+ list(TRANSFORM classes PREPEND "${CMAKE_JAVA_CLASS_OUTPUT_PATH}/")
+ if(classes)
+ file(REMOVE ${classes})
+ message(STATUS "Clean class files from previous build")
+ endif()
+ endif()
+else()
+ message(FATAL_ERROR "Can't find CMAKE_JAVA_CLASS_OUTPUT_PATH")
+endif()
diff --git a/Modules/UseSWIG.cmake b/Modules/UseSWIG.cmake
index 78522da..f6a20f8 100644
--- a/Modules/UseSWIG.cmake
+++ b/Modules/UseSWIG.cmake
@@ -341,6 +341,23 @@ function(SWIG_GET_EXTRA_OUTPUT_FILES language outfiles generatedpath infile)
list(APPEND files "${extra_file}")
endforeach()
+ if (language STREQUAL "FORTRAN" AND CMAKE_Fortran_COMPILER_LOADED)
+ # Process possible user-supplied extension in flags (obtained via parent
+ # scope variable) to determine the source file name.
+ list(FIND SWIG_COMPILATION_FLAGS "-fext" fext_idx)
+ if (fext_idx EQUAL -1)
+ # Default Fortran generated extension
+ set(fext "f90")
+ else()
+ # Get extension from user-provided flag
+ math(EXPR fext_idx "${fext_idx} + 1")
+ list(GET SWIG_COMPILATION_FLAGS "${fext_idx}" fext)
+ endif()
+ set(extra_file "${generatedpath}/${module_basename}.${fext}")
+ set_source_files_properties("${extra_file}" PROPERTIES LANGUAGE "Fortran")
+ list(APPEND files "${extra_file}")
+ endif()
+
set (${outfiles} ${files} PARENT_SCOPE)
endfunction()
@@ -415,6 +432,7 @@ function(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile)
get_filename_component(swig_source_file_fullname "${infile}" ABSOLUTE)
if (NOT SWIG_MODULE_${name}_NOPROXY)
+ set(SWIG_COMPILATION_FLAGS ${swig_source_file_flags})
SWIG_GET_EXTRA_OUTPUT_FILES(${SWIG_MODULE_${name}_LANGUAGE}
swig_extra_generated_files
"${outdir}"
@@ -787,6 +805,8 @@ function(SWIG_ADD_LIBRARY name)
if (APPLE)
set_target_properties (${target_name} PROPERTIES SUFFIX ".dylib")
endif ()
+ elseif (swig_lowercase_language STREQUAL "fortran")
+ # Do *not* override the target's library prefix
else()
# assume empty prefix because we expect the module to be dynamically loaded
set_target_properties (${target_name} PROPERTIES PREFIX "")
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index b1f7b29..ec473d2 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -1,6 +1,11 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
+# To ensure maximum portability across various compilers and platforms
+# deactivate any compiler extensions
+set(CMAKE_C_EXTENSIONS FALSE)
+set(CMAKE_CXX_EXTENSIONS FALSE)
+
include(CheckIncludeFile)
# Check if we can build support for ELF parsing.
if(CMAKE_CXX_PLATFORM_ID MATCHES "OpenBSD")
@@ -134,6 +139,9 @@ set(SRCS
LexerParser/cmFortranParser.cxx
LexerParser/cmFortranParserTokens.h
LexerParser/cmFortranParser.y
+ LexerParser/cmGccDepfileLexer.cxx
+ LexerParser/cmGccDepfileLexer.h
+ LexerParser/cmGccDepfileLexer.in.l
LexerParser/cmListFileLexer.c
LexerParser/cmListFileLexer.in.l
@@ -270,6 +278,10 @@ set(SRCS
cmFortranParserImpl.cxx
cmFSPermissions.cxx
cmFSPermissions.h
+ cmGccDepfileLexerHelper.cxx
+ cmGccDepfileLexerHelper.h
+ cmGccDepfileReader.cxx
+ cmGccDepfileReader.h
cmGeneratedFileStream.cxx
cmGeneratorExpressionContext.cxx
cmGeneratorExpressionContext.h
@@ -289,6 +301,8 @@ set(SRCS
cmGeneratorExpression.h
cmGeneratorTarget.cxx
cmGeneratorTarget.h
+ cmLinkItemGraphVisitor.cxx
+ cmLinkItemGraphVisitor.h
cmGetPipes.cxx
cmGetPipes.h
cmGlobalCommonGenerator.cxx
@@ -345,6 +359,7 @@ set(SRCS
cmMakefileTargetGenerator.cxx
cmMakefileExecutableTargetGenerator.cxx
cmMakefileLibraryTargetGenerator.cxx
+ cmMakefileProfilingData.cxx
cmMakefileUtilityTargetGenerator.cxx
cmMessageType.h
cmMessenger.cxx
@@ -475,6 +490,8 @@ set(SRCS
cmBuildCommand.h
cmBuildNameCommand.cxx
cmBuildNameCommand.h
+ cmCMakeCommand.cxx
+ cmCMakeCommand.h
cmCMakeHostSystemInformationCommand.cxx
cmCMakeHostSystemInformationCommand.h
cmCMakeMinimumRequired.cxx
@@ -681,7 +698,6 @@ set(SRCS
cmWriteFileCommand.cxx
cmWriteFileCommand.h
- cm_static_string_view.hxx
cm_get_date.h
cm_get_date.c
cm_utf8.h
@@ -691,6 +707,8 @@ set(SRCS
cmDuration.h
cmDuration.cxx
+
+ bindexplib.cxx
)
SET_PROPERTY(SOURCE cmProcessOutput.cxx APPEND PROPERTY COMPILE_DEFINITIONS
@@ -713,7 +731,6 @@ if (WIN32)
set(SRCS ${SRCS}
cmCallVisualStudioMacro.cxx
cmCallVisualStudioMacro.h
- bindexplib.cxx
)
if(NOT UNIX)
@@ -1193,6 +1210,11 @@ if(WIN32)
endforeach()
endif()
+if(CMake_JOB_POOL_LINK_BIN)
+ set_property(TARGET ${_tools} PROPERTY JOB_POOL_LINK "link-bin")
+ set_property(GLOBAL APPEND PROPERTY JOB_POOLS "link-bin=${CMake_JOB_POOL_LINK_BIN}")
+endif()
+
# Install tools
foreach(_tool ${_tools})
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 93a8b85..b820d73 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 16)
-set(CMake_VERSION_PATCH 6)
+set(CMake_VERSION_MINOR 17)
+set(CMake_VERSION_PATCH 20200515)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/CPack/IFW/cmCPackIFWCommon.cxx b/Source/CPack/IFW/cmCPackIFWCommon.cxx
index 9fa74be..20d392d 100644
--- a/Source/CPack/IFW/cmCPackIFWCommon.cxx
+++ b/Source/CPack/IFW/cmCPackIFWCommon.cxx
@@ -2,7 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCPackIFWCommon.h"
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
#include <sstream>
#include <utility>
#include <vector>
diff --git a/Source/CPack/IFW/cmCPackIFWGenerator.cxx b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
index 509ac65..2806c61 100644
--- a/Source/CPack/IFW/cmCPackIFWGenerator.cxx
+++ b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
@@ -544,10 +544,7 @@ std::string cmCPackIFWGenerator::GetGroupPackageName(
if (group->ParentGroup) {
cmCPackIFWPackage* package = this->GetGroupPackage(group->ParentGroup);
bool dot = !this->ResolveDuplicateNames;
- if (dot && name.substr(0, package->Name.size()) == package->Name) {
- dot = false;
- }
- if (dot) {
+ if (dot && !cmHasPrefix(name, package->Name)) {
name = package->Name + "." + name;
}
}
@@ -576,10 +573,7 @@ std::string cmCPackIFWGenerator::GetComponentPackageName(
return package->Name;
}
bool dot = !this->ResolveDuplicateNames;
- if (dot && name.substr(0, package->Name.size()) == package->Name) {
- dot = false;
- }
- if (dot) {
+ if (dot && !cmHasPrefix(name, package->Name)) {
name = package->Name + "." + name;
}
}
diff --git a/Source/CPack/IFW/cmCPackIFWPackage.cxx b/Source/CPack/IFW/cmCPackIFWPackage.cxx
index 9a9cd56..56a74c5 100644
--- a/Source/CPack/IFW/cmCPackIFWPackage.cxx
+++ b/Source/CPack/IFW/cmCPackIFWPackage.cxx
@@ -55,8 +55,7 @@ cmCPackIFWPackage::DependenceStruct::DependenceStruct(
if (dashPos != std::string::npos) {
pos = dashPos;
}
- this->Name =
- pos == std::string::npos ? dependence : dependence.substr(0, pos);
+ this->Name = dependence.substr(0, pos);
}
std::string cmCPackIFWPackage::DependenceStruct::NameWithCompare() const
diff --git a/Source/CPack/IFW/cmCPackIFWRepository.cxx b/Source/CPack/IFW/cmCPackIFWRepository.cxx
index a696549..f5e8744 100644
--- a/Source/CPack/IFW/cmCPackIFWRepository.cxx
+++ b/Source/CPack/IFW/cmCPackIFWRepository.cxx
@@ -21,11 +21,7 @@ bool cmCPackIFWRepository::IsValid() const
switch (this->Update) {
case cmCPackIFWRepository::None:
- valid = !this->Url.empty();
- break;
case cmCPackIFWRepository::Add:
- valid = !this->Url.empty();
- break;
case cmCPackIFWRepository::Remove:
valid = !this->Url.empty();
break;
diff --git a/Source/CPack/OSXScriptLauncher.cxx b/Source/CPack/OSXScriptLauncher.cxx
index 21d27a0..bdaf779 100644
--- a/Source/CPack/OSXScriptLauncher.cxx
+++ b/Source/CPack/OSXScriptLauncher.cxx
@@ -5,6 +5,8 @@
#include <string>
#include <vector>
+#include <cm/memory>
+
#include <CoreFoundation/CoreFoundation.h>
#include "cmsys/FStream.hxx"
@@ -26,7 +28,6 @@ int main(int argc, char* argv[])
CFStringRef fileName;
CFBundleRef appBundle;
CFURLRef scriptFileURL;
- UInt8* path;
// get CF URL for script
if (!(appBundle = CFBundleGetMainBundle())) {
@@ -41,13 +42,15 @@ int main(int argc, char* argv[])
}
// create path string
- if (!(path = new UInt8[PATH_MAX])) {
+ auto path = cm::make_unique<UInt8[]>(PATH_MAX);
+ if (!path) {
return 1;
}
// get the file system path of the url as a cstring
// in an encoding suitable for posix apis
- if (!CFURLGetFileSystemRepresentation(scriptFileURL, true, path, PATH_MAX)) {
+ if (!CFURLGetFileSystemRepresentation(scriptFileURL, true, path.get(),
+ PATH_MAX)) {
DebugError("CFURLGetFileSystemRepresentation failed");
return 1;
}
@@ -55,10 +58,10 @@ int main(int argc, char* argv[])
// dispose of the CF variable
CFRelease(scriptFileURL);
- std::string fullScriptPath = reinterpret_cast<char*>(path);
- delete[] path;
+ std::string fullScriptPath = reinterpret_cast<char*>(path.get());
+ path.reset();
- if (!cmsys::SystemTools::FileExists(fullScriptPath.c_str())) {
+ if (!cmsys::SystemTools::FileExists(fullScriptPath)) {
return 1;
}
@@ -80,7 +83,6 @@ int main(int argc, char* argv[])
cmsysProcess_SetTimeout(cp, 0);
cmsysProcess_Execute(cp);
- std::vector<char> tempOutput;
char* data;
int length;
while (cmsysProcess_WaitForData(cp, &data, &length, nullptr)) {
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
index e71a38f..72af10b 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
@@ -4,14 +4,15 @@
#include <algorithm>
+#include <cm/memory>
#include <cm/string_view>
+#include <cmext/algorithm>
#include "cmsys/Directory.hxx"
#include "cmsys/Encoding.hxx"
#include "cmsys/FStream.hxx"
#include "cmsys/SystemTools.hxx"
-#include "cmAlgorithms.h"
#include "cmCPackComponentGroup.h"
#include "cmCPackLog.h"
#include "cmCryptoHash.h"
@@ -35,22 +36,16 @@
#include "cmCMakeToWixPath.h"
cmCPackWIXGenerator::cmCPackWIXGenerator()
- : Patch(0)
- , ComponentGuidType(cmWIXSourceWriter::WIX_GENERATED_GUID)
+ : ComponentGuidType(cmWIXSourceWriter::WIX_GENERATED_GUID)
{
}
-cmCPackWIXGenerator::~cmCPackWIXGenerator()
-{
- if (this->Patch) {
- delete this->Patch;
- }
-}
+cmCPackWIXGenerator::~cmCPackWIXGenerator() = default;
int cmCPackWIXGenerator::InitializeInternal()
{
componentPackageMethod = ONE_PACKAGE;
- this->Patch = new cmWIXPatch(this->Logger);
+ this->Patch = cm::make_unique<cmWIXPatch>(this->Logger);
return this->Superclass::InitializeInternal();
}
@@ -103,7 +98,7 @@ bool cmCPackWIXGenerator::RunCandleCommand(std::string const& sourceFile,
command << " -ext " << QuotePath(ext);
}
- if (sourceFile.rfind(this->CPackTopLevel, 0) != 0) {
+ if (!cmHasSuffix(sourceFile, this->CPackTopLevel)) {
command << " " << QuotePath("-I" + this->CPackTopLevel);
}
@@ -355,8 +350,7 @@ void cmCPackWIXGenerator::CreateWiXPropertiesIncludeFile()
std::vector<std::string> options = GetOptions();
for (std::string const& name : options) {
- if (name.length() > prefix.length() &&
- name.substr(0, prefix.length()) == prefix) {
+ if (cmHasPrefix(name, prefix)) {
std::string id = name.substr(prefix.length());
std::string value = GetOption(name.c_str());
@@ -960,7 +954,7 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitions(
shortcut.workingDirectoryId = directoryId;
shortcuts.insert(cmWIXShortcuts::START_MENU, id, shortcut);
- if (cmContains(desktopExecutables, executableName)) {
+ if (cm::contains(desktopExecutables, executableName)) {
shortcuts.insert(cmWIXShortcuts::DESKTOP, id, shortcut);
}
}
@@ -1104,14 +1098,14 @@ std::string cmCPackWIXGenerator::CreateHashedId(
cmCryptoHash sha1(cmCryptoHash::AlgoSHA1);
std::string const hash = sha1.HashString(path);
- std::string identifier = cmStrCat(cm::string_view(hash).substr(0, 7), '_');
-
const size_t maxFileNameLength = 52;
+ std::string identifier =
+ cmStrCat(cm::string_view(hash).substr(0, 7), '_',
+ cm::string_view(normalizedFilename).substr(0, maxFileNameLength));
+
+ // if the name was truncated
if (normalizedFilename.length() > maxFileNameLength) {
- identifier += normalizedFilename.substr(0, maxFileNameLength - 3);
identifier += "...";
- } else {
- identifier += normalizedFilename;
}
return identifier;
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.h b/Source/CPack/WiX/cmCPackWIXGenerator.h
index d193348..d5a16ec 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.h
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.h
@@ -4,6 +4,7 @@
#define cmCPackWIXGenerator_h
#include <map>
+#include <memory>
#include <string>
#include "cmCPackGenerator.h"
@@ -24,6 +25,8 @@ public:
cmCPackTypeMacro(cmCPackWIXGenerator, cmCPackGenerator);
cmCPackWIXGenerator();
+ cmCPackWIXGenerator(const cmCPackWIXGenerator&) = delete;
+ const cmCPackWIXGenerator& operator=(const cmCPackWIXGenerator&) = delete;
~cmCPackWIXGenerator();
protected:
@@ -157,7 +160,7 @@ private:
std::string CPackTopLevel;
- cmWIXPatch* Patch;
+ std::unique_ptr<cmWIXPatch> Patch;
cmWIXSourceWriter::GuidType ComponentGuidType;
};
diff --git a/Source/CPack/WiX/cmWIXAccessControlList.cxx b/Source/CPack/WiX/cmWIXAccessControlList.cxx
index 3668b46..9685a7f 100644
--- a/Source/CPack/WiX/cmWIXAccessControlList.cxx
+++ b/Source/CPack/WiX/cmWIXAccessControlList.cxx
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmWIXAccessControlList.h"
+#include <cm/string_view>
+
#include "cmCPackGenerator.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -35,12 +37,13 @@ void cmWIXAccessControlList::CreatePermissionElement(std::string const& entry)
return;
}
- std::string user_and_domain = entry.substr(0, pos);
- std::string permission_string = entry.substr(pos + 1);
+ cm::string_view enview(entry);
+ cm::string_view user_and_domain = enview.substr(0, pos);
+ cm::string_view permission_string = enview.substr(pos + 1);
pos = user_and_domain.find('@');
- std::string user;
- std::string domain;
+ cm::string_view user;
+ cm::string_view domain;
if (pos != std::string::npos) {
user = user_and_domain.substr(0, pos);
domain = user_and_domain.substr(pos + 1);
@@ -51,9 +54,9 @@ void cmWIXAccessControlList::CreatePermissionElement(std::string const& entry)
std::vector<std::string> permissions = cmTokenize(permission_string, ",");
this->SourceWriter.BeginElement("Permission");
- this->SourceWriter.AddAttribute("User", user);
+ this->SourceWriter.AddAttribute("User", std::string(user));
if (!domain.empty()) {
- this->SourceWriter.AddAttribute("Domain", domain);
+ this->SourceWriter.AddAttribute("Domain", std::string(domain));
}
for (std::string const& permission : permissions) {
this->EmitBooleanAttribute(entry, cmTrimWhitespace(permission));
diff --git a/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx b/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
index c0d879a..b4085d5 100644
--- a/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
+++ b/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
@@ -1,5 +1,10 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
+#if defined(__CYGWIN__)
+// For S_IWRITE symbol
+# define _DEFAULT_SOURCE
+#endif
+
#include "cmWIXFilesSourceWriter.h"
#include "cm_sys_stat.h"
diff --git a/Source/CPack/WiX/cmWIXPatch.cxx b/Source/CPack/WiX/cmWIXPatch.cxx
index ca232f9..122ffaf 100644
--- a/Source/CPack/WiX/cmWIXPatch.cxx
+++ b/Source/CPack/WiX/cmWIXPatch.cxx
@@ -41,7 +41,7 @@ void cmWIXPatch::ApplyFragment(std::string const& id,
void cmWIXPatch::ApplyElementChildren(const cmWIXPatchElement& element,
cmWIXSourceWriter& writer)
{
- for (cmWIXPatchNode* node : element.children) {
+ for (const auto& node : element.children) {
switch (node->type()) {
case cmWIXPatchNode::ELEMENT:
ApplyElement(dynamic_cast<const cmWIXPatchElement&>(*node), writer);
diff --git a/Source/CPack/WiX/cmWIXPatchParser.cxx b/Source/CPack/WiX/cmWIXPatchParser.cxx
index fd9103b..8b26c4e 100644
--- a/Source/CPack/WiX/cmWIXPatchParser.cxx
+++ b/Source/CPack/WiX/cmWIXPatchParser.cxx
@@ -2,7 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmWIXPatchParser.h"
-#include "cm_expat.h"
+#include <utility>
+
+#include <cm/memory>
+
+#include <cm3p/expat.h>
#include "cmCPackGenerator.h"
@@ -20,12 +24,8 @@ cmWIXPatchNode::~cmWIXPatchNode()
{
}
-cmWIXPatchElement::~cmWIXPatchElement()
-{
- for (cmWIXPatchNode* child : children) {
- delete child;
- }
-}
+cmWIXPatchElement::cmWIXPatchElement() = default;
+cmWIXPatchElement::~cmWIXPatchElement() = default;
cmWIXPatchParser::cmWIXPatchParser(fragment_map_t& fragments,
cmCPackLog* logger)
@@ -54,8 +54,7 @@ void cmWIXPatchParser::StartElement(const std::string& name, const char** atts)
} else if (State == INSIDE_FRAGMENT) {
cmWIXPatchElement& parent = *ElementStack.back();
- cmWIXPatchElement* element = new cmWIXPatchElement;
- parent.children.push_back(element);
+ auto element = cm::make_unique<cmWIXPatchElement>();
element->name = name;
@@ -66,7 +65,8 @@ void cmWIXPatchParser::StartElement(const std::string& name, const char** atts)
element->attributes[key] = value;
}
- ElementStack.push_back(element);
+ ElementStack.push_back(element.get());
+ parent.children.push_back(std::move(element));
}
}
@@ -130,10 +130,10 @@ void cmWIXPatchParser::CharacterDataHandler(const char* data, int length)
std::string::size_type last = text.find_last_not_of(whitespace);
if (first != std::string::npos && last != std::string::npos) {
- cmWIXPatchText* text_node = new cmWIXPatchText;
+ auto text_node = cm::make_unique<cmWIXPatchText>();
text_node->text = text.substr(first, last - first + 1);
- parent.children.push_back(text_node);
+ parent.children.push_back(std::move(text_node));
}
}
}
diff --git a/Source/CPack/WiX/cmWIXPatchParser.h b/Source/CPack/WiX/cmWIXPatchParser.h
index 87dd892..8d5d2ad 100644
--- a/Source/CPack/WiX/cmWIXPatchParser.h
+++ b/Source/CPack/WiX/cmWIXPatchParser.h
@@ -4,6 +4,7 @@
#define cmCPackWIXPatchParser_h
#include <map>
+#include <memory>
#include <vector>
#include "cmCPackLog.h"
@@ -33,9 +34,14 @@ struct cmWIXPatchElement : cmWIXPatchNode
{
virtual Type type();
+ cmWIXPatchElement();
+
+ cmWIXPatchElement(const cmWIXPatchElement&) = delete;
+ const cmWIXPatchElement& operator=(const cmWIXPatchElement&) = delete;
+
~cmWIXPatchElement();
- using child_list_t = std::vector<cmWIXPatchNode*>;
+ using child_list_t = std::vector<std::unique_ptr<cmWIXPatchNode>>;
using attributes_t = std::map<std::string, std::string>;
std::string name;
diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx
index 43f2946..967cc60 100644
--- a/Source/CPack/cmCPackArchiveGenerator.cxx
+++ b/Source/CPack/cmCPackArchiveGenerator.cxx
@@ -8,6 +8,8 @@
#include <utility>
#include <vector>
+#include <cm3p/archive.h>
+
#include "cmCPackComponentGroup.h"
#include "cmCPackGenerator.h"
#include "cmCPackLog.h"
@@ -154,6 +156,20 @@ int cmCPackArchiveGenerator::addOneComponentToArchive(
} \
cmArchiveWrite archive(gf, this->Compress, this->ArchiveFormat); \
do { \
+ if (!this->SetArchiveOptions(&archive)) { \
+ cmCPackLogger(cmCPackLog::LOG_ERROR, \
+ "Problem to set archive options <" \
+ << (filename) << ">, ERROR = " << (archive).GetError() \
+ << std::endl); \
+ return 0; \
+ } \
+ if (!archive.Open()) { \
+ cmCPackLogger(cmCPackLog::LOG_ERROR, \
+ "Problem to open archive <" \
+ << (filename) << ">, ERROR = " << (archive).GetError() \
+ << std::endl); \
+ return 0; \
+ } \
if (!(archive)) { \
cmCPackLogger(cmCPackLog::LOG_ERROR, \
"Problem to create archive <" \
@@ -328,3 +344,23 @@ bool cmCPackArchiveGenerator::SupportsComponentInstallation() const
// (for backward compatibility reason)
return IsOn("CPACK_ARCHIVE_COMPONENT_INSTALL");
}
+
+bool cmCPackArchiveGenerator::SetArchiveOptions(cmArchiveWrite* archive)
+{
+#if ARCHIVE_VERSION_NUMBER >= 3004000
+ // Upstream fixed an issue with their integer parsing in 3.4.0 which would
+ // cause spurious errors to be raised from `strtoull`.
+ if (this->Compress == cmArchiveWrite::CompressXZ) {
+ const char* threads = "1";
+ if (this->IsSet("CPACK_ARCHIVE_THREADS")) {
+ threads = this->GetOption("CPACK_ARCHIVE_THREADS");
+ }
+
+ if (!archive->SetFilterOption("xz", "threads", threads)) {
+ return false;
+ }
+ }
+#endif
+
+ return true;
+}
diff --git a/Source/CPack/cmCPackArchiveGenerator.h b/Source/CPack/cmCPackArchiveGenerator.h
index 8d67720..7eb5665 100644
--- a/Source/CPack/cmCPackArchiveGenerator.h
+++ b/Source/CPack/cmCPackArchiveGenerator.h
@@ -86,6 +86,8 @@ private:
return this->OutputExtension.c_str();
}
+ bool SetArchiveOptions(cmArchiveWrite* archive);
+
private:
cmArchiveWrite::Compress Compress;
std::string ArchiveFormat;
diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx
index 5b7d8fb..3d5fe6b 100644
--- a/Source/CPack/cmCPackDebGenerator.cxx
+++ b/Source/CPack/cmCPackDebGenerator.cxx
@@ -135,16 +135,17 @@ void DebGenerator::generateDebianBinaryFile() const
{
// debian-binary file
const std::string dbfilename = WorkDir + "/debian-binary";
- cmGeneratedFileStream out(dbfilename);
- out << "2.0";
- out << std::endl; // required for valid debian package
+ cmGeneratedFileStream out;
+ out.Open(dbfilename, false, true);
+ out << "2.0\n"; // required for valid debian package
}
void DebGenerator::generateControlFile() const
{
std::string ctlfilename = WorkDir + "/control";
- cmGeneratedFileStream out(ctlfilename);
+ cmGeneratedFileStream out;
+ out.Open(ctlfilename, false, true);
for (auto const& kv : ControlValues) {
out << kv.first << ": " << kv.second << "\n";
}
@@ -156,8 +157,7 @@ void DebGenerator::generateControlFile() const
totalSize += cmSystemTools::FileLength(file);
}
}
- out << "Installed-Size: " << (totalSize + 1023) / 1024 << "\n";
- out << std::endl;
+ out << "Installed-Size: " << (totalSize + 1023) / 1024 << "\n\n";
}
bool DebGenerator::generateDataTar() const
@@ -173,6 +173,7 @@ bool DebGenerator::generateDataTar() const
}
cmArchiveWrite data_tar(fileStream_data_tar, TarCompressionType,
DebianArchiveType);
+ data_tar.Open();
// uid/gid should be the one of the root user, and this root user has
// always uid/gid equal to 0.
@@ -247,7 +248,8 @@ std::string DebGenerator::generateMD5File() const
{
std::string md5filename = WorkDir + "/md5sums";
- cmGeneratedFileStream out(md5filename);
+ cmGeneratedFileStream out;
+ out.Open(md5filename, false, true);
std::string topLevelWithTrailingSlash = cmStrCat(TemporaryDir, '/');
for (std::string const& file : PackageFiles) {
@@ -291,6 +293,7 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const
}
cmArchiveWrite control_tar(fileStream_control_tar,
cmArchiveWrite::CompressGZip, DebianArchiveType);
+ control_tar.Open();
// sets permissions and uid/gid for the files
control_tar.SetUIDAndGID(0u, 0u);
@@ -410,6 +413,7 @@ bool DebGenerator::generateDeb() const
cmGeneratedFileStream debStream;
debStream.Open(outputPath, false, true);
cmArchiveWrite deb(debStream, cmArchiveWrite::CompressNone, "arbsd");
+ deb.Open();
// uid/gid should be the one of the root user, and this root user has
// always uid/gid equal to 0.
@@ -484,6 +488,7 @@ int cmCPackDebGenerator::PackageOnePack(std::string const& initialTopLevel,
findExpr += "/*";
gl.RecurseOn();
gl.SetRecurseListDirs(true);
+ gl.SetRecurseThroughSymlinks(false);
if (!gl.FindFiles(findExpr)) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Cannot find any files in the installed directory"
@@ -508,6 +513,7 @@ int cmCPackDebGenerator::PackageOnePack(std::string const& initialTopLevel,
findExpr += "/*";
gl.RecurseOn();
gl.SetRecurseListDirs(true);
+ gl.SetRecurseThroughSymlinks(false);
if (!gl.FindFiles(findExpr)) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Cannot find any files in the installed directory"
@@ -627,6 +633,7 @@ int cmCPackDebGenerator::PackageComponentsAllInOne(
findExpr += "/*";
gl.RecurseOn();
gl.SetRecurseListDirs(true);
+ gl.SetRecurseThroughSymlinks(false);
if (!gl.FindFiles(findExpr)) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Cannot find any files in the installed directory"
@@ -751,15 +758,17 @@ int cmCPackDebGenerator::createDeb()
const bool gen_shibs = this->IsOn("CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS") &&
debian_pkg_shlibs && *debian_pkg_shlibs;
if (gen_shibs) {
- cmGeneratedFileStream out(shlibsfilename);
+ cmGeneratedFileStream out;
+ out.Open(shlibsfilename, false, true);
out << debian_pkg_shlibs;
- out << std::endl;
+ out << '\n';
}
const std::string postinst = strGenWDIR + "/postinst";
const std::string postrm = strGenWDIR + "/postrm";
if (this->IsOn("GEN_CPACK_DEBIAN_GENERATE_POSTINST")) {
- cmGeneratedFileStream out(postinst);
+ cmGeneratedFileStream out;
+ out.Open(postinst, false, true);
out << "#!/bin/sh\n\n"
"set -e\n\n"
"if [ \"$1\" = \"configure\" ]; then\n"
@@ -767,7 +776,8 @@ int cmCPackDebGenerator::createDeb()
"fi\n";
}
if (this->IsOn("GEN_CPACK_DEBIAN_GENERATE_POSTRM")) {
- cmGeneratedFileStream out(postrm);
+ cmGeneratedFileStream out;
+ out.Open(postrm, false, true);
out << "#!/bin/sh\n\n"
"set -e\n\n"
"if [ \"$1\" = \"remove\" ]; then\n"
diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx
index ea71007..fe7abf4 100644
--- a/Source/CPack/cmCPackDragNDropGenerator.cxx
+++ b/Source/CPack/cmCPackDragNDropGenerator.cxx
@@ -138,11 +138,16 @@ int cmCPackDragNDropGenerator::InitializeInternal()
}
for (auto const& language : languages) {
std::string license = slaDirectory + "/" + language + ".license.txt";
- if (!singleLicense && !cmSystemTools::FileExists(license)) {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Missing license file " << language << ".license.txt"
- << std::endl);
- return 0;
+ std::string license_rtf = slaDirectory + "/" + language + ".license.rtf";
+ if (!singleLicense) {
+ if (!cmSystemTools::FileExists(license) &&
+ !cmSystemTools::FileExists(license_rtf)) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Missing license file "
+ << language << ".license.txt"
+ << " / " << language << ".license.rtf" << std::endl);
+ return 0;
+ }
}
std::string menu = slaDirectory + "/" + language + ".menu.txt";
if (!cmSystemTools::FileExists(menu)) {
@@ -775,6 +780,11 @@ std::string cmCPackDragNDropGenerator::GetComponentInstallDirNameSuffix(
}
}
+ std::string componentFileName =
+ "CPACK_DMG_" + cmSystemTools::UpperCase(componentName) + "_FILE_NAME";
+ if (this->IsSet(componentFileName)) {
+ return this->GetOption(componentFileName);
+ }
return GetComponentPackageFileName(package_file_name, componentName, false);
}
@@ -788,13 +798,29 @@ bool cmCPackDragNDropGenerator::WriteLicense(
licenseLanguage = "English";
}
+ // License file
+ std::string license_format = "TEXT";
+ std::string actual_license;
+ if (!licenseFile.empty()) {
+ if (cmHasLiteralSuffix(licenseFile, ".rtf")) {
+ license_format = "RTF ";
+ }
+ actual_license = licenseFile;
+ } else {
+ std::string license_wo_ext =
+ slaDirectory + "/" + licenseLanguage + ".license";
+ if (cmSystemTools::FileExists(license_wo_ext + ".txt")) {
+ actual_license = license_wo_ext + ".txt";
+ } else {
+ license_format = "RTF ";
+ actual_license = license_wo_ext + ".rtf";
+ }
+ }
+
// License header
- outputStream << "data 'TEXT' (" << licenseNumber << ", \"" << licenseLanguage
- << "\") {\n";
+ outputStream << "data '" << license_format << "' (" << licenseNumber
+ << ", \"" << licenseLanguage << "\") {\n";
// License body
- std::string actual_license = !licenseFile.empty()
- ? licenseFile
- : (slaDirectory + "/" + licenseLanguage + ".license.txt");
cmsys::ifstream license_ifs;
license_ifs.open(actual_license.c_str());
if (license_ifs.is_open()) {
@@ -873,8 +899,9 @@ bool cmCPackDragNDropGenerator::BreakLongLine(const std::string& line,
std::string* error)
{
const size_t max_line_length = 512;
- for (size_t i = 0; i < line.size(); i += max_line_length) {
- size_t line_length = max_line_length;
+ size_t line_length = max_line_length;
+ for (size_t i = 0; i < line.size(); i += line_length) {
+ line_length = max_line_length;
if (i + line_length > line.size()) {
line_length = line.size() - i;
} else {
diff --git a/Source/CPack/cmCPackExternalGenerator.cxx b/Source/CPack/cmCPackExternalGenerator.cxx
index 142eb6f..11e1aec 100644
--- a/Source/CPack/cmCPackExternalGenerator.cxx
+++ b/Source/CPack/cmCPackExternalGenerator.cxx
@@ -8,10 +8,10 @@
#include <cm/memory>
-#include "cmsys/FStream.hxx"
+#include <cm3p/json/value.h>
+#include <cm3p/json/writer.h>
-#include "cm_jsoncpp_value.h"
-#include "cm_jsoncpp_writer.h"
+#include "cmsys/FStream.hxx"
#include "cmCPackComponentGroup.h"
#include "cmCPackLog.h"
diff --git a/Source/CPack/cmCPackFreeBSDGenerator.cxx b/Source/CPack/cmCPackFreeBSDGenerator.cxx
index e3cc352..b673006 100644
--- a/Source/CPack/cmCPackFreeBSDGenerator.cxx
+++ b/Source/CPack/cmCPackFreeBSDGenerator.cxx
@@ -8,6 +8,7 @@
#include "cmGeneratedFileStream.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmWorkingDirectory.h"
// Needed for ::open() and ::stat()
#include <algorithm>
@@ -285,8 +286,7 @@ int cmCPackFreeBSDGenerator::PackageFiles()
}
std::vector<std::string>::const_iterator fileIt;
- std::string dir = cmSystemTools::GetCurrentWorkingDirectory();
- cmSystemTools::ChangeDirectory(toplevel);
+ cmWorkingDirectory wd(toplevel);
files.erase(std::remove_if(files.begin(), files.end(), ignore_file),
files.end());
@@ -332,6 +332,5 @@ int cmCPackFreeBSDGenerator::PackageFiles()
}
}
- cmSystemTools::ChangeDirectory(dir);
return 1;
}
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index 6698f3c..08fd2a2 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -354,6 +354,7 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
"- Install directory: " << top << std::endl);
gl.RecurseOn();
gl.SetRecurseListDirs(true);
+ gl.SetRecurseThroughSymlinks(false);
if (!gl.FindFiles(findExpr)) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Cannot find any files in the installed directory"
@@ -402,7 +403,6 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
}
/* rebuild symlinks in the installed tree */
if (!symlinkedFiles.empty()) {
- std::string curDir = cmSystemTools::GetCurrentWorkingDirectory();
std::string goToDir = cmStrCat(tempDir, '/', subdir);
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"Change dir to: " << goToDir << std::endl);
@@ -441,7 +441,8 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
}
}
cmCPackLogger(cmCPackLog::LOG_DEBUG,
- "Going back to: " << curDir << std::endl);
+ "Going back to: " << workdir.GetOldDirectory()
+ << std::endl);
}
}
}
@@ -621,9 +622,9 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
buildConfigs.emplace_back();
}
- std::unique_ptr<cmGlobalGenerator> globalGenerator(
+ std::unique_ptr<cmGlobalGenerator> globalGenerator =
this->MakefileMap->GetCMakeInstance()->CreateGlobalGenerator(
- cmakeGenerator));
+ cmakeGenerator);
if (!globalGenerator) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Specified package generator not found. "
@@ -862,6 +863,7 @@ int cmCPackGenerator::InstallCMakeProject(
findExpr += "/*";
glB.RecurseOn();
glB.SetRecurseListDirs(true);
+ glB.SetRecurseThroughSymlinks(false);
glB.FindFiles(findExpr);
filesBefore = glB.GetFiles();
std::sort(filesBefore.begin(), filesBefore.end());
diff --git a/Source/CPack/cmCPackLog.cxx b/Source/CPack/cmCPackLog.cxx
index ca675fd..49e4113 100644
--- a/Source/CPack/cmCPackLog.cxx
+++ b/Source/CPack/cmCPackLog.cxx
@@ -4,54 +4,38 @@
#include <iostream>
+#include <cm/memory>
+
#include "cmGeneratedFileStream.h"
#include "cmSystemTools.h"
cmCPackLog::cmCPackLog()
{
- this->Verbose = false;
- this->Debug = false;
- this->Quiet = false;
- this->NewLine = true;
-
- this->LastTag = cmCPackLog::NOTAG;
this->DefaultOutput = &std::cout;
this->DefaultError = &std::cerr;
-
- this->LogOutput = nullptr;
- this->LogOutputCleanup = false;
}
-cmCPackLog::~cmCPackLog()
-{
- this->SetLogOutputStream(nullptr);
-}
+cmCPackLog::~cmCPackLog() = default;
void cmCPackLog::SetLogOutputStream(std::ostream* os)
{
- if (this->LogOutputCleanup && this->LogOutput) {
- delete this->LogOutput;
- }
- this->LogOutputCleanup = false;
+ this->LogOutputStream.reset();
this->LogOutput = os;
}
bool cmCPackLog::SetLogOutputFile(const char* fname)
{
- cmGeneratedFileStream* cg = nullptr;
+ this->LogOutputStream.reset();
if (fname) {
- cg = new cmGeneratedFileStream(fname);
- }
- if (cg && !*cg) {
- delete cg;
- cg = nullptr;
+ this->LogOutputStream = cm::make_unique<cmGeneratedFileStream>(fname);
}
- this->SetLogOutputStream(cg);
- if (!cg) {
- return false;
+ if (this->LogOutputStream && !*this->LogOutputStream) {
+ this->LogOutputStream.reset();
}
- this->LogOutputCleanup = true;
- return true;
+
+ this->LogOutput = this->LogOutputStream.get();
+
+ return this->LogOutput != nullptr;
}
void cmCPackLog::Log(int tag, const char* file, int line, const char* msg,
diff --git a/Source/CPack/cmCPackLog.h b/Source/CPack/cmCPackLog.h
index 1cb1643..68ffcce 100644
--- a/Source/CPack/cmCPackLog.h
+++ b/Source/CPack/cmCPackLog.h
@@ -5,6 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <memory>
#include <ostream>
#include <string>
@@ -97,13 +98,13 @@ public:
void SetErrorPrefix(std::string const& pfx) { this->ErrorPrefix = pfx; }
private:
- bool Verbose;
- bool Debug;
- bool Quiet;
+ bool Verbose = false;
+ bool Debug = false;
+ bool Quiet = false;
- bool NewLine;
+ bool NewLine = true;
- int LastTag;
+ int LastTag = cmCPackLog::NOTAG;
std::string Prefix;
std::string OutputPrefix;
@@ -112,13 +113,11 @@ private:
std::string WarningPrefix;
std::string ErrorPrefix;
- std::ostream* DefaultOutput;
- std::ostream* DefaultError;
+ std::ostream* DefaultOutput = nullptr;
+ std::ostream* DefaultError = nullptr;
- std::string LogOutputFileName;
- std::ostream* LogOutput;
- // Do we need to cleanup log output stream
- bool LogOutputCleanup;
+ std::ostream* LogOutput = nullptr;
+ std::unique_ptr<std::ostream> LogOutputStream;
};
class cmCPackLogWrite
diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx
index 9bf72df..058b090 100644
--- a/Source/CPack/cmCPackNSISGenerator.cxx
+++ b/Source/CPack/cmCPackNSISGenerator.cxx
@@ -9,10 +9,11 @@
#include <sstream>
#include <utility>
+#include <cmext/algorithm>
+
#include "cmsys/Directory.hxx"
#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
#include "cmCPackComponentGroup.h"
#include "cmCPackGenerator.h"
#include "cmCPackLog.h"
@@ -68,7 +69,7 @@ int cmCPackNSISGenerator::PackageFiles()
// Use the custom component install directory if we have one
if (pos != std::string::npos) {
- const std::string componentName = fileN.substr(0, pos);
+ auto componentName = cm::string_view(fileN).substr(0, pos);
outputDir = CustomComponentInstallDirectory(componentName);
} else {
outputDir = CustomComponentInstallDirectory(fileN);
@@ -103,7 +104,7 @@ int cmCPackNSISGenerator::PackageFiles()
componentName = fileN.substr(0, slash);
// Strip off the component part of the path.
- fileN = fileN.substr(slash + 1);
+ fileN.erase(0, slash + 1);
}
}
std::replace(fileN.begin(), fileN.end(), '/', '\\');
@@ -128,22 +129,26 @@ int cmCPackNSISGenerator::PackageFiles()
this->IsSet("CPACK_NSIS_MUI_UNIICON")) {
std::string installerIconCode;
if (this->IsSet("CPACK_NSIS_MUI_ICON")) {
- installerIconCode += "!define MUI_ICON \"";
- installerIconCode += this->GetOption("CPACK_NSIS_MUI_ICON");
- installerIconCode += "\"\n";
+ installerIconCode += cmStrCat(
+ "!define MUI_ICON \"", this->GetOption("CPACK_NSIS_MUI_ICON"), "\"\n");
}
if (this->IsSet("CPACK_NSIS_MUI_UNIICON")) {
- installerIconCode += "!define MUI_UNICON \"";
- installerIconCode += this->GetOption("CPACK_NSIS_MUI_UNIICON");
- installerIconCode += "\"\n";
+ installerIconCode +=
+ cmStrCat("!define MUI_UNICON \"",
+ this->GetOption("CPACK_NSIS_MUI_UNIICON"), "\"\n");
}
this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_MUI_ICON_CODE",
installerIconCode.c_str());
}
- if (this->IsSet("CPACK_PACKAGE_ICON")) {
- std::string installerIconCode =
- cmStrCat("!define MUI_HEADERIMAGE_BITMAP \"",
- this->GetOption("CPACK_PACKAGE_ICON"), "\"\n");
+ std::string installerHeaderImage;
+ if (this->IsSet("CPACK_NSIS_MUI_HEADERIMAGE")) {
+ installerHeaderImage = this->GetOption("CPACK_NSIS_MUI_HEADERIMAGE");
+ } else if (this->IsSet("CPACK_PACKAGE_ICON")) {
+ installerHeaderImage = this->GetOption("CPACK_PACKAGE_ICON");
+ }
+ if (!installerHeaderImage.empty()) {
+ std::string installerIconCode = cmStrCat(
+ "!define MUI_HEADERIMAGE_BITMAP \"", installerHeaderImage, "\"\n");
this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_ICON_CODE",
installerIconCode.c_str());
}
@@ -173,6 +178,37 @@ int cmCPackNSISGenerator::PackageFiles()
installerRunCode.c_str());
}
+ if (this->IsSet("CPACK_NSIS_WELCOME_TITLE")) {
+ std::string welcomeTitleCode =
+ cmStrCat("!define MUI_WELCOMEPAGE_TITLE \"",
+ this->GetOption("CPACK_NSIS_WELCOME_TITLE"), "\"");
+ this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_WELCOME_TITLE_CODE",
+ welcomeTitleCode.c_str());
+ }
+
+ if (this->IsSet("CPACK_NSIS_WELCOME_TITLE_3LINES")) {
+ this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_WELCOME_TITLE_3LINES_CODE",
+ "!define MUI_WELCOMEPAGE_TITLE_3LINES");
+ }
+
+ if (this->IsSet("CPACK_NSIS_FINISH_TITLE")) {
+ std::string finishTitleCode =
+ cmStrCat("!define MUI_FINISHPAGE_TITLE \"",
+ this->GetOption("CPACK_NSIS_FINISH_TITLE"), "\"");
+ this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_FINISH_TITLE_CODE",
+ finishTitleCode.c_str());
+ }
+
+ if (this->IsSet("CPACK_NSIS_FINISH_TITLE_3LINES")) {
+ this->SetOptionIfNotSet("CPACK_NSIS_INSTALLER_FINISH_TITLE_3LINES_CODE",
+ "!define MUI_FINISHPAGE_TITLE_3LINES");
+ }
+
+ if (this->IsSet("CPACK_NSIS_MANIFEST_DPI_AWARE")) {
+ this->SetOptionIfNotSet("CPACK_NSIS_MANIFEST_DPI_AWARE_CODE",
+ "ManifestDPIAware true");
+ }
+
// Setup all of the component sections
if (this->Components.empty()) {
this->SetOptionIfNotSet("CPACK_NSIS_INSTALLATION_TYPES", "");
@@ -423,12 +459,12 @@ int cmCPackNSISGenerator::InitializeInternal()
}
if (versionRex.find(output)) {
double nsisVersion = atof(versionRex.match(1).c_str());
- double minNSISVersion = 2.09;
+ double minNSISVersion = 3.0;
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"NSIS Version: " << nsisVersion << std::endl);
if (nsisVersion < minNSISVersion) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
- "CPack requires NSIS Version 2.09 or greater. "
+ "CPack requires NSIS Version 3.0 or greater. "
"NSIS found on the system was: "
<< nsisVersion << std::endl);
return 0;
@@ -494,7 +530,7 @@ int cmCPackNSISGenerator::InitializeInternal()
<< ".lnk\"" << std::endl;
// see if CPACK_CREATE_DESKTOP_LINK_ExeName is on
// if so add a desktop link
- if (cmContains(cpackPackageDesktopLinksVector, execName)) {
+ if (cm::contains(cpackPackageDesktopLinksVector, execName)) {
str << " StrCmp \"$INSTALL_DESKTOP\" \"1\" 0 +2\n";
str << " CreateShortCut \"$DESKTOP\\" << linkName
<< R"(.lnk" "$INSTDIR\)" << cpackNsisExecutablesDirectory << "\\"
@@ -642,7 +678,7 @@ std::string cmCPackNSISGenerator::CreateComponentDescription(
const std::string componentOutputDir =
CustomComponentInstallDirectory(component->Name);
- componentCode += " SetOutPath \"" + componentOutputDir + "\"\n";
+ componentCode += cmStrCat(" SetOutPath \"", componentOutputDir, "\"\n");
// Create the actual installation commands
if (component->IsDownloaded) {
@@ -891,12 +927,11 @@ std::string cmCPackNSISGenerator::CreateComponentGroupDescription(
}
std::string cmCPackNSISGenerator::CustomComponentInstallDirectory(
- const std::string& componentName)
+ cm::string_view componentName)
{
- const char* outputDir =
- this->GetOption("CPACK_NSIS_" + componentName + "_INSTALL_DIRECTORY");
- const std::string componentOutputDir = (outputDir ? outputDir : "$INSTDIR");
- return componentOutputDir;
+ const char* outputDir = this->GetOption(
+ cmStrCat("CPACK_NSIS_", componentName, "_INSTALL_DIRECTORY"));
+ return outputDir ? outputDir : "$INSTDIR";
}
std::string cmCPackNSISGenerator::TranslateNewlines(std::string str)
diff --git a/Source/CPack/cmCPackNSISGenerator.h b/Source/CPack/cmCPackNSISGenerator.h
index 0af37af..88cba45 100644
--- a/Source/CPack/cmCPackNSISGenerator.h
+++ b/Source/CPack/cmCPackNSISGenerator.h
@@ -10,6 +10,8 @@
#include <string>
#include <vector>
+#include <cm/string_view>
+
#include "cmCPackGenerator.h"
class cmCPackComponent;
@@ -75,8 +77,7 @@ protected:
/// Returns the custom install directory if available for the specified
/// component, otherwise $INSTDIR is returned.
- std::string CustomComponentInstallDirectory(
- const std::string& componentName);
+ std::string CustomComponentInstallDirectory(cm::string_view componentName);
/// Translations any newlines found in the string into \\r\\n, so that the
/// resulting string can be used within NSIS.
diff --git a/Source/CPack/cmCPackOSXX11Generator.cxx b/Source/CPack/cmCPackOSXX11Generator.cxx
index 951c65f..5de4a6f 100644
--- a/Source/CPack/cmCPackOSXX11Generator.cxx
+++ b/Source/CPack/cmCPackOSXX11Generator.cxx
@@ -178,6 +178,9 @@ int cmCPackOSXX11Generator::PackageFiles()
int cmCPackOSXX11Generator::InitializeInternal()
{
+ cmCPackLogger(cmCPackLog::LOG_WARNING,
+ "The OSXX11 generator is deprecated "
+ "and will be removed in a future version.\n");
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"cmCPackOSXX11Generator::Initialize()" << std::endl);
std::vector<std::string> path;
diff --git a/Source/CPack/cmCPackPKGGenerator.cxx b/Source/CPack/cmCPackPKGGenerator.cxx
index dae5ec9..ac3d64d 100644
--- a/Source/CPack/cmCPackPKGGenerator.cxx
+++ b/Source/CPack/cmCPackPKGGenerator.cxx
@@ -46,7 +46,66 @@ std::string cmCPackPKGGenerator::GetPackageName(
return component.ArchiveFile + ".pkg";
}
-void cmCPackPKGGenerator::WriteDistributionFile(const char* metapackageFile)
+void cmCPackPKGGenerator::CreateBackground(const char* themeName,
+ const char* metapackageFile,
+ cm::string_view genName,
+ cmXMLWriter& xout)
+{
+ std::string paramSuffix =
+ (themeName == nullptr) ? "" : cmSystemTools::UpperCase(themeName);
+ std::string opt = (themeName == nullptr)
+ ? cmStrCat("CPACK_", genName, "_BACKGROUND")
+ : cmStrCat("CPACK_", genName, "_BACKGROUND_", paramSuffix);
+ const char* bgFileName = this->GetOption(opt);
+ if (bgFileName == nullptr) {
+ return;
+ }
+
+ std::string bgFilePath = cmStrCat(metapackageFile, "/Contents/", bgFileName);
+
+ if (!cmSystemTools::FileExists(bgFilePath)) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Background image doesn't exist in the resource directory: "
+ << bgFileName << std::endl);
+ return;
+ }
+
+ if (themeName == nullptr) {
+ xout.StartElement("background");
+ } else {
+ xout.StartElement(cmStrCat("background-", themeName));
+ }
+
+ xout.Attribute("file", bgFileName);
+
+ const char* param = this->GetOption(cmStrCat(opt, "_ALIGNMENT"));
+ if (param != nullptr) {
+ xout.Attribute("alignment", param);
+ }
+
+ param = this->GetOption(cmStrCat(opt, "_SCALING"));
+ if (param != nullptr) {
+ xout.Attribute("scaling", param);
+ }
+
+ // Apple docs say that you must provide either mime-type or uti
+ // attribute for the background, but I've seen examples that
+ // doesn't have them, so don't make them mandatory.
+ param = this->GetOption(cmStrCat(opt, "_MIME_TYPE"));
+ if (param != nullptr) {
+ xout.Attribute("mime-type", param);
+ }
+
+ param = this->GetOption(cmStrCat(opt, "_UTI"));
+ if (param != nullptr) {
+ xout.Attribute("uti", param);
+ }
+
+ xout.EndElement();
+}
+
+void cmCPackPKGGenerator::WriteDistributionFile(const char* metapackageFile,
+ const char* genName)
{
std::string distributionTemplate =
this->FindTemplate("CPack.distribution.dist.in");
@@ -102,6 +161,11 @@ void cmCPackPKGGenerator::WriteDistributionFile(const char* metapackageFile)
CreateChoice(PostFlightComponent, xout);
}
+ // default background
+ this->CreateBackground(nullptr, metapackageFile, genName, xout);
+ // Dark Aqua
+ this->CreateBackground("darkAqua", metapackageFile, genName, xout);
+
this->SetOption("CPACK_PACKAGEMAKER_CHOICES", choiceOut.str().c_str());
// Create the distribution.dist file in the metapackage to turn it
diff --git a/Source/CPack/cmCPackPKGGenerator.h b/Source/CPack/cmCPackPKGGenerator.h
index 69286ff..be730ab 100644
--- a/Source/CPack/cmCPackPKGGenerator.h
+++ b/Source/CPack/cmCPackPKGGenerator.h
@@ -9,6 +9,8 @@
#include <sstream>
#include <string>
+#include <cm/string_view>
+
#include "cmCPackComponentGroup.h"
#include "cmCPackGenerator.h"
@@ -57,7 +59,7 @@ protected:
// inter-component dependencies. metapackageFile is the name of the
// metapackage for the distribution. Only valid for a
// component-based install.
- void WriteDistributionFile(const char* metapackageFile);
+ void WriteDistributionFile(const char* metapackageFile, const char* genName);
// Subroutine of WriteDistributionFile that writes out the
// dependency attributes for inter-component dependencies.
@@ -85,6 +87,10 @@ protected:
/// installer GUI.
void CreateChoice(const cmCPackComponent& component, cmXMLWriter& xout);
+ /// Creates a background in the distribution XML.
+ void CreateBackground(const char* themeName, const char* metapackageFile,
+ cm::string_view genName, cmXMLWriter& xout);
+
// The PostFlight component when creating a metapackage
cmCPackComponent PostFlightComponent;
};
diff --git a/Source/CPack/cmCPackPackageMakerGenerator.cxx b/Source/CPack/cmCPackPackageMakerGenerator.cxx
index c5ba726..f51ea42 100644
--- a/Source/CPack/cmCPackPackageMakerGenerator.cxx
+++ b/Source/CPack/cmCPackPackageMakerGenerator.cxx
@@ -279,7 +279,7 @@ int cmCPackPackageMakerGenerator::PackageFiles()
} else {
// We have built the package in place. Generate the
// distribution.dist file to describe it for the installer.
- WriteDistributionFile(packageDirFileName.c_str());
+ WriteDistributionFile(packageDirFileName.c_str(), "PACKAGEMAKER");
}
std::string tmpFile = cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"),
@@ -321,6 +321,9 @@ int cmCPackPackageMakerGenerator::PackageFiles()
int cmCPackPackageMakerGenerator::InitializeInternal()
{
+ cmCPackLogger(cmCPackLog::LOG_WARNING,
+ "The PackageMaker generator is deprecated "
+ "and will be removed in a future version.\n");
this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/usr");
// Starting with Xcode 4.3, PackageMaker is a separate app, and you
diff --git a/Source/CPack/cmCPackProductBuildGenerator.cxx b/Source/CPack/cmCPackProductBuildGenerator.cxx
index dae268c..a3e55de 100644
--- a/Source/CPack/cmCPackProductBuildGenerator.cxx
+++ b/Source/CPack/cmCPackProductBuildGenerator.cxx
@@ -81,7 +81,7 @@ int cmCPackProductBuildGenerator::PackageFiles()
}
// combine package(s) into a distribution
- WriteDistributionFile(packageDirFileName.c_str());
+ WriteDistributionFile(packageDirFileName.c_str(), "PRODUCTBUILD");
std::ostringstream pkgCmd;
std::string version = this->GetOption("CPACK_PACKAGE_VERSION");
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index 5895652..2e5bde2 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -85,7 +85,7 @@ int cpackDefinitionArgument(const char* argument, const char* cValue,
return 0;
}
std::string key = value.substr(0, pos);
- value = value.substr(pos + 1);
+ value.erase(0, pos + 1);
def->Map[key] = value;
cmCPack_Log(def->Log, cmCPackLog::LOG_DEBUG,
"Set CPack variable: " << key << " to \"" << value << "\""
@@ -115,7 +115,6 @@ int main(int argc, char const* const* argv)
argc = args.argc();
argv = args.argv();
- cmSystemTools::EnableMSVCDebugHook();
cmSystemTools::InitializeLibUV();
cmSystemTools::FindCMakeResources(argv[0]);
cmCPackLog log;
@@ -314,7 +313,7 @@ int main(int argc, char const* const* argv)
else {
// get a default value (current working directory)
cpackProjectDirectory = cmsys::SystemTools::GetCurrentWorkingDirectory();
- // use default value iff no value has been provided by the config file
+ // use default value if no value has been provided by the config file
if (!globalMF.IsSet("CPACK_PACKAGE_DIRECTORY")) {
globalMF.AddDefinition("CPACK_PACKAGE_DIRECTORY",
cpackProjectDirectory);
@@ -324,6 +323,12 @@ int main(int argc, char const* const* argv)
globalMF.AddDefinition(cd.first, cd.second);
}
+ // Force CPACK_PACKAGE_DIRECTORY as absolute path
+ cpackProjectDirectory = globalMF.GetDefinition("CPACK_PACKAGE_DIRECTORY");
+ cpackProjectDirectory =
+ cmSystemTools::CollapseFullPath(cpackProjectDirectory);
+ globalMF.AddDefinition("CPACK_PACKAGE_DIRECTORY", cpackProjectDirectory);
+
const char* cpackModulesPath = globalMF.GetDefinition("CPACK_MODULE_PATH");
if (cpackModulesPath) {
globalMF.AddDefinition("CMAKE_MODULE_PATH", cpackModulesPath);
diff --git a/Source/CTest/cmCTestBZR.cxx b/Source/CTest/cmCTestBZR.cxx
index 8640c46..c533cd7 100644
--- a/Source/CTest/cmCTestBZR.cxx
+++ b/Source/CTest/cmCTestBZR.cxx
@@ -8,11 +8,12 @@
#include <ostream>
#include <vector>
-#include "cmsys/RegularExpression.hxx"
+#include <cmext/algorithm>
+
+#include <cm3p/expat.h>
-#include "cm_expat.h"
+#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestVC.h"
#include "cmProcessTools.h"
@@ -245,7 +246,7 @@ private:
void CharacterDataHandler(const char* data, int length) override
{
- cmAppend(this->CData, data, data + length);
+ cm::append(this->CData, data, data + length);
}
void EndElement(const std::string& name) override
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx
index 2ad661c..db426b2 100644
--- a/Source/CTest/cmCTestBuildAndTestHandler.cxx
+++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx
@@ -215,11 +215,11 @@ int cmCTestBuildAndTestHandler::RunCMakeAndTest(std::string* outstring)
if (this->BuildNoCMake) {
// Make the generator available for the Build call below.
- cmGlobalGenerator* gen = cm.CreateGlobalGenerator(this->BuildGenerator);
- cm.SetGlobalGenerator(gen);
+ cm.SetGlobalGenerator(cm.CreateGlobalGenerator(this->BuildGenerator));
if (!this->BuildGeneratorPlatform.empty()) {
- cmMakefile mf(gen, cm.GetCurrentSnapshot());
- if (!gen->SetGeneratorPlatform(this->BuildGeneratorPlatform, &mf)) {
+ cmMakefile mf(cm.GetGlobalGenerator(), cm.GetCurrentSnapshot());
+ if (!cm.GetGlobalGenerator()->SetGeneratorPlatform(
+ this->BuildGeneratorPlatform, &mf)) {
return 1;
}
}
@@ -379,7 +379,7 @@ int cmCTestBuildAndTestHandler::ProcessCommandLineArguments(
const std::vector<std::string>& allArgs)
{
// --build-and-test options
- if (currentArg.find("--build-and-test", 0) == 0 &&
+ if (cmHasLiteralPrefix(currentArg, "--build-and-test") &&
idx < allArgs.size() - 1) {
if (idx + 2 < allArgs.size()) {
idx++;
@@ -397,25 +397,29 @@ int cmCTestBuildAndTestHandler::ProcessCommandLineArguments(
return 0;
}
}
- if (currentArg.find("--build-target", 0) == 0 && idx < allArgs.size() - 1) {
+ if (cmHasLiteralPrefix(currentArg, "--build-target") &&
+ idx < allArgs.size() - 1) {
idx++;
this->BuildTargets.push_back(allArgs[idx]);
}
- if (currentArg.find("--build-nocmake", 0) == 0) {
+ if (cmHasLiteralPrefix(currentArg, "--build-nocmake")) {
this->BuildNoCMake = true;
}
- if (currentArg.find("--build-run-dir", 0) == 0 && idx < allArgs.size() - 1) {
+ if (cmHasLiteralPrefix(currentArg, "--build-run-dir") &&
+ idx < allArgs.size() - 1) {
idx++;
this->BuildRunDir = allArgs[idx];
}
- if (currentArg.find("--build-two-config", 0) == 0) {
+ if (cmHasLiteralPrefix(currentArg, "--build-two-config")) {
this->BuildTwoConfig = true;
}
- if (currentArg.find("--build-exe-dir", 0) == 0 && idx < allArgs.size() - 1) {
+ if (cmHasLiteralPrefix(currentArg, "--build-exe-dir") &&
+ idx < allArgs.size() - 1) {
idx++;
this->ExecutableDirectory = allArgs[idx];
}
- if (currentArg.find("--test-timeout", 0) == 0 && idx < allArgs.size() - 1) {
+ if (cmHasLiteralPrefix(currentArg, "--test-timeout") &&
+ idx < allArgs.size() - 1) {
idx++;
this->Timeout = cmDuration(atof(allArgs[idx].c_str()));
}
@@ -431,31 +435,33 @@ int cmCTestBuildAndTestHandler::ProcessCommandLineArguments(
idx++;
this->BuildGeneratorToolset = allArgs[idx];
}
- if (currentArg.find("--build-project", 0) == 0 && idx < allArgs.size() - 1) {
+ if (cmHasLiteralPrefix(currentArg, "--build-project") &&
+ idx < allArgs.size() - 1) {
idx++;
this->BuildProject = allArgs[idx];
}
- if (currentArg.find("--build-makeprogram", 0) == 0 &&
+ if (cmHasLiteralPrefix(currentArg, "--build-makeprogram") &&
idx < allArgs.size() - 1) {
idx++;
this->BuildMakeProgram = allArgs[idx];
}
- if (currentArg.find("--build-config-sample", 0) == 0 &&
+ if (cmHasLiteralPrefix(currentArg, "--build-config-sample") &&
idx < allArgs.size() - 1) {
idx++;
this->ConfigSample = allArgs[idx];
}
- if (currentArg.find("--build-noclean", 0) == 0) {
+ if (cmHasLiteralPrefix(currentArg, "--build-noclean")) {
this->BuildNoClean = true;
}
- if (currentArg.find("--build-options", 0) == 0) {
+ if (cmHasLiteralPrefix(currentArg, "--build-options")) {
while (idx + 1 < allArgs.size() && allArgs[idx + 1] != "--build-target" &&
allArgs[idx + 1] != "--test-command") {
++idx;
this->BuildOptions.push_back(allArgs[idx]);
}
}
- if (currentArg.find("--test-command", 0) == 0 && idx < allArgs.size() - 1) {
+ if (cmHasLiteralPrefix(currentArg, "--test-command") &&
+ idx < allArgs.size() - 1) {
++idx;
this->TestCommand = allArgs[idx];
while (idx + 1 < allArgs.size()) {
diff --git a/Source/CTest/cmCTestBuildCommand.cxx b/Source/CTest/cmCTestBuildCommand.cxx
index 18df214..44fdc29 100644
--- a/Source/CTest/cmCTestBuildCommand.cxx
+++ b/Source/CTest/cmCTestBuildCommand.cxx
@@ -5,7 +5,7 @@
#include <cstring>
#include <sstream>
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
#include "cmCTest.h"
#include "cmCTestBuildHandler.h"
@@ -29,13 +29,7 @@ void cmCTestBuildCommand::BindArguments()
this->Bind("PROJECT_NAME"_s, this->ProjectName);
}
-cmCTestBuildCommand::~cmCTestBuildCommand()
-{
- if (this->GlobalGenerator) {
- delete this->GlobalGenerator;
- this->GlobalGenerator = nullptr;
- }
-}
+cmCTestBuildCommand::~cmCTestBuildCommand() = default;
cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler()
{
@@ -79,8 +73,7 @@ cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler()
}
if (this->GlobalGenerator) {
if (this->GlobalGenerator->GetName() != cmakeGeneratorName) {
- delete this->GlobalGenerator;
- this->GlobalGenerator = nullptr;
+ this->GlobalGenerator.reset();
}
}
if (!this->GlobalGenerator) {
diff --git a/Source/CTest/cmCTestBuildCommand.h b/Source/CTest/cmCTestBuildCommand.h
index da00a43..0f82817 100644
--- a/Source/CTest/cmCTestBuildCommand.h
+++ b/Source/CTest/cmCTestBuildCommand.h
@@ -48,7 +48,7 @@ public:
bool InitialPass(std::vector<std::string> const& args,
cmExecutionStatus& status) override;
- cmGlobalGenerator* GlobalGenerator = nullptr;
+ std::unique_ptr<cmGlobalGenerator> GlobalGenerator;
protected:
cmCTestBuildHandler* Handler;
diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx
index 9cb5449..35c2b11 100644
--- a/Source/CTest/cmCTestBuildHandler.cxx
+++ b/Source/CTest/cmCTestBuildHandler.cxx
@@ -7,11 +7,12 @@
#include <set>
#include <utility>
+#include <cmext/algorithm>
+
#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
#include "cmsys/Process.h"
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmDuration.h"
#include "cmFileTimeCache.h"
@@ -385,24 +386,20 @@ int cmCTestBuildHandler::ProcessHandler()
if (this->CTest->GetCTestConfiguration("SourceDirectory").size() > 20) {
std::string srcdir =
this->CTest->GetCTestConfiguration("SourceDirectory") + "/";
- for (cc = srcdir.size() - 2; cc > 0; cc--) {
- if (srcdir[cc] == '/') {
- srcdir = srcdir.substr(0, cc + 1);
- break;
- }
+ cc = srcdir.rfind('/', srcdir.size() - 2);
+ if (cc != std::string::npos) {
+ srcdir.resize(cc + 1);
+ this->SimplifySourceDir = std::move(srcdir);
}
- this->SimplifySourceDir = srcdir;
}
if (this->CTest->GetCTestConfiguration("BuildDirectory").size() > 20) {
std::string bindir =
this->CTest->GetCTestConfiguration("BuildDirectory") + "/";
- for (cc = bindir.size() - 2; cc > 0; cc--) {
- if (bindir[cc] == '/') {
- bindir = bindir.substr(0, cc + 1);
- break;
- }
+ cc = bindir.rfind('/', bindir.size() - 2);
+ if (cc != std::string::npos) {
+ bindir.resize(cc + 1);
+ this->SimplifyBuildDir = std::move(bindir);
}
- this->SimplifyBuildDir = bindir;
}
// Ok, let's do the build
@@ -544,11 +541,11 @@ void cmCTestBuildHandler::GenerateXMLLaunched(cmXMLWriter& xml)
const char* fname = launchDir.GetFile(i);
if (this->IsLaunchedErrorFile(fname) && numErrorsAllowed) {
numErrorsAllowed--;
- fragments.insert(this->CTestLaunchDir + "/" + fname);
+ fragments.insert(this->CTestLaunchDir + '/' + fname);
++this->TotalErrors;
} else if (this->IsLaunchedWarningFile(fname) && numWarningsAllowed) {
numWarningsAllowed--;
- fragments.insert(this->CTestLaunchDir + "/" + fname);
+ fragments.insert(this->CTestLaunchDir + '/' + fname);
++this->TotalWarnings;
}
}
@@ -969,7 +966,7 @@ void cmCTestBuildHandler::ProcessBuffer(const char* data, size_t length,
if (it != queue->end()) {
// Create a contiguous array for the line
this->CurrentProcessingLine.clear();
- cmAppend(this->CurrentProcessingLine, queue->begin(), it);
+ cm::append(this->CurrentProcessingLine, queue->begin(), it);
this->CurrentProcessingLine.push_back(0);
const char* line = this->CurrentProcessingLine.data();
diff --git a/Source/CTest/cmCTestCVS.cxx b/Source/CTest/cmCTestCVS.cxx
index 45ec390..1209e06 100644
--- a/Source/CTest/cmCTestCVS.cxx
+++ b/Source/CTest/cmCTestCVS.cxx
@@ -152,10 +152,12 @@ private:
this->FinishRevision();
}
} else if (this->Section == SectionRevisions) {
+ // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
+ // NOLINTNEXTLINE(bugprone-branch-clone)
if (!this->Rev.Log.empty()) {
// Continue the existing log.
this->Rev.Log += this->Line;
- this->Rev.Log += "\n";
+ this->Rev.Log += '\n';
} else if (this->Rev.Rev.empty() &&
this->RegexRevision.find(this->Line)) {
this->Rev.Rev = this->RegexRevision.match(1);
@@ -166,7 +168,7 @@ private:
} else if (!this->RegexBranches.find(this->Line)) {
// Start the log.
this->Rev.Log += this->Line;
- this->Rev.Log += "\n";
+ this->Rev.Log += '\n';
}
}
return this->Section != SectionEnd;
diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx
index f2f42b4..f42c3f1 100644
--- a/Source/CTest/cmCTestConfigureCommand.cxx
+++ b/Source/CTest/cmCTestConfigureCommand.cxx
@@ -6,7 +6,7 @@
#include <sstream>
#include <vector>
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
#include "cmCTest.h"
#include "cmCTestConfigureHandler.h"
@@ -69,12 +69,11 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler()
bool multiConfig = false;
bool cmakeBuildTypeInOptions = false;
- cmGlobalGenerator* gg =
- this->Makefile->GetCMakeInstance()->CreateGlobalGenerator(
- cmakeGeneratorName);
+ auto gg = this->Makefile->GetCMakeInstance()->CreateGlobalGenerator(
+ cmakeGeneratorName);
if (gg) {
multiConfig = gg->IsMultiConfig();
- delete gg;
+ gg.reset();
}
std::string cmakeConfigureCommand =
diff --git a/Source/CTest/cmCTestCoverageCommand.cxx b/Source/CTest/cmCTestCoverageCommand.cxx
index d6e6be3..7432d08 100644
--- a/Source/CTest/cmCTestCoverageCommand.cxx
+++ b/Source/CTest/cmCTestCoverageCommand.cxx
@@ -4,9 +4,9 @@
#include <set>
-#include "cm_static_string_view.hxx"
+#include <cmext/algorithm>
+#include <cmext/string_view>
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestCoverageHandler.h"
@@ -22,7 +22,7 @@ void cmCTestCoverageCommand::CheckArguments(
std::vector<std::string> const& keywords)
{
this->LabelsMentioned =
- !this->Labels.empty() || cmContains(keywords, "LABELS");
+ !this->Labels.empty() || cm::contains(keywords, "LABELS");
}
cmCTestGenericHandler* cmCTestCoverageCommand::InitializeHandler()
diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx
index 4cd783f..daa10c9 100644
--- a/Source/CTest/cmCTestCoverageHandler.cxx
+++ b/Source/CTest/cmCTestCoverageHandler.cxx
@@ -12,12 +12,13 @@
#include <sstream>
#include <utility>
+#include <cmext/algorithm>
+
#include "cmsys/FStream.hxx"
#include "cmsys/Glob.hxx"
#include "cmsys/Process.h"
#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmDuration.h"
#include "cmGeneratedFileStream.h"
@@ -679,8 +680,9 @@ void cmCTestCoverageHandler::PopulateCustomVectors(cmMakefile* mf)
//
#ifdef _WIN32
# define fnc(s) cmSystemTools::LowerCase(s)
+# define fnc_prefix(s, t) fnc(s.substr(0, t.size())) == fnc(t)
#else
-# define fnc(s) s
+# define fnc_prefix(s, t) cmHasPrefix(s, t)
#endif
bool IsFileInDir(const std::string& infile, const std::string& indir)
@@ -688,8 +690,8 @@ bool IsFileInDir(const std::string& infile, const std::string& indir)
std::string file = cmSystemTools::CollapseFullPath(infile);
std::string dir = cmSystemTools::CollapseFullPath(indir);
- return file.size() > dir.size() &&
- fnc(file.substr(0, dir.size())) == fnc(dir) && file[dir.size()] == '/';
+ return file.size() > dir.size() && fnc_prefix(file, dir) &&
+ file[dir.size()] == '/';
}
int cmCTestCoverageHandler::HandlePHPCoverage(
@@ -819,7 +821,7 @@ int cmCTestCoverageHandler::HandleJacocoCoverage(
std::string binaryDir = this->CTest->GetCTestConfiguration("BuildDirectory");
std::string binCoverageFile = binaryDir + "/*jacoco.xml";
g2.FindFiles(binCoverageFile);
- cmAppend(files, g2.GetFiles());
+ cm::append(files, g2.GetFiles());
if (!files.empty()) {
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
@@ -1462,7 +1464,7 @@ int cmCTestCoverageHandler::HandleLCovCoverage(
" looking for LCOV files in: " << daGlob << std::endl, this->Quiet);
gl.FindFiles(daGlob);
// Keep a list of all LCOV files
- cmAppend(lcovFiles, gl.GetFiles());
+ cm::append(lcovFiles, gl.GetFiles());
for (std::string const& file : lcovFiles) {
lcovFile = file;
@@ -1599,10 +1601,10 @@ void cmCTestCoverageHandler::FindGCovFiles(std::vector<std::string>& files)
" globbing for coverage in: " << lm.first << std::endl, this->Quiet);
std::string daGlob = cmStrCat(lm.first, "/*.da");
gl.FindFiles(daGlob);
- cmAppend(files, gl.GetFiles());
+ cm::append(files, gl.GetFiles());
daGlob = cmStrCat(lm.first, "/*.gcda");
gl.FindFiles(daGlob);
- cmAppend(files, gl.GetFiles());
+ cm::append(files, gl.GetFiles());
}
}
@@ -1638,7 +1640,7 @@ bool cmCTestCoverageHandler::FindLCovFiles(std::vector<std::string>& files)
"Error while finding files matching " << daGlob << std::endl);
return false;
}
- cmAppend(files, gl.GetFiles());
+ cm::append(files, gl.GetFiles());
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Now searching in: " << daGlob << std::endl, this->Quiet);
return true;
@@ -1708,29 +1710,26 @@ int cmCTestCoverageHandler::HandleTracePyCoverage(
// Read the coverage count from the beginning of the Trace.py output
// line
- std::string prefix = nl.substr(0, 6);
- if (prefix[5] != ' ' && prefix[5] != ':') {
- // This is a hack. We should really do something more elaborate
- prefix = nl.substr(0, 7);
- if (prefix[6] != ' ' && prefix[6] != ':') {
- prefix = nl.substr(0, 8);
- if (prefix[7] != ' ' && prefix[7] != ':') {
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- "Currently the limit is maximum coverage of 999999"
- << std::endl);
- }
+ std::string::size_type pos;
+ int cov = 0;
+ // This is a hack. We should really do something more elaborate
+ for (pos = 5; pos < 8; pos++) {
+ if (nl[pos] == ' ') {
+ // This line does not have ':' so no coverage here. That said,
+ // Trace.py does not handle not covered lines versus comments etc.
+ // So, this will be set to 0.
+ break;
+ }
+ if (nl[pos] == ':') {
+ cov = atoi(nl.substr(0, pos - 1).c_str());
+ break;
}
}
- int cov = atoi(prefix.c_str());
- if (prefix[prefix.size() - 1] != ':') {
- // This line does not have ':' so no coverage here. That said,
- // Trace.py does not handle not covered lines versus comments etc.
- // So, this will be set to 0.
- cov = 0;
+ if (pos == 8) {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Currently the limit is maximum coverage of 999999"
+ << std::endl);
}
- cmCTestOptionalLog(
- this->CTest, DEBUG,
- "Prefix: " << prefix << " cov: " << cov << std::endl, this->Quiet);
// Read the line number starting at the 10th character of the gcov
// output line
long lineIdx = cnt;
diff --git a/Source/CTest/cmCTestCurl.cxx b/Source/CTest/cmCTestCurl.cxx
index ccac832..69c5793 100644
--- a/Source/CTest/cmCTestCurl.cxx
+++ b/Source/CTest/cmCTestCurl.cxx
@@ -5,7 +5,8 @@
#include <cstdio>
#include <ostream>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmCTest.h"
#include "cmCurl.h"
#include "cmStringAlgorithms.h"
@@ -46,15 +47,15 @@ size_t curlWriteMemoryCallback(void* ptr, size_t size, size_t nmemb,
{
int realsize = static_cast<int>(size * nmemb);
const char* chPtr = static_cast<char*>(ptr);
- cmAppend(*static_cast<std::vector<char>*>(data), chPtr, chPtr + realsize);
+ cm::append(*static_cast<std::vector<char>*>(data), chPtr, chPtr + realsize);
return realsize;
}
size_t curlDebugCallback(CURL* /*unused*/, curl_infotype /*unused*/,
char* chPtr, size_t size, void* data)
{
- cmAppend(*static_cast<std::vector<char>*>(data), chPtr, chPtr + size);
- return size;
+ cm::append(*static_cast<std::vector<char>*>(data), chPtr, chPtr + size);
+ return 0;
}
}
diff --git a/Source/CTest/cmCTestCurl.h b/Source/CTest/cmCTestCurl.h
index 9c5ba66..b0d7f07 100644
--- a/Source/CTest/cmCTestCurl.h
+++ b/Source/CTest/cmCTestCurl.h
@@ -8,7 +8,7 @@
#include <string>
#include <vector>
-#include "cm_curl.h"
+#include <cm3p/curl/curl.h>
class cmCTest;
diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx
index 3f3c107..568b091 100644
--- a/Source/CTest/cmCTestGIT.cxx
+++ b/Source/CTest/cmCTestGIT.cxx
@@ -6,6 +6,7 @@
#include <cstdio>
#include <cstdlib>
#include <ctime>
+#include <utility>
#include <vector>
#include "cmsys/FStream.hxx"
@@ -193,7 +194,8 @@ bool cmCTestGIT::UpdateByFetchAndReset()
if (line.find("\tnot-for-merge\t") == std::string::npos) {
std::string::size_type pos = line.find('\t');
if (pos != std::string::npos) {
- sha1 = line.substr(0, pos);
+ sha1 = std::move(line);
+ sha1.resize(pos);
}
}
}
diff --git a/Source/CTest/cmCTestHG.cxx b/Source/CTest/cmCTestHG.cxx
index 3265498..5f4581e 100644
--- a/Source/CTest/cmCTestHG.cxx
+++ b/Source/CTest/cmCTestHG.cxx
@@ -5,9 +5,10 @@
#include <ostream>
#include <vector>
+#include <cmext/algorithm>
+
#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestVC.h"
#include "cmProcessTools.h"
@@ -204,7 +205,7 @@ private:
void CharacterDataHandler(const char* data, int length) override
{
- cmAppend(this->CData, data, data + length);
+ cm::append(this->CData, data, data + length);
}
void EndElement(const std::string& name) override
diff --git a/Source/CTest/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx
index b1034c9..a755632 100644
--- a/Source/CTest/cmCTestHandlerCommand.cxx
+++ b/Source/CTest/cmCTestHandlerCommand.cxx
@@ -7,7 +7,7 @@
#include <cstring>
#include <sstream>
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
#include "cmCTest.h"
#include "cmCTestGenericHandler.h"
diff --git a/Source/CTest/cmCTestMemCheckCommand.cxx b/Source/CTest/cmCTestMemCheckCommand.cxx
index 39dec6d..d0e2974 100644
--- a/Source/CTest/cmCTestMemCheckCommand.cxx
+++ b/Source/CTest/cmCTestMemCheckCommand.cxx
@@ -2,7 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestMemCheckCommand.h"
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
#include "cmCTest.h"
#include "cmCTestMemCheckHandler.h"
diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx
index a5ec1ae..85b8ab1 100644
--- a/Source/CTest/cmCTestMemCheckHandler.cxx
+++ b/Source/CTest/cmCTestMemCheckHandler.cxx
@@ -2,12 +2,16 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestMemCheckHandler.h"
+#include <algorithm>
#include <chrono>
#include <cstring>
#include <iostream>
+#include <iterator>
#include <sstream>
#include <utility>
+#include <cmext/algorithm>
+
#include "cmsys/FStream.hxx"
#include "cmsys/Glob.hxx"
#include "cmsys/RegularExpression.hxx"
@@ -162,12 +166,13 @@ int cmCTestMemCheckHandler::PostProcessHandler()
void cmCTestMemCheckHandler::GenerateTestCommand(
std::vector<std::string>& args, int test)
{
- std::string index;
- std::ostringstream stream;
+ std::string index = std::to_string(test);
std::string memcheckcommand =
cmSystemTools::ConvertToOutputPath(this->MemoryTester);
- stream << test;
- index = stream.str();
+
+ std::vector<std::string> dirs;
+ bool nextArgIsDir = false;
+
for (std::string arg : this->MemoryTesterDynamicOptions) {
std::string::size_type pos = arg.find("??");
if (pos != std::string::npos) {
@@ -177,6 +182,16 @@ void cmCTestMemCheckHandler::GenerateTestCommand(
memcheckcommand += " \"";
memcheckcommand += arg;
memcheckcommand += "\"";
+
+ if (nextArgIsDir) {
+ nextArgIsDir = false;
+ dirs.push_back(arg);
+ }
+
+ if (this->MemoryTesterStyle == cmCTestMemCheckHandler::DRMEMORY &&
+ (arg == "-logdir" || arg == "-symcache_dir")) {
+ nextArgIsDir = true;
+ }
}
// Create a copy of the memory tester environment variable.
// This is used for memory testing programs that pass options
@@ -208,6 +223,11 @@ void cmCTestMemCheckHandler::GenerateTestCommand(
memcheckcommand += " " + memTesterEnvironmentVariable;
args.push_back(memTesterEnvironmentVariable);
}
+
+ for (std::string const& dir : dirs) {
+ cmSystemTools::MakeDirectory(dir);
+ }
+
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Memory check command: " << memcheckcommand << std::endl,
this->Quiet);
@@ -278,9 +298,6 @@ void cmCTestMemCheckHandler::PopulateCustomVectors(cmMakefile* mf)
this->CTest->PopulateCustomVector(mf, "CTEST_CUSTOM_MEMCHECK_IGNORE",
this->CustomTestsIgnore);
- std::string cmake = cmSystemTools::GetCMakeCommand();
- this->CTest->SetCTestConfiguration("CMakeCommand", cmake.c_str(),
- this->Quiet);
}
int cmCTestMemCheckHandler::GetDefectCount()
@@ -300,6 +317,9 @@ void cmCTestMemCheckHandler::GenerateDartOutput(cmXMLWriter& xml)
case cmCTestMemCheckHandler::VALGRIND:
xml.Attribute("Checker", "Valgrind");
break;
+ case cmCTestMemCheckHandler::DRMEMORY:
+ xml.Attribute("Checker", "DrMemory");
+ break;
case cmCTestMemCheckHandler::PURIFY:
xml.Attribute("Checker", "Purify");
break;
@@ -387,11 +407,11 @@ void cmCTestMemCheckHandler::GenerateDartOutput(cmXMLWriter& xml)
}
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
"MemCheck log files can be found here: "
- "( * corresponds to test number)"
+ "(<#> corresponds to test number)"
<< std::endl,
this->Quiet);
std::string output = this->MemoryTesterOutputFile;
- cmSystemTools::ReplaceString(output, "??", "*");
+ cmSystemTools::ReplaceString(output, "??", "<#>");
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, output << std::endl,
this->Quiet);
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
@@ -437,6 +457,10 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
if (testerName.find("valgrind") != std::string::npos ||
this->CTest->GetCTestConfiguration("MemoryCheckType") == "Valgrind") {
this->MemoryTesterStyle = cmCTestMemCheckHandler::VALGRIND;
+ } else if (testerName.find("drmemory") != std::string::npos ||
+ this->CTest->GetCTestConfiguration("MemoryCheckType") ==
+ "DrMemory") {
+ this->MemoryTesterStyle = cmCTestMemCheckHandler::DRMEMORY;
} else if (testerName.find("purify") != std::string::npos) {
this->MemoryTesterStyle = cmCTestMemCheckHandler::PURIFY;
} else if (testerName.find("BC") != std::string::npos) {
@@ -453,6 +477,10 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
this->MemoryTester = this->CTest->GetCTestConfiguration("ValgrindCommand");
this->MemoryTesterStyle = cmCTestMemCheckHandler::VALGRIND;
} else if (cmSystemTools::FileExists(
+ this->CTest->GetCTestConfiguration("DrMemoryCommand"))) {
+ this->MemoryTester = this->CTest->GetCTestConfiguration("DrMemoryCommand");
+ this->MemoryTesterStyle = cmCTestMemCheckHandler::DRMEMORY;
+ } else if (cmSystemTools::FileExists(
this->CTest->GetCTestConfiguration("BoundsCheckerCommand"))) {
this->MemoryTester =
this->CTest->GetCTestConfiguration("BoundsCheckerCommand");
@@ -460,31 +488,31 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
}
if (this->CTest->GetCTestConfiguration("MemoryCheckType") ==
"AddressSanitizer") {
- this->MemoryTester = this->CTest->GetCTestConfiguration("CMakeCommand");
+ this->MemoryTester = cmSystemTools::GetCMakeCommand();
this->MemoryTesterStyle = cmCTestMemCheckHandler::ADDRESS_SANITIZER;
this->LogWithPID = true; // even if we give the log file the pid is added
}
if (this->CTest->GetCTestConfiguration("MemoryCheckType") ==
"LeakSanitizer") {
- this->MemoryTester = this->CTest->GetCTestConfiguration("CMakeCommand");
+ this->MemoryTester = cmSystemTools::GetCMakeCommand();
this->MemoryTesterStyle = cmCTestMemCheckHandler::LEAK_SANITIZER;
this->LogWithPID = true; // even if we give the log file the pid is added
}
if (this->CTest->GetCTestConfiguration("MemoryCheckType") ==
"ThreadSanitizer") {
- this->MemoryTester = this->CTest->GetCTestConfiguration("CMakeCommand");
+ this->MemoryTester = cmSystemTools::GetCMakeCommand();
this->MemoryTesterStyle = cmCTestMemCheckHandler::THREAD_SANITIZER;
this->LogWithPID = true; // even if we give the log file the pid is added
}
if (this->CTest->GetCTestConfiguration("MemoryCheckType") ==
"MemorySanitizer") {
- this->MemoryTester = this->CTest->GetCTestConfiguration("CMakeCommand");
+ this->MemoryTester = cmSystemTools::GetCMakeCommand();
this->MemoryTesterStyle = cmCTestMemCheckHandler::MEMORY_SANITIZER;
this->LogWithPID = true; // even if we give the log file the pid is added
}
if (this->CTest->GetCTestConfiguration("MemoryCheckType") ==
"UndefinedBehaviorSanitizer") {
- this->MemoryTester = this->CTest->GetCTestConfiguration("CMakeCommand");
+ this->MemoryTester = cmSystemTools::GetCMakeCommand();
this->MemoryTesterStyle = cmCTestMemCheckHandler::UB_SANITIZER;
this->LogWithPID = true; // even if we give the log file the pid is added
}
@@ -498,6 +526,8 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
this->MemoryTesterStyle = cmCTestMemCheckHandler::BOUNDS_CHECKER;
} else if (checkType == "Valgrind") {
this->MemoryTesterStyle = cmCTestMemCheckHandler::VALGRIND;
+ } else if (checkType == "DrMemory") {
+ this->MemoryTesterStyle = cmCTestMemCheckHandler::DRMEMORY;
}
}
if (this->MemoryTester.empty()) {
@@ -519,6 +549,10 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
.empty()) {
memoryTesterOptions =
this->CTest->GetCTestConfiguration("ValgrindCommandOptions");
+ } else if (!this->CTest->GetCTestConfiguration("DrMemoryCommandOptions")
+ .empty()) {
+ memoryTesterOptions =
+ this->CTest->GetCTestConfiguration("DrMemoryCommandOptions");
}
this->MemoryTesterOptions =
cmSystemTools::ParseArguments(memoryTesterOptions);
@@ -554,6 +588,64 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
this->MemoryTesterOutputFile);
break;
}
+ case cmCTestMemCheckHandler::DRMEMORY: {
+ std::string tempDrMemoryDir =
+ this->CTest->GetBinaryDir() + "/Testing/Temporary/DrMemory";
+
+ if (!cm::contains(this->MemoryTesterOptions, "-quiet")) {
+ this->MemoryTesterOptions.emplace_back("-quiet");
+ }
+
+ if (!cm::contains(this->MemoryTesterOptions, "-batch")) {
+ this->MemoryTesterOptions.emplace_back("-batch");
+ }
+
+ this->MemoryTesterDynamicOptions.emplace_back("-logdir");
+ auto logdirOption =
+ std::find(this->MemoryTesterOptions.begin(),
+ this->MemoryTesterOptions.end(), "-logdir");
+ if (logdirOption == this->MemoryTesterOptions.end()) {
+ // No logdir found in memory tester options
+ std::string drMemoryLogDir = tempDrMemoryDir + "/??";
+ this->MemoryTesterDynamicOptions.push_back(drMemoryLogDir);
+ this->MemoryTesterOutputFile = drMemoryLogDir;
+ } else {
+ // Use logdir found in memory tester options
+ auto logdirLocation = std::next(logdirOption);
+ this->MemoryTesterOutputFile = *logdirLocation;
+ this->MemoryTesterDynamicOptions.push_back(*logdirLocation);
+ this->MemoryTesterOptions.erase(logdirOption, logdirLocation + 1);
+ }
+ this->MemoryTesterOutputFile += "/*/results.txt";
+
+ if (std::find(this->MemoryTesterOptions.begin(),
+ this->MemoryTesterOptions.end(),
+ "-symcache_dir") == this->MemoryTesterOptions.end()) {
+ this->MemoryTesterDynamicOptions.emplace_back("-symcache_dir");
+ std::string drMemoryCacheDir = tempDrMemoryDir + "/cache";
+ this->MemoryTesterDynamicOptions.push_back(drMemoryCacheDir);
+ }
+
+ if (!this->CTest->GetCTestConfiguration("MemoryCheckSuppressionFile")
+ .empty()) {
+ if (!cmSystemTools::FileExists(this->CTest->GetCTestConfiguration(
+ "MemoryCheckSuppressionFile"))) {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Cannot find memory checker suppression file: "
+ << this->CTest->GetCTestConfiguration(
+ "MemoryCheckSuppressionFile")
+ << std::endl);
+ return false;
+ }
+ this->MemoryTesterOptions.emplace_back("-suppress");
+ this->MemoryTesterOptions.push_back(
+ this->CTest->GetCTestConfiguration("MemoryCheckSuppressionFile"));
+ }
+
+ this->MemoryTesterOptions.emplace_back("--");
+
+ break;
+ }
case cmCTestMemCheckHandler::PURIFY: {
std::string outputFile;
#ifdef _WIN32
@@ -667,6 +759,8 @@ bool cmCTestMemCheckHandler::ProcessMemCheckOutput(const std::string& str,
switch (this->MemoryTesterStyle) {
case cmCTestMemCheckHandler::VALGRIND:
return this->ProcessMemCheckValgrindOutput(str, log, results);
+ case cmCTestMemCheckHandler::DRMEMORY:
+ return this->ProcessMemCheckDrMemoryOutput(str, log, results);
case cmCTestMemCheckHandler::PURIFY:
return this->ProcessMemCheckPurifyOutput(str, log, results);
case cmCTestMemCheckHandler::ADDRESS_SANITIZER:
@@ -861,35 +955,25 @@ bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput(
"valgrind line " << lines[cc] << std::endl,
this->Quiet);
int failure = cmCTestMemCheckHandler::NO_MEMORY_FAULT;
- if (vgFIM.find(lines[cc])) {
+ auto& line = lines[cc];
+ if (vgFIM.find(line)) {
failure = cmCTestMemCheckHandler::FIM;
- } else if (vgFMM.find(lines[cc])) {
+ } else if (vgFMM.find(line)) {
failure = cmCTestMemCheckHandler::FMM;
- } else if (vgMLK1.find(lines[cc])) {
- failure = cmCTestMemCheckHandler::MLK;
- } else if (vgMLK2.find(lines[cc])) {
+ } else if (vgMLK1.find(line) || vgMLK2.find(line)) {
failure = cmCTestMemCheckHandler::MLK;
- } else if (vgPAR.find(lines[cc])) {
+ } else if (vgPAR.find(line)) {
failure = cmCTestMemCheckHandler::PAR;
- } else if (vgMPK1.find(lines[cc])) {
- failure = cmCTestMemCheckHandler::MPK;
- } else if (vgMPK2.find(lines[cc])) {
+ } else if (vgMPK1.find(line) || vgMPK2.find(line)) {
failure = cmCTestMemCheckHandler::MPK;
- } else if (vgUMC.find(lines[cc])) {
+ } else if (vgUMC.find(line)) {
failure = cmCTestMemCheckHandler::UMC;
- } else if (vgUMR1.find(lines[cc])) {
- failure = cmCTestMemCheckHandler::UMR;
- } else if (vgUMR2.find(lines[cc])) {
- failure = cmCTestMemCheckHandler::UMR;
- } else if (vgUMR3.find(lines[cc])) {
- failure = cmCTestMemCheckHandler::UMR;
- } else if (vgUMR4.find(lines[cc])) {
+ } else if (vgUMR1.find(line) || vgUMR2.find(line) || vgUMR3.find(line) ||
+ vgUMR4.find(line) || vgUMR5.find(line)) {
failure = cmCTestMemCheckHandler::UMR;
- } else if (vgUMR5.find(lines[cc])) {
- failure = cmCTestMemCheckHandler::UMR;
- } else if (vgIPW.find(lines[cc])) {
+ } else if (vgIPW.find(line)) {
failure = cmCTestMemCheckHandler::IPW;
- } else if (vgABR.find(lines[cc])) {
+ } else if (vgABR.find(line)) {
failure = cmCTestMemCheckHandler::ABR;
}
@@ -932,6 +1016,43 @@ bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput(
return defects == 0;
}
+bool cmCTestMemCheckHandler::ProcessMemCheckDrMemoryOutput(
+ const std::string& str, std::string& log, std::vector<int>& results)
+{
+ std::vector<std::string> lines;
+ cmsys::SystemTools::Split(str, lines);
+
+ cmsys::RegularExpression drMemoryError("^Error #[0-9]+");
+
+ cmsys::RegularExpression unaddressableAccess("UNADDRESSABLE ACCESS");
+ cmsys::RegularExpression uninitializedRead("UNINITIALIZED READ");
+ cmsys::RegularExpression invalidHeapArgument("INVALID HEAP ARGUMENT");
+ cmsys::RegularExpression leak("LEAK");
+ cmsys::RegularExpression handleLeak("HANDLE LEAK");
+
+ int defects = 0;
+
+ std::ostringstream ostr;
+ for (const auto& l : lines) {
+ ostr << l << std::endl;
+ if (drMemoryError.find(l)) {
+ defects++;
+ if (unaddressableAccess.find(l) || uninitializedRead.find(l)) {
+ results[cmCTestMemCheckHandler::UMR]++;
+ } else if (leak.find(l) || handleLeak.find(l)) {
+ results[cmCTestMemCheckHandler::MLK]++;
+ } else if (invalidHeapArgument.find(l)) {
+ results[cmCTestMemCheckHandler::FMM]++;
+ }
+ }
+ }
+
+ log = ostr.str();
+
+ this->DefectCount += defects;
+ return defects == 0;
+}
+
bool cmCTestMemCheckHandler::ProcessMemCheckBoundsCheckerOutput(
const std::string& str, std::string& log, std::vector<int>& results)
{
@@ -991,6 +1112,8 @@ void cmCTestMemCheckHandler::PostProcessTest(cmCTestTestResult& res, int test)
this->Quiet);
if (this->MemoryTesterStyle == cmCTestMemCheckHandler::BOUNDS_CHECKER) {
this->PostProcessBoundsCheckerTest(res, test);
+ } else if (this->MemoryTesterStyle == cmCTestMemCheckHandler::DRMEMORY) {
+ this->PostProcessDrMemoryTest(res, test);
} else {
std::vector<std::string> files;
this->TestOutputFileNames(test, files);
@@ -1045,6 +1168,37 @@ void cmCTestMemCheckHandler::PostProcessBoundsCheckerTest(
this->Quiet);
}
+void cmCTestMemCheckHandler::PostProcessDrMemoryTest(
+ cmCTestTestHandler::cmCTestTestResult& res, int test)
+{
+ std::string drMemoryLogDir = this->MemoryTesterOutputFile.substr(
+ 0, this->MemoryTesterOutputFile.find("/*/results.txt"));
+
+ // replace placeholder of test
+ std::string::size_type pos = drMemoryLogDir.find("??");
+ if (pos != std::string::npos) {
+ drMemoryLogDir.replace(pos, 2, std::to_string(test));
+ }
+
+ cmsys::Glob g;
+ g.FindFiles(drMemoryLogDir + "/resfile.*");
+ const std::vector<std::string>& files = g.GetFiles();
+
+ for (const std::string& f : files) {
+ cmsys::ifstream ifs(f.c_str());
+ if (!ifs) {
+ std::string log = "Cannot read memory tester output file: " + f;
+ cmCTestLog(this->CTest, ERROR_MESSAGE, log << std::endl);
+ return;
+ }
+ std::string resultFileLocation;
+ cmSystemTools::GetLineFromStream(ifs, resultFileLocation);
+ this->AppendMemTesterOutput(res, resultFileLocation);
+ ifs.close();
+ cmSystemTools::RemoveFile(f);
+ }
+}
+
void cmCTestMemCheckHandler::AppendMemTesterOutput(cmCTestTestResult& res,
std::string const& ofile)
{
diff --git a/Source/CTest/cmCTestMemCheckHandler.h b/Source/CTest/cmCTestMemCheckHandler.h
index eda65f7..52667f8 100644
--- a/Source/CTest/cmCTestMemCheckHandler.h
+++ b/Source/CTest/cmCTestMemCheckHandler.h
@@ -43,6 +43,7 @@ private:
UNKNOWN = 0,
VALGRIND,
PURIFY,
+ DRMEMORY,
BOUNDS_CHECKER,
// checkers after here do not use the standard error list
ADDRESS_SANITIZER,
@@ -132,6 +133,8 @@ private:
std::vector<int>& results);
bool ProcessMemCheckValgrindOutput(const std::string& str, std::string& log,
std::vector<int>& results);
+ bool ProcessMemCheckDrMemoryOutput(const std::string& str, std::string& log,
+ std::vector<int>& results);
bool ProcessMemCheckPurifyOutput(const std::string& str, std::string& log,
std::vector<int>& results);
bool ProcessMemCheckSanitizerOutput(const std::string& str, std::string& log,
@@ -142,6 +145,7 @@ private:
void PostProcessTest(cmCTestTestResult& res, int test);
void PostProcessBoundsCheckerTest(cmCTestTestResult& res, int test);
+ void PostProcessDrMemoryTest(cmCTestTestResult& res, int test);
//! append MemoryTesterOutputFile to the test log
void AppendMemTesterOutput(cmCTestTestHandler::cmCTestTestResult& res,
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx
index 02d396e..a08cb34 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.cxx
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -6,28 +6,29 @@
#include <cassert>
#include <chrono>
#include <cmath>
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <list>
-#include <memory>
#include <sstream>
#include <stack>
#include <unordered_map>
#include <utility>
#include <vector>
+#include <cm/memory>
+#include <cmext/algorithm>
+
+#include <cm3p/json/value.h>
+#include <cm3p/json/writer.h>
+#include <cm3p/uv.h>
+
#include "cmsys/FStream.hxx"
#include "cmsys/SystemInformation.hxx"
-#include "cm_jsoncpp_value.h"
-#include "cm_jsoncpp_writer.h"
-#include "cm_uv.h"
-
#include "cmAffinity.h"
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestBinPacker.h"
#include "cmCTestRunTest.h"
@@ -136,7 +137,7 @@ void cmCTestMultiProcessHandler::RunTests()
uv_run(&this->Loop, UV_RUN_DEFAULT);
uv_loop_close(&this->Loop);
- if (!this->StopTimePassed) {
+ if (!this->StopTimePassed && !this->CheckStopOnFailure()) {
assert(this->Completed == this->Total);
assert(this->Tests.empty());
}
@@ -170,10 +171,11 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test)
this->EraseTest(test);
this->RunningCount += GetProcessorsUsed(test);
- cmCTestRunTest* testRun = new cmCTestRunTest(*this);
- if (this->CTest->GetRepeatUntilFail()) {
- testRun->SetRunUntilFailOn();
- testRun->SetNumberOfRuns(this->CTest->GetTestRepeat());
+ auto testRun = cm::make_unique<cmCTestRunTest>(*this);
+
+ if (this->RepeatMode != cmCTest::Repeat::Never) {
+ testRun->SetRepeatMode(this->RepeatMode);
+ testRun->SetNumberOfRuns(this->RepeatCount);
}
testRun->SetIndex(test);
testRun->SetTestProperties(this->Properties[test]);
@@ -185,7 +187,7 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test)
// Find any failed dependencies for this test. We assume the more common
// scenario has no failed tests, so make it the outer loop.
for (std::string const& f : *this->Failed) {
- if (cmContains(this->Properties[test]->RequireSuccessDepends, f)) {
+ if (cm::contains(this->Properties[test]->RequireSuccessDepends, f)) {
testRun->AddFailedDependency(f);
}
}
@@ -194,28 +196,58 @@ bool cmCTestMultiProcessHandler::StartTestProcess(int test)
// working directory because FinishTestProcess() will try to unlock them
this->LockResources(test);
- if (!this->TestsHaveSufficientResources[test]) {
- testRun->StartFailure("Insufficient resources");
- this->FinishTestProcess(testRun, false);
+ if (!this->ResourceAllocationErrors[test].empty()) {
+ std::ostringstream e;
+ e << "Insufficient resources for test " << this->Properties[test]->Name
+ << ":\n\n";
+ for (auto const& it : this->ResourceAllocationErrors[test]) {
+ switch (it.second) {
+ case ResourceAllocationError::NoResourceType:
+ e << " Test requested resources of type '" << it.first
+ << "' which does not exist\n";
+ break;
+
+ case ResourceAllocationError::InsufficientResources:
+ e << " Test requested resources of type '" << it.first
+ << "' in the following amounts:\n";
+ for (auto const& group : this->Properties[test]->ResourceGroups) {
+ for (auto const& requirement : group) {
+ if (requirement.ResourceType == it.first) {
+ e << " " << requirement.SlotsNeeded
+ << (requirement.SlotsNeeded == 1 ? " slot\n" : " slots\n");
+ }
+ }
+ }
+ e << " but only the following units were available:\n";
+ for (auto const& res :
+ this->ResourceAllocator.GetResources().at(it.first)) {
+ e << " '" << res.first << "': " << res.second.Total
+ << (res.second.Total == 1 ? " slot\n" : " slots\n");
+ }
+ break;
+ }
+ e << "\n";
+ }
+ e << "Resource spec file:\n\n " << this->TestHandler->ResourceSpecFile;
+ cmCTestRunTest::StartFailure(std::move(testRun), e.str(),
+ "Insufficient resources");
return false;
}
cmWorkingDirectory workdir(this->Properties[test]->Directory);
if (workdir.Failed()) {
- testRun->StartFailure("Failed to change working directory to " +
- this->Properties[test]->Directory + " : " +
- std::strerror(workdir.GetLastResult()));
- } else {
- if (testRun->StartTest(this->Completed, this->Total)) {
- // Ownership of 'testRun' has moved to another structure.
- // When the test finishes, FinishTestProcess will be called.
- return true;
- }
+ cmCTestRunTest::StartFailure(std::move(testRun),
+ "Failed to change working directory to " +
+ this->Properties[test]->Directory + " : " +
+ std::strerror(workdir.GetLastResult()),
+ "Failed to change working directory");
+ return false;
}
- // Pass ownership of 'testRun'.
- this->FinishTestProcess(testRun, false);
- return false;
+ // Ownership of 'testRun' has moved to another structure.
+ // When the test finishes, FinishTestProcess will be called.
+ return cmCTestRunTest::StartTest(std::move(testRun), this->Completed,
+ this->Total);
}
bool cmCTestMultiProcessHandler::AllocateResources(int index)
@@ -247,7 +279,8 @@ bool cmCTestMultiProcessHandler::AllocateResources(int index)
bool cmCTestMultiProcessHandler::TryAllocateResources(
int index,
- std::map<std::string, std::vector<cmCTestBinPackerAllocation>>& allocations)
+ std::map<std::string, std::vector<cmCTestBinPackerAllocation>>& allocations,
+ std::map<std::string, ResourceAllocationError>* errors)
{
allocations.clear();
@@ -262,18 +295,28 @@ bool cmCTestMultiProcessHandler::TryAllocateResources(
++processIndex;
}
+ bool result = true;
auto const& availableResources = this->ResourceAllocator.GetResources();
for (auto& it : allocations) {
if (!availableResources.count(it.first)) {
- return false;
- }
- if (!cmAllocateCTestResourcesRoundRobin(availableResources.at(it.first),
- it.second)) {
- return false;
+ if (errors) {
+ (*errors)[it.first] = ResourceAllocationError::NoResourceType;
+ result = false;
+ } else {
+ return false;
+ }
+ } else if (!cmAllocateCTestResourcesRoundRobin(
+ availableResources.at(it.first), it.second)) {
+ if (errors) {
+ (*errors)[it.first] = ResourceAllocationError::InsufficientResources;
+ result = false;
+ } else {
+ return false;
+ }
}
}
- return true;
+ return result;
}
void cmCTestMultiProcessHandler::DeallocateResources(int index)
@@ -314,14 +357,21 @@ bool cmCTestMultiProcessHandler::AllResourcesAvailable()
void cmCTestMultiProcessHandler::CheckResourcesAvailable()
{
- for (auto test : this->SortedTests) {
- std::map<std::string, std::vector<cmCTestBinPackerAllocation>> allocations;
- this->TestsHaveSufficientResources[test] =
- !this->TestHandler->UseResourceSpec ||
- this->TryAllocateResources(test, allocations);
+ if (this->TestHandler->UseResourceSpec) {
+ for (auto test : this->SortedTests) {
+ std::map<std::string, std::vector<cmCTestBinPackerAllocation>>
+ allocations;
+ this->TryAllocateResources(test, allocations,
+ &this->ResourceAllocationErrors[test]);
+ }
}
}
+bool cmCTestMultiProcessHandler::CheckStopOnFailure()
+{
+ return this->CTest->GetStopOnFailure();
+}
+
bool cmCTestMultiProcessHandler::CheckStopTimePassed()
{
if (!this->StopTimePassed) {
@@ -399,13 +449,13 @@ bool cmCTestMultiProcessHandler::StartTest(int test)
{
// Check for locked resources
for (std::string const& i : this->Properties[test]->LockedResources) {
- if (cmContains(this->LockedResources, i)) {
+ if (cm::contains(this->LockedResources, i)) {
return false;
}
}
// Allocate resources
- if (this->TestsHaveSufficientResources[test] &&
+ if (this->ResourceAllocationErrors[test].empty() &&
!this->AllocateResources(test)) {
this->DeallocateResources(test);
return false;
@@ -438,6 +488,10 @@ void cmCTestMultiProcessHandler::StartNextTests()
return;
}
+ if (this->CheckStopOnFailure() && !this->Failed->empty()) {
+ return;
+ }
+
size_t numToStart = 0;
if (this->RunningCount < this->ParallelLevel) {
@@ -492,7 +546,8 @@ void cmCTestMultiProcessHandler::StartNextTests()
if (this->SerialTestRunning) {
break;
}
- // We can only start a RUN_SERIAL test if no other tests are also running.
+ // We can only start a RUN_SERIAL test if no other tests are also
+ // running.
if (this->Properties[test]->RunSerial && this->RunningCount > 0) {
continue;
}
@@ -570,8 +625,8 @@ void cmCTestMultiProcessHandler::OnTestLoadRetryCB(uv_timer_t* timer)
self->StartNextTests();
}
-void cmCTestMultiProcessHandler::FinishTestProcess(cmCTestRunTest* runner,
- bool started)
+void cmCTestMultiProcessHandler::FinishTestProcess(
+ std::unique_ptr<cmCTestRunTest> runner, bool started)
{
this->Completed++;
@@ -583,7 +638,8 @@ void cmCTestMultiProcessHandler::FinishTestProcess(cmCTestRunTest* runner,
this->SetStopTimePassed();
}
if (started) {
- if (!this->StopTimePassed && runner->StartAgain(this->Completed)) {
+ if (!this->StopTimePassed &&
+ cmCTestRunTest::StartAgain(std::move(runner), this->Completed)) {
this->Completed--; // remove the completed test because run again
return;
}
@@ -611,7 +667,7 @@ void cmCTestMultiProcessHandler::FinishTestProcess(cmCTestRunTest* runner,
}
properties->Affinity.clear();
- delete runner;
+ runner.reset();
if (started) {
this->StartNextTests();
}
@@ -754,7 +810,7 @@ void cmCTestMultiProcessHandler::CreateParallelTestCostList()
// In parallel test runs add previously failed tests to the front
// of the cost list and queue other tests for further sorting
for (auto const& t : this->Tests) {
- if (cmContains(this->LastTestsFailed, this->Properties[t.first]->Name)) {
+ if (cm::contains(this->LastTestsFailed, this->Properties[t.first]->Name)) {
// If the test failed last time, it should be run first.
this->SortedTests.push_back(t.first);
alreadySortedTests.insert(t.first);
@@ -788,12 +844,12 @@ void cmCTestMultiProcessHandler::CreateParallelTestCostList()
// Sort tests within each level by COST and append them to the cost list.
for (TestSet const& currentSet : cmReverseRange(priorityStack)) {
TestList sortedCopy;
- cmAppend(sortedCopy, currentSet);
+ cm::append(sortedCopy, currentSet);
std::stable_sort(sortedCopy.begin(), sortedCopy.end(),
TestComparator(this));
for (auto const& j : sortedCopy) {
- if (!cmContains(alreadySortedTests, j)) {
+ if (!cm::contains(alreadySortedTests, j)) {
this->SortedTests.push_back(j);
alreadySortedTests.insert(j);
}
@@ -825,7 +881,7 @@ void cmCTestMultiProcessHandler::CreateSerialTestCostList()
TestSet alreadySortedTests;
for (int test : presortedList) {
- if (cmContains(alreadySortedTests, test)) {
+ if (cm::contains(alreadySortedTests, test)) {
continue;
}
@@ -833,7 +889,7 @@ void cmCTestMultiProcessHandler::CreateSerialTestCostList()
GetAllTestDependencies(test, dependencies);
for (int testDependency : dependencies) {
- if (!cmContains(alreadySortedTests, testDependency)) {
+ if (!cm::contains(alreadySortedTests, testDependency)) {
alreadySortedTests.insert(testDependency);
this->SortedTests.push_back(testDependency);
}
@@ -1154,7 +1210,7 @@ static Json::Value DumpCTestInfo(
const std::vector<std::string>& args = testRun.GetArguments();
if (!args.empty()) {
commandAndArgs.reserve(args.size() + 1);
- cmAppend(commandAndArgs, args);
+ cm::append(commandAndArgs, args);
}
testInfo["command"] = DumpToJsonArray(commandAndArgs);
}
diff --git a/Source/CTest/cmCTestMultiProcessHandler.h b/Source/CTest/cmCTestMultiProcessHandler.h
index 1db4bfd..e21b912 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.h
+++ b/Source/CTest/cmCTestMultiProcessHandler.h
@@ -6,19 +6,19 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <map>
+#include <memory>
#include <set>
#include <string>
#include <vector>
+#include <cm3p/uv.h>
#include <stddef.h>
-#include "cm_uv.h"
-
+#include "cmCTest.h"
#include "cmCTestResourceAllocator.h"
#include "cmCTestTestHandler.h"
#include "cmUVHandlePtr.h"
-class cmCTest;
struct cmCTestBinPackerAllocation;
class cmCTestResourceSpec;
class cmCTestRunTest;
@@ -85,6 +85,12 @@ public:
cmCTestTestHandler* GetTestHandler() { return this->TestHandler; }
+ void SetRepeatMode(cmCTest::Repeat mode, int count)
+ {
+ this->RepeatMode = mode;
+ this->RepeatCount = count;
+ }
+
void SetQuiet(bool b) { this->Quiet = b; }
void InitResourceAllocator(const cmCTestResourceSpec& spec)
@@ -118,7 +124,7 @@ protected:
// Removes the checkpoint file
void MarkFinished();
void EraseTest(int index);
- void FinishTestProcess(cmCTestRunTest* runner, bool started);
+ void FinishTestProcess(std::unique_ptr<cmCTestRunTest> runner, bool started);
static void OnTestLoadRetryCB(uv_timer_t* timer);
@@ -131,17 +137,26 @@ protected:
inline size_t GetProcessorsUsed(int index);
std::string GetName(int index);
+ bool CheckStopOnFailure();
+
bool CheckStopTimePassed();
void SetStopTimePassed();
void LockResources(int index);
void UnlockResources(int index);
+ enum class ResourceAllocationError
+ {
+ NoResourceType,
+ InsufficientResources,
+ };
+
bool AllocateResources(int index);
bool TryAllocateResources(
int index,
std::map<std::string, std::vector<cmCTestBinPackerAllocation>>&
- allocations);
+ allocations,
+ std::map<std::string, ResourceAllocationError>* errors = nullptr);
void DeallocateResources(int index);
bool AllResourcesAvailable();
@@ -168,7 +183,8 @@ protected:
std::map<int,
std::vector<std::map<std::string, std::vector<ResourceAllocation>>>>
AllocatedResources;
- std::map<int, bool> TestsHaveSufficientResources;
+ std::map<int, std::map<std::string, ResourceAllocationError>>
+ ResourceAllocationErrors;
cmCTestResourceAllocator ResourceAllocator;
std::vector<cmCTestTestHandler::cmCTestTestResult>* TestResults;
size_t ParallelLevel; // max number of process that can be run at once
@@ -179,6 +195,8 @@ protected:
cmCTestTestHandler* TestHandler;
cmCTest* CTest;
bool HasCycles;
+ cmCTest::Repeat RepeatMode = cmCTest::Repeat::Never;
+ int RepeatCount = 1;
bool Quiet;
bool SerialTestRunning;
};
diff --git a/Source/CTest/cmCTestP4.cxx b/Source/CTest/cmCTestP4.cxx
index e2063e1..1375be4 100644
--- a/Source/CTest/cmCTestP4.cxx
+++ b/Source/CTest/cmCTestP4.cxx
@@ -7,9 +7,10 @@
#include <ostream>
#include <utility>
+#include <cmext/algorithm>
+
#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestVC.h"
#include "cmProcessTools.h"
@@ -326,7 +327,7 @@ void cmCTestP4::SetP4Options(std::vector<char const*>& CommandOptions)
// The CTEST_P4_OPTIONS variable adds additional Perforce command line
// options before the main command
std::string opts = this->CTest->GetCTestConfiguration("P4Options");
- cmAppend(P4Options, cmSystemTools::ParseArguments(opts));
+ cm::append(P4Options, cmSystemTools::ParseArguments(opts));
}
CommandOptions.clear();
diff --git a/Source/CTest/cmCTestResourceSpec.cxx b/Source/CTest/cmCTestResourceSpec.cxx
index 8f91efb..21c97de 100644
--- a/Source/CTest/cmCTestResourceSpec.cxx
+++ b/Source/CTest/cmCTestResourceSpec.cxx
@@ -7,12 +7,12 @@
#include <utility>
#include <vector>
+#include <cm3p/json/reader.h>
+#include <cm3p/json/value.h>
+
#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"
-#include "cm_jsoncpp_reader.h"
-#include "cm_jsoncpp_value.h"
-
static const cmsys::RegularExpression IdentifierRegex{ "^[a-z_][a-z0-9_]*$" };
static const cmsys::RegularExpression IdRegex{ "^[a-z0-9_]+$" };
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index 3091050..7674d7a 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -3,7 +3,7 @@
#include "cmCTestRunTest.h"
#include <chrono>
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
#include <cstdint>
#include <cstdio>
#include <cstring>
@@ -34,9 +34,6 @@ cmCTestRunTest::cmCTestRunTest(cmCTestMultiProcessHandler& multiHandler)
this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
this->TestResult.TestCount = 0;
this->TestResult.Properties = nullptr;
- this->NumberOfRunsLeft = 1; // default to 1 run of the test
- this->RunUntilFail = false; // default to run the test once
- this->RunAgain = false; // default to not having to run again
}
void cmCTestRunTest::CheckOutput(std::string const& line)
@@ -310,43 +307,52 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
}
// If the test does not need to rerun push the current TestResult onto the
// TestHandler vector
- if (!this->NeedsToRerun()) {
+ if (!this->NeedsToRepeat()) {
this->TestHandler->TestResults.push_back(this->TestResult);
}
this->TestProcess.reset();
return passed || skipped;
}
-bool cmCTestRunTest::StartAgain(size_t completed)
+bool cmCTestRunTest::StartAgain(std::unique_ptr<cmCTestRunTest> runner,
+ size_t completed)
{
- if (!this->RunAgain) {
+ auto* testRun = runner.get();
+
+ if (!testRun->RunAgain) {
return false;
}
- this->RunAgain = false; // reset
+ testRun->RunAgain = false; // reset
+ testRun->TestProcess = cm::make_unique<cmProcess>(std::move(runner));
// change to tests directory
- cmWorkingDirectory workdir(this->TestProperties->Directory);
+ cmWorkingDirectory workdir(testRun->TestProperties->Directory);
if (workdir.Failed()) {
- this->StartFailure("Failed to change working directory to " +
- this->TestProperties->Directory + " : " +
- std::strerror(workdir.GetLastResult()));
+ testRun->StartFailure("Failed to change working directory to " +
+ testRun->TestProperties->Directory + " : " +
+ std::strerror(workdir.GetLastResult()),
+ "Failed to change working directory");
return true;
}
- this->StartTest(completed, this->TotalNumberOfTests);
+ testRun->StartTest(completed, testRun->TotalNumberOfTests);
return true;
}
-bool cmCTestRunTest::NeedsToRerun()
+bool cmCTestRunTest::NeedsToRepeat()
{
this->NumberOfRunsLeft--;
if (this->NumberOfRunsLeft == 0) {
return false;
}
// if number of runs left is not 0, and we are running until
- // we find a failed test, then return true so the test can be
+ // we find a failed (or passed) test, then return true so the test can be
// restarted
- if (this->RunUntilFail &&
- this->TestResult.Status == cmCTestTestHandler::COMPLETED) {
+ if ((this->RepeatMode == cmCTest::Repeat::UntilFail &&
+ this->TestResult.Status == cmCTestTestHandler::COMPLETED) ||
+ (this->RepeatMode == cmCTest::Repeat::UntilPass &&
+ this->TestResult.Status != cmCTestTestHandler::COMPLETED) ||
+ (this->RepeatMode == cmCTest::Repeat::AfterTimeout &&
+ this->TestResult.Status == cmCTestTestHandler::TIMEOUT)) {
this->RunAgain = true;
return true;
}
@@ -380,7 +386,20 @@ void cmCTestRunTest::MemCheckPostProcess()
handler->PostProcessTest(this->TestResult, this->Index);
}
-void cmCTestRunTest::StartFailure(std::string const& output)
+void cmCTestRunTest::StartFailure(std::unique_ptr<cmCTestRunTest> runner,
+ std::string const& output,
+ std::string const& detail)
+{
+ auto* testRun = runner.get();
+
+ testRun->TestProcess = cm::make_unique<cmProcess>(std::move(runner));
+ testRun->StartFailure(output, detail);
+
+ testRun->FinalizeTest(false);
+}
+
+void cmCTestRunTest::StartFailure(std::string const& output,
+ std::string const& detail)
{
// Still need to log the Start message so the test summary records our
// attempt to start this test
@@ -403,14 +422,13 @@ void cmCTestRunTest::StartFailure(std::string const& output)
this->TestResult.ExecutionTime = cmDuration::zero();
this->TestResult.CompressOutput = false;
this->TestResult.ReturnValue = -1;
- this->TestResult.CompletionStatus = "Failed to start";
+ this->TestResult.CompletionStatus = detail;
this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
this->TestResult.TestCount = this->TestProperties->Index;
this->TestResult.Name = this->TestProperties->Name;
this->TestResult.Path = this->TestProperties->Directory;
this->TestResult.Output = output;
this->TestResult.FullCommandLine.clear();
- this->TestProcess = cm::make_unique<cmProcess>(*this);
}
std::string cmCTestRunTest::GetTestPrefix(size_t completed, size_t total) const
@@ -434,6 +452,21 @@ std::string cmCTestRunTest::GetTestPrefix(size_t completed, size_t total) const
return outputStream.str();
}
+bool cmCTestRunTest::StartTest(std::unique_ptr<cmCTestRunTest> runner,
+ size_t completed, size_t total)
+{
+ auto* testRun = runner.get();
+
+ testRun->TestProcess = cm::make_unique<cmProcess>(std::move(runner));
+
+ if (!testRun->StartTest(completed, total)) {
+ testRun->FinalizeTest(false);
+ return false;
+ }
+
+ return true;
+}
+
// Starts the execution of a test. Returns once it has started
bool cmCTestRunTest::StartTest(size_t completed, size_t total)
{
@@ -465,7 +498,6 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total)
if (this->TestProperties->Disabled) {
this->TestResult.CompletionStatus = "Disabled";
this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
- this->TestProcess = cm::make_unique<cmProcess>(*this);
this->TestResult.Output = "Disabled";
this->TestResult.FullCommandLine.clear();
return false;
@@ -479,7 +511,6 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total)
// its arguments are irrelevant. This matters for the case where a fixture
// dependency might be creating the executable we want to run.
if (!this->FailedDependencies.empty()) {
- this->TestProcess = cm::make_unique<cmProcess>(*this);
std::string msg = "Failed test dependencies:";
for (std::string const& failedDep : this->FailedDependencies) {
msg += " " + failedDep;
@@ -496,7 +527,6 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total)
this->ComputeArguments();
std::vector<std::string>& args = this->TestProperties->Args;
if (args.size() >= 2 && args[1] == "NOT_AVAILABLE") {
- this->TestProcess = cm::make_unique<cmProcess>(*this);
std::string msg;
if (this->CTest->GetConfigType().empty()) {
msg = "Test not available without configuration. (Missing \"-C "
@@ -518,7 +548,6 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total)
for (std::string const& file : this->TestProperties->RequiredFiles) {
if (!cmSystemTools::FileExists(file)) {
// Required file was not found
- this->TestProcess = cm::make_unique<cmProcess>(*this);
*this->TestHandler->LogFile << "Unable to find required file: " << file
<< std::endl;
cmCTestLog(this->CTest, ERROR_MESSAGE,
@@ -534,7 +563,6 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total)
if (this->ActualCommand.empty()) {
// if the command was not found create a TestResult object
// that has that information
- this->TestProcess = cm::make_unique<cmProcess>(*this);
*this->TestHandler->LogFile << "Unable to find executable: " << args[1]
<< std::endl;
cmCTestLog(this->CTest, ERROR_MESSAGE,
@@ -646,7 +674,6 @@ bool cmCTestRunTest::ForkProcess(cmDuration testTimeOut, bool explicitTimeout,
std::vector<std::string>* environment,
std::vector<size_t>* affinity)
{
- this->TestProcess = cm::make_unique<cmProcess>(*this);
this->TestProcess->SetId(this->Index);
this->TestProcess->SetWorkingDirectory(this->TestProperties->Directory);
this->TestProcess->SetCommand(this->ActualCommand);
@@ -746,7 +773,12 @@ void cmCTestRunTest::WriteLogOutputTop(size_t completed, size_t total)
// then it will never print out the completed / total, same would
// got for run until pass. Trick is when this is called we don't
// yet know if we are passing or failing.
- if (this->NumberOfRunsLeft == 1 || this->CTest->GetTestProgressOutput()) {
+ bool const progressOnLast =
+ (this->RepeatMode != cmCTest::Repeat::UntilPass &&
+ this->RepeatMode != cmCTest::Repeat::AfterTimeout);
+ if ((progressOnLast && this->NumberOfRunsLeft == 1) ||
+ (!progressOnLast && this->NumberOfRunsLeft == this->NumberOfRunsTotal) ||
+ this->CTest->GetTestProgressOutput()) {
outputStream << std::setw(getNumWidth(total)) << completed << "/";
outputStream << std::setw(getNumWidth(total)) << total << " ";
}
@@ -808,7 +840,8 @@ void cmCTestRunTest::WriteLogOutputTop(size_t completed, size_t total)
"Testing " << this->TestProperties->Name << " ... ");
}
-void cmCTestRunTest::FinalizeTest()
+void cmCTestRunTest::FinalizeTest(bool started)
{
- this->MultiTestHandler.FinishTestProcess(this, true);
+ this->MultiTestHandler.FinishTestProcess(this->TestProcess->GetRunner(),
+ started);
}
diff --git a/Source/CTest/cmCTestRunTest.h b/Source/CTest/cmCTestRunTest.h
index f781c7a..b1d188a 100644
--- a/Source/CTest/cmCTestRunTest.h
+++ b/Source/CTest/cmCTestRunTest.h
@@ -13,13 +13,12 @@
#include <stddef.h>
+#include "cmCTest.h"
#include "cmCTestMultiProcessHandler.h"
#include "cmCTestTestHandler.h"
#include "cmDuration.h"
#include "cmProcess.h"
-class cmCTest;
-
/** \class cmRunTest
* \brief represents a single test to be run
*
@@ -30,8 +29,13 @@ class cmCTestRunTest
public:
explicit cmCTestRunTest(cmCTestMultiProcessHandler& multiHandler);
- void SetNumberOfRuns(int n) { this->NumberOfRunsLeft = n; }
- void SetRunUntilFailOn() { this->RunUntilFail = true; }
+ void SetNumberOfRuns(int n)
+ {
+ this->NumberOfRunsLeft = n;
+ this->NumberOfRunsTotal = n;
+ }
+
+ void SetRepeatMode(cmCTest::Repeat r) { this->RepeatMode = r; }
void SetTestProperties(cmCTestTestHandler::cmCTestTestProperties* prop)
{
this->TestProperties = prop;
@@ -61,6 +65,15 @@ public:
// Read and store output. Returns true if it must be called again.
void CheckOutput(std::string const& line);
+ static bool StartTest(std::unique_ptr<cmCTestRunTest> runner,
+ size_t completed, size_t total);
+ static bool StartAgain(std::unique_ptr<cmCTestRunTest> runner,
+ size_t completed);
+
+ static void StartFailure(std::unique_ptr<cmCTestRunTest> runner,
+ std::string const& output,
+ std::string const& detail);
+
// launch the test process, return whether it started correctly
bool StartTest(size_t completed, size_t total);
// capture and report the test results
@@ -70,9 +83,7 @@ public:
void ComputeWeightedCost();
- bool StartAgain(size_t completed);
-
- void StartFailure(std::string const& output);
+ void StartFailure(std::string const& output, std::string const& detail);
cmCTest* GetCTest() const { return this->CTest; }
@@ -80,7 +91,7 @@ public:
const std::vector<std::string>& GetArguments() { return this->Arguments; }
- void FinalizeTest();
+ void FinalizeTest(bool started = true);
bool TimedOutForStopTime() const { return this->TimeoutIsForStopTime; }
@@ -98,7 +109,7 @@ public:
}
private:
- bool NeedsToRerun();
+ bool NeedsToRepeat();
void DartProcessing();
void ExeNotFound(std::string exe);
bool ForkProcess(cmDuration testTimeOut, bool explicitTimeout,
@@ -132,9 +143,10 @@ private:
std::vector<std::map<
std::string, std::vector<cmCTestMultiProcessHandler::ResourceAllocation>>>
AllocatedResources;
- bool RunUntilFail;
- int NumberOfRunsLeft;
- bool RunAgain;
+ cmCTest::Repeat RepeatMode = cmCTest::Repeat::Never;
+ int NumberOfRunsLeft = 1; // default to 1 run of the test
+ int NumberOfRunsTotal = 1; // default to 1 run of the test
+ bool RunAgain = false; // default to not having to run again
size_t TotalNumberOfTests;
};
diff --git a/Source/CTest/cmCTestSVN.cxx b/Source/CTest/cmCTestSVN.cxx
index 34395c9..44dfab2 100644
--- a/Source/CTest/cmCTestSVN.cxx
+++ b/Source/CTest/cmCTestSVN.cxx
@@ -7,9 +7,10 @@
#include <map>
#include <ostream>
+#include <cmext/algorithm>
+
#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestVC.h"
#include "cmProcessTools.h"
@@ -271,7 +272,7 @@ bool cmCTestSVN::RunSVNCommand(std::vector<char const*> const& parameters,
std::vector<char const*> args;
args.push_back(this->CommandLineTool.c_str());
- cmAppend(args, parameters);
+ cm::append(args, parameters);
args.push_back("--non-interactive");
std::string userOptions = this->CTest->GetCTestConfiguration("SVNOptions");
@@ -344,7 +345,7 @@ private:
void CharacterDataHandler(const char* data, int length) override
{
- cmAppend(this->CData, data, data + length);
+ cm::append(this->CData, data, data + length);
}
void EndElement(const std::string& name) override
diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx
index 60facbd..4fa4dc0 100644
--- a/Source/CTest/cmCTestScriptHandler.cxx
+++ b/Source/CTest/cmCTestScriptHandler.cxx
@@ -6,7 +6,6 @@
#include <cstdlib>
#include <cstring>
#include <map>
-#include <memory>
#include <ratio>
#include <sstream>
#include <utility>
@@ -51,22 +50,7 @@
#define CTEST_INITIAL_CMAKE_OUTPUT_FILE_NAME "CTestInitialCMakeOutput.log"
-cmCTestScriptHandler::cmCTestScriptHandler()
-{
- this->Backup = false;
- this->EmptyBinDir = false;
- this->EmptyBinDirOnce = false;
- this->Makefile = nullptr;
- this->ParentMakefile = nullptr;
- this->CMake = nullptr;
- this->GlobalGenerator = nullptr;
-
- this->ScriptStartTime = std::chrono::steady_clock::time_point();
-
- // the *60 is because the settings are in minutes but GetTime is seconds
- this->MinimumInterval = 30 * 60;
- this->ContinuousDuration = -1;
-}
+cmCTestScriptHandler::cmCTestScriptHandler() = default;
void cmCTestScriptHandler::Initialize()
{
@@ -95,22 +79,15 @@ void cmCTestScriptHandler::Initialize()
// what time in seconds did this script start running
this->ScriptStartTime = std::chrono::steady_clock::time_point();
- delete this->Makefile;
- this->Makefile = nullptr;
+ this->Makefile.reset();
this->ParentMakefile = nullptr;
- delete this->GlobalGenerator;
- this->GlobalGenerator = nullptr;
+ this->GlobalGenerator.reset();
- delete this->CMake;
+ this->CMake.reset();
}
-cmCTestScriptHandler::~cmCTestScriptHandler()
-{
- delete this->Makefile;
- delete this->GlobalGenerator;
- delete this->CMake;
-}
+cmCTestScriptHandler::~cmCTestScriptHandler() = default;
// just adds an argument to the vector
void cmCTestScriptHandler::AddConfigurationScript(const char* script,
@@ -247,23 +224,20 @@ int cmCTestScriptHandler::ExecuteScript(const std::string& total_script_arg)
void cmCTestScriptHandler::CreateCMake()
{
// create a cmake instance to read the configuration script
- if (this->CMake) {
- delete this->CMake;
- delete this->GlobalGenerator;
- delete this->Makefile;
- }
- this->CMake = new cmake(cmake::RoleScript, cmState::CTest);
+ this->CMake = cm::make_unique<cmake>(cmake::RoleScript, cmState::CTest);
this->CMake->SetHomeDirectory("");
this->CMake->SetHomeOutputDirectory("");
this->CMake->GetCurrentSnapshot().SetDefaultDefinitions();
this->CMake->AddCMakePaths();
- this->GlobalGenerator = new cmGlobalGenerator(this->CMake);
+ this->GlobalGenerator =
+ cm::make_unique<cmGlobalGenerator>(this->CMake.get());
cmStateSnapshot snapshot = this->CMake->GetCurrentSnapshot();
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
snapshot.GetDirectory().SetCurrentSource(cwd);
snapshot.GetDirectory().SetCurrentBinary(cwd);
- this->Makefile = new cmMakefile(this->GlobalGenerator, snapshot);
+ this->Makefile =
+ cm::make_unique<cmMakefile>(this->GlobalGenerator.get(), snapshot);
if (this->ParentMakefile) {
this->Makefile->SetRecursionDepth(
this->ParentMakefile->GetRecursionDepth());
@@ -310,12 +284,14 @@ int cmCTestScriptHandler::ReadInScript(const std::string& total_script_arg)
// if the argument has a , in it then it needs to be broken into the fist
// argument (which is the script) and the second argument which will be
// passed into the scripts as S_ARG
- std::string script = total_script_arg;
+ std::string script;
std::string script_arg;
const std::string::size_type comma_pos = total_script_arg.find(',');
if (comma_pos != std::string::npos) {
script = total_script_arg.substr(0, comma_pos);
script_arg = total_script_arg.substr(comma_pos + 1);
+ } else {
+ script = total_script_arg;
}
// make sure the file exists
if (!cmSystemTools::FileExists(script)) {
@@ -340,6 +316,13 @@ int cmCTestScriptHandler::ReadInScript(const std::string& total_script_arg)
this->SetRunCurrentScript(true);
this->UpdateElapsedTime();
+ // set the CTEST_CONFIGURATION_TYPE variable to the current value of the
+ // the -C argument on the command line.
+ if (!this->CTest->GetConfigType().empty()) {
+ this->Makefile->AddDefinition("CTEST_CONFIGURATION_TYPE",
+ this->CTest->GetConfigType());
+ }
+
// add the script arg if defined
if (!script_arg.empty()) {
this->Makefile->AddDefinition("CTEST_SCRIPT_ARG", script_arg);
@@ -871,7 +854,7 @@ bool cmCTestScriptHandler::RunScript(cmCTest* ctest, cmMakefile* mf,
const char* sname, bool InProcess,
int* returnValue)
{
- cmCTestScriptHandler* sh = new cmCTestScriptHandler();
+ auto sh = cm::make_unique<cmCTestScriptHandler>();
sh->SetCTestInstance(ctest);
sh->ParentMakefile = mf;
sh->AddConfigurationScript(sname, InProcess);
@@ -879,7 +862,6 @@ bool cmCTestScriptHandler::RunScript(cmCTest* ctest, cmMakefile* mf,
if (returnValue) {
*returnValue = res;
}
- delete sh;
return true;
}
diff --git a/Source/CTest/cmCTestScriptHandler.h b/Source/CTest/cmCTestScriptHandler.h
index d003199..ebb7905 100644
--- a/Source/CTest/cmCTestScriptHandler.h
+++ b/Source/CTest/cmCTestScriptHandler.h
@@ -101,12 +101,14 @@ public:
cmDuration GetRemainingTimeAllowed();
cmCTestScriptHandler();
+ cmCTestScriptHandler(const cmCTestScriptHandler&) = delete;
+ const cmCTestScriptHandler& operator=(const cmCTestScriptHandler&) = delete;
~cmCTestScriptHandler() override;
void Initialize() override;
void CreateCMake();
- cmake* GetCMake() { return this->CMake; }
+ cmake* GetCMake() { return this->CMake.get(); }
void SetRunCurrentScript(bool value);
@@ -143,9 +145,9 @@ private:
bool ShouldRunCurrentScript;
- bool Backup;
- bool EmptyBinDir;
- bool EmptyBinDirOnce;
+ bool Backup = false;
+ bool EmptyBinDir = false;
+ bool EmptyBinDirOnce = false;
std::string SourceDir;
std::string BinaryDir;
@@ -161,16 +163,18 @@ private:
std::string CMOutFile;
std::vector<std::string> ExtraUpdates;
- double MinimumInterval;
- double ContinuousDuration;
+ // the *60 is because the settings are in minutes but GetTime is seconds
+ double MinimumInterval = 30 * 60;
+ double ContinuousDuration = -1;
// what time in seconds did this script start running
- std::chrono::steady_clock::time_point ScriptStartTime;
+ std::chrono::steady_clock::time_point ScriptStartTime =
+ std::chrono::steady_clock::time_point();
- cmMakefile* Makefile;
- cmMakefile* ParentMakefile;
- cmGlobalGenerator* GlobalGenerator;
- cmake* CMake;
+ std::unique_ptr<cmMakefile> Makefile;
+ cmMakefile* ParentMakefile = nullptr;
+ std::unique_ptr<cmGlobalGenerator> GlobalGenerator;
+ std::unique_ptr<cmake> CMake;
};
#endif
diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx
index 46b00b1..279216e 100644
--- a/Source/CTest/cmCTestSubmitCommand.cxx
+++ b/Source/CTest/cmCTestSubmitCommand.cxx
@@ -7,10 +7,10 @@
#include <utility>
#include <cm/memory>
+#include <cm/vector>
+#include <cmext/algorithm>
+#include <cmext/string_view>
-#include "cm_static_string_view.hxx"
-
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestSubmitHandler.h"
#include "cmCommand.h"
@@ -171,10 +171,12 @@ void cmCTestSubmitCommand::BindArguments()
void cmCTestSubmitCommand::CheckArguments(
std::vector<std::string> const& keywords)
{
- this->PartsMentioned = !this->Parts.empty() || cmContains(keywords, "PARTS");
- this->FilesMentioned = !this->Files.empty() || cmContains(keywords, "FILES");
+ this->PartsMentioned =
+ !this->Parts.empty() || cm::contains(keywords, "PARTS");
+ this->FilesMentioned =
+ !this->Files.empty() || cm::contains(keywords, "FILES");
- cmEraseIf(this->Parts, [this](std::string const& arg) -> bool {
+ cm::erase_if(this->Parts, [this](std::string const& arg) -> bool {
cmCTest::Part p = this->CTest->GetPartFromName(arg.c_str());
if (p == cmCTest::PartCount) {
std::ostringstream e;
@@ -185,7 +187,7 @@ void cmCTestSubmitCommand::CheckArguments(
return false;
});
- cmEraseIf(this->Files, [this](std::string const& arg) -> bool {
+ 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 "
diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx
index 2ac5af6..2989025 100644
--- a/Source/CTest/cmCTestSubmitHandler.cxx
+++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -7,9 +7,11 @@
#include <cstdlib>
#include <sstream>
-#include "cm_curl.h"
-#include "cm_jsoncpp_reader.h"
-#include "cm_jsoncpp_value.h"
+#include <cmext/algorithm>
+
+#include <cm3p/curl/curl.h>
+#include <cm3p/json/reader.h>
+#include <cm3p/json/value.h>
#include "cmAlgorithms.h"
#include "cmCTest.h"
@@ -65,7 +67,7 @@ private:
void CharacterDataHandler(const char* data, int length) override
{
- cmAppend(this->CurrentValue, data, data + length);
+ cm::append(this->CurrentValue, data, data + length);
}
void EndElement(const std::string& name) override
@@ -96,8 +98,8 @@ static size_t cmCTestSubmitHandlerWriteMemoryCallback(void* ptr, size_t size,
{
int realsize = static_cast<int>(size * nmemb);
const char* chPtr = static_cast<char*>(ptr);
- cmAppend(*static_cast<cmCTestSubmitHandlerVectorOfChar*>(data), chPtr,
- chPtr + realsize);
+ cm::append(*static_cast<cmCTestSubmitHandlerVectorOfChar*>(data), chPtr,
+ chPtr + realsize);
return realsize;
}
@@ -106,9 +108,9 @@ static size_t cmCTestSubmitHandlerCurlDebugCallback(CURL* /*unused*/,
char* chPtr, size_t size,
void* data)
{
- cmAppend(*static_cast<cmCTestSubmitHandlerVectorOfChar*>(data), chPtr,
- chPtr + size);
- return size;
+ cm::append(*static_cast<cmCTestSubmitHandlerVectorOfChar*>(data), chPtr,
+ chPtr + size);
+ return 0;
}
cmCTestSubmitHandler::cmCTestSubmitHandler()
@@ -258,11 +260,10 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(
cmCTestScriptHandler* ch = this->CTest->GetScriptHandler();
cmake* cm = ch->GetCMake();
if (cm) {
- const char* subproject =
- cm->GetState()->GetGlobalProperty("SubProject");
+ cmProp subproject = cm->GetState()->GetGlobalProperty("SubProject");
if (subproject) {
upload_as += "&subproject=";
- upload_as += ctest_curl.Escape(subproject);
+ upload_as += ctest_curl.Escape(*subproject);
}
}
}
@@ -504,18 +505,19 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file,
curl.SetTimeOutSeconds(SUBMIT_TIMEOUT_IN_SECONDS_DEFAULT);
curl.SetHttpHeaders(this->HttpHeaders);
std::string url = this->CTest->GetSubmitURL();
- std::string fields;
- std::string::size_type pos = url.find('?');
- if (pos != std::string::npos) {
- fields = url.substr(pos + 1);
- url = url.substr(0, pos);
- }
if (!cmHasLiteralPrefix(url, "http://") &&
!cmHasLiteralPrefix(url, "https://")) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Only http and https are supported for CDASH_UPLOAD\n");
return -1;
}
+
+ std::string fields;
+ std::string::size_type pos = url.find('?');
+ if (pos != std::string::npos) {
+ fields = url.substr(pos + 1);
+ url.erase(pos);
+ }
bool internalTest = cmIsOn(this->GetOption("InternalTest"));
// Get RETRY_COUNT and RETRY_DELAY values if they were set.
@@ -553,11 +555,11 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file,
// a "&subproject=subprojectname" to the first POST.
cmCTestScriptHandler* ch = this->CTest->GetScriptHandler();
cmake* cm = ch->GetCMake();
- const char* subproject = cm->GetState()->GetGlobalProperty("SubProject");
+ cmProp subproject = cm->GetState()->GetGlobalProperty("SubProject");
// TODO: Encode values for a URL instead of trusting caller.
std::ostringstream str;
if (subproject) {
- str << "subproject=" << curl.Escape(subproject) << "&";
+ str << "subproject=" << curl.Escape(*subproject) << "&";
}
auto timeNow =
std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
@@ -768,7 +770,7 @@ int cmCTestSubmitHandler::ProcessHandler()
if (!this->Files.empty()) {
// Submit the explicitly selected files:
- cmAppend(files, this->Files);
+ cm::append(files, this->Files);
}
// Add to the list of files to submit from any selected, existing parts:
@@ -814,7 +816,7 @@ int cmCTestSubmitHandler::ProcessHandler()
}
// Submit files from this part.
- cmAppend(files, this->CTest->GetSubmitFiles(p));
+ cm::append(files, this->CTest->GetSubmitFiles(p));
}
// Make sure files are unique, but preserve order.
diff --git a/Source/CTest/cmCTestTestCommand.cxx b/Source/CTest/cmCTestTestCommand.cxx
index 9784214..c71b409 100644
--- a/Source/CTest/cmCTestTestCommand.cxx
+++ b/Source/CTest/cmCTestTestCommand.cxx
@@ -6,7 +6,7 @@
#include <cstdlib>
#include <sstream>
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
#include "cmCTest.h"
#include "cmCTestGenericHandler.h"
@@ -29,10 +29,12 @@ void cmCTestTestCommand::BindArguments()
this->Bind("EXCLUDE_FIXTURE_SETUP"_s, this->ExcludeFixtureSetup);
this->Bind("EXCLUDE_FIXTURE_CLEANUP"_s, this->ExcludeFixtureCleanup);
this->Bind("PARALLEL_LEVEL"_s, this->ParallelLevel);
+ this->Bind("REPEAT"_s, this->Repeat);
this->Bind("SCHEDULE_RANDOM"_s, this->ScheduleRandom);
this->Bind("STOP_TIME"_s, this->StopTime);
this->Bind("TEST_LOAD"_s, this->TestLoad);
this->Bind("RESOURCE_SPEC_FILE"_s, this->ResourceSpecFile);
+ this->Bind("STOP_ON_FAILURE"_s, this->StopOnFailure);
}
cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
@@ -51,6 +53,13 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
}
}
this->CTest->SetTimeOut(timeout);
+
+ const char* resourceSpecFile =
+ this->Makefile->GetDefinition("CTEST_RESOURCE_SPEC_FILE");
+ if (this->ResourceSpecFile.empty() && resourceSpecFile) {
+ this->ResourceSpecFile = resourceSpecFile;
+ }
+
cmCTestGenericHandler* handler = this->InitializeActualHandler();
if (!this->Start.empty() || !this->End.empty() || !this->Stride.empty()) {
handler->SetOption(
@@ -82,9 +91,15 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
handler->SetOption("ExcludeFixtureCleanupRegularExpression",
this->ExcludeFixtureCleanup.c_str());
}
+ if (this->StopOnFailure) {
+ handler->SetOption("StopOnFailure", "ON");
+ }
if (!this->ParallelLevel.empty()) {
handler->SetOption("ParallelLevel", this->ParallelLevel.c_str());
}
+ if (!this->Repeat.empty()) {
+ handler->SetOption("Repeat", this->Repeat.c_str());
+ }
if (!this->ScheduleRandom.empty()) {
handler->SetOption("ScheduleRandom", this->ScheduleRandom.c_str());
}
diff --git a/Source/CTest/cmCTestTestCommand.h b/Source/CTest/cmCTestTestCommand.h
index 4019694..7925586 100644
--- a/Source/CTest/cmCTestTestCommand.h
+++ b/Source/CTest/cmCTestTestCommand.h
@@ -55,10 +55,12 @@ protected:
std::string ExcludeFixtureSetup;
std::string ExcludeFixtureCleanup;
std::string ParallelLevel;
+ std::string Repeat;
std::string ScheduleRandom;
std::string StopTime;
std::string TestLoad;
std::string ResourceSpecFile;
+ bool StopOnFailure = false;
};
#endif
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index c8bbb0b..8fc5cd6 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -5,7 +5,7 @@
#include <algorithm>
#include <chrono>
#include <cmath>
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
#include <cstdio>
#include <cstdlib>
#include <cstring>
@@ -18,6 +18,9 @@
#include <utility>
#include <cm/memory>
+#include <cm/string_view>
+#include <cmext/algorithm>
+#include <cmext/string_view>
#include "cmsys/FStream.hxx"
#include <cmsys/Base64.h>
@@ -26,7 +29,6 @@
#include "cm_utf8.h"
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestMultiProcessHandler.h"
#include "cmCTestResourceGroupsLexerHelper.h"
@@ -406,14 +408,21 @@ int cmCTestTestHandler::ProcessHandler()
// start the real time clock
auto clock_start = std::chrono::steady_clock::now();
- this->ProcessDirectory(passed, failed);
+ if (!this->ProcessDirectory(passed, failed)) {
+ return -1;
+ }
auto clock_finish = std::chrono::steady_clock::now();
+ bool noTestsFoundError = false;
if (passed.size() + failed.size() == 0) {
- if (!this->CTest->GetShowOnly() && !this->CTest->ShouldPrintLabels()) {
+ if (!this->CTest->GetShowOnly() && !this->CTest->ShouldPrintLabels() &&
+ this->CTest->GetNoTestsMode() != cmCTest::NoTests::Ignore) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"No tests were found!!!" << std::endl);
+ if (this->CTest->GetNoTestsMode() == cmCTest::NoTests::Error) {
+ noTestsFoundError = true;
+ }
}
} else {
if (this->HandlerVerbose && !passed.empty() &&
@@ -459,6 +468,12 @@ int cmCTestTestHandler::ProcessHandler()
this->LogFile = nullptr;
return -1;
}
+
+ if (noTestsFoundError) {
+ this->LogFile = nullptr;
+ return -1;
+ }
+
this->LogFile = nullptr;
return 0;
}
@@ -471,10 +486,38 @@ bool cmCTestTestHandler::ProcessOptions()
if (cmIsOn(this->GetOption("ScheduleRandom"))) {
this->CTest->SetScheduleType("Random");
}
+ if (const char* repeat = this->GetOption("Repeat")) {
+ cmsys::RegularExpression repeatRegex(
+ "^(UNTIL_FAIL|UNTIL_PASS|AFTER_TIMEOUT):([0-9]+)$");
+ if (repeatRegex.find(repeat)) {
+ std::string const& count = repeatRegex.match(2);
+ unsigned long n = 1;
+ cmStrToULong(count, &n); // regex guarantees success
+ this->RepeatCount = static_cast<int>(n);
+ if (this->RepeatCount > 1) {
+ std::string const& mode = repeatRegex.match(1);
+ if (mode == "UNTIL_FAIL") {
+ this->RepeatMode = cmCTest::Repeat::UntilFail;
+ } else if (mode == "UNTIL_PASS") {
+ this->RepeatMode = cmCTest::Repeat::UntilPass;
+ } else if (mode == "AFTER_TIMEOUT") {
+ this->RepeatMode = cmCTest::Repeat::AfterTimeout;
+ }
+ }
+ } else {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Repeat option invalid value: " << repeat << std::endl);
+ return false;
+ }
+ }
if (this->GetOption("ParallelLevel")) {
this->CTest->SetParallelLevel(atoi(this->GetOption("ParallelLevel")));
}
+ if (this->GetOption("StopOnFailure")) {
+ this->CTest->SetStopOnFailure(true);
+ }
+
const char* val;
val = this->GetOption("LabelRegularExpression");
if (val) {
@@ -508,21 +551,11 @@ bool cmCTestTestHandler::ProcessOptions()
if (val) {
this->ExcludeFixtureCleanupRegExp = val;
}
- this->SetRerunFailed(cmIsOn(this->GetOption("RerunFailed")));
-
val = this->GetOption("ResourceSpecFile");
if (val) {
- this->UseResourceSpec = true;
- auto result = this->ResourceSpec.ReadFromJSONFile(val);
- if (result != cmCTestResourceSpec::ReadFileResult::READ_OK) {
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- "Could not read/parse resource spec file "
- << val << ": "
- << cmCTestResourceSpec::ResultToString(result)
- << std::endl);
- return false;
- }
+ this->ResourceSpecFile = val;
}
+ this->SetRerunFailed(cmIsOn(this->GetOption("RerunFailed")));
return true;
}
@@ -682,7 +715,7 @@ void cmCTestTestHandler::PrintLabelOrSubprojectSummary(bool doSubProject)
cmCTestTestProperties& p = *result.Properties;
for (std::string const& l : p.Labels) {
// only use labels found in labels
- if (cmContains(labels, l)) {
+ if (cm::contains(labels, l)) {
labelTimes[l] +=
result.ExecutionTime.count() * result.Properties->Processors;
++labelCounts[l];
@@ -824,14 +857,15 @@ void cmCTestTestHandler::ComputeTestList()
if (this->UseUnion) {
// if it is not in the list and not in the regexp then skip
- if ((!this->TestsToRun.empty() && !cmContains(this->TestsToRun, cnt)) &&
+ if ((!this->TestsToRun.empty() &&
+ !cm::contains(this->TestsToRun, cnt)) &&
!tp.IsInBasedOnREOptions) {
continue;
}
} else {
// is this test in the list of tests to run? If not then skip it
if ((!this->TestsToRun.empty() &&
- !cmContains(this->TestsToRun, inREcnt)) ||
+ !cm::contains(this->TestsToRun, inREcnt)) ||
!tp.IsInBasedOnREOptions) {
continue;
}
@@ -860,7 +894,7 @@ void cmCTestTestHandler::ComputeTestListForRerunFailed()
cnt++;
// if this test is not in our list of tests to run, then skip it.
- if (!this->TestsToRun.empty() && !cmContains(this->TestsToRun, cnt)) {
+ if (!this->TestsToRun.empty() && !cm::contains(this->TestsToRun, cnt)) {
continue;
}
@@ -979,7 +1013,7 @@ void cmCTestTestHandler::UpdateForFixtures(ListOfTests& tests) const
for (auto sIt = setupRange.first; sIt != setupRange.second; ++sIt) {
const std::string& setupTestName = sIt->second->Name;
tests[i].RequireSuccessDepends.insert(setupTestName);
- if (!cmContains(tests[i].Depends, setupTestName)) {
+ if (!cm::contains(tests[i].Depends, setupTestName)) {
tests[i].Depends.push_back(setupTestName);
}
}
@@ -1083,7 +1117,7 @@ void cmCTestTestHandler::UpdateForFixtures(ListOfTests& tests) const
const std::vector<size_t>& indices = cIt->second;
for (size_t index : indices) {
const std::string& reqTestName = tests[index].Name;
- if (!cmContains(p.Depends, reqTestName)) {
+ if (!cm::contains(p.Depends, reqTestName)) {
p.Depends.push_back(reqTestName);
}
}
@@ -1096,7 +1130,7 @@ void cmCTestTestHandler::UpdateForFixtures(ListOfTests& tests) const
const std::vector<size_t>& indices = cIt->second;
for (size_t index : indices) {
const std::string& setupTestName = tests[index].Name;
- if (!cmContains(p.Depends, setupTestName)) {
+ if (!cm::contains(p.Depends, setupTestName)) {
p.Depends.push_back(setupTestName);
}
}
@@ -1223,7 +1257,7 @@ bool cmCTestTestHandler::GetValue(const char* tag, std::string& value,
return ret;
}
-void cmCTestTestHandler::ProcessDirectory(std::vector<std::string>& passed,
+bool cmCTestTestHandler::ProcessDirectory(std::vector<std::string>& passed,
std::vector<std::string>& failed)
{
this->ComputeTestList();
@@ -1231,17 +1265,33 @@ void cmCTestTestHandler::ProcessDirectory(std::vector<std::string>& passed,
this->StartTestTime = std::chrono::system_clock::now();
auto elapsed_time_start = std::chrono::steady_clock::now();
- cmCTestMultiProcessHandler* parallel = new cmCTestMultiProcessHandler;
+ auto parallel = cm::make_unique<cmCTestMultiProcessHandler>();
parallel->SetCTest(this->CTest);
parallel->SetParallelLevel(this->CTest->GetParallelLevel());
parallel->SetTestHandler(this);
+ if (this->RepeatMode != cmCTest::Repeat::Never) {
+ parallel->SetRepeatMode(this->RepeatMode, this->RepeatCount);
+ } else {
+ parallel->SetRepeatMode(this->CTest->GetRepeatMode(),
+ this->CTest->GetRepeatCount());
+ }
parallel->SetQuiet(this->Quiet);
if (this->TestLoad > 0) {
parallel->SetTestLoad(this->TestLoad);
} else {
parallel->SetTestLoad(this->CTest->GetTestLoad());
}
- if (this->UseResourceSpec) {
+ if (!this->ResourceSpecFile.empty()) {
+ this->UseResourceSpec = true;
+ auto result = this->ResourceSpec.ReadFromJSONFile(this->ResourceSpecFile);
+ if (result != cmCTestResourceSpec::ReadFileResult::READ_OK) {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Could not read/parse resource spec file "
+ << this->ResourceSpecFile << ": "
+ << cmCTestResourceSpec::ResultToString(result)
+ << std::endl);
+ return false;
+ }
parallel->InitResourceAllocator(this->ResourceSpec);
}
@@ -1296,12 +1346,13 @@ void cmCTestTestHandler::ProcessDirectory(std::vector<std::string>& passed,
} else {
parallel->RunTests();
}
- delete parallel;
this->EndTest = this->CTest->CurrentTime();
this->EndTestTime = std::chrono::system_clock::now();
this->ElapsedTestingTime =
std::chrono::steady_clock::now() - elapsed_time_start;
*this->LogFile << "End testing: " << this->CTest->CurrentTime() << std::endl;
+
+ return true;
}
void cmCTestTestHandler::GenerateTestCommand(
@@ -1700,6 +1751,10 @@ void cmCTestTestHandler::GetListOfTests()
if (cmSystemTools::GetErrorOccuredFlag()) {
return;
}
+ const char* specFile = mf.GetDefinition("CTEST_RESOURCE_SPEC_FILE");
+ if (this->ResourceSpecFile.empty() && specFile) {
+ this->ResourceSpecFile = specFile;
+ }
cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"Done constructing a list of tests" << std::endl,
this->Quiet);
@@ -1852,7 +1907,8 @@ void cmCTestTestHandler::ExpandTestsToRunInformationForRerunFailed()
continue;
}
- int val = atoi(line.substr(0, pos).c_str());
+ line.erase(pos);
+ int val = atoi(line.c_str());
this->TestsToRun.push_back(val);
}
ifs.close();
@@ -1974,13 +2030,13 @@ void cmCTestTestHandler::GenerateRegressionImages(cmXMLWriter& xml,
| std::ios::binary
#endif
);
- unsigned char* file_buffer = new unsigned char[len + 1];
- ifs.read(reinterpret_cast<char*>(file_buffer), len);
- unsigned char* encoded_buffer = new unsigned char[static_cast<int>(
- static_cast<double>(len) * 1.5 + 5.0)];
+ auto file_buffer = cm::make_unique<unsigned char[]>(len + 1);
+ ifs.read(reinterpret_cast<char*>(file_buffer.get()), len);
+ auto encoded_buffer = cm::make_unique<unsigned char[]>(
+ static_cast<int>(static_cast<double>(len) * 1.5 + 5.0));
- size_t rlen =
- cmsysBase64_Encode(file_buffer, len, encoded_buffer, 1);
+ size_t rlen = cmsysBase64_Encode(file_buffer.get(), len,
+ encoded_buffer.get(), 1);
xml.StartElement("NamedMeasurement");
xml.Attribute(measurementfile.match(1).c_str(),
@@ -1997,8 +2053,6 @@ void cmCTestTestHandler::GenerateRegressionImages(cmXMLWriter& xml,
}
xml.Element("Value", ostr.str());
xml.EndElement(); // NamedMeasurement
- delete[] file_buffer;
- delete[] encoded_buffer;
}
} else {
int idx = 4;
@@ -2043,19 +2097,18 @@ void cmCTestTestHandler::SetTestsToRunInformation(const char* in)
if (cmSystemTools::FileExists(in)) {
cmsys::ifstream fin(in);
unsigned long filelen = cmSystemTools::FileLength(in);
- char* buff = new char[filelen + 1];
- fin.getline(buff, filelen);
+ auto buff = cm::make_unique<char[]>(filelen + 1);
+ fin.getline(buff.get(), filelen);
buff[fin.gcount()] = 0;
- this->TestsToRunString = buff;
- delete[] buff;
+ this->TestsToRunString = buff.get();
}
}
-bool cmCTestTestHandler::CleanTestOutput(std::string& output, size_t length)
+void cmCTestTestHandler::CleanTestOutput(std::string& output, size_t length)
{
if (!length || length >= output.size() ||
output.find("CTEST_FULL_OUTPUT") != std::string::npos) {
- return true;
+ return;
}
// Truncate at given length but do not break in the middle of a multi-byte
@@ -2076,7 +2129,7 @@ bool cmCTestTestHandler::CleanTestOutput(std::string& output, size_t length)
++current;
}
}
- output = output.substr(0, current - begin);
+ output.erase(current - begin);
// Append truncation message.
std::ostringstream msg;
@@ -2086,7 +2139,6 @@ bool cmCTestTestHandler::CleanTestOutput(std::string& output, size_t length)
"of "
<< length << " bytes.\n";
output += msg.str();
- return true;
}
bool cmCTestTestHandler::SetTestsProperties(
@@ -2107,16 +2159,16 @@ bool cmCTestTestHandler::SetTestsProperties(
}
++it; // skip PROPERTIES
for (; it != args.end(); ++it) {
- std::string key = *it;
+ std::string const& key = *it;
++it;
if (it == args.end()) {
break;
}
- std::string val = *it;
+ std::string const& val = *it;
for (std::string const& t : tests) {
for (cmCTestTestProperties& rt : this->TestList) {
if (t == rt.Name) {
- if (key == "_BACKTRACE_TRIPLES") {
+ if (key == "_BACKTRACE_TRIPLES"_s) {
std::vector<std::string> triples;
// allow empty args in the triples
cmExpandList(val, triples, true);
@@ -2140,91 +2192,70 @@ bool cmCTestTestHandler::SetTestsProperties(
rt.Backtrace = rt.Backtrace.Push(fc);
}
}
- }
- if (key == "WILL_FAIL") {
+ } else if (key == "WILL_FAIL"_s) {
rt.WillFail = cmIsOn(val);
- }
- if (key == "DISABLED") {
+ } else if (key == "DISABLED"_s) {
rt.Disabled = cmIsOn(val);
- }
- if (key == "ATTACHED_FILES") {
+ } else if (key == "ATTACHED_FILES"_s) {
cmExpandList(val, rt.AttachedFiles);
- }
- if (key == "ATTACHED_FILES_ON_FAIL") {
+ } else if (key == "ATTACHED_FILES_ON_FAIL"_s) {
cmExpandList(val, rt.AttachOnFail);
- }
- if (key == "RESOURCE_LOCK") {
+ } else if (key == "RESOURCE_LOCK"_s) {
std::vector<std::string> lval = cmExpandedList(val);
rt.LockedResources.insert(lval.begin(), lval.end());
- }
- if (key == "FIXTURES_SETUP") {
+ } else if (key == "FIXTURES_SETUP"_s) {
std::vector<std::string> lval = cmExpandedList(val);
rt.FixturesSetup.insert(lval.begin(), lval.end());
- }
- if (key == "FIXTURES_CLEANUP") {
+ } else if (key == "FIXTURES_CLEANUP"_s) {
std::vector<std::string> lval = cmExpandedList(val);
rt.FixturesCleanup.insert(lval.begin(), lval.end());
- }
- if (key == "FIXTURES_REQUIRED") {
+ } else if (key == "FIXTURES_REQUIRED"_s) {
std::vector<std::string> lval = cmExpandedList(val);
rt.FixturesRequired.insert(lval.begin(), lval.end());
- }
- if (key == "TIMEOUT") {
+ } else if (key == "TIMEOUT"_s) {
rt.Timeout = cmDuration(atof(val.c_str()));
rt.ExplicitTimeout = true;
- }
- if (key == "COST") {
+ } else if (key == "COST"_s) {
rt.Cost = static_cast<float>(atof(val.c_str()));
- }
- if (key == "REQUIRED_FILES") {
+ } else if (key == "REQUIRED_FILES"_s) {
cmExpandList(val, rt.RequiredFiles);
- }
- if (key == "RUN_SERIAL") {
+ } else if (key == "RUN_SERIAL"_s) {
rt.RunSerial = cmIsOn(val);
- }
- if (key == "FAIL_REGULAR_EXPRESSION") {
+ } else if (key == "FAIL_REGULAR_EXPRESSION"_s) {
std::vector<std::string> lval = cmExpandedList(val);
for (std::string const& cr : lval) {
rt.ErrorRegularExpressions.emplace_back(cr, cr);
}
- }
- if (key == "SKIP_REGULAR_EXPRESSION") {
+ } else if (key == "SKIP_REGULAR_EXPRESSION"_s) {
std::vector<std::string> lval = cmExpandedList(val);
for (std::string const& cr : lval) {
rt.SkipRegularExpressions.emplace_back(cr, cr);
}
- }
- if (key == "PROCESSORS") {
+ } else if (key == "PROCESSORS"_s) {
rt.Processors = atoi(val.c_str());
if (rt.Processors < 1) {
rt.Processors = 1;
}
- }
- if (key == "PROCESSOR_AFFINITY") {
+ } else if (key == "PROCESSOR_AFFINITY"_s) {
rt.WantAffinity = cmIsOn(val);
- }
- if (key == "RESOURCE_GROUPS") {
+ } else if (key == "RESOURCE_GROUPS"_s) {
if (!ParseResourceGroupsProperty(val, rt.ResourceGroups)) {
return false;
}
- }
- if (key == "SKIP_RETURN_CODE") {
+ } else if (key == "SKIP_RETURN_CODE"_s) {
rt.SkipReturnCode = atoi(val.c_str());
if (rt.SkipReturnCode < 0 || rt.SkipReturnCode > 255) {
rt.SkipReturnCode = -1;
}
- }
- if (key == "DEPENDS") {
+ } else if (key == "DEPENDS"_s) {
cmExpandList(val, rt.Depends);
- }
- if (key == "ENVIRONMENT") {
+ } else if (key == "ENVIRONMENT"_s) {
cmExpandList(val, rt.Environment);
- }
- if (key == "LABELS") {
+ } else if (key == "LABELS"_s) {
std::vector<std::string> Labels = cmExpandedList(val);
rt.Labels.insert(rt.Labels.end(), Labels.begin(), Labels.end());
// sort the array
@@ -2232,8 +2263,7 @@ bool cmCTestTestHandler::SetTestsProperties(
// remove duplicates
auto new_end = std::unique(rt.Labels.begin(), rt.Labels.end());
rt.Labels.erase(new_end, rt.Labels.end());
- }
- if (key == "MEASUREMENT") {
+ } else if (key == "MEASUREMENT"_s) {
size_t pos = val.find_first_of('=');
if (pos != std::string::npos) {
std::string mKey = val.substr(0, pos);
@@ -2242,17 +2272,14 @@ bool cmCTestTestHandler::SetTestsProperties(
} else {
rt.Measurements[val] = "1";
}
- }
- if (key == "PASS_REGULAR_EXPRESSION") {
+ } else if (key == "PASS_REGULAR_EXPRESSION"_s) {
std::vector<std::string> lval = cmExpandedList(val);
for (std::string const& cr : lval) {
rt.RequiredRegularExpressions.emplace_back(cr, cr);
}
- }
- if (key == "WORKING_DIRECTORY") {
+ } else if (key == "WORKING_DIRECTORY"_s) {
rt.Directory = val;
- }
- if (key == "TIMEOUT_AFTER_MATCH") {
+ } else if (key == "TIMEOUT_AFTER_MATCH"_s) {
std::vector<std::string> propArgs = cmExpandedList(val);
if (propArgs.size() != 2) {
cmCTestLog(this->CTest, WARNING,
@@ -2292,16 +2319,16 @@ bool cmCTestTestHandler::SetDirectoryProperties(
}
++it; // skip PROPERTIES
for (; it != args.end(); ++it) {
- std::string key = *it;
+ std::string const& key = *it;
++it;
if (it == args.end()) {
break;
}
- std::string val = *it;
+ std::string const& val = *it;
for (cmCTestTestProperties& rt : this->TestList) {
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
if (cwd == rt.Directory) {
- if (key == "LABELS") {
+ if (key == "LABELS"_s) {
std::vector<std::string> DirectoryLabels = cmExpandedList(val);
rt.Labels.insert(rt.Labels.end(), DirectoryLabels.begin(),
DirectoryLabels.end());
@@ -2380,10 +2407,9 @@ bool cmCTestTestHandler::AddTest(const std::vector<std::string>& args)
test.SkipReturnCode = -1;
test.PreviousRuns = 0;
if (this->UseIncludeRegExpFlag &&
- !this->IncludeTestsRegularExpression.find(testname)) {
- test.IsInBasedOnREOptions = false;
- } else if (this->UseExcludeRegExpFlag && !this->UseExcludeRegExpFirst &&
- this->ExcludeTestsRegularExpression.find(testname)) {
+ (!this->IncludeTestsRegularExpression.find(testname) ||
+ (!this->UseExcludeRegExpFirst &&
+ this->ExcludeTestsRegularExpression.find(testname)))) {
test.IsInBasedOnREOptions = false;
}
this->TestList.push_back(test);
diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h
index eab75d0..55cecb6 100644
--- a/Source/CTest/cmCTestTestHandler.h
+++ b/Source/CTest/cmCTestTestHandler.h
@@ -18,12 +18,12 @@
#include "cmsys/RegularExpression.hxx"
+#include "cmCTest.h"
#include "cmCTestGenericHandler.h"
#include "cmCTestResourceSpec.h"
#include "cmDuration.h"
#include "cmListFileCache.h"
-class cmCTest;
class cmMakefile;
class cmXMLWriter;
@@ -235,7 +235,7 @@ protected:
void AttachFiles(cmXMLWriter& xml, cmCTestTestResult& result);
//! Clean test output to specified length
- bool CleanTestOutput(std::string& output, size_t length);
+ void CleanTestOutput(std::string& output, size_t length);
cmDuration ElapsedTestingTime;
@@ -278,7 +278,7 @@ private:
/**
* Run the tests for a directory and any subdirectories
*/
- void ProcessDirectory(std::vector<std::string>& passed,
+ bool ProcessDirectory(std::vector<std::string>& passed,
std::vector<std::string>& failed);
/**
@@ -338,6 +338,7 @@ private:
bool UseResourceSpec;
cmCTestResourceSpec ResourceSpec;
+ std::string ResourceSpecFile;
void GenerateRegressionImages(cmXMLWriter& xml, const std::string& dart);
cmsys::RegularExpression DartStuff1;
@@ -353,6 +354,8 @@ private:
std::ostream* LogFile;
+ cmCTest::Repeat RepeatMode = cmCTest::Repeat::Never;
+ int RepeatCount = 1;
bool RerunFailed;
};
diff --git a/Source/CTest/cmCTestUploadCommand.cxx b/Source/CTest/cmCTestUploadCommand.cxx
index d0e3848..f86ee0d 100644
--- a/Source/CTest/cmCTestUploadCommand.cxx
+++ b/Source/CTest/cmCTestUploadCommand.cxx
@@ -4,11 +4,10 @@
#include <set>
#include <sstream>
-#include <vector>
-#include "cm_static_string_view.hxx"
+#include <cm/vector>
+#include <cmext/string_view>
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestUploadHandler.h"
#include "cmMakefile.h"
@@ -24,7 +23,7 @@ void cmCTestUploadCommand::BindArguments()
void cmCTestUploadCommand::CheckArguments(std::vector<std::string> const&)
{
- cmEraseIf(this->Files, [this](std::string const& arg) -> bool {
+ 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 "
diff --git a/Source/CTest/cmCTestVC.cxx b/Source/CTest/cmCTestVC.cxx
index 6026c69..452d714 100644
--- a/Source/CTest/cmCTestVC.cxx
+++ b/Source/CTest/cmCTestVC.cxx
@@ -38,7 +38,7 @@ void cmCTestVC::SetSourceDirectory(std::string const& dir)
this->SourceDirectory = dir;
}
-bool cmCTestVC::InitialCheckout(const char* command)
+bool cmCTestVC::InitialCheckout(const std::string& command)
{
cmCTestLog(this->CTest, HANDLER_OUTPUT,
" First perform the initial checkout: " << command << "\n");
diff --git a/Source/CTest/cmCTestVC.h b/Source/CTest/cmCTestVC.h
index 2a4765d..3037e01 100644
--- a/Source/CTest/cmCTestVC.h
+++ b/Source/CTest/cmCTestVC.h
@@ -36,7 +36,7 @@ public:
std::string GetNightlyTime();
/** Prepare the work tree. */
- bool InitialCheckout(const char* command);
+ bool InitialCheckout(const std::string& command);
/** Perform cleanup operations on the work tree. */
void Cleanup();
diff --git a/Source/CTest/cmParseCacheCoverage.cxx b/Source/CTest/cmParseCacheCoverage.cxx
index 8c4da75..84d7de0 100644
--- a/Source/CTest/cmParseCacheCoverage.cxx
+++ b/Source/CTest/cmParseCacheCoverage.cxx
@@ -4,6 +4,7 @@
#include <cstdlib>
#include <map>
#include <utility>
+#include <vector>
#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
@@ -19,7 +20,7 @@ cmParseCacheCoverage::cmParseCacheCoverage(
{
}
-bool cmParseCacheCoverage::LoadCoverageData(const char* d)
+bool cmParseCacheCoverage::LoadCoverageData(std::string const& d)
{
// load all the .mcov files in the specified directory
cmsys::Directory dir;
@@ -69,26 +70,6 @@ void cmParseCacheCoverage::RemoveUnCoveredFiles()
}
}
-bool cmParseCacheCoverage::SplitString(std::vector<std::string>& args,
- std::string const& line)
-{
- std::string::size_type pos1 = 0;
- std::string::size_type pos2 = line.find(',', 0);
- if (pos2 == std::string::npos) {
- return false;
- }
- std::string arg;
- while (pos2 != std::string::npos) {
- arg = line.substr(pos1, pos2 - pos1);
- args.push_back(arg);
- pos1 = pos2 + 1;
- pos2 = line.find(',', pos1);
- }
- arg = line.substr(pos1);
- args.push_back(arg);
- return true;
-}
-
bool cmParseCacheCoverage::ReadCMCovFile(const char* file)
{
cmsys::ifstream in(file);
@@ -97,7 +78,6 @@ bool cmParseCacheCoverage::ReadCMCovFile(const char* file)
return false;
}
std::string line;
- std::vector<std::string> separateLine;
if (!cmSystemTools::GetLineFromStream(in, line)) {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Empty file : " << file
@@ -106,8 +86,8 @@ bool cmParseCacheCoverage::ReadCMCovFile(const char* file)
<< line << "]\n");
return false;
}
- separateLine.clear();
- this->SplitString(separateLine, line);
+ std::vector<std::string> separateLine =
+ cmSystemTools::SplitString(line, ',');
if (separateLine.size() != 4 || separateLine[0] != "Routine" ||
separateLine[1] != "Line" || separateLine[2] != "RtnLine" ||
separateLine[3] != "Code") {
@@ -120,10 +100,8 @@ bool cmParseCacheCoverage::ReadCMCovFile(const char* file)
std::string routine;
std::string filepath;
while (cmSystemTools::GetLineFromStream(in, line)) {
- // clear out line argument vector
- separateLine.clear();
// parse the comma separated line
- this->SplitString(separateLine, line);
+ separateLine = cmSystemTools::SplitString(line, ',');
// might have more because code could have a quoted , in it
// but we only care about the first 3 args anyway
if (separateLine.size() < 4) {
@@ -155,7 +133,7 @@ bool cmParseCacheCoverage::ReadCMCovFile(const char* file)
// if we have a routine name, check for end of routine
else {
// Totals in arg 0 marks the end of a routine
- if (separateLine[0].substr(0, 6) == "Totals") {
+ if (cmHasLiteralPrefix(separateLine[0], "Totals")) {
routine.clear(); // at the end of this routine
filepath.clear();
continue; // move to next line
diff --git a/Source/CTest/cmParseCacheCoverage.h b/Source/CTest/cmParseCacheCoverage.h
index e89b9e4..a8200b7 100644
--- a/Source/CTest/cmParseCacheCoverage.h
+++ b/Source/CTest/cmParseCacheCoverage.h
@@ -6,7 +6,6 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <string>
-#include <vector>
#include "cmParseMumpsCoverage.h"
@@ -26,13 +25,11 @@ public:
protected:
// implement virtual from parent
- bool LoadCoverageData(const char* dir) override;
+ bool LoadCoverageData(std::string const& dir) override;
// remove files with no coverage
void RemoveUnCoveredFiles();
// Read a single mcov file
bool ReadCMCovFile(const char* f);
- // split a string based on ,
- bool SplitString(std::vector<std::string>& args, std::string const& line);
};
#endif
diff --git a/Source/CTest/cmParseCoberturaCoverage.cxx b/Source/CTest/cmParseCoberturaCoverage.cxx
index 05da84e..711a856 100644
--- a/Source/CTest/cmParseCoberturaCoverage.cxx
+++ b/Source/CTest/cmParseCoberturaCoverage.cxx
@@ -67,7 +67,7 @@ protected:
// Check if this is an absolute path that falls within our
// source or binary directories.
for (std::string const& filePath : FilePaths) {
- if (filename.find(filePath) == 0) {
+ if (cmHasPrefix(filename, filePath)) {
this->CurFileName = filename;
break;
}
diff --git a/Source/CTest/cmParseGTMCoverage.cxx b/Source/CTest/cmParseGTMCoverage.cxx
index 1dc5b70..14417cc 100644
--- a/Source/CTest/cmParseGTMCoverage.cxx
+++ b/Source/CTest/cmParseGTMCoverage.cxx
@@ -19,7 +19,7 @@ cmParseGTMCoverage::cmParseGTMCoverage(cmCTestCoverageHandlerContainer& cont,
{
}
-bool cmParseGTMCoverage::LoadCoverageData(const char* d)
+bool cmParseGTMCoverage::LoadCoverageData(std::string const& d)
{
// load all the .mcov files in the specified directory
cmsys::Directory dir;
diff --git a/Source/CTest/cmParseGTMCoverage.h b/Source/CTest/cmParseGTMCoverage.h
index fe0ae0b..41cc7f5 100644
--- a/Source/CTest/cmParseGTMCoverage.h
+++ b/Source/CTest/cmParseGTMCoverage.h
@@ -25,7 +25,7 @@ public:
protected:
// implement virtual from parent
- bool LoadCoverageData(const char* dir) override;
+ bool LoadCoverageData(std::string const& dir) override;
// Read a single mcov file
bool ReadMCovFile(const char* f);
// find out what line in a mumps file (filepath) the given entry point
diff --git a/Source/CTest/cmParseMumpsCoverage.cxx b/Source/CTest/cmParseMumpsCoverage.cxx
index b16f101..dc3064d 100644
--- a/Source/CTest/cmParseMumpsCoverage.cxx
+++ b/Source/CTest/cmParseMumpsCoverage.cxx
@@ -39,9 +39,9 @@ bool cmParseMumpsCoverage::ReadCoverageFile(const char* file)
std::string type = line.substr(0, pos);
std::string path = line.substr(pos + 1);
if (type == "packages") {
- this->LoadPackages(path.c_str());
+ this->LoadPackages(path);
} else if (type == "coverage_dir") {
- this->LoadCoverageData(path.c_str());
+ this->LoadCoverageData(path);
} else {
cmCTestLog(this->CTest, ERROR_MESSAGE,
"Parse Error in Mumps coverage file :\n"
@@ -105,7 +105,7 @@ void cmParseMumpsCoverage::InitializeMumpsFile(std::string& file)
}
}
-bool cmParseMumpsCoverage::LoadPackages(const char* d)
+bool cmParseMumpsCoverage::LoadPackages(std::string const& d)
{
cmsys::Glob glob;
glob.RecurseOn();
@@ -113,7 +113,8 @@ bool cmParseMumpsCoverage::LoadPackages(const char* d)
glob.FindFiles(pat);
for (std::string& file : glob.GetFiles()) {
std::string name = cmSystemTools::GetFilenameName(file);
- this->RoutineToDirectory[name.substr(0, name.size() - 2)] = file;
+ name.erase(name.size() - 2);
+ this->RoutineToDirectory[name] = file;
// initialize each file, this is left out until CDash is fixed
// to handle large numbers of files
this->InitializeMumpsFile(file);
diff --git a/Source/CTest/cmParseMumpsCoverage.h b/Source/CTest/cmParseMumpsCoverage.h
index 2c54495..8c08702 100644
--- a/Source/CTest/cmParseMumpsCoverage.h
+++ b/Source/CTest/cmParseMumpsCoverage.h
@@ -29,10 +29,10 @@ public:
protected:
// sub classes will use this to
// load all coverage files found in the given directory
- virtual bool LoadCoverageData(const char* d) = 0;
+ virtual bool LoadCoverageData(std::string const& d) = 0;
// search the package directory for mumps files and fill
// in the RoutineToDirectory map
- bool LoadPackages(const char* dir);
+ bool LoadPackages(std::string const& dir);
// initialize the coverage information for a single mumps file
void InitializeMumpsFile(std::string& file);
// Find mumps file for routine
diff --git a/Source/CTest/cmParsePHPCoverage.cxx b/Source/CTest/cmParsePHPCoverage.cxx
index a494b92..044f518 100644
--- a/Source/CTest/cmParsePHPCoverage.cxx
+++ b/Source/CTest/cmParsePHPCoverage.cxx
@@ -3,6 +3,8 @@
#include <cstdlib>
#include <cstring>
+#include <cm/memory>
+
#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
@@ -142,17 +144,15 @@ bool cmParsePHPCoverage::ReadFileInformation(std::istream& in)
int size = 0;
if (this->ReadInt(in, size)) {
size++; // add one for null termination
- char* s = new char[size + 1];
+ auto s = cm::make_unique<char[]>(size + 1);
// read open quote
if (in.get(c) && c != '"') {
- delete[] s;
return false;
}
// read the string data
- in.read(s, size - 1);
+ in.read(s.get(), size - 1);
s[size - 1] = 0;
- std::string fileName = s;
- delete[] s;
+ std::string fileName = s.get();
// read close quote
if (in.get(c) && c != '"') {
cmCTestLog(this->CTest, ERROR_MESSAGE,
diff --git a/Source/CTest/cmProcess.cxx b/Source/CTest/cmProcess.cxx
index 87f7147..a549117 100644
--- a/Source/CTest/cmProcess.cxx
+++ b/Source/CTest/cmProcess.cxx
@@ -5,24 +5,25 @@
#include <csignal>
#include <iostream>
#include <string>
+#include <utility>
+
+#include <cmext/algorithm>
#include "cmsys/Process.h"
-#include "cmAlgorithms.h"
#include "cmCTest.h"
#include "cmCTestRunTest.h"
#include "cmCTestTestHandler.h"
#include "cmGetPipes.h"
#include "cmStringAlgorithms.h"
#if defined(_WIN32)
-# include "cm_kwiml.h"
+# include <cm3p/kwiml/int.h>
#endif
-#include <utility>
#define CM_PROCESS_BUF_SIZE 65536
-cmProcess::cmProcess(cmCTestRunTest& runner)
- : Runner(runner)
+cmProcess::cmProcess(std::unique_ptr<cmCTestRunTest> runner)
+ : Runner(std::move(runner))
, Conv(cmProcessOutput::UTF8, CM_PROCESS_BUF_SIZE)
{
this->Timeout = cmDuration::zero();
@@ -68,7 +69,7 @@ bool cmProcess::StartProcess(uv_loop_t& loop, std::vector<size_t>* affinity)
cm::uv_timer_ptr timer;
int status = timer.init(loop, this);
if (status != 0) {
- cmCTestLog(this->Runner.GetCTest(), ERROR_MESSAGE,
+ cmCTestLog(this->Runner->GetCTest(), ERROR_MESSAGE,
"Error initializing timer: " << uv_strerror(status)
<< std::endl);
return false;
@@ -83,7 +84,7 @@ bool cmProcess::StartProcess(uv_loop_t& loop, std::vector<size_t>* affinity)
int fds[2] = { -1, -1 };
status = cmGetPipes(fds);
if (status != 0) {
- cmCTestLog(this->Runner.GetCTest(), ERROR_MESSAGE,
+ cmCTestLog(this->Runner->GetCTest(), ERROR_MESSAGE,
"Error initializing pipe: " << uv_strerror(status)
<< std::endl);
return false;
@@ -126,7 +127,7 @@ bool cmProcess::StartProcess(uv_loop_t& loop, std::vector<size_t>* affinity)
uv_read_start(pipe_reader, &cmProcess::OnAllocateCB, &cmProcess::OnReadCB);
if (status != 0) {
- cmCTestLog(this->Runner.GetCTest(), ERROR_MESSAGE,
+ cmCTestLog(this->Runner->GetCTest(), ERROR_MESSAGE,
"Error starting read events: " << uv_strerror(status)
<< std::endl);
return false;
@@ -134,7 +135,7 @@ bool cmProcess::StartProcess(uv_loop_t& loop, std::vector<size_t>* affinity)
status = this->Process.spawn(loop, options, this);
if (status != 0) {
- cmCTestLog(this->Runner.GetCTest(), ERROR_MESSAGE,
+ cmCTestLog(this->Runner->GetCTest(), ERROR_MESSAGE,
"Process not started\n " << this->Command << "\n["
<< uv_strerror(status) << "]\n");
return false;
@@ -151,7 +152,7 @@ bool cmProcess::StartProcess(uv_loop_t& loop, std::vector<size_t>* affinity)
void cmProcess::StartTimer()
{
- auto properties = this->Runner.GetTestProperties();
+ auto properties = this->Runner->GetTestProperties();
auto msec =
std::chrono::duration_cast<std::chrono::milliseconds>(this->Timeout);
@@ -218,10 +219,10 @@ void cmProcess::OnRead(ssize_t nread, const uv_buf_t* buf)
if (nread > 0) {
std::string strdata;
this->Conv.DecodeText(buf->base, static_cast<size_t>(nread), strdata);
- cmAppend(this->Output, strdata);
+ cm::append(this->Output, strdata);
while (this->Output.GetLine(line)) {
- this->Runner.CheckOutput(line);
+ this->Runner->CheckOutput(line);
line.clear();
}
@@ -235,20 +236,20 @@ void cmProcess::OnRead(ssize_t nread, const uv_buf_t* buf)
// The process will provide no more data.
if (nread != UV_EOF) {
auto error = static_cast<int>(nread);
- cmCTestLog(this->Runner.GetCTest(), ERROR_MESSAGE,
+ cmCTestLog(this->Runner->GetCTest(), ERROR_MESSAGE,
"Error reading stream: " << uv_strerror(error) << std::endl);
}
// Look for partial last lines.
if (this->Output.GetLast(line)) {
- this->Runner.CheckOutput(line);
+ this->Runner->CheckOutput(line);
}
this->ReadHandleClosed = true;
this->PipeReader.reset();
if (this->ProcessHandleClosed) {
uv_timer_stop(this->Timer);
- this->Runner.FinalizeTest();
+ this->Finish();
}
}
@@ -277,9 +278,6 @@ void cmProcess::OnTimeoutCB(uv_timer_t* timer)
void cmProcess::OnTimeout()
{
- if (this->ProcessState != cmProcess::State::Executing) {
- return;
- }
this->ProcessState = cmProcess::State::Expired;
bool const was_still_reading = !this->ReadHandleClosed;
if (!this->ReadHandleClosed) {
@@ -293,7 +291,7 @@ void cmProcess::OnTimeout()
// Our on-exit handler already ran but did not finish the test
// because we were still reading output. We've just dropped
// our read handler, so we need to finish the test now.
- this->Runner.FinalizeTest();
+ this->Finish();
}
}
@@ -323,6 +321,16 @@ void cmProcess::OnExit(int64_t exit_status, int term_signal)
// Record exit information.
this->ExitValue = exit_status;
this->Signal = term_signal;
+
+ this->ProcessHandleClosed = true;
+ if (this->ReadHandleClosed) {
+ uv_timer_stop(this->Timer);
+ this->Finish();
+ }
+}
+
+void cmProcess::Finish()
+{
this->TotalTime = std::chrono::steady_clock::now() - this->StartTime;
// Because of a processor clock scew the runtime may become slightly
// negative. If someone changed the system clock while the process was
@@ -331,12 +339,7 @@ void cmProcess::OnExit(int64_t exit_status, int term_signal)
if (this->TotalTime <= cmDuration::zero()) {
this->TotalTime = cmDuration::zero();
}
-
- this->ProcessHandleClosed = true;
- if (this->ReadHandleClosed) {
- uv_timer_stop(this->Timer);
- this->Runner.FinalizeTest();
- }
+ this->Runner->FinalizeTest();
}
cmProcess::State cmProcess::GetProcessStatus()
diff --git a/Source/CTest/cmProcess.h b/Source/CTest/cmProcess.h
index 2c24f2d..1e6578c 100644
--- a/Source/CTest/cmProcess.h
+++ b/Source/CTest/cmProcess.h
@@ -6,14 +6,15 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <chrono>
+#include <memory>
#include <string>
+#include <utility>
#include <vector>
+#include <cm3p/uv.h>
#include <stddef.h>
#include <stdint.h>
-#include "cm_uv.h"
-
#include "cmDuration.h"
#include "cmProcessOutput.h"
#include "cmUVHandlePtr.h"
@@ -28,7 +29,7 @@ class cmCTestRunTest;
class cmProcess
{
public:
- explicit cmProcess(cmCTestRunTest& runner);
+ explicit cmProcess(std::unique_ptr<cmCTestRunTest> runner);
~cmProcess();
void SetCommand(std::string const& command);
void SetCommandArguments(std::vector<std::string> const& arg);
@@ -70,6 +71,11 @@ public:
Exception GetExitException();
std::string GetExitExceptionString();
+ std::unique_ptr<cmCTestRunTest> GetRunner()
+ {
+ return std::move(this->Runner);
+ }
+
private:
cmDuration Timeout;
std::chrono::steady_clock::time_point StartTime;
@@ -82,7 +88,7 @@ private:
cm::uv_timer_ptr Timer;
std::vector<char> Buf;
- cmCTestRunTest& Runner;
+ std::unique_ptr<cmCTestRunTest> Runner;
cmProcessOutput Conv;
int Signal = 0;
cmProcess::State ProcessState = cmProcess::State::Starting;
@@ -101,6 +107,7 @@ private:
void OnAllocate(size_t suggested_size, uv_buf_t* buf);
void StartTimer();
+ void Finish();
class Buffer : public std::vector<char>
{
diff --git a/Source/Checks/Curses.cmake b/Source/Checks/Curses.cmake
index 2942b66..d35dd2a 100644
--- a/Source/Checks/Curses.cmake
+++ b/Source/Checks/Curses.cmake
@@ -1,4 +1,7 @@
-message(STATUS "Checking for curses support")
+include(${CMAKE_CURRENT_LIST_DIR}/cm_message_checks_compat.cmake)
+cm_message_checks_compat(
+ "Checking for curses support" __checkStart __checkPass __checkFail)
+message(${__checkStart})
# Try compiling a simple project using curses.
# Pass in any cache entries that the user may have set.
@@ -31,11 +34,11 @@ set(CMakeCheckCurses_COMPILED "${CMakeCheckCurses_COMPILED}")
unset(CMakeCheckCurses_COMPILED CACHE)
if(CMakeCheckCurses_COMPILED)
- message(STATUS "Checking for curses support - Success")
+ message(${__checkPass} "Success")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Checking for curses support passed with the following output:\n${CMakeCheckCurses_OUTPUT}\n\n")
else()
- message(STATUS "Checking for curses support - Failed")
+ message(${__checkFail} "Failed")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Checking for curses support failed with the following output:\n${CMakeCheckCurses_OUTPUT}\n\n")
endif()
diff --git a/Source/Checks/cm_c11_thread_local.cmake b/Source/Checks/cm_c11_thread_local.cmake
index 6b8d10b..2263be3 100644
--- a/Source/Checks/cm_c11_thread_local.cmake
+++ b/Source/Checks/cm_c11_thread_local.cmake
@@ -1,7 +1,11 @@
set(CMake_C11_THREAD_LOCAL_BROKEN 0)
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_C11_STANDARD_COMPILE_OPTION)
if(NOT DEFINED CMake_C11_THREAD_LOCAL_WORKS)
- message(STATUS "Checking if compiler supports C11 _Thread_local")
+ include(${CMAKE_CURRENT_LIST_DIR}/cm_message_checks_compat.cmake)
+ cm_message_checks_compat(
+ "Checking if compiler supports C11 _Thread_local"
+ __checkStart __checkPass __checkFail)
+ message(${__checkStart})
try_compile(CMake_C11_THREAD_LOCAL_WORKS
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_LIST_DIR}/cm_c11_thread_local.c
@@ -12,14 +16,14 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_C11_STANDARD_COMPILE_OPTION)
set_property(CACHE CMake_C11_THREAD_LOCAL_WORKS PROPERTY VALUE 0)
endif()
if(CMake_C11_THREAD_LOCAL_WORKS)
- message(STATUS "Checking if compiler supports C11 _Thread_local - yes")
+ message(${__checkPass} "yes")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if compiler supports C11 _Thread_local passed with the following output:\n"
"${OUTPUT}\n"
"\n"
)
else()
- message(STATUS "Checking if compiler supports C11 _Thread_local - no")
+ message(${__checkFail} "no")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if compiler supports C11 _Thread_local failed with the following output:\n"
"${OUTPUT}\n"
diff --git a/Source/Checks/cm_cxx14_check.cmake b/Source/Checks/cm_cxx14_check.cmake
index 38606b9..e5656bf 100644
--- a/Source/Checks/cm_cxx14_check.cmake
+++ b/Source/Checks/cm_cxx14_check.cmake
@@ -1,10 +1,14 @@
set(CMake_CXX14_BROKEN 0)
-if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|PGI")
+if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|PGI|Intel")
if(NOT CMAKE_CXX14_STANDARD_COMPILE_OPTION)
set(CMake_CXX14_WORKS 0)
endif()
if(NOT DEFINED CMake_CXX14_WORKS)
- message(STATUS "Checking if compiler supports needed C++14 constructs")
+ include(${CMAKE_CURRENT_LIST_DIR}/cm_message_checks_compat.cmake)
+ cm_message_checks_compat(
+ "Checking if compiler supports needed C++14 constructs"
+ __checkStart __checkPass __checkFail)
+ message(${__checkStart})
try_compile(CMake_CXX14_WORKS
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_LIST_DIR}/cm_cxx14_check.cpp
@@ -15,14 +19,14 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|PGI")
set_property(CACHE CMake_CXX14_WORKS PROPERTY VALUE 0)
endif()
if(CMake_CXX14_WORKS)
- message(STATUS "Checking if compiler supports needed C++14 constructs - yes")
+ message(${__checkPass} "yes")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if compiler supports needed C++14 constructs passed with the following output:\n"
"${OUTPUT}\n"
"\n"
)
else()
- message(STATUS "Checking if compiler supports needed C++14 constructs - no")
+ message(${__checkFail} "no")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if compiler supports needed C++14 constructs failed with the following output:\n"
"${OUTPUT}\n"
diff --git a/Source/Checks/cm_cxx17_check.cmake b/Source/Checks/cm_cxx17_check.cmake
index 4da2fd7..dba3eaf 100644
--- a/Source/Checks/cm_cxx17_check.cmake
+++ b/Source/Checks/cm_cxx17_check.cmake
@@ -1,10 +1,14 @@
set(CMake_CXX17_BROKEN 0)
-if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|PGI")
+if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|PGI|Intel")
if(NOT CMAKE_CXX17_STANDARD_COMPILE_OPTION)
set(CMake_CXX17_WORKS 0)
endif()
if(NOT DEFINED CMake_CXX17_WORKS)
- message(STATUS "Checking if compiler supports needed C++17 constructs")
+ include(${CMAKE_CURRENT_LIST_DIR}/cm_message_checks_compat.cmake)
+ cm_message_checks_compat(
+ "Checking if compiler supports needed C++17 constructs"
+ __checkStart __checkPass __checkFail)
+ message(${__checkStart})
try_compile(CMake_CXX17_WORKS
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_LIST_DIR}/cm_cxx17_check.cpp
@@ -15,14 +19,14 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|PGI")
set_property(CACHE CMake_CXX17_WORKS PROPERTY VALUE 0)
endif()
if(CMake_CXX17_WORKS)
- message(STATUS "Checking if compiler supports needed C++17 constructs - yes")
+ message(${__checkPass} "yes")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if compiler supports needed C++17 constructs passed with the following output:\n"
"${OUTPUT}\n"
"\n"
)
else()
- message(STATUS "Checking if compiler supports needed C++17 constructs - no")
+ message(${__checkFail} "no")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if compiler supports needed C++17 constructs failed with the following output:\n"
"${OUTPUT}\n"
diff --git a/Source/Checks/cm_cxx17_check.cpp b/Source/Checks/cm_cxx17_check.cpp
index 29863b1..abbe22c 100644
--- a/Source/Checks/cm_cxx17_check.cpp
+++ b/Source/Checks/cm_cxx17_check.cpp
@@ -8,6 +8,13 @@
# include <comdef.h>
#endif
+template <typename T,
+ typename std::invoke_result<decltype(&T::get), T>::type = nullptr>
+typename T::pointer get_ptr(T& item)
+{
+ return item.get();
+}
+
int main()
{
int a[] = { 0, 1, 2 };
@@ -20,6 +27,9 @@ int main()
std::unique_ptr<int> u(new int(0));
+ // Intel compiler do not handle correctly 'decltype' inside 'invoke_result'
+ get_ptr(u);
+
#ifdef _MSC_VER
// clang-cl has problems instantiating this constructor in C++17 mode
// error: indirection requires pointer operand ('const _GUID' invalid)
diff --git a/Source/Checks/cm_cxx_features.cmake b/Source/Checks/cm_cxx_features.cmake
index fb68ed7..50ccc7c 100644
--- a/Source/Checks/cm_cxx_features.cmake
+++ b/Source/Checks/cm_cxx_features.cmake
@@ -1,8 +1,12 @@
+include(${CMAKE_CURRENT_LIST_DIR}/cm_message_checks_compat.cmake)
function(cm_check_cxx_feature name)
string(TOUPPER ${name} FEATURE)
if(NOT DEFINED CMake_HAVE_CXX_${FEATURE})
- message(STATUS "Checking if compiler supports C++ ${name}")
+ cm_message_checks_compat(
+ "Checking if compiler supports C++ ${name}"
+ __checkStart __checkPass __checkFail)
+ message(${__checkStart})
if(CMAKE_CXX_STANDARD)
set(maybe_cxx_standard -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD})
else()
@@ -24,21 +28,27 @@ function(cm_check_cxx_feature name)
string(REGEX REPLACE "[^\n]*warning:[^\n]*object file compiled with -mlong-branch which is no longer needed[^\n]*" "" check_output "${check_output}")
# Filter out other warnings unrelated to feature checks.
string(REGEX REPLACE "[^\n]*warning:[^\n]*sprintf\\(\\) is often misused, please use snprintf[^\n]*" "" check_output "${check_output}")
+ # Filter out libhugetlbfs warnings.
+ string(REGEX REPLACE "[^\n]*libhugetlbfs [^\n]*: WARNING[^\n]*" "" check_output "${check_output}")
# Filter out xcodebuild warnings.
string(REGEX REPLACE "[^\n]* xcodebuild\\[[0-9]*:[0-9]*\\] warning: [^\n]*" "" check_output "${check_output}")
+ # Filter out icpc warnings
+ string(REGEX REPLACE "[^\n]*icpc: command line warning #10121: overriding [^\n]*" "" check_output "${check_output}")
+ # Filter out ld warnings.
+ string(REGEX REPLACE "[^\n]*ld: warning: [^\n]*" "" check_output "${check_output}")
# If using the feature causes warnings, treat it as broken/unavailable.
if(check_output MATCHES "(^|[ :])[Ww][Aa][Rr][Nn][Ii][Nn][Gg]")
set(CMake_HAVE_CXX_${FEATURE} OFF CACHE INTERNAL "TRY_COMPILE" FORCE)
endif()
if(CMake_HAVE_CXX_${FEATURE})
- message(STATUS "Checking if compiler supports C++ ${name} - yes")
+ message(${__checkPass} "yes")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if compiler supports C++ ${name} passed with the following output:\n"
"${OUTPUT}\n"
"\n"
)
else()
- message(STATUS "Checking if compiler supports C++ ${name} - no")
+ message(${__checkFail} "no")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if compiler supports C++ ${name} failed with the following output:\n"
"${OUTPUT}\n"
diff --git a/Source/Checks/cm_message_checks_compat.cmake b/Source/Checks/cm_message_checks_compat.cmake
new file mode 100644
index 0000000..024c397
--- /dev/null
+++ b/Source/Checks/cm_message_checks_compat.cmake
@@ -0,0 +1,13 @@
+# Supporting using the CHECK_... message modes if available
+# and fall back to the older behavior if not
+macro(cm_message_checks_compat description startVar passVar failVar)
+ if(CMAKE_VERSION VERSION_GREATER 3.16.2019)
+ set(${startVar} CHECK_START "${description}")
+ set(${passVar} CHECK_PASS)
+ set(${failVar} CHECK_FAIL)
+ else()
+ set(${startVar} STATUS "${description}")
+ set(${passVar} STATUS "${description} - ")
+ set(${failVar} STATUS "${description} - ")
+ endif()
+endmacro()
diff --git a/Source/CursesDialog/CMakeLists.txt b/Source/CursesDialog/CMakeLists.txt
index 7009717..c24ee76 100644
--- a/Source/CursesDialog/CMakeLists.txt
+++ b/Source/CursesDialog/CMakeLists.txt
@@ -5,6 +5,7 @@ add_executable(ccmake
ccmake.cxx
cmCursesBoolWidget.cxx
cmCursesCacheEntryComposite.cxx
+ cmCursesColor.cxx
cmCursesDummyWidget.cxx
cmCursesFilePathWidget.cxx
cmCursesForm.cxx
@@ -17,21 +18,45 @@ add_executable(ccmake
cmCursesWidget.cxx
)
target_include_directories(ccmake PRIVATE ${CURSES_INCLUDE_PATH})
+set(CMAKE_REQUIRED_INCLUDES ${CURSES_INCLUDE_PATH})
target_link_libraries(ccmake CMakeLib)
if(CMAKE_USE_SYSTEM_FORM)
find_path(CURSES_FORM_INCLUDE_DIR NAMES form.h HINTS ${CURSES_INCLUDE_PATH} ${CURSES_INCLUDE_PATH}/ncurses)
if(CURSES_FORM_INCLUDE_DIR)
target_include_directories(ccmake PRIVATE ${CURSES_FORM_INCLUDE_DIR})
+ list(APPEND CMAKE_REQUIRED_INCLUDES ${CURSES_FORM_INCLUDE_DIR})
endif()
target_link_libraries(ccmake
${CURSES_FORM_LIBRARY}
${CURSES_LIBRARY}
)
+ set(CMAKE_REQUIRED_LIBRARIES
+ ${CURSES_FORM_LIBRARY}
+ ${CURSES_LIBRARY}
+ )
if(CURSES_EXTRA_LIBRARY)
target_link_libraries(ccmake ${CURSES_EXTRA_LIBRARY})
+ list(APPEND CMAKE_REQUIRED_LIBRARIES ${CURSES_EXTRA_LIBRARY})
endif()
else()
target_link_libraries(ccmake cmForm)
+ get_target_property(cmFormIncludeDirs cmForm INTERFACE_INCLUDE_DIRECTORIES)
+ list(APPEND CMAKE_REQUIRED_INCLUDES ${cmFormIncludeDirs})
+ get_target_property(cmFormLibraries cmForm INTERFACE_LINK_LIBRARIES)
+ set(CMAKE_REQUIRED_LIBRARIES ${cmFormLibraries})
+endif()
+
+include(CheckSymbolExists)
+check_symbol_exists(use_default_colors
+ "form.h"
+ HAVE_CURSES_USE_DEFAULT_COLORS)
+if(HAVE_CURSES_USE_DEFAULT_COLORS)
+ set_source_files_properties(cmCursesColor.cxx
+ PROPERTIES COMPILE_DEFINITIONS HAVE_CURSES_USE_DEFAULT_COLORS)
+endif()
+
+if(CMake_JOB_POOL_LINK_BIN)
+ set_property(TARGET ccmake PROPERTY JOB_POOL_LINK "link-bin")
endif()
CMake_OPTIONAL_COMPONENT(ccmake)
diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx
index 9e9dfbd..9a26db5 100644
--- a/Source/CursesDialog/ccmake.cxx
+++ b/Source/CursesDialog/ccmake.cxx
@@ -9,12 +9,14 @@
#include "cmsys/Encoding.hxx"
+#include "cmCursesColor.h"
#include "cmCursesForm.h"
#include "cmCursesMainForm.h"
#include "cmCursesStandardIncludes.h"
#include "cmDocumentation.h"
#include "cmDocumentationEntry.h" // IWYU pragma: keep
#include "cmState.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
@@ -110,8 +112,8 @@ int main(int argc, char const* const* argv)
std::string cacheDir = cmSystemTools::GetCurrentWorkingDirectory();
for (i = 1; i < args.size(); ++i) {
- std::string arg = args[i];
- if (arg.find("-B", 0) == 0) {
+ std::string const& arg = args[i];
+ if (cmHasPrefix(arg, "-B")) {
cacheDir = arg.substr(2);
}
}
@@ -126,6 +128,7 @@ int main(int argc, char const* const* argv)
noecho(); /* Echo off */
cbreak(); /* nl- or cr not needed */
keypad(stdscr, true); /* Use key symbols as KEY_DOWN */
+ cmCursesColor::InitColors();
signal(SIGWINCH, onsig);
@@ -153,10 +156,28 @@ int main(int argc, char const* const* argv)
return 1;
}
+ /*
+ * The message is stored in a list by the form which will be
+ * joined by '\n' before display.
+ * Removing any trailing '\n' avoid extra empty lines in the final results
+ */
+ auto cleanMessage = [](const std::string& message) -> std::string {
+ auto msg = message;
+ if (!msg.empty() && msg.back() == '\n') {
+ msg.pop_back();
+ }
+ return msg;
+ };
cmSystemTools::SetMessageCallback(
- [myform](const std::string& message, const char* title) {
- myform->AddError(message, title);
+ [&](const std::string& message, const char* title) {
+ myform->AddError(cleanMessage(message), title);
});
+ cmSystemTools::SetStderrCallback([&](const std::string& message) {
+ myform->AddError(cleanMessage(message), "");
+ });
+ cmSystemTools::SetStdoutCallback([&](const std::string& message) {
+ myform->UpdateProgress(cleanMessage(message), -1);
+ });
cmCursesForm::CurrentForm = myform;
diff --git a/Source/CursesDialog/cmCursesBoolWidget.cxx b/Source/CursesDialog/cmCursesBoolWidget.cxx
index 97b0811..c4dbed8 100644
--- a/Source/CursesDialog/cmCursesBoolWidget.cxx
+++ b/Source/CursesDialog/cmCursesBoolWidget.cxx
@@ -4,6 +4,7 @@
#include <string>
+#include "cmCursesColor.h"
#include "cmCursesWidget.h"
#include "cmStateTypes.h"
@@ -12,8 +13,10 @@ cmCursesBoolWidget::cmCursesBoolWidget(int width, int height, int left,
: cmCursesWidget(width, height, left, top)
{
this->Type = cmStateEnums::BOOL;
- set_field_fore(this->Field, A_NORMAL);
- set_field_back(this->Field, A_STANDOUT);
+ if (!cmCursesColor::HasColors()) {
+ set_field_fore(this->Field, A_NORMAL);
+ set_field_back(this->Field, A_STANDOUT);
+ }
field_opts_off(this->Field, O_STATIC);
this->SetValueAsBool(false);
}
@@ -42,8 +45,16 @@ void cmCursesBoolWidget::SetValueAsBool(bool value)
{
if (value) {
this->SetValue("ON");
+ if (cmCursesColor::HasColors()) {
+ set_field_fore(this->Field, COLOR_PAIR(cmCursesColor::BoolOn));
+ set_field_back(this->Field, COLOR_PAIR(cmCursesColor::BoolOn));
+ }
} else {
this->SetValue("OFF");
+ if (cmCursesColor::HasColors()) {
+ set_field_fore(this->Field, COLOR_PAIR(cmCursesColor::BoolOff));
+ set_field_back(this->Field, COLOR_PAIR(cmCursesColor::BoolOff));
+ }
}
}
diff --git a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
index 4d3131b..9250fbc 100644
--- a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
+++ b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
@@ -48,42 +48,42 @@ cmCursesCacheEntryComposite::cmCursesCacheEntryComposite(
this->IsNewLabel = cm::make_unique<cmCursesLabelWidget>(1, 1, 1, 1, " ");
}
- const char* value = state->GetCacheEntryValue(key);
+ cmProp value = state->GetCacheEntryValue(key);
assert(value);
switch (state->GetCacheEntryType(key)) {
case cmStateEnums::BOOL: {
auto bw = cm::make_unique<cmCursesBoolWidget>(this->EntryWidth, 1, 1, 1);
- bw->SetValueAsBool(cmIsOn(value));
+ bw->SetValueAsBool(cmIsOn(*value));
this->Entry = std::move(bw);
break;
}
case cmStateEnums::PATH: {
auto pw = cm::make_unique<cmCursesPathWidget>(this->EntryWidth, 1, 1, 1);
- pw->SetString(value);
+ pw->SetString(*value);
this->Entry = std::move(pw);
break;
}
case cmStateEnums::FILEPATH: {
auto fpw =
cm::make_unique<cmCursesFilePathWidget>(this->EntryWidth, 1, 1, 1);
- fpw->SetString(value);
+ fpw->SetString(*value);
this->Entry = std::move(fpw);
break;
}
case cmStateEnums::STRING: {
- const char* stringsProp = state->GetCacheEntryProperty(key, "STRINGS");
+ cmProp stringsProp = state->GetCacheEntryProperty(key, "STRINGS");
if (stringsProp) {
auto ow =
cm::make_unique<cmCursesOptionsWidget>(this->EntryWidth, 1, 1, 1);
- for (std::string const& opt : cmExpandedList(stringsProp)) {
+ for (std::string const& opt : cmExpandedList(*stringsProp)) {
ow->AddOption(opt);
}
- ow->SetOption(value);
+ ow->SetOption(*value);
this->Entry = std::move(ow);
} else {
auto sw =
cm::make_unique<cmCursesStringWidget>(this->EntryWidth, 1, 1, 1);
- sw->SetString(value);
+ sw->SetString(*value);
this->Entry = std::move(sw);
}
break;
diff --git a/Source/CursesDialog/cmCursesColor.cxx b/Source/CursesDialog/cmCursesColor.cxx
new file mode 100644
index 0000000..c0b468b
--- /dev/null
+++ b/Source/CursesDialog/cmCursesColor.cxx
@@ -0,0 +1,78 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmCursesColor.h"
+
+#include <cctype>
+#include <cstdlib>
+#include <cstring>
+#include <unordered_map>
+#include <utility>
+
+#include "cmCursesStandardIncludes.h"
+
+bool cmCursesColor::HasColors()
+{
+#ifdef HAVE_CURSES_USE_DEFAULT_COLORS
+ return has_colors();
+#else
+ return false;
+#endif
+}
+
+void cmCursesColor::InitColors()
+{
+#ifdef HAVE_CURSES_USE_DEFAULT_COLORS
+ if (HasColors()) {
+ start_color();
+ use_default_colors();
+ init_pair(BoolOff, GetColor('N', COLOR_RED), -1);
+ init_pair(BoolOn, GetColor('Y', COLOR_GREEN), -1);
+ init_pair(String, GetColor('S', COLOR_CYAN), -1);
+ init_pair(Path, GetColor('P', COLOR_YELLOW), -1);
+ init_pair(Choice, GetColor('C', COLOR_MAGENTA), -1);
+ }
+#endif
+}
+
+short cmCursesColor::GetColor(char id, short fallback)
+{
+ static bool initialized = false;
+ static std::unordered_map<char, short> env;
+
+ if (!initialized) {
+ if (auto* v = getenv("CCMAKE_COLORS")) {
+ while (v[0] && v[1] && v[1] == '=') {
+ auto const n = std::toupper(*v);
+
+ char buffer[12];
+ memset(buffer, 0, sizeof(buffer));
+
+ if (auto* const e = strchr(v, ':')) {
+ if (static_cast<size_t>(e - v) > sizeof(buffer)) {
+ break;
+ }
+
+ strncpy(buffer, v + 2, static_cast<size_t>(e - v - 2));
+ v = e + 1;
+ } else {
+ auto const l = strlen(v);
+ if (l > sizeof(buffer)) {
+ break;
+ }
+
+ strncpy(buffer, v + 2, l - 2);
+ v += l;
+ }
+
+ auto const c = atoi(buffer);
+ if (c && c < COLORS) {
+ env.emplace(n, static_cast<short>(c));
+ }
+ }
+ }
+ initialized = true;
+ }
+
+ auto const iter = env.find(id);
+ return (iter == env.end() ? fallback : iter->second);
+}
diff --git a/Source/CursesDialog/cmCursesColor.h b/Source/CursesDialog/cmCursesColor.h
new file mode 100644
index 0000000..f83265f
--- /dev/null
+++ b/Source/CursesDialog/cmCursesColor.h
@@ -0,0 +1,27 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmCursesColor_h
+#define cmCursesColor_h
+
+class cmCursesColor
+{
+public:
+ enum Color
+ {
+ // Default color is pair 0
+ BoolOff = 1,
+ BoolOn,
+ String,
+ Path,
+ Choice
+ };
+
+ static bool HasColors();
+
+ static void InitColors();
+
+protected:
+ static short GetColor(char id, short fallback);
+};
+
+#endif // cmCursesColor_h
diff --git a/Source/CursesDialog/cmCursesLongMessageForm.cxx b/Source/CursesDialog/cmCursesLongMessageForm.cxx
index e2d8d06..664ba2f 100644
--- a/Source/CursesDialog/cmCursesLongMessageForm.cxx
+++ b/Source/CursesDialog/cmCursesLongMessageForm.cxx
@@ -8,6 +8,7 @@
#include "cmCursesForm.h"
#include "cmCursesMainForm.h"
#include "cmCursesStandardIncludes.h"
+#include "cmStringAlgorithms.h"
#include "cmVersion.h"
inline int ctrl(int z)
@@ -16,14 +17,12 @@ inline int ctrl(int z)
}
cmCursesLongMessageForm::cmCursesLongMessageForm(
- std::vector<std::string> const& messages, const char* title)
+ std::vector<std::string> const& messages, const char* title,
+ ScrollBehavior scrollBehavior)
+ : Scrolling(scrollBehavior)
{
// Append all messages into on big string
- for (std::string const& message : messages) {
- this->Messages += message;
- // Add one blank line after each message
- this->Messages += "\n\n";
- }
+ this->Messages = cmJoin(messages, "\n");
this->Title = title;
this->Fields[0] = nullptr;
this->Fields[1] = nullptr;
@@ -36,6 +35,23 @@ cmCursesLongMessageForm::~cmCursesLongMessageForm()
}
}
+void cmCursesLongMessageForm::UpdateContent(std::string const& output,
+ std::string const& title)
+{
+ this->Title = title;
+
+ if (!output.empty() && this->Messages.size() < MAX_CONTENT_SIZE) {
+ this->Messages.push_back('\n');
+ this->Messages.append(output);
+ form_driver(this->Form, REQ_NEW_LINE);
+ this->DrawMessage(output.c_str());
+ }
+
+ this->UpdateStatusBar();
+ touchwin(stdscr);
+ refresh();
+}
+
void cmCursesLongMessageForm::UpdateStatusBar()
{
int x;
@@ -48,7 +64,7 @@ void cmCursesLongMessageForm::UpdateStatusBar()
size = cmCursesMainForm::MAX_WIDTH - 1;
}
strncpy(bar, this->Title.c_str(), size);
- for (size_t i = size - 1; i < cmCursesMainForm::MAX_WIDTH; i++) {
+ for (size_t i = size; i < cmCursesMainForm::MAX_WIDTH; i++) {
bar[i] = ' ';
}
int width;
@@ -89,7 +105,7 @@ void cmCursesLongMessageForm::PrintKeys()
return;
}
char firstLine[512];
- sprintf(firstLine, "Press [e] to exit help");
+ sprintf(firstLine, "Press [e] to exit screen");
char fmt_s[] = "%s";
curses_move(y - 2, 0);
@@ -110,10 +126,6 @@ void cmCursesLongMessageForm::Render(int /*left*/, int /*top*/, int /*width*/,
this->Form = nullptr;
}
- const char* msg = this->Messages.c_str();
-
- curses_clear();
-
if (this->Fields[0]) {
free_field(this->Fields[0]);
this->Fields[0] = nullptr;
@@ -126,9 +138,18 @@ void cmCursesLongMessageForm::Render(int /*left*/, int /*top*/, int /*width*/,
this->Form = new_form(this->Fields);
post_form(this->Form);
- int i = 0;
form_driver(this->Form, REQ_BEG_FIELD);
- while (msg[i] != '\0' && i < 60000) {
+ this->DrawMessage(this->Messages.c_str());
+
+ this->UpdateStatusBar();
+ touchwin(stdscr);
+ refresh();
+}
+
+void cmCursesLongMessageForm::DrawMessage(const char* msg) const
+{
+ int i = 0;
+ while (msg[i] != '\0' && i < MAX_CONTENT_SIZE) {
if (msg[i] == '\n' && msg[i + 1] != '\0') {
form_driver(this->Form, REQ_NEW_LINE);
} else {
@@ -136,12 +157,11 @@ void cmCursesLongMessageForm::Render(int /*left*/, int /*top*/, int /*width*/,
}
i++;
}
- form_driver(this->Form, REQ_BEG_FIELD);
-
- this->UpdateStatusBar();
- this->PrintKeys();
- touchwin(stdscr);
- refresh();
+ if (this->Scrolling == ScrollBehavior::ScrollDown) {
+ form_driver(this->Form, REQ_END_FIELD);
+ } else {
+ form_driver(this->Form, REQ_BEG_FIELD);
+ }
}
void cmCursesLongMessageForm::HandleInput()
@@ -153,6 +173,7 @@ void cmCursesLongMessageForm::HandleInput()
char debugMessage[128];
for (;;) {
+ this->PrintKeys();
int key = getch();
sprintf(debugMessage, "Message widget handling input, key: %d", key);
@@ -173,7 +194,6 @@ void cmCursesLongMessageForm::HandleInput()
}
this->UpdateStatusBar();
- this->PrintKeys();
touchwin(stdscr);
wrefresh(stdscr);
}
diff --git a/Source/CursesDialog/cmCursesLongMessageForm.h b/Source/CursesDialog/cmCursesLongMessageForm.h
index 42f9c71..da9fea2 100644
--- a/Source/CursesDialog/cmCursesLongMessageForm.h
+++ b/Source/CursesDialog/cmCursesLongMessageForm.h
@@ -14,13 +14,21 @@
class cmCursesLongMessageForm : public cmCursesForm
{
public:
+ enum class ScrollBehavior
+ {
+ NoScroll,
+ ScrollDown
+ };
+
cmCursesLongMessageForm(std::vector<std::string> const& messages,
- const char* title);
+ const char* title, ScrollBehavior scrollBehavior);
~cmCursesLongMessageForm() override;
cmCursesLongMessageForm(cmCursesLongMessageForm const&) = delete;
cmCursesLongMessageForm& operator=(cmCursesLongMessageForm const&) = delete;
+ void UpdateContent(std::string const& output, std::string const& title);
+
// Description:
// Handle user input.
void HandleInput() override;
@@ -41,8 +49,13 @@ public:
void UpdateStatusBar() override;
protected:
+ static constexpr int MAX_CONTENT_SIZE = 60000;
+
+ void DrawMessage(const char* msg) const;
+
std::string Messages;
std::string Title;
+ ScrollBehavior Scrolling;
FIELD* Fields[2];
};
diff --git a/Source/CursesDialog/cmCursesMainForm.cxx b/Source/CursesDialog/cmCursesMainForm.cxx
index 6b71e8a..df34283 100644
--- a/Source/CursesDialog/cmCursesMainForm.cxx
+++ b/Source/CursesDialog/cmCursesMainForm.cxx
@@ -34,6 +34,7 @@ cmCursesMainForm::cmCursesMainForm(std::vector<std::string> args,
: Args(std::move(args))
, InitialWidth(initWidth)
{
+ this->HasNonStatusOutputs = false;
this->NumberOfPages = 0;
this->AdvancedMode = false;
this->NumberOfVisibleEntries = 0;
@@ -160,7 +161,7 @@ void cmCursesMainForm::RePost()
// If normal mode, count only non-advanced entries
this->NumberOfVisibleEntries = 0;
for (cmCursesCacheEntryComposite& entry : this->Entries) {
- const char* existingValue =
+ cmProp existingValue =
this->CMakeInstance->GetState()->GetCacheEntryValue(entry.GetValue());
bool advanced =
this->CMakeInstance->GetState()->GetCacheEntryPropertyAsBool(
@@ -181,7 +182,7 @@ void cmCursesMainForm::RePost()
// Assign fields
for (cmCursesCacheEntryComposite& entry : this->Entries) {
- const char* existingValue =
+ cmProp existingValue =
this->CMakeInstance->GetState()->GetCacheEntryValue(entry.GetValue());
bool advanced =
this->CMakeInstance->GetState()->GetCacheEntryPropertyAsBool(
@@ -240,7 +241,7 @@ void cmCursesMainForm::Render(int left, int top, int width, int height)
// If normal, display only non-advanced entries
this->NumberOfVisibleEntries = 0;
for (cmCursesCacheEntryComposite& entry : this->Entries) {
- const char* existingValue =
+ cmProp existingValue =
this->CMakeInstance->GetState()->GetCacheEntryValue(entry.GetValue());
bool advanced =
this->CMakeInstance->GetState()->GetCacheEntryPropertyAsBool(
@@ -258,7 +259,7 @@ void cmCursesMainForm::Render(int left, int top, int width, int height)
bool isNewPage;
int i = 0;
for (cmCursesCacheEntryComposite& entry : this->Entries) {
- const char* existingValue =
+ cmProp existingValue =
this->CMakeInstance->GetState()->GetCacheEntryValue(entry.GetValue());
bool advanced =
this->CMakeInstance->GetState()->GetCacheEntryPropertyAsBool(
@@ -321,25 +322,25 @@ void cmCursesMainForm::PrintKeys(int process /* = 0 */)
} else {
if (this->OkToGenerate) {
sprintf(firstLine,
- "Press [c] to configure Press [g] to generate and exit");
+ " [l] Show log output [c] Configure"
+ " [g] Generate ");
} else {
sprintf(firstLine,
- "Press [c] to configure ");
+ " [l] Show log output [c] Configure"
+ " ");
}
{
const char* toggleKeyInstruction =
- "Press [t] to toggle advanced mode (Currently %s)";
+ " [t] Toggle advanced mode (currently %s)";
sprintf(thirdLine, toggleKeyInstruction,
- this->AdvancedMode ? "On" : "Off");
+ this->AdvancedMode ? "on" : "off");
}
sprintf(secondLine,
- "Press [h] for help "
- "Press [q] to quit without generating");
+ " [h] Help [q] Quit without generating");
}
curses_move(y - 4, 0);
- char fmt[512] =
- "Press [enter] to edit option Press [d] to delete an entry";
+ char fmt[512] = "Keys: [enter] Edit an entry [d] Delete an entry";
if (process) {
memset(fmt, ' ', 57);
}
@@ -364,7 +365,7 @@ void cmCursesMainForm::PrintKeys(int process /* = 0 */)
// Print the key of the current entry and the CMake version
// on the status bar. Designed for a width of 80 chars.
-void cmCursesMainForm::UpdateStatusBar(const char* message)
+void cmCursesMainForm::UpdateStatusBar(cm::optional<std::string> message)
{
int x;
int y;
@@ -385,119 +386,92 @@ void cmCursesMainForm::UpdateStatusBar(const char* message)
return;
}
- // Get the key of the current entry
- FIELD* cur = current_field(this->Form);
- int findex = field_index(cur);
- cmCursesWidget* lbl = nullptr;
- if (findex >= 0) {
- lbl = reinterpret_cast<cmCursesWidget*>(
- field_userptr(this->Fields[findex - 2]));
- }
- char help[128] = "";
- const char* curField = "";
- if (lbl) {
- curField = lbl->GetValue();
+ // Find the current label index
+ // Field are grouped by 3, the label should be 2 less than the current index
+ using size_type = decltype(this->Fields)::size_type;
+ size_type currentLabelIndex = field_index(current_field(this->Form)) - 2;
+
+ // Use the status message if any, otherwise join the key and help string
+ std::string bar;
+ if (message) {
+ bar = *message;
+ } else {
+ // Get the key of the current entry
+ cmCursesWidget* labelWidget = reinterpret_cast<cmCursesWidget*>(
+ field_userptr(this->Fields[currentLabelIndex]));
+ std::string labelValue = labelWidget->GetValue();
+ bar = labelValue + ": ";
// Get the help string of the current entry
// and add it to the help string
- const char* existingValue =
- this->CMakeInstance->GetState()->GetCacheEntryValue(curField);
+ auto cmakeState = this->CMakeInstance->GetState();
+ cmProp existingValue = cmakeState->GetCacheEntryValue(labelValue);
if (existingValue) {
- const char* hs = this->CMakeInstance->GetState()->GetCacheEntryProperty(
- curField, "HELPSTRING");
- if (hs) {
- strncpy(help, hs, 127);
- help[127] = '\0';
- } else {
- help[0] = 0;
+ cmProp help =
+ cmakeState->GetCacheEntryProperty(labelValue, "HELPSTRING");
+ if (help) {
+ bar += *help;
}
- } else {
- sprintf(help, " ");
}
}
+ // Pad with spaces to erase any previous text,
+ // or truncate as necessary to fit the screen
+ bar.resize(x, ' ');
+ curses_move(y - 5, 0);
+ attron(A_STANDOUT);
+ char fmt_s[] = "%s";
+ printw(fmt_s, bar.c_str());
+ attroff(A_STANDOUT);
- // Join the key, help string and pad with spaces
- // (or truncate) as necessary
- char bar[cmCursesMainForm::MAX_WIDTH];
- size_t curFieldLen = strlen(curField);
- size_t helpLen = strlen(help);
-
- size_t width = std::min<size_t>(x, cmCursesMainForm::MAX_WIDTH);
-
- if (message) {
- curField = message;
- curFieldLen = strlen(message);
- strncpy(bar, curField, width);
- if (curFieldLen < width) {
- memset(bar + curFieldLen, ' ', width - curFieldLen);
- }
- } else {
- strncpy(bar, curField, width);
- if (curFieldLen < width) {
- bar[curFieldLen] = ':';
- bar[curFieldLen + 1] = ' ';
- strncpy(bar + curFieldLen + 2, help, width - curFieldLen - 2);
- if (curFieldLen + helpLen + 2 < width) {
- memset(bar + curFieldLen + helpLen + 2, ' ',
- width - (curFieldLen + helpLen + 2));
- }
- }
+ // Highlight the current label, reset others
+ // Fields are grouped by 3, the first one being the label
+ // so start at 0 and move up by 3 avoiding the last null entry
+ for (size_type index = 0; index < this->Fields.size() - 1; index += 3) {
+ bool currentLabel = index == currentLabelIndex;
+ set_field_fore(this->Fields[index], currentLabel ? A_STANDOUT : A_NORMAL);
}
- bar[width] = '\0';
-
- // Display CMake version info on the next line
+ // Display CMake version under the status bar
// We want to display this on the right
- char version[cmCursesMainForm::MAX_WIDTH];
- char vertmp[128];
- sprintf(vertmp, "CMake Version %s", cmVersion::GetCMakeVersion());
- size_t sideSpace = (width - strlen(vertmp));
- memset(version, ' ', sideSpace);
- sprintf(version + sideSpace, "%s", vertmp);
- version[width] = '\0';
-
- // Now print both lines
- char fmt_s[] = "%s";
- curses_move(y - 5, 0);
- attron(A_STANDOUT);
- printw(fmt_s, bar);
- attroff(A_STANDOUT);
- curses_move(y - 4, 0);
- printw(fmt_s, version);
+ std::string version = "CMake Version ";
+ version += cmVersion::GetCMakeVersion();
+ version.resize(std::min<std::string::size_type>(x, version.size()));
+ curses_move(y - 4, x - static_cast<int>(version.size()));
+ printw(fmt_s, version.c_str());
+
pos_form_cursor(this->Form);
}
void cmCursesMainForm::UpdateProgress(const std::string& msg, float prog)
{
- char tmp[1024];
- const char* cmsg = tmp;
if (prog >= 0) {
- sprintf(tmp, "%s %i%%", msg.c_str(), static_cast<int>(100 * prog));
+ constexpr int progressBarWidth = 40;
+ int progressBarCompleted = static_cast<int>(progressBarWidth * prog);
+ int percentCompleted = static_cast<int>(100 * prog);
+ this->LastProgress = (percentCompleted < 100 ? " " : "");
+ this->LastProgress += (percentCompleted < 10 ? " " : "");
+ this->LastProgress += std::to_string(percentCompleted) + "% [";
+ this->LastProgress.append(progressBarCompleted, '#');
+ this->LastProgress.append(progressBarWidth - progressBarCompleted, ' ');
+ this->LastProgress += "] " + msg + "...";
+ this->DisplayOutputs(std::string());
} else {
- cmsg = msg.c_str();
+ this->Outputs.emplace_back(msg);
+ this->DisplayOutputs(msg);
}
- this->UpdateStatusBar(cmsg);
- this->PrintKeys(1);
- curses_move(1, 1);
- touchwin(stdscr);
- refresh();
}
int cmCursesMainForm::Configure(int noconfigure)
{
- int xi;
- int yi;
- getmaxyx(stdscr, yi, xi);
-
- curses_move(1, 1);
- this->UpdateStatusBar("Configuring, please wait...");
- this->PrintKeys(1);
- touchwin(stdscr);
- refresh();
- this->CMakeInstance->SetProgressCallback(
- [this](const std::string& msg, float prog) {
- this->UpdateProgress(msg, prog);
- });
+ this->ResetOutputs();
+
+ if (noconfigure == 0) {
+ this->UpdateProgress("Configuring", 0);
+ this->CMakeInstance->SetProgressCallback(
+ [this](const std::string& msg, float prog) {
+ this->UpdateProgress(msg, prog);
+ });
+ }
// always save the current gui values to disk
this->FillCacheManagerFromUI();
@@ -505,9 +479,6 @@ int cmCursesMainForm::Configure(int noconfigure)
this->CMakeInstance->GetHomeOutputDirectory());
this->LoadCache(nullptr);
- // Get rid of previous errors
- this->Errors = std::vector<std::string>();
-
// run the generate process
this->OkToGenerate = true;
int retVal;
@@ -524,7 +495,7 @@ int cmCursesMainForm::Configure(int noconfigure)
keypad(stdscr, true); /* Use key symbols as KEY_DOWN */
- if (retVal != 0 || !this->Errors.empty()) {
+ if (retVal != 0 || this->HasNonStatusOutputs) {
// see if there was an error
if (cmSystemTools::GetErrorOccuredFlag()) {
this->OkToGenerate = false;
@@ -532,11 +503,13 @@ int cmCursesMainForm::Configure(int noconfigure)
int xx;
int yy;
getmaxyx(stdscr, yy, xx);
- cmCursesLongMessageForm* msgs =
- new cmCursesLongMessageForm(this->Errors,
- cmSystemTools::GetErrorOccuredFlag()
- ? "Errors occurred during the last pass."
- : "CMake produced the following output.");
+ const char* title = "Configure produced the following output";
+ if (cmSystemTools::GetErrorOccuredFlag()) {
+ title = "Configure failed with the following output";
+ }
+ cmCursesLongMessageForm* msgs = new cmCursesLongMessageForm(
+ this->Outputs, title,
+ cmCursesLongMessageForm::ScrollBehavior::ScrollDown);
// reset error condition
cmSystemTools::ResetErrorOccuredFlag();
CurrentForm = msgs;
@@ -547,11 +520,13 @@ int cmCursesMainForm::Configure(int noconfigure)
if (retVal == -2) {
return retVal;
}
- CurrentForm = this;
- this->Render(1, 1, xx, yy);
}
this->InitializeUI();
+ CurrentForm = this;
+ int xi;
+ int yi;
+ getmaxyx(stdscr, yi, xi);
this->Render(1, 1, xi, yi);
return 0;
@@ -559,30 +534,21 @@ int cmCursesMainForm::Configure(int noconfigure)
int cmCursesMainForm::Generate()
{
- int xi;
- int yi;
- getmaxyx(stdscr, yi, xi);
+ this->ResetOutputs();
- curses_move(1, 1);
- this->UpdateStatusBar("Generating, please wait...");
- this->PrintKeys(1);
- touchwin(stdscr);
- refresh();
+ this->UpdateProgress("Generating", 0);
this->CMakeInstance->SetProgressCallback(
[this](const std::string& msg, float prog) {
this->UpdateProgress(msg, prog);
});
- // Get rid of previous errors
- this->Errors = std::vector<std::string>();
-
// run the generate process
int retVal = this->CMakeInstance->Generate();
this->CMakeInstance->SetProgressCallback(nullptr);
keypad(stdscr, true); /* Use key symbols as KEY_DOWN */
- if (retVal != 0 || !this->Errors.empty()) {
+ if (retVal != 0 || this->HasNonStatusOutputs) {
// see if there was an error
if (cmSystemTools::GetErrorOccuredFlag()) {
this->OkToGenerate = false;
@@ -592,12 +558,13 @@ int cmCursesMainForm::Generate()
int xx;
int yy;
getmaxyx(stdscr, yy, xx);
- const char* title = "Messages during last pass.";
+ const char* title = "Generate produced the following output";
if (cmSystemTools::GetErrorOccuredFlag()) {
- title = "Errors occurred during the last pass.";
+ title = "Generate failed with the following output";
}
- cmCursesLongMessageForm* msgs =
- new cmCursesLongMessageForm(this->Errors, title);
+ cmCursesLongMessageForm* msgs = new cmCursesLongMessageForm(
+ this->Outputs, title,
+ cmCursesLongMessageForm::ScrollBehavior::ScrollDown);
CurrentForm = msgs;
msgs->Render(1, 1, xx, yy);
msgs->HandleInput();
@@ -606,11 +573,13 @@ int cmCursesMainForm::Generate()
if (retVal == -2) {
return retVal;
}
- CurrentForm = this;
- this->Render(1, 1, xx, yy);
}
this->InitializeUI();
+ CurrentForm = this;
+ int xi;
+ int yi;
+ getmaxyx(stdscr, yi, xi);
this->Render(1, 1, xi, yi);
return 0;
@@ -619,7 +588,9 @@ int cmCursesMainForm::Generate()
void cmCursesMainForm::AddError(const std::string& message,
const char* /*unused*/)
{
- this->Errors.emplace_back(message);
+ this->Outputs.emplace_back(message);
+ this->HasNonStatusOutputs = true;
+ this->DisplayOutputs(message);
}
void cmCursesMainForm::RemoveEntry(const char* value)
@@ -646,10 +617,10 @@ void cmCursesMainForm::FillCacheManagerFromUI()
{
for (cmCursesCacheEntryComposite& entry : this->Entries) {
const std::string& cacheKey = entry.Key;
- const char* existingValue =
+ cmProp existingValue =
this->CMakeInstance->GetState()->GetCacheEntryValue(cacheKey);
if (existingValue) {
- std::string oldValue = existingValue;
+ std::string oldValue = *existingValue;
std::string newValue = entry.Entry->GetValue();
std::string fixedOldValue;
std::string fixedNewValue;
@@ -704,7 +675,7 @@ void cmCursesMainForm::HandleInput()
this->PrintKeys();
if (this->SearchMode) {
std::string searchstr = "Search: " + this->SearchString;
- this->UpdateStatusBar(searchstr.c_str());
+ this->UpdateStatusBar(searchstr);
this->PrintKeys(1);
curses_move(y - 5, static_cast<unsigned int>(searchstr.size()));
// curses_move(1,1);
@@ -832,9 +803,9 @@ void cmCursesMainForm::HandleInput()
cmCursesWidget* lbl = reinterpret_cast<cmCursesWidget*>(
field_userptr(this->Fields[findex - 2]));
const char* curField = lbl->GetValue();
- const char* helpString = nullptr;
+ cmProp helpString = nullptr;
- const char* existingValue =
+ cmProp existingValue =
this->CMakeInstance->GetState()->GetCacheEntryValue(curField);
if (existingValue) {
helpString = this->CMakeInstance->GetState()->GetCacheEntryProperty(
@@ -843,13 +814,14 @@ void cmCursesMainForm::HandleInput()
if (helpString) {
this->HelpMessage[1] =
cmStrCat("Current option is: ", curField, '\n',
- "Help string for this option is: ", helpString, '\n');
+ "Help string for this option is: ", *helpString, '\n');
} else {
this->HelpMessage[1] = "";
}
- cmCursesLongMessageForm* msgs =
- new cmCursesLongMessageForm(this->HelpMessage, "Help.");
+ cmCursesLongMessageForm* msgs = new cmCursesLongMessageForm(
+ this->HelpMessage, "Help",
+ cmCursesLongMessageForm::ScrollBehavior::NoScroll);
CurrentForm = msgs;
msgs->Render(1, 1, x, y);
msgs->HandleInput();
@@ -861,7 +833,8 @@ void cmCursesMainForm::HandleInput()
else if (key == 'l') {
getmaxyx(stdscr, y, x);
cmCursesLongMessageForm* msgs = new cmCursesLongMessageForm(
- this->Errors, "Errors occurred during the last pass.");
+ this->Outputs, "CMake produced the following output",
+ cmCursesLongMessageForm::ScrollBehavior::NoScroll);
CurrentForm = msgs;
msgs->Render(1, 1, x, y);
msgs->HandleInput();
@@ -1007,15 +980,6 @@ void cmCursesMainForm::JumpToCacheEntry(const char* astr)
} else {
form_driver(this->Form, REQ_NEXT_FIELD);
}
- /*
- char buffer[1024];
- sprintf(buffer, "Line: %d != %d / %d\n", findex, idx,
- this->NumberOfVisibleEntries);
- touchwin(stdscr);
- refresh();
- this->UpdateStatusBar( buffer );
- usleep(100000);
- */
cur = current_field(this->Form);
findex = field_index(cur);
if (findex == start_index) {
@@ -1024,6 +988,32 @@ void cmCursesMainForm::JumpToCacheEntry(const char* astr)
}
}
+void cmCursesMainForm::ResetOutputs()
+{
+ this->LogForm.reset();
+ this->Outputs.clear();
+ this->HasNonStatusOutputs = false;
+ this->LastProgress.clear();
+}
+
+void cmCursesMainForm::DisplayOutputs(std::string const& newOutput)
+{
+ int xi;
+ int yi;
+ getmaxyx(stdscr, yi, xi);
+
+ if (CurrentForm != this->LogForm.get()) {
+ auto newLogForm = new cmCursesLongMessageForm(
+ this->Outputs, this->LastProgress.c_str(),
+ cmCursesLongMessageForm::ScrollBehavior::ScrollDown);
+ CurrentForm = newLogForm;
+ this->LogForm.reset(newLogForm);
+ this->LogForm->Render(1, 1, xi, yi);
+ } else {
+ this->LogForm->UpdateContent(newOutput, this->LastProgress);
+ }
+}
+
const char* cmCursesMainForm::s_ConstHelpMessage =
"CMake is used to configure and generate build files for software projects. "
"The basic steps for configuring a project with ccmake are as follows:\n\n"
@@ -1080,7 +1070,7 @@ const char* cmCursesMainForm::s_ConstHelpMessage =
" c : process the configuration files with the current options\n"
" g : generate build files and exit, only available when there are no "
"new options and no errors have been detected during last configuration.\n"
- " l : shows last errors\n"
+ " l : shows cmake output\n"
" d : delete an option\n"
" t : toggles advanced mode. In normal mode, only the most important "
"options are shown. In advanced mode, all options are shown. We recommend "
diff --git a/Source/CursesDialog/cmCursesMainForm.h b/Source/CursesDialog/cmCursesMainForm.h
index b8769b7..2e06b90 100644
--- a/Source/CursesDialog/cmCursesMainForm.h
+++ b/Source/CursesDialog/cmCursesMainForm.h
@@ -10,12 +10,15 @@
#include <string>
#include <vector>
+#include <cm/optional>
+
#include "cmCursesCacheEntryComposite.h"
#include "cmCursesForm.h"
#include "cmCursesStandardIncludes.h"
#include "cmStateTypes.h"
class cmake;
+class cmCursesLongMessageForm;
/** \class cmCursesMainForm
* \brief The main page of ccmake
@@ -66,8 +69,8 @@ public:
* exception is during a resize. The optional argument specifies the
* string to be displayed in the status bar.
*/
- void UpdateStatusBar() override { this->UpdateStatusBar(nullptr); }
- virtual void UpdateStatusBar(const char* message);
+ void UpdateStatusBar() override { this->UpdateStatusBar(cm::nullopt); }
+ void UpdateStatusBar(cm::optional<std::string> message);
/**
* Display current commands and their keys on the toolbar. This
@@ -122,10 +125,24 @@ protected:
// Jump to the cache entry whose name matches the string.
void JumpToCacheEntry(const char* str);
+ // Clear and reset the output log and state
+ void ResetOutputs();
+
+ // Display the current progress and output
+ void DisplayOutputs(std::string const& newOutput);
+
// Copies of cache entries stored in the user interface
std::vector<cmCursesCacheEntryComposite> Entries;
- // Errors produced during last run of cmake
- std::vector<std::string> Errors;
+
+ // The form used to display logs during processing
+ std::unique_ptr<cmCursesLongMessageForm> LogForm;
+ // Output produced by the last pass
+ std::vector<std::string> Outputs;
+ // Did the last pass produced outputs of interest (errors, warnings, ...)
+ bool HasNonStatusOutputs;
+ // Last progress bar
+ std::string LastProgress;
+
// Command line arguments to be passed to cmake each time
// it is run
std::vector<std::string> Args;
diff --git a/Source/CursesDialog/cmCursesOptionsWidget.cxx b/Source/CursesDialog/cmCursesOptionsWidget.cxx
index eb773ad..8df32e2 100644
--- a/Source/CursesDialog/cmCursesOptionsWidget.cxx
+++ b/Source/CursesDialog/cmCursesOptionsWidget.cxx
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCursesOptionsWidget.h"
+#include "cmCursesColor.h"
#include "cmCursesWidget.h"
#include "cmStateTypes.h"
@@ -15,8 +16,13 @@ cmCursesOptionsWidget::cmCursesOptionsWidget(int width, int height, int left,
// there is no option type, and string type causes ccmake to cast
// the widget into a string widget at some point. BOOL is safe for
// now.
- set_field_fore(this->Field, A_NORMAL);
- set_field_back(this->Field, A_STANDOUT);
+ if (cmCursesColor::HasColors()) {
+ set_field_fore(this->Field, COLOR_PAIR(cmCursesColor::Choice));
+ set_field_back(this->Field, COLOR_PAIR(cmCursesColor::Choice));
+ } else {
+ set_field_fore(this->Field, A_NORMAL);
+ set_field_back(this->Field, A_STANDOUT);
+ }
field_opts_off(this->Field, O_STATIC);
}
diff --git a/Source/CursesDialog/cmCursesPathWidget.cxx b/Source/CursesDialog/cmCursesPathWidget.cxx
index bb3808e..8ed42de 100644
--- a/Source/CursesDialog/cmCursesPathWidget.cxx
+++ b/Source/CursesDialog/cmCursesPathWidget.cxx
@@ -4,6 +4,7 @@
#include <vector>
+#include "cmCursesColor.h"
#include "cmCursesMainForm.h"
#include "cmCursesStringWidget.h"
#include "cmStateTypes.h"
@@ -16,6 +17,13 @@ cmCursesPathWidget::cmCursesPathWidget(int width, int height, int left,
this->Type = cmStateEnums::PATH;
this->Cycle = false;
this->CurrentIndex = 0;
+ if (cmCursesColor::HasColors()) {
+ set_field_fore(this->Field, COLOR_PAIR(cmCursesColor::Path));
+ set_field_back(this->Field, COLOR_PAIR(cmCursesColor::Path));
+ } else {
+ set_field_fore(this->Field, A_NORMAL);
+ set_field_back(this->Field, A_STANDOUT);
+ }
}
void cmCursesPathWidget::OnType(int& key, cmCursesMainForm* fm, WINDOW* w)
diff --git a/Source/CursesDialog/cmCursesStringWidget.cxx b/Source/CursesDialog/cmCursesStringWidget.cxx
index 6296af2..c629478 100644
--- a/Source/CursesDialog/cmCursesStringWidget.cxx
+++ b/Source/CursesDialog/cmCursesStringWidget.cxx
@@ -4,6 +4,7 @@
#include <cstdio>
+#include "cmCursesColor.h"
#include "cmCursesForm.h"
#include "cmCursesMainForm.h"
#include "cmCursesStandardIncludes.h"
@@ -21,8 +22,13 @@ cmCursesStringWidget::cmCursesStringWidget(int width, int height, int left,
{
this->InEdit = false;
this->Type = cmStateEnums::STRING;
- set_field_fore(this->Field, A_NORMAL);
- set_field_back(this->Field, A_STANDOUT);
+ if (cmCursesColor::HasColors()) {
+ set_field_fore(this->Field, COLOR_PAIR(cmCursesColor::String));
+ set_field_back(this->Field, COLOR_PAIR(cmCursesColor::String));
+ } else {
+ set_field_fore(this->Field, A_NORMAL);
+ set_field_back(this->Field, A_STANDOUT);
+ }
field_opts_off(this->Field, O_STATIC);
}
diff --git a/Source/LexerParser/.gitattributes b/Source/LexerParser/.gitattributes
index bf70249..63d9afb 100644
--- a/Source/LexerParser/.gitattributes
+++ b/Source/LexerParser/.gitattributes
@@ -16,4 +16,6 @@
/cmFortranLexer.h generated
/cmFortranParser.cxx generated
/cmFortranParserTokens.h generated
+/cmGccDepfileLexer.cxx generated
+/cmGccDepfileLexer.h generated
/cmListFileLexer.c generated
diff --git a/Source/LexerParser/cmCommandArgumentParser.cxx b/Source/LexerParser/cmCommandArgumentParser.cxx
index ae7fb42..34dc8ec 100644
--- a/Source/LexerParser/cmCommandArgumentParser.cxx
+++ b/Source/LexerParser/cmCommandArgumentParser.cxx
@@ -1,4 +1,4 @@
-/* A Bison parser, made by GNU Bison 3.3.2. */
+/* A Bison parser, made by GNU Bison 3.4.2. */
/* Bison implementation for Yacc-like parsers in C
@@ -48,7 +48,7 @@
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "3.3.2"
+#define YYBISON_VERSION "3.4.2"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -72,7 +72,7 @@
/* First part of user prologue. */
-#line 1 "cmCommandArgumentParser.y" /* yacc.c:337 */
+#line 1 "cmCommandArgumentParser.y"
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
@@ -134,7 +134,8 @@ static void cmCommandArgument_yyerror(yyscan_t yyscanner, const char* message);
# pragma GCC diagnostic ignored "-Wconversion"
#endif
-#line 138 "cmCommandArgumentParser.cxx" /* yacc.c:337 */
+#line 138 "cmCommandArgumentParser.cxx"
+
# ifndef YY_NULLPTR
# if defined __cplusplus
# if 201103L <= __cplusplus
@@ -155,8 +156,8 @@ static void cmCommandArgument_yyerror(yyscan_t yyscanner, const char* message);
# define YYERROR_VERBOSE 1
#endif
-/* In a future release of Bison, this section will be replaced
- by #include "cmCommandArgumentParserTokens.h". */
+/* Use api.header.include to #include this header
+ instead of duplicating it here. */
#ifndef YY_CMCOMMANDARGUMENT_YY_CMCOMMANDARGUMENTPARSERTOKENS_H_INCLUDED
# define YY_CMCOMMANDARGUMENT_YY_CMCOMMANDARGUMENTPARSERTOKENS_H_INCLUDED
/* Debug traces. */
@@ -310,6 +311,8 @@ typedef short yytype_int16;
#endif
+#define YY_ASSERT(E) ((void) (0 && (E)))
+
#if ! defined yyoverflow || YYERROR_VERBOSE
/* The parser invokes alloca or malloc; define the necessary symbols. */
@@ -700,7 +703,9 @@ yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, yy
if (yytype < YYNTOKENS)
YYPRINT (yyo, yytoknum[yytype], *yyvaluep);
# endif
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
YYUSE (yytype);
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
}
@@ -1138,6 +1143,8 @@ yynewstate:
| yynewstate -- set current state (the top of the stack) to yystate. |
`--------------------------------------------------------------------*/
yysetstate:
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+ YY_ASSERT (0 <= yystate && yystate < YYNSTATES);
*yyssp = (yytype_int16) yystate;
if (yyss + yystacksize - 1 <= yyssp)
@@ -1200,8 +1207,6 @@ yysetstate:
}
#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
- YYDPRINTF ((stderr, "Entering state %d\n", yystate));
-
if (yystate == YYFINAL)
YYACCEPT;
@@ -1269,7 +1274,6 @@ yybackup:
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
*++yyvsp = yylval;
YY_IGNORE_MAYBE_UNINITIALIZED_END
-
goto yynewstate;
@@ -1304,193 +1308,194 @@ yyreduce:
YY_REDUCE_PRINT (yyn);
switch (yyn)
{
- case 2:
-#line 99 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+ case 2:
+#line 99 "cmCommandArgumentParser.y"
{
(yyval.str) = 0;
yyGetParser->SetResult((yyvsp[0].str));
}
-#line 1314 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1318 "cmCommandArgumentParser.cxx"
break;
case 3:
-#line 105 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 105 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1322 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1326 "cmCommandArgumentParser.cxx"
break;
case 4:
-#line 108 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 108 "cmCommandArgumentParser.y"
{
(yyval.str) = yyGetParser->CombineUnions((yyvsp[-1].str), (yyvsp[0].str));
}
-#line 1330 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1334 "cmCommandArgumentParser.cxx"
break;
case 5:
-#line 113 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 113 "cmCommandArgumentParser.y"
{
(yyval.str) = 0;
}
-#line 1338 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1342 "cmCommandArgumentParser.cxx"
break;
case 6:
-#line 116 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 116 "cmCommandArgumentParser.y"
{
(yyval.str) = yyGetParser->CombineUnions((yyvsp[-1].str), (yyvsp[0].str));
}
-#line 1346 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1350 "cmCommandArgumentParser.cxx"
break;
case 7:
-#line 121 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 121 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1354 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1358 "cmCommandArgumentParser.cxx"
break;
case 8:
-#line 124 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 124 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1362 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1366 "cmCommandArgumentParser.cxx"
break;
case 9:
-#line 129 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 129 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1370 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1374 "cmCommandArgumentParser.cxx"
break;
case 10:
-#line 132 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 132 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1378 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1382 "cmCommandArgumentParser.cxx"
break;
case 11:
-#line 135 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 135 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1386 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1390 "cmCommandArgumentParser.cxx"
break;
case 12:
-#line 138 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 138 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1394 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1398 "cmCommandArgumentParser.cxx"
break;
case 13:
-#line 141 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 141 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1402 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1406 "cmCommandArgumentParser.cxx"
break;
case 14:
-#line 144 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 144 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1410 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1414 "cmCommandArgumentParser.cxx"
break;
case 15:
-#line 149 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 149 "cmCommandArgumentParser.y"
{
(yyval.str) = yyGetParser->ExpandSpecialVariable((yyvsp[-2].str), (yyvsp[-1].str));
}
-#line 1418 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1422 "cmCommandArgumentParser.cxx"
break;
case 16:
-#line 152 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 152 "cmCommandArgumentParser.y"
{
(yyval.str) = yyGetParser->ExpandSpecialVariable((yyvsp[-2].str), (yyvsp[-1].str));
}
-#line 1426 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1430 "cmCommandArgumentParser.cxx"
break;
case 17:
-#line 155 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 155 "cmCommandArgumentParser.y"
{
(yyval.str) = yyGetParser->ExpandVariable((yyvsp[-1].str));
}
-#line 1434 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1438 "cmCommandArgumentParser.cxx"
break;
case 18:
-#line 158 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 158 "cmCommandArgumentParser.y"
{
(yyval.str) = yyGetParser->ExpandVariableForAt((yyvsp[0].str));
}
-#line 1442 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1446 "cmCommandArgumentParser.cxx"
break;
case 19:
-#line 163 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 163 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1450 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1454 "cmCommandArgumentParser.cxx"
break;
case 20:
-#line 166 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 166 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[-1].str);
}
-#line 1458 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1462 "cmCommandArgumentParser.cxx"
break;
case 21:
-#line 171 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 171 "cmCommandArgumentParser.y"
{
(yyval.str) = 0;
}
-#line 1466 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1470 "cmCommandArgumentParser.cxx"
break;
case 22:
-#line 174 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 174 "cmCommandArgumentParser.y"
{
(yyval.str) = yyGetParser->CombineUnions((yyvsp[-1].str), (yyvsp[0].str));
}
-#line 1474 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1478 "cmCommandArgumentParser.cxx"
break;
case 23:
-#line 179 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 179 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1482 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1486 "cmCommandArgumentParser.cxx"
break;
case 24:
-#line 182 "cmCommandArgumentParser.y" /* yacc.c:1652 */
+#line 182 "cmCommandArgumentParser.y"
{
(yyval.str) = (yyvsp[0].str);
}
-#line 1490 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1494 "cmCommandArgumentParser.cxx"
break;
-#line 1494 "cmCommandArgumentParser.cxx" /* yacc.c:1652 */
+#line 1498 "cmCommandArgumentParser.cxx"
+
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -1723,7 +1728,7 @@ yyreturn:
#endif
return yyresult;
}
-#line 187 "cmCommandArgumentParser.y" /* yacc.c:1918 */
+#line 187 "cmCommandArgumentParser.y"
/* End of grammar */
diff --git a/Source/LexerParser/cmCommandArgumentParserTokens.h b/Source/LexerParser/cmCommandArgumentParserTokens.h
index 56c9794..033b899 100644
--- a/Source/LexerParser/cmCommandArgumentParserTokens.h
+++ b/Source/LexerParser/cmCommandArgumentParserTokens.h
@@ -1,4 +1,4 @@
-/* A Bison parser, made by GNU Bison 3.3.2. */
+/* A Bison parser, made by GNU Bison 3.4.2. */
/* Bison interface for Yacc-like parsers in C
diff --git a/Source/LexerParser/cmDependsJavaParser.cxx b/Source/LexerParser/cmDependsJavaParser.cxx
index 6c1fb2c..b15082d 100644
--- a/Source/LexerParser/cmDependsJavaParser.cxx
+++ b/Source/LexerParser/cmDependsJavaParser.cxx
@@ -1,4 +1,4 @@
-/* A Bison parser, made by GNU Bison 3.3.2. */
+/* A Bison parser, made by GNU Bison 3.4.2. */
/* Bison implementation for Yacc-like parsers in C
@@ -48,7 +48,7 @@
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "3.3.2"
+#define YYBISON_VERSION "3.4.2"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -72,7 +72,7 @@
/* First part of user prologue. */
-#line 1 "cmDependsJavaParser.y" /* yacc.c:337 */
+#line 1 "cmDependsJavaParser.y"
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
@@ -123,7 +123,8 @@ static void cmDependsJava_yyerror(yyscan_t yyscanner, const char* message);
# pragma GCC diagnostic ignored "-Wconversion"
#endif
-#line 127 "cmDependsJavaParser.cxx" /* yacc.c:337 */
+#line 127 "cmDependsJavaParser.cxx"
+
# ifndef YY_NULLPTR
# if defined __cplusplus
# if 201103L <= __cplusplus
@@ -144,8 +145,8 @@ static void cmDependsJava_yyerror(yyscan_t yyscanner, const char* message);
# define YYERROR_VERBOSE 1
#endif
-/* In a future release of Bison, this section will be replaced
- by #include "cmDependsJavaParserTokens.h". */
+/* Use api.header.include to #include this header
+ instead of duplicating it here. */
#ifndef YY_CMDEPENDSJAVA_YY_CMDEPENDSJAVAPARSERTOKENS_H_INCLUDED
# define YY_CMDEPENDSJAVA_YY_CMDEPENDSJAVAPARSERTOKENS_H_INCLUDED
/* Debug traces. */
@@ -481,6 +482,8 @@ typedef short yytype_int16;
#endif
+#define YY_ASSERT(E) ((void) (0 && (E)))
+
#if ! defined yyoverflow || YYERROR_VERBOSE
/* The parser invokes alloca or malloc; define the necessary symbols. */
@@ -1685,7 +1688,9 @@ yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, yy
if (yytype < YYNTOKENS)
YYPRINT (yyo, yytoknum[yytype], *yyvaluep);
# endif
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
YYUSE (yytype);
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
}
@@ -2123,6 +2128,8 @@ yynewstate:
| yynewstate -- set current state (the top of the stack) to yystate. |
`--------------------------------------------------------------------*/
yysetstate:
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+ YY_ASSERT (0 <= yystate && yystate < YYNSTATES);
*yyssp = (yytype_int16) yystate;
if (yyss + yystacksize - 1 <= yyssp)
@@ -2185,8 +2192,6 @@ yysetstate:
}
#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
- YYDPRINTF ((stderr, "Entering state %d\n", yystate));
-
if (yystate == YYFINAL)
YYACCEPT;
@@ -2254,7 +2259,6 @@ yybackup:
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
*++yyvsp = yylval;
YY_IGNORE_MAYBE_UNINITIALIZED_END
-
goto yynewstate;
@@ -2289,215 +2293,215 @@ yyreduce:
YY_REDUCE_PRINT (yyn);
switch (yyn)
{
- case 2:
-#line 183 "cmDependsJavaParser.y" /* yacc.c:1652 */
+ case 2:
+#line 183 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2301 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2305 "cmDependsJavaParser.cxx"
break;
case 3:
-#line 192 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 192 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2312 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2316 "cmDependsJavaParser.cxx"
break;
case 4:
-#line 200 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 200 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2323 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2327 "cmDependsJavaParser.cxx"
break;
case 5:
-#line 208 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 208 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2334 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2338 "cmDependsJavaParser.cxx"
break;
case 6:
-#line 216 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 216 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2345 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2349 "cmDependsJavaParser.cxx"
break;
case 7:
-#line 224 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 224 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2356 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2360 "cmDependsJavaParser.cxx"
break;
case 8:
-#line 232 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 232 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2367 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2371 "cmDependsJavaParser.cxx"
break;
case 9:
-#line 241 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 241 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2378 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2382 "cmDependsJavaParser.cxx"
break;
case 10:
-#line 249 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 249 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2389 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2393 "cmDependsJavaParser.cxx"
break;
case 11:
-#line 258 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 258 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2400 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2404 "cmDependsJavaParser.cxx"
break;
case 12:
-#line 266 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 266 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2411 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2415 "cmDependsJavaParser.cxx"
break;
case 13:
-#line 275 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 275 "cmDependsJavaParser.y"
{
jpElementStart(0);
}
-#line 2419 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2423 "cmDependsJavaParser.cxx"
break;
case 14:
-#line 280 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 280 "cmDependsJavaParser.y"
{
jpElementStart(0);
}
-#line 2427 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2431 "cmDependsJavaParser.cxx"
break;
case 15:
-#line 285 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 285 "cmDependsJavaParser.y"
{
jpElementStart(0);
}
-#line 2435 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2439 "cmDependsJavaParser.cxx"
break;
case 16:
-#line 290 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 290 "cmDependsJavaParser.y"
{
jpElementStart(0);
}
-#line 2443 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2447 "cmDependsJavaParser.cxx"
break;
case 17:
-#line 295 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 295 "cmDependsJavaParser.y"
{
jpElementStart(0);
}
-#line 2451 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2455 "cmDependsJavaParser.cxx"
break;
case 18:
-#line 300 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 300 "cmDependsJavaParser.y"
{
jpElementStart(0);
}
-#line 2459 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2463 "cmDependsJavaParser.cxx"
break;
case 19:
-#line 305 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 305 "cmDependsJavaParser.y"
{
jpElementStart(0);
}
-#line 2467 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2471 "cmDependsJavaParser.cxx"
break;
case 20:
-#line 310 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 310 "cmDependsJavaParser.y"
{
jpElementStart(0);
}
-#line 2475 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2479 "cmDependsJavaParser.cxx"
break;
case 21:
-#line 316 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 316 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2486 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2490 "cmDependsJavaParser.cxx"
break;
case 22:
-#line 324 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 324 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2497 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2501 "cmDependsJavaParser.cxx"
break;
case 23:
-#line 333 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 333 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpStoreClass((yyvsp[0].str));
@@ -2505,44 +2509,44 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2509 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2513 "cmDependsJavaParser.cxx"
break;
case 24:
-#line 343 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 343 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2520 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2524 "cmDependsJavaParser.cxx"
break;
case 25:
-#line 352 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 352 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2531 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2535 "cmDependsJavaParser.cxx"
break;
case 26:
-#line 361 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 361 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2542 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2546 "cmDependsJavaParser.cxx"
break;
case 27:
-#line 369 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 369 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpStoreClass((yyvsp[-1].str));
@@ -2550,56 +2554,56 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2554 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2558 "cmDependsJavaParser.cxx"
break;
case 28:
-#line 379 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 379 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = (yyvsp[0].str);
}
-#line 2563 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2567 "cmDependsJavaParser.cxx"
break;
case 29:
-#line 385 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 385 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = (yyvsp[0].str);
}
-#line 2572 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2576 "cmDependsJavaParser.cxx"
break;
case 30:
-#line 392 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 392 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = (yyvsp[0].str);
}
-#line 2581 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2585 "cmDependsJavaParser.cxx"
break;
case 31:
-#line 399 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 399 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = (yyvsp[0].str);
}
-#line 2590 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2594 "cmDependsJavaParser.cxx"
break;
case 32:
-#line 405 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 405 "cmDependsJavaParser.y"
{
jpElementStart(2);
(yyval.str) = (yyvsp[0].str);
}
-#line 2599 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2603 "cmDependsJavaParser.cxx"
break;
case 33:
-#line 412 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 412 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->AddClassFound((yyvsp[-2].str));
@@ -2607,11 +2611,11 @@ yyreduce:
yyGetParser->DeallocateParserType(&((yyvsp[-2].str)));
(yyval.str) = const_cast<char*>(yyGetParser->GetCurrentCombine());
}
-#line 2611 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2615 "cmDependsJavaParser.cxx"
break;
case 34:
-#line 421 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 421 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpStoreClass((yyvsp[-2].str));
@@ -2620,11 +2624,11 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2624 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2628 "cmDependsJavaParser.cxx"
break;
case 35:
-#line 431 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 431 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpStoreClass((yyvsp[-2].str));
@@ -2633,118 +2637,118 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2637 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2641 "cmDependsJavaParser.cxx"
break;
case 36:
-#line 441 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 441 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2648 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2652 "cmDependsJavaParser.cxx"
break;
case 37:
-#line 450 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 450 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2659 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2663 "cmDependsJavaParser.cxx"
break;
case 38:
-#line 458 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 458 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2670 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2674 "cmDependsJavaParser.cxx"
break;
case 39:
-#line 467 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 467 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2681 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2685 "cmDependsJavaParser.cxx"
break;
case 40:
-#line 475 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 475 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2691 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2695 "cmDependsJavaParser.cxx"
break;
case 41:
-#line 482 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 482 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2702 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2706 "cmDependsJavaParser.cxx"
break;
case 42:
-#line 490 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 490 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2712 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2716 "cmDependsJavaParser.cxx"
break;
case 43:
-#line 497 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 497 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2723 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2727 "cmDependsJavaParser.cxx"
break;
case 44:
-#line 505 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 505 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2733 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2737 "cmDependsJavaParser.cxx"
break;
case 45:
-#line 512 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 512 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2744 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2748 "cmDependsJavaParser.cxx"
break;
case 46:
-#line 521 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 521 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->SetCurrentPackage((yyvsp[-1].str));
@@ -2754,33 +2758,33 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2758 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2762 "cmDependsJavaParser.cxx"
break;
case 47:
-#line 533 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 533 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2769 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2773 "cmDependsJavaParser.cxx"
break;
case 48:
-#line 541 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 541 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2780 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2784 "cmDependsJavaParser.cxx"
break;
case 49:
-#line 550 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 550 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->AddPackagesImport((yyvsp[-1].str));
@@ -2790,11 +2794,11 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2794 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2798 "cmDependsJavaParser.cxx"
break;
case 50:
-#line 562 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 562 "cmDependsJavaParser.y"
{
jpElementStart(5);
std::string str = (yyvsp[-3].str);
@@ -2805,77 +2809,77 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2809 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2813 "cmDependsJavaParser.cxx"
break;
case 51:
-#line 575 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 575 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2820 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2824 "cmDependsJavaParser.cxx"
break;
case 52:
-#line 583 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 583 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2831 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2835 "cmDependsJavaParser.cxx"
break;
case 53:
-#line 591 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 591 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2842 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2846 "cmDependsJavaParser.cxx"
break;
case 54:
-#line 600 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 600 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2853 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2857 "cmDependsJavaParser.cxx"
break;
case 55:
-#line 608 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 608 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2864 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2868 "cmDependsJavaParser.cxx"
break;
case 67:
-#line 623 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 623 "cmDependsJavaParser.y"
{
yyGetParser->StartClass((yyvsp[0].str));
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
jpCheckEmpty(3);
}
-#line 2875 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2879 "cmDependsJavaParser.cxx"
break;
case 68:
-#line 633 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 633 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -2883,11 +2887,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
yyGetParser->EndClass();
}
-#line 2887 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2891 "cmDependsJavaParser.cxx"
break;
case 69:
-#line 642 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 642 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(2);
@@ -2895,11 +2899,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
yyGetParser->EndClass();
}
-#line 2899 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2903 "cmDependsJavaParser.cxx"
break;
case 70:
-#line 651 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 651 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -2907,11 +2911,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
yyGetParser->EndClass();
}
-#line 2911 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2915 "cmDependsJavaParser.cxx"
break;
case 71:
-#line 660 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 660 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -2919,226 +2923,226 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
yyGetParser->EndClass();
}
-#line 2923 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2927 "cmDependsJavaParser.cxx"
break;
case 72:
-#line 669 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 669 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2933 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2937 "cmDependsJavaParser.cxx"
break;
case 73:
-#line 676 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 676 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2944 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2948 "cmDependsJavaParser.cxx"
break;
case 74:
-#line 685 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 685 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2955 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2959 "cmDependsJavaParser.cxx"
break;
case 75:
-#line 694 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 694 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2966 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2970 "cmDependsJavaParser.cxx"
break;
case 76:
-#line 703 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 703 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2977 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2981 "cmDependsJavaParser.cxx"
break;
case 77:
-#line 711 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 711 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2988 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 2992 "cmDependsJavaParser.cxx"
break;
case 78:
-#line 720 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 720 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 2999 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3003 "cmDependsJavaParser.cxx"
break;
case 79:
-#line 728 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 728 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3009 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3013 "cmDependsJavaParser.cxx"
break;
case 80:
-#line 735 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 735 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3020 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3024 "cmDependsJavaParser.cxx"
break;
case 81:
-#line 744 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 744 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3031 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3035 "cmDependsJavaParser.cxx"
break;
case 82:
-#line 752 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 752 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3042 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3046 "cmDependsJavaParser.cxx"
break;
case 83:
-#line 760 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 760 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3053 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3057 "cmDependsJavaParser.cxx"
break;
case 84:
-#line 768 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 768 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3064 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3068 "cmDependsJavaParser.cxx"
break;
case 85:
-#line 777 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 777 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3075 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3079 "cmDependsJavaParser.cxx"
break;
case 86:
-#line 785 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 785 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3086 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3090 "cmDependsJavaParser.cxx"
break;
case 87:
-#line 794 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 794 "cmDependsJavaParser.y"
{
jpElementStart(4);
}
-#line 3094 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3098 "cmDependsJavaParser.cxx"
break;
case 88:
-#line 800 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 800 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3105 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3109 "cmDependsJavaParser.cxx"
break;
case 89:
-#line 808 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 808 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3116 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3120 "cmDependsJavaParser.cxx"
break;
case 90:
-#line 817 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 817 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3127 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3131 "cmDependsJavaParser.cxx"
break;
case 91:
-#line 825 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 825 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3138 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3142 "cmDependsJavaParser.cxx"
break;
case 92:
-#line 834 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 834 "cmDependsJavaParser.y"
{
jpElementStart(1);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -3146,77 +3150,77 @@ yyreduce:
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3150 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3154 "cmDependsJavaParser.cxx"
break;
case 93:
-#line 843 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 843 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3161 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3165 "cmDependsJavaParser.cxx"
break;
case 94:
-#line 852 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 852 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3172 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3176 "cmDependsJavaParser.cxx"
break;
case 95:
-#line 860 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 860 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3183 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3187 "cmDependsJavaParser.cxx"
break;
case 96:
-#line 869 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 869 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3194 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3198 "cmDependsJavaParser.cxx"
break;
case 97:
-#line 877 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 877 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3205 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3209 "cmDependsJavaParser.cxx"
break;
case 98:
-#line 885 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 885 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3216 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3220 "cmDependsJavaParser.cxx"
break;
case 99:
-#line 894 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 894 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -3224,11 +3228,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3228 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3232 "cmDependsJavaParser.cxx"
break;
case 100:
-#line 903 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 903 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -3236,22 +3240,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3240 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3244 "cmDependsJavaParser.cxx"
break;
case 101:
-#line 912 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 912 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3251 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3255 "cmDependsJavaParser.cxx"
break;
case 102:
-#line 920 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 920 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3259,11 +3263,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3263 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3267 "cmDependsJavaParser.cxx"
break;
case 103:
-#line 930 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 930 "cmDependsJavaParser.y"
{
jpElementStart(4);
yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -3272,40 +3276,40 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3276 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3280 "cmDependsJavaParser.cxx"
break;
case 104:
-#line 940 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 940 "cmDependsJavaParser.y"
{
jpElementStart(3);
}
-#line 3285 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3289 "cmDependsJavaParser.cxx"
break;
case 105:
-#line 946 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 946 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3296 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3300 "cmDependsJavaParser.cxx"
break;
case 107:
-#line 957 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 957 "cmDependsJavaParser.y"
{
jpElementStart(1);
}
-#line 3305 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3309 "cmDependsJavaParser.cxx"
break;
case 108:
-#line 963 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 963 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3313,11 +3317,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3317 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3321 "cmDependsJavaParser.cxx"
break;
case 109:
-#line 973 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 973 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3325,11 +3329,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3329 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3333 "cmDependsJavaParser.cxx"
break;
case 110:
-#line 983 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 983 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3337,20 +3341,20 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3341 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3345 "cmDependsJavaParser.cxx"
break;
case 111:
-#line 993 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 993 "cmDependsJavaParser.y"
{
jpElementStart(1);
}
-#line 3350 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3354 "cmDependsJavaParser.cxx"
break;
case 112:
-#line 999 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 999 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3358,11 +3362,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3362 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3366 "cmDependsJavaParser.cxx"
break;
case 113:
-#line 1009 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1009 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3370,11 +3374,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3374 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3378 "cmDependsJavaParser.cxx"
break;
case 114:
-#line 1019 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1019 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3382,11 +3386,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3386 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3390 "cmDependsJavaParser.cxx"
break;
case 115:
-#line 1029 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1029 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -3394,11 +3398,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3398 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3402 "cmDependsJavaParser.cxx"
break;
case 116:
-#line 1038 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1038 "cmDependsJavaParser.y"
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -3406,11 +3410,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3410 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3414 "cmDependsJavaParser.cxx"
break;
case 117:
-#line 1048 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1048 "cmDependsJavaParser.y"
{
jpElementStart(4);
yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -3419,11 +3423,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3423 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3427 "cmDependsJavaParser.cxx"
break;
case 118:
-#line 1059 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1059 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -3431,22 +3435,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3435 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3439 "cmDependsJavaParser.cxx"
break;
case 119:
-#line 1068 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1068 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3446 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3450 "cmDependsJavaParser.cxx"
break;
case 120:
-#line 1076 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1076 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3454,11 +3458,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3458 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3462 "cmDependsJavaParser.cxx"
break;
case 121:
-#line 1086 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1086 "cmDependsJavaParser.y"
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -3466,11 +3470,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3470 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3474 "cmDependsJavaParser.cxx"
break;
case 122:
-#line 1095 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1095 "cmDependsJavaParser.y"
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -3478,22 +3482,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3482 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3486 "cmDependsJavaParser.cxx"
break;
case 123:
-#line 1105 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1105 "cmDependsJavaParser.y"
{
yyGetParser->StartClass((yyvsp[0].str));
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
jpCheckEmpty(3);
}
-#line 3493 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3497 "cmDependsJavaParser.cxx"
break;
case 124:
-#line 1114 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1114 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3501,21 +3505,21 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
yyGetParser->EndClass();
}
-#line 3505 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3509 "cmDependsJavaParser.cxx"
break;
case 125:
-#line 1123 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1123 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3515 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3519 "cmDependsJavaParser.cxx"
break;
case 126:
-#line 1130 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1130 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3523,11 +3527,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3527 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3531 "cmDependsJavaParser.cxx"
break;
case 127:
-#line 1140 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1140 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3535,11 +3539,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3539 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3543 "cmDependsJavaParser.cxx"
break;
case 128:
-#line 1149 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1149 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3547,11 +3551,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3551 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3555 "cmDependsJavaParser.cxx"
break;
case 129:
-#line 1159 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1159 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3559,33 +3563,33 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3563 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3567 "cmDependsJavaParser.cxx"
break;
case 130:
-#line 1168 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1168 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3574 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3578 "cmDependsJavaParser.cxx"
break;
case 131:
-#line 1176 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1176 "cmDependsJavaParser.y"
{
jpElementStart(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3585 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3589 "cmDependsJavaParser.cxx"
break;
case 132:
-#line 1185 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1185 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3593,11 +3597,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3597 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3601 "cmDependsJavaParser.cxx"
break;
case 133:
-#line 1194 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1194 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3605,11 +3609,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3609 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3613 "cmDependsJavaParser.cxx"
break;
case 134:
-#line 1203 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1203 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3617,22 +3621,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3621 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3625 "cmDependsJavaParser.cxx"
break;
case 135:
-#line 1212 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1212 "cmDependsJavaParser.y"
{
jpElementStart(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3632 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3636 "cmDependsJavaParser.cxx"
break;
case 136:
-#line 1220 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1220 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3640,22 +3644,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3644 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3648 "cmDependsJavaParser.cxx"
break;
case 137:
-#line 1229 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1229 "cmDependsJavaParser.y"
{
jpElementStart(2);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3655 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3659 "cmDependsJavaParser.cxx"
break;
case 138:
-#line 1238 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1238 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3663,11 +3667,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3667 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3671 "cmDependsJavaParser.cxx"
break;
case 139:
-#line 1248 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1248 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3675,11 +3679,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3679 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3683 "cmDependsJavaParser.cxx"
break;
case 140:
-#line 1258 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1258 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3687,11 +3691,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3691 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3695 "cmDependsJavaParser.cxx"
break;
case 141:
-#line 1267 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1267 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3699,11 +3703,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3703 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3707 "cmDependsJavaParser.cxx"
break;
case 142:
-#line 1277 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1277 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3711,22 +3715,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3715 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3719 "cmDependsJavaParser.cxx"
break;
case 143:
-#line 1286 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1286 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3726 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3730 "cmDependsJavaParser.cxx"
break;
case 144:
-#line 1294 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1294 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3734,11 +3738,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3738 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3742 "cmDependsJavaParser.cxx"
break;
case 145:
-#line 1303 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1303 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -3746,11 +3750,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3750 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3754 "cmDependsJavaParser.cxx"
break;
case 146:
-#line 1313 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1313 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3758,11 +3762,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3762 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3766 "cmDependsJavaParser.cxx"
break;
case 147:
-#line 1322 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1322 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -3770,33 +3774,33 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3774 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3778 "cmDependsJavaParser.cxx"
break;
case 148:
-#line 1332 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1332 "cmDependsJavaParser.y"
{
jpElementStart(4);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3785 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3789 "cmDependsJavaParser.cxx"
break;
case 149:
-#line 1340 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1340 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 3796 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3800 "cmDependsJavaParser.cxx"
break;
case 150:
-#line 1348 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1348 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3804,11 +3808,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3808 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3812 "cmDependsJavaParser.cxx"
break;
case 151:
-#line 1358 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1358 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3816,11 +3820,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3820 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3824 "cmDependsJavaParser.cxx"
break;
case 152:
-#line 1367 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1367 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(2);
@@ -3828,11 +3832,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3832 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3836 "cmDependsJavaParser.cxx"
break;
case 153:
-#line 1377 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1377 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3840,11 +3844,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3844 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3848 "cmDependsJavaParser.cxx"
break;
case 154:
-#line 1386 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1386 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3852,11 +3856,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3856 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3860 "cmDependsJavaParser.cxx"
break;
case 155:
-#line 1395 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1395 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3864,11 +3868,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3868 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3872 "cmDependsJavaParser.cxx"
break;
case 156:
-#line 1405 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1405 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(2);
@@ -3876,11 +3880,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3880 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3884 "cmDependsJavaParser.cxx"
break;
case 157:
-#line 1415 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1415 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(3);
@@ -3888,11 +3892,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3892 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3896 "cmDependsJavaParser.cxx"
break;
case 158:
-#line 1424 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1424 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(2);
@@ -3900,11 +3904,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3904 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3908 "cmDependsJavaParser.cxx"
break;
case 159:
-#line 1434 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1434 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3912,11 +3916,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3916 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3920 "cmDependsJavaParser.cxx"
break;
case 160:
-#line 1443 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1443 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3924,11 +3928,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3928 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3932 "cmDependsJavaParser.cxx"
break;
case 161:
-#line 1452 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1452 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3936,11 +3940,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3940 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3944 "cmDependsJavaParser.cxx"
break;
case 162:
-#line 1461 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1461 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3948,11 +3952,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3952 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3956 "cmDependsJavaParser.cxx"
break;
case 163:
-#line 1470 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1470 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3960,11 +3964,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3964 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3968 "cmDependsJavaParser.cxx"
break;
case 164:
-#line 1479 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1479 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3972,11 +3976,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3976 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3980 "cmDependsJavaParser.cxx"
break;
case 165:
-#line 1489 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1489 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3984,11 +3988,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 3988 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 3992 "cmDependsJavaParser.cxx"
break;
case 166:
-#line 1498 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1498 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -3996,11 +4000,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4000 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4004 "cmDependsJavaParser.cxx"
break;
case 167:
-#line 1507 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1507 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4008,11 +4012,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4012 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4016 "cmDependsJavaParser.cxx"
break;
case 168:
-#line 1516 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1516 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4020,11 +4024,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4024 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4028 "cmDependsJavaParser.cxx"
break;
case 169:
-#line 1525 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1525 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4032,11 +4036,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4036 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4040 "cmDependsJavaParser.cxx"
break;
case 170:
-#line 1535 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1535 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4044,11 +4048,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4048 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4052 "cmDependsJavaParser.cxx"
break;
case 171:
-#line 1544 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1544 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4056,11 +4060,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4060 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4064 "cmDependsJavaParser.cxx"
break;
case 172:
-#line 1553 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1553 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4068,11 +4072,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4072 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4076 "cmDependsJavaParser.cxx"
break;
case 173:
-#line 1562 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1562 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4080,11 +4084,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4084 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4088 "cmDependsJavaParser.cxx"
break;
case 174:
-#line 1571 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1571 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4092,11 +4096,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4096 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4100 "cmDependsJavaParser.cxx"
break;
case 175:
-#line 1580 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1580 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4104,11 +4108,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4108 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4112 "cmDependsJavaParser.cxx"
break;
case 176:
-#line 1589 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1589 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4116,11 +4120,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4120 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4124 "cmDependsJavaParser.cxx"
break;
case 177:
-#line 1598 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1598 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4128,11 +4132,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4132 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4136 "cmDependsJavaParser.cxx"
break;
case 178:
-#line 1607 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1607 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4140,11 +4144,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4144 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4148 "cmDependsJavaParser.cxx"
break;
case 179:
-#line 1616 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1616 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4152,11 +4156,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4156 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4160 "cmDependsJavaParser.cxx"
break;
case 180:
-#line 1625 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1625 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4164,11 +4168,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4168 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4172 "cmDependsJavaParser.cxx"
break;
case 181:
-#line 1634 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1634 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4176,11 +4180,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4180 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4184 "cmDependsJavaParser.cxx"
break;
case 182:
-#line 1644 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1644 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4188,11 +4192,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4192 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4196 "cmDependsJavaParser.cxx"
break;
case 183:
-#line 1654 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1654 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[-2].str)));
@@ -4201,11 +4205,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4205 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4209 "cmDependsJavaParser.cxx"
break;
case 184:
-#line 1665 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1665 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4213,11 +4217,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4217 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4221 "cmDependsJavaParser.cxx"
break;
case 185:
-#line 1675 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1675 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -4225,11 +4229,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4229 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4233 "cmDependsJavaParser.cxx"
break;
case 186:
-#line 1685 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1685 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4237,11 +4241,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4241 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4245 "cmDependsJavaParser.cxx"
break;
case 187:
-#line 1694 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1694 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4249,11 +4253,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4253 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4257 "cmDependsJavaParser.cxx"
break;
case 188:
-#line 1703 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1703 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4261,11 +4265,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4265 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4269 "cmDependsJavaParser.cxx"
break;
case 189:
-#line 1712 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1712 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4273,11 +4277,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4277 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4281 "cmDependsJavaParser.cxx"
break;
case 190:
-#line 1721 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1721 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4285,11 +4289,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4289 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4293 "cmDependsJavaParser.cxx"
break;
case 191:
-#line 1730 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1730 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4297,11 +4301,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4301 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4305 "cmDependsJavaParser.cxx"
break;
case 192:
-#line 1739 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1739 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4309,11 +4313,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4313 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4317 "cmDependsJavaParser.cxx"
break;
case 193:
-#line 1749 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1749 "cmDependsJavaParser.y"
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -4321,11 +4325,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4325 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4329 "cmDependsJavaParser.cxx"
break;
case 194:
-#line 1759 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1759 "cmDependsJavaParser.y"
{
jpElementStart(7);
jpCheckEmpty(7);
@@ -4333,11 +4337,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4337 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4341 "cmDependsJavaParser.cxx"
break;
case 195:
-#line 1769 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1769 "cmDependsJavaParser.y"
{
jpElementStart(7);
jpCheckEmpty(7);
@@ -4345,40 +4349,40 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4349 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4353 "cmDependsJavaParser.cxx"
break;
case 196:
-#line 1779 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1779 "cmDependsJavaParser.y"
{
jpElementStart(5);
}
-#line 4358 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4362 "cmDependsJavaParser.cxx"
break;
case 197:
-#line 1786 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1786 "cmDependsJavaParser.y"
{
jpElementStart(4);
}
-#line 4367 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4371 "cmDependsJavaParser.cxx"
break;
case 198:
-#line 1792 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1792 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4378 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4382 "cmDependsJavaParser.cxx"
break;
case 199:
-#line 1800 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1800 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4386,22 +4390,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4390 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4394 "cmDependsJavaParser.cxx"
break;
case 200:
-#line 1809 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1809 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4401 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4405 "cmDependsJavaParser.cxx"
break;
case 201:
-#line 1817 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1817 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -4409,11 +4413,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4413 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4417 "cmDependsJavaParser.cxx"
break;
case 202:
-#line 1827 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1827 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -4421,11 +4425,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4425 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4429 "cmDependsJavaParser.cxx"
break;
case 203:
-#line 1837 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1837 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4433,11 +4437,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4437 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4441 "cmDependsJavaParser.cxx"
break;
case 204:
-#line 1846 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1846 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -4445,11 +4449,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4449 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4453 "cmDependsJavaParser.cxx"
break;
case 205:
-#line 1856 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1856 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4457,11 +4461,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4461 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4465 "cmDependsJavaParser.cxx"
break;
case 206:
-#line 1865 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1865 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -4469,58 +4473,58 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4473 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4477 "cmDependsJavaParser.cxx"
break;
case 207:
-#line 1875 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1875 "cmDependsJavaParser.y"
{
jpElementStart(5);
}
-#line 4482 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4486 "cmDependsJavaParser.cxx"
break;
case 208:
-#line 1882 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1882 "cmDependsJavaParser.y"
{
jpElementStart(5);
}
-#line 4491 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4495 "cmDependsJavaParser.cxx"
break;
case 209:
-#line 1889 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1889 "cmDependsJavaParser.y"
{
jpElementStart(7);
}
-#line 4500 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4504 "cmDependsJavaParser.cxx"
break;
case 210:
-#line 1897 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1897 "cmDependsJavaParser.y"
{
jpElementStart(9);
}
-#line 4509 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4513 "cmDependsJavaParser.cxx"
break;
case 211:
-#line 1903 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1903 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4520 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4524 "cmDependsJavaParser.cxx"
break;
case 212:
-#line 1911 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1911 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4528,22 +4532,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4532 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4536 "cmDependsJavaParser.cxx"
break;
case 213:
-#line 1920 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1920 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4543 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4547 "cmDependsJavaParser.cxx"
break;
case 214:
-#line 1928 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1928 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4551,33 +4555,33 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4555 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4559 "cmDependsJavaParser.cxx"
break;
case 215:
-#line 1939 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1939 "cmDependsJavaParser.y"
{
jpElementStart(9);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4566 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4570 "cmDependsJavaParser.cxx"
break;
case 216:
-#line 1947 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1947 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4577 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4581 "cmDependsJavaParser.cxx"
break;
case 217:
-#line 1955 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1955 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4585,11 +4589,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4589 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4593 "cmDependsJavaParser.cxx"
break;
case 218:
-#line 1965 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1965 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4597,11 +4601,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4601 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4605 "cmDependsJavaParser.cxx"
break;
case 219:
-#line 1974 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1974 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4609,11 +4613,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4613 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4617 "cmDependsJavaParser.cxx"
break;
case 220:
-#line 1984 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1984 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4621,11 +4625,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4625 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4629 "cmDependsJavaParser.cxx"
break;
case 221:
-#line 1994 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 1994 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4633,11 +4637,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4637 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4641 "cmDependsJavaParser.cxx"
break;
case 222:
-#line 2003 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2003 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4645,11 +4649,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4649 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4653 "cmDependsJavaParser.cxx"
break;
case 223:
-#line 2013 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2013 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4657,11 +4661,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4661 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4665 "cmDependsJavaParser.cxx"
break;
case 224:
-#line 2022 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2022 "cmDependsJavaParser.y"
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -4669,11 +4673,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4673 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4677 "cmDependsJavaParser.cxx"
break;
case 225:
-#line 2032 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2032 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[-1].str)));
@@ -4682,31 +4686,31 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4686 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4690 "cmDependsJavaParser.cxx"
break;
case 226:
-#line 2042 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2042 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4697 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4701 "cmDependsJavaParser.cxx"
break;
case 227:
-#line 2050 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2050 "cmDependsJavaParser.y"
{
jpElementStart(1);
}
-#line 4706 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4710 "cmDependsJavaParser.cxx"
break;
case 228:
-#line 2057 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2057 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[-1].str)));
@@ -4715,11 +4719,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4719 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4723 "cmDependsJavaParser.cxx"
break;
case 229:
-#line 2068 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2068 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4727,11 +4731,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4731 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4735 "cmDependsJavaParser.cxx"
break;
case 230:
-#line 2078 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2078 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4739,11 +4743,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4743 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4747 "cmDependsJavaParser.cxx"
break;
case 231:
-#line 2088 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2088 "cmDependsJavaParser.y"
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -4751,11 +4755,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4755 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4759 "cmDependsJavaParser.cxx"
break;
case 232:
-#line 2098 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2098 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4763,11 +4767,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4767 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4771 "cmDependsJavaParser.cxx"
break;
case 233:
-#line 2107 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2107 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -4775,22 +4779,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4779 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4783 "cmDependsJavaParser.cxx"
break;
case 234:
-#line 2116 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2116 "cmDependsJavaParser.y"
{
jpElementStart(1);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4790 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4794 "cmDependsJavaParser.cxx"
break;
case 235:
-#line 2124 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2124 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4798,11 +4802,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4802 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4806 "cmDependsJavaParser.cxx"
break;
case 236:
-#line 2134 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2134 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4810,11 +4814,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4814 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4818 "cmDependsJavaParser.cxx"
break;
case 237:
-#line 2143 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2143 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -4822,20 +4826,20 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4826 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4830 "cmDependsJavaParser.cxx"
break;
case 238:
-#line 2153 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2153 "cmDependsJavaParser.y"
{
jpElementStart(5);
}
-#line 4835 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4839 "cmDependsJavaParser.cxx"
break;
case 239:
-#line 2160 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2160 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -4843,11 +4847,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4847 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4851 "cmDependsJavaParser.cxx"
break;
case 240:
-#line 2170 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2170 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4855,11 +4859,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4859 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4863 "cmDependsJavaParser.cxx"
break;
case 241:
-#line 2179 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2179 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4867,11 +4871,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4871 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4875 "cmDependsJavaParser.cxx"
break;
case 242:
-#line 2189 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2189 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4879,20 +4883,20 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4883 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4887 "cmDependsJavaParser.cxx"
break;
case 243:
-#line 2198 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2198 "cmDependsJavaParser.y"
{
jpElementStart(1);
}
-#line 4892 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4896 "cmDependsJavaParser.cxx"
break;
case 244:
-#line 2204 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2204 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -4900,11 +4904,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4904 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4908 "cmDependsJavaParser.cxx"
break;
case 245:
-#line 2213 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2213 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4912,11 +4916,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4916 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4920 "cmDependsJavaParser.cxx"
break;
case 246:
-#line 2222 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2222 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4924,11 +4928,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4928 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4932 "cmDependsJavaParser.cxx"
break;
case 247:
-#line 2231 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2231 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4936,11 +4940,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4940 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4944 "cmDependsJavaParser.cxx"
break;
case 248:
-#line 2240 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2240 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4948,11 +4952,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4952 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4956 "cmDependsJavaParser.cxx"
break;
case 249:
-#line 2250 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2250 "cmDependsJavaParser.y"
{
jpElementStart(6);
jpCheckEmpty(6);
@@ -4960,22 +4964,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4964 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4968 "cmDependsJavaParser.cxx"
break;
case 250:
-#line 2259 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2259 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4975 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4979 "cmDependsJavaParser.cxx"
break;
case 251:
-#line 2267 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2267 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -4983,22 +4987,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 4987 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 4991 "cmDependsJavaParser.cxx"
break;
case 252:
-#line 2276 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2276 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 4998 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5002 "cmDependsJavaParser.cxx"
break;
case 253:
-#line 2284 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2284 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5006,11 +5010,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5010 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5014 "cmDependsJavaParser.cxx"
break;
case 254:
-#line 2294 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2294 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5018,11 +5022,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5022 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5026 "cmDependsJavaParser.cxx"
break;
case 255:
-#line 2303 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2303 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5030,11 +5034,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5034 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5038 "cmDependsJavaParser.cxx"
break;
case 256:
-#line 2313 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2313 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -5042,11 +5046,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5046 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5050 "cmDependsJavaParser.cxx"
break;
case 257:
-#line 2322 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2322 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -5054,11 +5058,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5058 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5062 "cmDependsJavaParser.cxx"
break;
case 258:
-#line 2331 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2331 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -5066,11 +5070,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5070 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5074 "cmDependsJavaParser.cxx"
break;
case 259:
-#line 2340 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2340 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -5078,22 +5082,22 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5082 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5086 "cmDependsJavaParser.cxx"
break;
case 260:
-#line 2349 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2349 "cmDependsJavaParser.y"
{
jpElementStart(0);
(yyval.str) = 0;
yyGetParser->SetCurrentCombine("");
}
-#line 5093 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5097 "cmDependsJavaParser.cxx"
break;
case 261:
-#line 2357 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2357 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5101,11 +5105,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5105 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5109 "cmDependsJavaParser.cxx"
break;
case 262:
-#line 2367 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2367 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5113,11 +5117,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5117 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5121 "cmDependsJavaParser.cxx"
break;
case 263:
-#line 2376 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2376 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5125,11 +5129,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5129 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5133 "cmDependsJavaParser.cxx"
break;
case 264:
-#line 2386 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2386 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5137,29 +5141,29 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5141 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5145 "cmDependsJavaParser.cxx"
break;
case 265:
-#line 2396 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2396 "cmDependsJavaParser.y"
{
jpElementStart(2);
}
-#line 5150 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5154 "cmDependsJavaParser.cxx"
break;
case 266:
-#line 2402 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2402 "cmDependsJavaParser.y"
{
jpElementStart(3);
}
-#line 5159 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5163 "cmDependsJavaParser.cxx"
break;
case 267:
-#line 2409 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2409 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5168,11 +5172,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5172 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5176 "cmDependsJavaParser.cxx"
break;
case 268:
-#line 2419 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2419 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5181,11 +5185,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5185 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5189 "cmDependsJavaParser.cxx"
break;
case 269:
-#line 2429 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2429 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5194,11 +5198,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5198 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5202 "cmDependsJavaParser.cxx"
break;
case 270:
-#line 2439 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2439 "cmDependsJavaParser.y"
{
jpElementStart(3);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5207,11 +5211,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5211 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5215 "cmDependsJavaParser.cxx"
break;
case 271:
-#line 2450 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2450 "cmDependsJavaParser.y"
{
jpElementStart(4);
yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -5220,11 +5224,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5224 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5228 "cmDependsJavaParser.cxx"
break;
case 272:
-#line 2460 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2460 "cmDependsJavaParser.y"
{
jpElementStart(6);
yyGetParser->DeallocateParserType(&((yyvsp[-5].str)));
@@ -5234,11 +5238,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5238 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5242 "cmDependsJavaParser.cxx"
break;
case 273:
-#line 2471 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2471 "cmDependsJavaParser.y"
{
jpElementStart(6);
yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -5247,11 +5251,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5251 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5255 "cmDependsJavaParser.cxx"
break;
case 274:
-#line 2481 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2481 "cmDependsJavaParser.y"
{
jpElementStart(6);
yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -5260,11 +5264,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5264 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5268 "cmDependsJavaParser.cxx"
break;
case 275:
-#line 2492 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2492 "cmDependsJavaParser.y"
{
jpElementStart(4);
yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -5273,11 +5277,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5277 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5281 "cmDependsJavaParser.cxx"
break;
case 276:
-#line 2502 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2502 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -5285,11 +5289,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5289 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5293 "cmDependsJavaParser.cxx"
break;
case 277:
-#line 2512 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2512 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5297,11 +5301,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5301 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5305 "cmDependsJavaParser.cxx"
break;
case 278:
-#line 2521 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2521 "cmDependsJavaParser.y"
{
jpElementStart(1);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5309,11 +5313,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5313 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5317 "cmDependsJavaParser.cxx"
break;
case 279:
-#line 2530 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2530 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5321,11 +5325,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5325 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5329 "cmDependsJavaParser.cxx"
break;
case 280:
-#line 2539 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2539 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5333,11 +5337,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5337 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5341 "cmDependsJavaParser.cxx"
break;
case 281:
-#line 2548 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2548 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5345,11 +5349,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5349 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5353 "cmDependsJavaParser.cxx"
break;
case 282:
-#line 2558 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2558 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5357,11 +5361,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5361 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5365 "cmDependsJavaParser.cxx"
break;
case 283:
-#line 2568 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2568 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5369,11 +5373,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5373 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5377 "cmDependsJavaParser.cxx"
break;
case 284:
-#line 2578 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2578 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5381,11 +5385,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5385 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5389 "cmDependsJavaParser.cxx"
break;
case 285:
-#line 2587 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2587 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5393,11 +5397,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5397 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5401 "cmDependsJavaParser.cxx"
break;
case 286:
-#line 2596 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2596 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5405,11 +5409,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5409 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5413 "cmDependsJavaParser.cxx"
break;
case 287:
-#line 2605 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2605 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5417,11 +5421,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5421 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5425 "cmDependsJavaParser.cxx"
break;
case 288:
-#line 2614 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2614 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5429,11 +5433,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5433 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5437 "cmDependsJavaParser.cxx"
break;
case 289:
-#line 2624 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2624 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5441,11 +5445,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5445 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5449 "cmDependsJavaParser.cxx"
break;
case 290:
-#line 2634 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2634 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5453,11 +5457,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5457 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5461 "cmDependsJavaParser.cxx"
break;
case 291:
-#line 2644 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2644 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5465,11 +5469,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5469 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5473 "cmDependsJavaParser.cxx"
break;
case 292:
-#line 2653 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2653 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5477,11 +5481,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5481 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5485 "cmDependsJavaParser.cxx"
break;
case 293:
-#line 2662 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2662 "cmDependsJavaParser.y"
{
jpElementStart(2);
jpCheckEmpty(2);
@@ -5489,11 +5493,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5493 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5497 "cmDependsJavaParser.cxx"
break;
case 294:
-#line 2671 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2671 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5501,11 +5505,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5505 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5509 "cmDependsJavaParser.cxx"
break;
case 295:
-#line 2681 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2681 "cmDependsJavaParser.y"
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -5513,11 +5517,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5517 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5521 "cmDependsJavaParser.cxx"
break;
case 296:
-#line 2690 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2690 "cmDependsJavaParser.y"
{
jpElementStart(4);
jpCheckEmpty(4);
@@ -5525,20 +5529,20 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5529 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5533 "cmDependsJavaParser.cxx"
break;
case 297:
-#line 2699 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2699 "cmDependsJavaParser.y"
{
jpElementStart(5);
}
-#line 5538 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5542 "cmDependsJavaParser.cxx"
break;
case 298:
-#line 2706 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2706 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5546,11 +5550,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5550 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5554 "cmDependsJavaParser.cxx"
break;
case 299:
-#line 2715 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2715 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5558,11 +5562,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5562 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5566 "cmDependsJavaParser.cxx"
break;
case 300:
-#line 2724 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2724 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5570,11 +5574,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5574 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5578 "cmDependsJavaParser.cxx"
break;
case 301:
-#line 2733 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2733 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5582,11 +5586,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5586 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5590 "cmDependsJavaParser.cxx"
break;
case 302:
-#line 2743 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2743 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5594,11 +5598,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5598 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5602 "cmDependsJavaParser.cxx"
break;
case 303:
-#line 2752 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2752 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5606,11 +5610,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5610 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5614 "cmDependsJavaParser.cxx"
break;
case 304:
-#line 2761 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2761 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5618,11 +5622,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5622 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5626 "cmDependsJavaParser.cxx"
break;
case 305:
-#line 2771 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2771 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5630,11 +5634,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5634 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5638 "cmDependsJavaParser.cxx"
break;
case 306:
-#line 2780 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2780 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5642,11 +5646,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5646 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5650 "cmDependsJavaParser.cxx"
break;
case 307:
-#line 2789 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2789 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5654,11 +5658,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5658 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5662 "cmDependsJavaParser.cxx"
break;
case 308:
-#line 2798 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2798 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5666,11 +5670,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5670 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5674 "cmDependsJavaParser.cxx"
break;
case 309:
-#line 2808 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2808 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5678,11 +5682,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5682 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5686 "cmDependsJavaParser.cxx"
break;
case 310:
-#line 2817 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2817 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5690,11 +5694,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5694 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5698 "cmDependsJavaParser.cxx"
break;
case 311:
-#line 2826 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2826 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5702,11 +5706,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5706 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5710 "cmDependsJavaParser.cxx"
break;
case 312:
-#line 2835 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2835 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5714,11 +5718,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5718 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5722 "cmDependsJavaParser.cxx"
break;
case 313:
-#line 2844 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2844 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5726,11 +5730,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5730 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5734 "cmDependsJavaParser.cxx"
break;
case 314:
-#line 2853 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2853 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5738,11 +5742,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5742 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5746 "cmDependsJavaParser.cxx"
break;
case 315:
-#line 2863 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2863 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5750,11 +5754,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5754 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5758 "cmDependsJavaParser.cxx"
break;
case 316:
-#line 2872 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2872 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5762,11 +5766,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5766 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5770 "cmDependsJavaParser.cxx"
break;
case 317:
-#line 2881 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2881 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5774,11 +5778,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5778 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5782 "cmDependsJavaParser.cxx"
break;
case 318:
-#line 2891 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2891 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5786,11 +5790,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5790 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5794 "cmDependsJavaParser.cxx"
break;
case 319:
-#line 2900 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2900 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5798,11 +5802,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5802 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5806 "cmDependsJavaParser.cxx"
break;
case 320:
-#line 2910 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2910 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5810,11 +5814,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5814 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5818 "cmDependsJavaParser.cxx"
break;
case 321:
-#line 2919 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2919 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5822,11 +5826,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5826 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5830 "cmDependsJavaParser.cxx"
break;
case 322:
-#line 2929 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2929 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5834,11 +5838,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5838 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5842 "cmDependsJavaParser.cxx"
break;
case 323:
-#line 2938 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2938 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5846,11 +5850,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5850 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5854 "cmDependsJavaParser.cxx"
break;
case 324:
-#line 2948 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2948 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5858,11 +5862,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5862 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5866 "cmDependsJavaParser.cxx"
break;
case 325:
-#line 2957 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2957 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5870,11 +5874,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5874 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5878 "cmDependsJavaParser.cxx"
break;
case 326:
-#line 2967 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2967 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5882,11 +5886,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5886 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5890 "cmDependsJavaParser.cxx"
break;
case 327:
-#line 2976 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2976 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5894,11 +5898,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5898 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5902 "cmDependsJavaParser.cxx"
break;
case 328:
-#line 2986 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2986 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5906,11 +5910,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5910 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5914 "cmDependsJavaParser.cxx"
break;
case 329:
-#line 2995 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 2995 "cmDependsJavaParser.y"
{
jpElementStart(5);
jpCheckEmpty(5);
@@ -5918,11 +5922,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5922 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5926 "cmDependsJavaParser.cxx"
break;
case 330:
-#line 3005 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3005 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5930,11 +5934,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5934 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5938 "cmDependsJavaParser.cxx"
break;
case 331:
-#line 3014 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3014 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5942,11 +5946,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5946 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5950 "cmDependsJavaParser.cxx"
break;
case 332:
-#line 3024 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3024 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpCheckEmpty(3);
@@ -5954,11 +5958,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5958 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5962 "cmDependsJavaParser.cxx"
break;
case 333:
-#line 3034 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3034 "cmDependsJavaParser.y"
{
jpElementStart(1);
yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5967,11 +5971,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5971 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5975 "cmDependsJavaParser.cxx"
break;
case 334:
-#line 3044 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3044 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5979,11 +5983,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5983 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5987 "cmDependsJavaParser.cxx"
break;
case 335:
-#line 3053 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3053 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -5991,11 +5995,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 5995 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 5999 "cmDependsJavaParser.cxx"
break;
case 336:
-#line 3063 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3063 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6003,11 +6007,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6007 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6011 "cmDependsJavaParser.cxx"
break;
case 337:
-#line 3072 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3072 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6015,11 +6019,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6019 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6023 "cmDependsJavaParser.cxx"
break;
case 338:
-#line 3081 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3081 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6027,11 +6031,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6031 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6035 "cmDependsJavaParser.cxx"
break;
case 339:
-#line 3090 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3090 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6039,11 +6043,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6043 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6047 "cmDependsJavaParser.cxx"
break;
case 340:
-#line 3099 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3099 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6051,11 +6055,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6055 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6059 "cmDependsJavaParser.cxx"
break;
case 341:
-#line 3108 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3108 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6063,11 +6067,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6067 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6071 "cmDependsJavaParser.cxx"
break;
case 342:
-#line 3117 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3117 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6075,11 +6079,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6079 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6083 "cmDependsJavaParser.cxx"
break;
case 343:
-#line 3126 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3126 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6087,11 +6091,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6091 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6095 "cmDependsJavaParser.cxx"
break;
case 344:
-#line 3135 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3135 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6099,11 +6103,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6103 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6107 "cmDependsJavaParser.cxx"
break;
case 345:
-#line 3144 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3144 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6111,11 +6115,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6115 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6119 "cmDependsJavaParser.cxx"
break;
case 346:
-#line 3153 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3153 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6123,11 +6127,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6127 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6131 "cmDependsJavaParser.cxx"
break;
case 347:
-#line 3162 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3162 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6135,11 +6139,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6139 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6143 "cmDependsJavaParser.cxx"
break;
case 348:
-#line 3172 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3172 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6147,11 +6151,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6151 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6155 "cmDependsJavaParser.cxx"
break;
case 349:
-#line 3182 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3182 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6159,11 +6163,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6163 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6167 "cmDependsJavaParser.cxx"
break;
case 350:
-#line 3192 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3192 "cmDependsJavaParser.y"
{
jpElementStart(1);
jpCheckEmpty(1);
@@ -6171,11 +6175,11 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6175 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6179 "cmDependsJavaParser.cxx"
break;
case 351:
-#line 3201 "cmDependsJavaParser.y" /* yacc.c:1652 */
+#line 3201 "cmDependsJavaParser.y"
{
jpElementStart(3);
jpStoreClass((yyvsp[-2].str));
@@ -6184,11 +6188,12 @@ yyreduce:
yyGetParser->SetCurrentCombine("");
}
-#line 6188 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6192 "cmDependsJavaParser.cxx"
break;
-#line 6192 "cmDependsJavaParser.cxx" /* yacc.c:1652 */
+#line 6196 "cmDependsJavaParser.cxx"
+
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -6421,7 +6426,7 @@ yyreturn:
#endif
return yyresult;
}
-#line 3210 "cmDependsJavaParser.y" /* yacc.c:1918 */
+#line 3210 "cmDependsJavaParser.y"
/* End of grammar */
diff --git a/Source/LexerParser/cmDependsJavaParserTokens.h b/Source/LexerParser/cmDependsJavaParserTokens.h
index 6bbc084..e0dfa01 100644
--- a/Source/LexerParser/cmDependsJavaParserTokens.h
+++ b/Source/LexerParser/cmDependsJavaParserTokens.h
@@ -1,4 +1,4 @@
-/* A Bison parser, made by GNU Bison 3.3.2. */
+/* A Bison parser, made by GNU Bison 3.4.2. */
/* Bison interface for Yacc-like parsers in C
diff --git a/Source/LexerParser/cmExprParser.cxx b/Source/LexerParser/cmExprParser.cxx
index 8416e72..562b35b 100644
--- a/Source/LexerParser/cmExprParser.cxx
+++ b/Source/LexerParser/cmExprParser.cxx
@@ -1,4 +1,4 @@
-/* A Bison parser, made by GNU Bison 3.3.2. */
+/* A Bison parser, made by GNU Bison 3.4.2. */
/* Bison implementation for Yacc-like parsers in C
@@ -48,7 +48,7 @@
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "3.3.2"
+#define YYBISON_VERSION "3.4.2"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -72,7 +72,7 @@
/* First part of user prologue. */
-#line 1 "cmExprParser.y" /* yacc.c:337 */
+#line 1 "cmExprParser.y"
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
@@ -116,7 +116,8 @@ static void cmExpr_yyerror(yyscan_t yyscanner, const char* message);
# pragma GCC diagnostic ignored "-Wconversion"
#endif
-#line 120 "cmExprParser.cxx" /* yacc.c:337 */
+#line 120 "cmExprParser.cxx"
+
# ifndef YY_NULLPTR
# if defined __cplusplus
# if 201103L <= __cplusplus
@@ -137,8 +138,8 @@ static void cmExpr_yyerror(yyscan_t yyscanner, const char* message);
# define YYERROR_VERBOSE 1
#endif
-/* In a future release of Bison, this section will be replaced
- by #include "cmExprParserTokens.h". */
+/* Use api.header.include to #include this header
+ instead of duplicating it here. */
#ifndef YY_CMEXPR_YY_CMEXPRPARSERTOKENS_H_INCLUDED
# define YY_CMEXPR_YY_CMEXPRPARSERTOKENS_H_INCLUDED
/* Debug traces. */
@@ -296,6 +297,8 @@ typedef short yytype_int16;
#endif
+#define YY_ASSERT(E) ((void) (0 && (E)))
+
#if ! defined yyoverflow || YYERROR_VERBOSE
/* The parser invokes alloca or malloc; define the necessary symbols. */
@@ -688,7 +691,9 @@ yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, yy
if (yytype < YYNTOKENS)
YYPRINT (yyo, yytoknum[yytype], *yyvaluep);
# endif
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
YYUSE (yytype);
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
}
@@ -1126,6 +1131,8 @@ yynewstate:
| yynewstate -- set current state (the top of the stack) to yystate. |
`--------------------------------------------------------------------*/
yysetstate:
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+ YY_ASSERT (0 <= yystate && yystate < YYNSTATES);
*yyssp = (yytype_int16) yystate;
if (yyss + yystacksize - 1 <= yyssp)
@@ -1188,8 +1195,6 @@ yysetstate:
}
#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
- YYDPRINTF ((stderr, "Entering state %d\n", yystate));
-
if (yystate == YYFINAL)
YYACCEPT;
@@ -1257,7 +1262,6 @@ yybackup:
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
*++yyvsp = yylval;
YY_IGNORE_MAYBE_UNINITIALIZED_END
-
goto yynewstate;
@@ -1292,195 +1296,196 @@ yyreduce:
YY_REDUCE_PRINT (yyn);
switch (yyn)
{
- case 2:
-#line 77 "cmExprParser.y" /* yacc.c:1652 */
+ case 2:
+#line 77 "cmExprParser.y"
{
cmExpr_yyget_extra(yyscanner)->SetResult((yyvsp[0].Number));
}
-#line 1301 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1305 "cmExprParser.cxx"
break;
case 3:
-#line 82 "cmExprParser.y" /* yacc.c:1652 */
+#line 82 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1309 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1313 "cmExprParser.cxx"
break;
case 4:
-#line 85 "cmExprParser.y" /* yacc.c:1652 */
+#line 85 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) | (yyvsp[0].Number);
}
-#line 1317 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1321 "cmExprParser.cxx"
break;
case 5:
-#line 90 "cmExprParser.y" /* yacc.c:1652 */
+#line 90 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1325 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1329 "cmExprParser.cxx"
break;
case 6:
-#line 93 "cmExprParser.y" /* yacc.c:1652 */
+#line 93 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) ^ (yyvsp[0].Number);
}
-#line 1333 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1337 "cmExprParser.cxx"
break;
case 7:
-#line 98 "cmExprParser.y" /* yacc.c:1652 */
+#line 98 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1341 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1345 "cmExprParser.cxx"
break;
case 8:
-#line 101 "cmExprParser.y" /* yacc.c:1652 */
+#line 101 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) & (yyvsp[0].Number);
}
-#line 1349 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1353 "cmExprParser.cxx"
break;
case 9:
-#line 106 "cmExprParser.y" /* yacc.c:1652 */
+#line 106 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1357 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1361 "cmExprParser.cxx"
break;
case 10:
-#line 109 "cmExprParser.y" /* yacc.c:1652 */
+#line 109 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) << (yyvsp[0].Number);
}
-#line 1365 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1369 "cmExprParser.cxx"
break;
case 11:
-#line 112 "cmExprParser.y" /* yacc.c:1652 */
+#line 112 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) >> (yyvsp[0].Number);
}
-#line 1373 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1377 "cmExprParser.cxx"
break;
case 12:
-#line 117 "cmExprParser.y" /* yacc.c:1652 */
+#line 117 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1381 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1385 "cmExprParser.cxx"
break;
case 13:
-#line 120 "cmExprParser.y" /* yacc.c:1652 */
+#line 120 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) + (yyvsp[0].Number);
}
-#line 1389 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1393 "cmExprParser.cxx"
break;
case 14:
-#line 123 "cmExprParser.y" /* yacc.c:1652 */
+#line 123 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) - (yyvsp[0].Number);
}
-#line 1397 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1401 "cmExprParser.cxx"
break;
case 15:
-#line 128 "cmExprParser.y" /* yacc.c:1652 */
+#line 128 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1405 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1409 "cmExprParser.cxx"
break;
case 16:
-#line 131 "cmExprParser.y" /* yacc.c:1652 */
+#line 131 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) * (yyvsp[0].Number);
}
-#line 1413 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1417 "cmExprParser.cxx"
break;
case 17:
-#line 134 "cmExprParser.y" /* yacc.c:1652 */
+#line 134 "cmExprParser.y"
{
if (yyvsp[0].Number == 0) {
throw std::overflow_error("divide by zero");
}
(yyval.Number) = (yyvsp[-2].Number) / (yyvsp[0].Number);
}
-#line 1424 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1428 "cmExprParser.cxx"
break;
case 18:
-#line 140 "cmExprParser.y" /* yacc.c:1652 */
+#line 140 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-2].Number) % (yyvsp[0].Number);
}
-#line 1432 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1436 "cmExprParser.cxx"
break;
case 19:
-#line 145 "cmExprParser.y" /* yacc.c:1652 */
+#line 145 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1440 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1444 "cmExprParser.cxx"
break;
case 20:
-#line 148 "cmExprParser.y" /* yacc.c:1652 */
+#line 148 "cmExprParser.y"
{
(yyval.Number) = + (yyvsp[0].Number);
}
-#line 1448 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1452 "cmExprParser.cxx"
break;
case 21:
-#line 151 "cmExprParser.y" /* yacc.c:1652 */
+#line 151 "cmExprParser.y"
{
(yyval.Number) = - (yyvsp[0].Number);
}
-#line 1456 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1460 "cmExprParser.cxx"
break;
case 22:
-#line 154 "cmExprParser.y" /* yacc.c:1652 */
+#line 154 "cmExprParser.y"
{
(yyval.Number) = ~ (yyvsp[0].Number);
}
-#line 1464 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1468 "cmExprParser.cxx"
break;
case 23:
-#line 159 "cmExprParser.y" /* yacc.c:1652 */
+#line 159 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[0].Number);
}
-#line 1472 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1476 "cmExprParser.cxx"
break;
case 24:
-#line 162 "cmExprParser.y" /* yacc.c:1652 */
+#line 162 "cmExprParser.y"
{
(yyval.Number) = (yyvsp[-1].Number);
}
-#line 1480 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1484 "cmExprParser.cxx"
break;
-#line 1484 "cmExprParser.cxx" /* yacc.c:1652 */
+#line 1488 "cmExprParser.cxx"
+
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -1713,7 +1718,7 @@ yyreturn:
#endif
return yyresult;
}
-#line 167 "cmExprParser.y" /* yacc.c:1918 */
+#line 167 "cmExprParser.y"
/* End of grammar */
diff --git a/Source/LexerParser/cmExprParserTokens.h b/Source/LexerParser/cmExprParserTokens.h
index 5ffd7c5..e30a832 100644
--- a/Source/LexerParser/cmExprParserTokens.h
+++ b/Source/LexerParser/cmExprParserTokens.h
@@ -1,4 +1,4 @@
-/* A Bison parser, made by GNU Bison 3.3.2. */
+/* A Bison parser, made by GNU Bison 3.4.2. */
/* Bison interface for Yacc-like parsers in C
diff --git a/Source/LexerParser/cmFortranParser.cxx b/Source/LexerParser/cmFortranParser.cxx
index 2ca7927..2494aad 100644
--- a/Source/LexerParser/cmFortranParser.cxx
+++ b/Source/LexerParser/cmFortranParser.cxx
@@ -1,4 +1,4 @@
-/* A Bison parser, made by GNU Bison 3.3.2. */
+/* A Bison parser, made by GNU Bison 3.4.2. */
/* Bison implementation for Yacc-like parsers in C
@@ -48,7 +48,7 @@
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "3.3.2"
+#define YYBISON_VERSION "3.4.2"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -72,7 +72,7 @@
/* First part of user prologue. */
-#line 1 "cmFortranParser.y" /* yacc.c:337 */
+#line 1 "cmFortranParser.y"
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
@@ -135,7 +135,8 @@ static void cmFortran_yyerror(yyscan_t yyscanner, const char* message)
# pragma GCC diagnostic ignored "-Wconversion"
#endif
-#line 139 "cmFortranParser.cxx" /* yacc.c:337 */
+#line 139 "cmFortranParser.cxx"
+
# ifndef YY_NULLPTR
# if defined __cplusplus
# if 201103L <= __cplusplus
@@ -156,8 +157,8 @@ static void cmFortran_yyerror(yyscan_t yyscanner, const char* message)
# define YYERROR_VERBOSE 1
#endif
-/* In a future release of Bison, this section will be replaced
- by #include "cmFortranParserTokens.h". */
+/* Use api.header.include to #include this header
+ instead of duplicating it here. */
#ifndef YY_CMFORTRAN_YY_CMFORTRANPARSERTOKENS_H_INCLUDED
# define YY_CMFORTRAN_YY_CMFORTRANPARSERTOKENS_H_INCLUDED
/* Debug traces. */
@@ -255,16 +256,15 @@ extern int cmFortran_yydebug;
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-
union YYSTYPE
{
-#line 73 "cmFortranParser.y" /* yacc.c:352 */
+#line 73 "cmFortranParser.y"
char* string;
-#line 266 "cmFortranParser.cxx" /* yacc.c:352 */
-};
+#line 266 "cmFortranParser.cxx"
+};
typedef union YYSTYPE YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1
@@ -378,6 +378,8 @@ typedef short yytype_int16;
#endif
+#define YY_ASSERT(E) ((void) (0 && (E)))
+
#if ! defined yyoverflow || YYERROR_VERBOSE
/* The parser invokes alloca or malloc; define the necessary symbols. */
@@ -509,16 +511,16 @@ union yyalloc
/* YYFINAL -- State number of the termination state. */
#define YYFINAL 2
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 593
+#define YYLAST 594
/* YYNTOKENS -- Number of terminals. */
#define YYNTOKENS 41
/* YYNNTS -- Number of nonterminals. */
#define YYNNTS 14
/* YYNRULES -- Number of rules. */
-#define YYNRULES 63
+#define YYNRULES 64
/* YYNSTATES -- Number of states. */
-#define YYNSTATES 126
+#define YYNSTATES 127
#define YYUNDEFTOK 2
#define YYMAXUTOK 295
@@ -574,7 +576,7 @@ static const yytype_uint8 yyrline[] =
220, 220, 221, 221, 222, 222, 223, 223, 224, 224,
225, 225, 226, 226, 227, 227, 228, 228, 231, 232,
233, 234, 235, 236, 237, 238, 239, 240, 241, 242,
- 243, 244, 245, 246
+ 243, 244, 245, 246, 247
};
#endif
@@ -626,16 +628,16 @@ static const yytype_int16 yypact[] =
-39, 21, -39, 1, -39, -20, -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, 39, -39, 15, 16, 18, 19, 33, -39, -39,
+ -3, 40, -39, 15, 16, 17, 19, 34, -39, -39,
-39, -39, -39, -39, 59, -39, -39, -39, -39, -39,
- 35, 36, 37, -39, -39, -39, -39, -39, -39, 76,
- 114, 129, 167, 182, -39, -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, -39, -39, -39, -39,
- -39, -39, 220, 235, 273, 288, -21, 26, -39, 326,
- 341, 379, 394, 432, 447, -39, -39, -39, -39, -39,
- -39, -39, -39, -39, 38, 40, 41, 485, -39, -39,
- -39, -39, -39, -39, 45, -39, -39, -39, 43, 500,
- 538, -39, -39, -39, 553, -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
};
/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -649,13 +651,13 @@ static const yytype_uint8 yydefact[] =
0, 0, 3, 0, 0, 0, 0, 0, 46, 46,
46, 46, 26, 46, 0, 46, 46, 4, 46, 46,
0, 0, 0, 46, 46, 46, 46, 46, 46, 0,
- 0, 0, 0, 0, 15, 57, 56, 62, 58, 59,
- 60, 61, 63, 55, 48, 49, 50, 51, 52, 53,
- 54, 47, 0, 0, 0, 0, 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
+ 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,
+ 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
};
/* YYPGOTO[NTERM-NUM]. */
@@ -669,7 +671,7 @@ static const yytype_int8 yypgoto[] =
static const yytype_int8 yydefgoto[] =
{
-1, 1, 32, 33, 34, 35, 36, 37, 38, 39,
- 40, 41, 44, 81
+ 40, 41, 44, 82
};
/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
@@ -677,66 +679,66 @@ static const yytype_int8 yydefgoto[] =
number is the opposite. If YYTABLE_NINF, syntax error. */
static const yytype_uint8 yytable[] =
{
- 59, 60, 61, 62, 42, 63, 104, 82, 83, 105,
- 84, 85, 43, 45, 46, 89, 90, 91, 92, 93,
- 94, 2, 3, 47, 4, 49, 50, 5, 6, 7,
+ 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,
8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
- 18, 19, 20, 21, 22, 23, 24, 54, 0, 55,
- 107, 56, 57, 48, 106, 25, 26, 27, 28, 29,
- 30, 31, 64, 65, 66, 51, 58, 52, 86, 87,
- 88, 114, 53, 115, 116, 118, 121, 119, 120, 95,
- 65, 66, 0, 124, 0, 67, 68, 69, 70, 71,
- 72, 73, 74, 0, 75, 76, 77, 78, 79, 80,
- 0, 0, 67, 68, 69, 70, 71, 72, 73, 74,
- 0, 75, 76, 77, 78, 79, 80, 96, 65, 66,
+ 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,
+ 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,
+ 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, 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, 101, 65, 66, 67, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 102,
+ 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,
+ 67, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 104, 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,
+ 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, 0, 97, 65, 66, 0, 0, 0, 0, 0,
- 67, 68, 69, 70, 71, 72, 73, 74, 0, 75,
- 76, 77, 78, 79, 80, 67, 68, 69, 70, 71,
- 72, 73, 74, 0, 75, 76, 77, 78, 79, 80,
- 98, 65, 66, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 99, 65, 66, 0, 0,
- 0, 0, 0, 67, 68, 69, 70, 71, 72, 73,
- 74, 0, 75, 76, 77, 78, 79, 80, 67, 68,
- 69, 70, 71, 72, 73, 74, 0, 75, 76, 77,
- 78, 79, 80, 100, 65, 66, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 101, 65,
- 66, 0, 0, 0, 0, 0, 67, 68, 69, 70,
- 71, 72, 73, 74, 0, 75, 76, 77, 78, 79,
- 80, 67, 68, 69, 70, 71, 72, 73, 74, 0,
- 75, 76, 77, 78, 79, 80, 102, 65, 66, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 103, 65, 66, 0, 0, 0, 0, 0, 67,
- 68, 69, 70, 71, 72, 73, 74, 0, 75, 76,
- 77, 78, 79, 80, 67, 68, 69, 70, 71, 72,
- 73, 74, 0, 75, 76, 77, 78, 79, 80, 108,
- 65, 66, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 109, 65, 66, 0, 0, 0,
- 0, 0, 67, 68, 69, 70, 71, 72, 73, 74,
- 0, 75, 76, 77, 78, 79, 80, 67, 68, 69,
- 70, 71, 72, 73, 74, 0, 75, 76, 77, 78,
- 79, 80, 110, 65, 66, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 111, 65, 66,
- 0, 0, 0, 0, 0, 67, 68, 69, 70, 71,
- 72, 73, 74, 0, 75, 76, 77, 78, 79, 80,
- 67, 68, 69, 70, 71, 72, 73, 74, 0, 75,
- 76, 77, 78, 79, 80, 112, 65, 66, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 113, 65, 66, 0, 0, 0, 0, 0, 67, 68,
- 69, 70, 71, 72, 73, 74, 0, 75, 76, 77,
- 78, 79, 80, 67, 68, 69, 70, 71, 72, 73,
- 74, 0, 75, 76, 77, 78, 79, 80, 117, 65,
- 66, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 122, 65, 66, 0, 0, 0, 0,
- 0, 67, 68, 69, 70, 71, 72, 73, 74, 0,
- 75, 76, 77, 78, 79, 80, 67, 68, 69, 70,
- 71, 72, 73, 74, 0, 75, 76, 77, 78, 79,
- 80, 123, 65, 66, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 125, 65, 66, 0,
- 0, 0, 0, 0, 67, 68, 69, 70, 71, 72,
- 73, 74, 0, 75, 76, 77, 78, 79, 80, 67,
- 68, 69, 70, 71, 72, 73, 74, 0, 75, 76,
- 77, 78, 79, 80
+ 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
};
static const yytype_int8 yycheck[] =
@@ -745,62 +747,62 @@ static const yytype_int8 yycheck[] =
48, 49, 32, 37, 32, 53, 54, 55, 56, 57,
58, 0, 1, 3, 3, 33, 29, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
- 19, 20, 21, 22, 23, 24, 25, 32, -1, 33,
- 88, 33, 33, 33, 28, 34, 35, 36, 37, 38,
- 39, 40, 3, 4, 5, 26, 33, 28, 33, 33,
- 33, 33, 33, 33, 33, 30, 33, 115, 116, 3,
- 4, 5, -1, 121, -1, 26, 27, 28, 29, 30,
+ 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,
31, 32, 33, -1, 35, 36, 37, 38, 39, 40,
- -1, -1, 26, 27, 28, 29, 30, 31, 32, 33,
+ -1, -1, -1, 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,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 3, 4, 5, -1, -1, -1, -1, -1,
+ 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, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 3, 4, 5, -1, -1,
+ 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, -1, -1, -1, -1,
+ 38, 39, 40, 3, 4, 5, 6, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, 3, 4,
- 5, -1, -1, -1, -1, -1, 26, 27, 28, 29,
+ 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, -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, -1, -1, -1, -1, -1, 26,
+ -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, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 3, 4, 5, -1, -1, -1,
+ 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, -1, -1, -1, -1, -1,
+ 39, 40, 3, 4, 5, 6, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, 3, 4, 5,
- -1, -1, -1, -1, -1, 26, 27, 28, 29, 30,
+ 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, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 3, 4, 5, -1, -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, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 3, 4, 5, -1, -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, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 3, 4, 5, -1,
- -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
+ 36, 37, 38, 39, 40
};
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
@@ -813,13 +815,13 @@ static const yytype_uint8 yystos[] =
39, 40, 43, 44, 45, 46, 47, 48, 49, 50,
51, 52, 3, 32, 53, 37, 32, 3, 33, 33,
29, 26, 28, 33, 32, 33, 33, 33, 33, 53,
- 53, 53, 53, 53, 3, 4, 5, 26, 27, 28,
- 29, 30, 31, 32, 33, 35, 36, 37, 38, 39,
- 40, 54, 53, 53, 53, 53, 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
+ 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,
+ 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
};
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
@@ -831,7 +833,7 @@ static const yytype_uint8 yyr1[] =
45, 45, 46, 46, 47, 47, 48, 48, 49, 49,
50, 50, 51, 51, 52, 52, 53, 53, 54, 54,
54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
- 54, 54, 54, 54
+ 54, 54, 54, 54, 54
};
/* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
@@ -843,7 +845,7 @@ static const yytype_uint8 yyr2[] =
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 0, 2, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1
+ 1, 1, 1, 1, 1
};
@@ -930,7 +932,9 @@ yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, yy
if (yytype < YYNTOKENS)
YYPRINT (yyo, yytoknum[yytype], *yyvaluep);
# endif
+ YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
YYUSE (yytype);
+ YY_IGNORE_MAYBE_UNINITIALIZED_END
}
@@ -1368,6 +1372,8 @@ yynewstate:
| yynewstate -- set current state (the top of the stack) to yystate. |
`--------------------------------------------------------------------*/
yysetstate:
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+ YY_ASSERT (0 <= yystate && yystate < YYNSTATES);
*yyssp = (yytype_int16) yystate;
if (yyss + yystacksize - 1 <= yyssp)
@@ -1430,8 +1436,6 @@ yysetstate:
}
#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
- YYDPRINTF ((stderr, "Entering state %d\n", yystate));
-
if (yystate == YYFINAL)
YYACCEPT;
@@ -1499,7 +1503,6 @@ yybackup:
YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
*++yyvsp = yylval;
YY_IGNORE_MAYBE_UNINITIALIZED_END
-
goto yynewstate;
@@ -1534,27 +1537,27 @@ yyreduce:
YY_REDUCE_PRINT (yyn);
switch (yyn)
{
- case 4:
-#line 104 "cmFortranParser.y" /* yacc.c:1652 */
+ case 4:
+#line 104 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_SetInInterface(parser, true);
}
-#line 1544 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1547 "cmFortranParser.cxx"
break;
case 5:
-#line 108 "cmFortranParser.y" /* yacc.c:1652 */
+#line 108 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleUse(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1554 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1557 "cmFortranParser.cxx"
break;
case 6:
-#line 113 "cmFortranParser.y" /* yacc.c:1652 */
+#line 113 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
if (cmsysString_strcasecmp((yyvsp[-2].string), "function") != 0 &&
@@ -1564,22 +1567,22 @@ yyreduce:
}
free((yyvsp[-2].string));
}
-#line 1568 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1571 "cmFortranParser.cxx"
break;
case 7:
-#line 122 "cmFortranParser.y" /* yacc.c:1652 */
+#line 122 "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));
}
-#line 1579 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1582 "cmFortranParser.cxx"
break;
case 8:
-#line 128 "cmFortranParser.y" /* yacc.c:1652 */
+#line 128 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleSubmoduleNested(parser, (yyvsp[-6].string), (yyvsp[-4].string), (yyvsp[-2].string));
@@ -1587,40 +1590,40 @@ yyreduce:
free((yyvsp[-4].string));
free((yyvsp[-2].string));
}
-#line 1591 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1594 "cmFortranParser.cxx"
break;
case 9:
-#line 135 "cmFortranParser.y" /* yacc.c:1652 */
+#line 135 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_SetInInterface(parser, true);
free((yyvsp[-2].string));
}
-#line 1601 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1604 "cmFortranParser.cxx"
break;
case 10:
-#line 140 "cmFortranParser.y" /* yacc.c:1652 */
+#line 140 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_SetInInterface(parser, false);
}
-#line 1610 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1613 "cmFortranParser.cxx"
break;
case 11:
-#line 144 "cmFortranParser.y" /* yacc.c:1652 */
+#line 144 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleUse(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1620 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1623 "cmFortranParser.cxx"
break;
case 12:
-#line 149 "cmFortranParser.y" /* yacc.c:1652 */
+#line 149 "cmFortranParser.y"
{
if (cmsysString_strcasecmp((yyvsp[-4].string), "non_intrinsic") == 0) {
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
@@ -1629,139 +1632,140 @@ yyreduce:
free((yyvsp[-4].string));
free((yyvsp[-2].string));
}
-#line 1633 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1636 "cmFortranParser.cxx"
break;
case 13:
-#line 157 "cmFortranParser.y" /* yacc.c:1652 */
+#line 157 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1643 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1646 "cmFortranParser.cxx"
break;
case 14:
-#line 162 "cmFortranParser.y" /* yacc.c:1652 */
+#line 162 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleLineDirective(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1653 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1656 "cmFortranParser.cxx"
break;
case 15:
-#line 167 "cmFortranParser.y" /* yacc.c:1652 */
+#line 167 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1663 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1666 "cmFortranParser.cxx"
break;
case 16:
-#line 172 "cmFortranParser.y" /* yacc.c:1652 */
+#line 172 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1673 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1676 "cmFortranParser.cxx"
break;
case 17:
-#line 177 "cmFortranParser.y" /* yacc.c:1652 */
+#line 177 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleDefine(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1683 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1686 "cmFortranParser.cxx"
break;
case 18:
-#line 182 "cmFortranParser.y" /* yacc.c:1652 */
+#line 182 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleUndef(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1693 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1696 "cmFortranParser.cxx"
break;
case 19:
-#line 187 "cmFortranParser.y" /* yacc.c:1652 */
+#line 187 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleIfdef(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1703 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1706 "cmFortranParser.cxx"
break;
case 20:
-#line 192 "cmFortranParser.y" /* yacc.c:1652 */
+#line 192 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleIfndef(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1713 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1716 "cmFortranParser.cxx"
break;
case 21:
-#line 197 "cmFortranParser.y" /* yacc.c:1652 */
+#line 197 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleIf(parser);
}
-#line 1722 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1725 "cmFortranParser.cxx"
break;
case 22:
-#line 201 "cmFortranParser.y" /* yacc.c:1652 */
+#line 201 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleElif(parser);
}
-#line 1731 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1734 "cmFortranParser.cxx"
break;
case 23:
-#line 205 "cmFortranParser.y" /* yacc.c:1652 */
+#line 205 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleElse(parser);
}
-#line 1740 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1743 "cmFortranParser.cxx"
break;
case 24:
-#line 209 "cmFortranParser.y" /* yacc.c:1652 */
+#line 209 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleEndif(parser);
}
-#line 1749 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1752 "cmFortranParser.cxx"
break;
case 48:
-#line 231 "cmFortranParser.y" /* yacc.c:1652 */
+#line 231 "cmFortranParser.y"
{ free ((yyvsp[0].string)); }
-#line 1755 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1758 "cmFortranParser.cxx"
break;
case 55:
-#line 238 "cmFortranParser.y" /* yacc.c:1652 */
+#line 238 "cmFortranParser.y"
{ free ((yyvsp[0].string)); }
-#line 1761 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1764 "cmFortranParser.cxx"
break;
-#line 1765 "cmFortranParser.cxx" /* yacc.c:1652 */
+#line 1768 "cmFortranParser.cxx"
+
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -1994,6 +1998,6 @@ yyreturn:
#endif
return yyresult;
}
-#line 249 "cmFortranParser.y" /* yacc.c:1918 */
+#line 250 "cmFortranParser.y"
/* End of grammar */
diff --git a/Source/LexerParser/cmFortranParser.y b/Source/LexerParser/cmFortranParser.y
index 87f3e0a..1b54dd9 100644
--- a/Source/LexerParser/cmFortranParser.y
+++ b/Source/LexerParser/cmFortranParser.y
@@ -244,6 +244,7 @@ misc_code:
| RPAREN
| COMMA
| UNTERMINATED_STRING
+| CPP_LINE_DIRECTIVE
;
%%
diff --git a/Source/LexerParser/cmFortranParserTokens.h b/Source/LexerParser/cmFortranParserTokens.h
index 0da4c1c..f66a15c 100644
--- a/Source/LexerParser/cmFortranParserTokens.h
+++ b/Source/LexerParser/cmFortranParserTokens.h
@@ -1,4 +1,4 @@
-/* A Bison parser, made by GNU Bison 3.3.2. */
+/* A Bison parser, made by GNU Bison 3.4.2. */
/* Bison interface for Yacc-like parsers in C
@@ -131,16 +131,15 @@ extern int cmFortran_yydebug;
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-
union YYSTYPE
{
-#line 73 "cmFortranParser.y" /* yacc.c:1921 */
+#line 73 "cmFortranParser.y"
char* string;
-#line 142 "cmFortranParserTokens.h" /* yacc.c:1921 */
-};
+#line 141 "cmFortranParserTokens.h"
+};
typedef union YYSTYPE YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1
diff --git a/Source/LexerParser/cmGccDepfileLexer.cxx b/Source/LexerParser/cmGccDepfileLexer.cxx
new file mode 100644
index 0000000..a98969d
--- /dev/null
+++ b/Source/LexerParser/cmGccDepfileLexer.cxx
@@ -0,0 +1,2210 @@
+#include "cmStandardLexer.h"
+
+#define FLEXINT_H 1
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 6
+#define YY_FLEX_SUBMINOR_VERSION 4
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+#ifdef yy_create_buffer
+#define cmGccDepfile_yy_create_buffer_ALREADY_DEFINED
+#else
+#define yy_create_buffer cmGccDepfile_yy_create_buffer
+#endif
+
+#ifdef yy_delete_buffer
+#define cmGccDepfile_yy_delete_buffer_ALREADY_DEFINED
+#else
+#define yy_delete_buffer cmGccDepfile_yy_delete_buffer
+#endif
+
+#ifdef yy_scan_buffer
+#define cmGccDepfile_yy_scan_buffer_ALREADY_DEFINED
+#else
+#define yy_scan_buffer cmGccDepfile_yy_scan_buffer
+#endif
+
+#ifdef yy_scan_string
+#define cmGccDepfile_yy_scan_string_ALREADY_DEFINED
+#else
+#define yy_scan_string cmGccDepfile_yy_scan_string
+#endif
+
+#ifdef yy_scan_bytes
+#define cmGccDepfile_yy_scan_bytes_ALREADY_DEFINED
+#else
+#define yy_scan_bytes cmGccDepfile_yy_scan_bytes
+#endif
+
+#ifdef yy_init_buffer
+#define cmGccDepfile_yy_init_buffer_ALREADY_DEFINED
+#else
+#define yy_init_buffer cmGccDepfile_yy_init_buffer
+#endif
+
+#ifdef yy_flush_buffer
+#define cmGccDepfile_yy_flush_buffer_ALREADY_DEFINED
+#else
+#define yy_flush_buffer cmGccDepfile_yy_flush_buffer
+#endif
+
+#ifdef yy_load_buffer_state
+#define cmGccDepfile_yy_load_buffer_state_ALREADY_DEFINED
+#else
+#define yy_load_buffer_state cmGccDepfile_yy_load_buffer_state
+#endif
+
+#ifdef yy_switch_to_buffer
+#define cmGccDepfile_yy_switch_to_buffer_ALREADY_DEFINED
+#else
+#define yy_switch_to_buffer cmGccDepfile_yy_switch_to_buffer
+#endif
+
+#ifdef yypush_buffer_state
+#define cmGccDepfile_yypush_buffer_state_ALREADY_DEFINED
+#else
+#define yypush_buffer_state cmGccDepfile_yypush_buffer_state
+#endif
+
+#ifdef yypop_buffer_state
+#define cmGccDepfile_yypop_buffer_state_ALREADY_DEFINED
+#else
+#define yypop_buffer_state cmGccDepfile_yypop_buffer_state
+#endif
+
+#ifdef yyensure_buffer_stack
+#define cmGccDepfile_yyensure_buffer_stack_ALREADY_DEFINED
+#else
+#define yyensure_buffer_stack cmGccDepfile_yyensure_buffer_stack
+#endif
+
+#ifdef yylex
+#define cmGccDepfile_yylex_ALREADY_DEFINED
+#else
+#define yylex cmGccDepfile_yylex
+#endif
+
+#ifdef yyrestart
+#define cmGccDepfile_yyrestart_ALREADY_DEFINED
+#else
+#define yyrestart cmGccDepfile_yyrestart
+#endif
+
+#ifdef yylex_init
+#define cmGccDepfile_yylex_init_ALREADY_DEFINED
+#else
+#define yylex_init cmGccDepfile_yylex_init
+#endif
+
+#ifdef yylex_init_extra
+#define cmGccDepfile_yylex_init_extra_ALREADY_DEFINED
+#else
+#define yylex_init_extra cmGccDepfile_yylex_init_extra
+#endif
+
+#ifdef yylex_destroy
+#define cmGccDepfile_yylex_destroy_ALREADY_DEFINED
+#else
+#define yylex_destroy cmGccDepfile_yylex_destroy
+#endif
+
+#ifdef yyget_debug
+#define cmGccDepfile_yyget_debug_ALREADY_DEFINED
+#else
+#define yyget_debug cmGccDepfile_yyget_debug
+#endif
+
+#ifdef yyset_debug
+#define cmGccDepfile_yyset_debug_ALREADY_DEFINED
+#else
+#define yyset_debug cmGccDepfile_yyset_debug
+#endif
+
+#ifdef yyget_extra
+#define cmGccDepfile_yyget_extra_ALREADY_DEFINED
+#else
+#define yyget_extra cmGccDepfile_yyget_extra
+#endif
+
+#ifdef yyset_extra
+#define cmGccDepfile_yyset_extra_ALREADY_DEFINED
+#else
+#define yyset_extra cmGccDepfile_yyset_extra
+#endif
+
+#ifdef yyget_in
+#define cmGccDepfile_yyget_in_ALREADY_DEFINED
+#else
+#define yyget_in cmGccDepfile_yyget_in
+#endif
+
+#ifdef yyset_in
+#define cmGccDepfile_yyset_in_ALREADY_DEFINED
+#else
+#define yyset_in cmGccDepfile_yyset_in
+#endif
+
+#ifdef yyget_out
+#define cmGccDepfile_yyget_out_ALREADY_DEFINED
+#else
+#define yyget_out cmGccDepfile_yyget_out
+#endif
+
+#ifdef yyset_out
+#define cmGccDepfile_yyset_out_ALREADY_DEFINED
+#else
+#define yyset_out cmGccDepfile_yyset_out
+#endif
+
+#ifdef yyget_leng
+#define cmGccDepfile_yyget_leng_ALREADY_DEFINED
+#else
+#define yyget_leng cmGccDepfile_yyget_leng
+#endif
+
+#ifdef yyget_text
+#define cmGccDepfile_yyget_text_ALREADY_DEFINED
+#else
+#define yyget_text cmGccDepfile_yyget_text
+#endif
+
+#ifdef yyget_lineno
+#define cmGccDepfile_yyget_lineno_ALREADY_DEFINED
+#else
+#define yyget_lineno cmGccDepfile_yyget_lineno
+#endif
+
+#ifdef yyset_lineno
+#define cmGccDepfile_yyset_lineno_ALREADY_DEFINED
+#else
+#define yyset_lineno cmGccDepfile_yyset_lineno
+#endif
+
+#ifdef yyget_column
+#define cmGccDepfile_yyget_column_ALREADY_DEFINED
+#else
+#define yyget_column cmGccDepfile_yyget_column
+#endif
+
+#ifdef yyset_column
+#define cmGccDepfile_yyset_column_ALREADY_DEFINED
+#else
+#define yyset_column cmGccDepfile_yyset_column
+#endif
+
+#ifdef yywrap
+#define cmGccDepfile_yywrap_ALREADY_DEFINED
+#else
+#define yywrap cmGccDepfile_yywrap
+#endif
+
+#ifdef yyalloc
+#define cmGccDepfile_yyalloc_ALREADY_DEFINED
+#else
+#define yyalloc cmGccDepfile_yyalloc
+#endif
+
+#ifdef yyrealloc
+#define cmGccDepfile_yyrealloc_ALREADY_DEFINED
+#else
+#define yyrealloc cmGccDepfile_yyrealloc
+#endif
+
+#ifdef yyfree
+#define cmGccDepfile_yyfree_ALREADY_DEFINED
+#else
+#define yyfree cmGccDepfile_yyfree
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#ifndef SIZE_MAX
+#define SIZE_MAX (~(size_t)0)
+#endif
+
+#endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+/* begin standard C++ headers. */
+
+/* TODO: this is always defined, so inline it */
+#define yyconst const
+
+#if defined(__GNUC__) && __GNUC__ >= 3
+#define yynoreturn __attribute__((__noreturn__))
+#else
+#define yynoreturn
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an
+ * integer in range [0..255] for use as an array index.
+ */
+#define YY_SC_TO_UI(c) ((YY_CHAR) (c))
+
+/* An opaque pointer. */
+#ifndef YY_TYPEDEF_YY_SCANNER_T
+#define YY_TYPEDEF_YY_SCANNER_T
+typedef void* yyscan_t;
+#endif
+
+/* For convenience, these vars (plus the bison vars far below)
+ are macros in the reentrant scanner. */
+#define yyin yyg->yyin_r
+#define yyout yyg->yyout_r
+#define yyextra yyg->yyextra_r
+#define yyleng yyg->yyleng_r
+#define yytext yyg->yytext_r
+#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
+#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
+#define yy_flex_debug yyg->yy_flex_debug_r
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yyg->yy_start = 1 + 2 *
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yyg->yy_start - 1) / 2)
+#define YYSTATE YY_START
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin , yyscanner )
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
+#define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+ #define YY_LESS_LINENO(n)
+ #define YY_LINENO_REWIND_TO(ptr)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = yyg->yy_hold_char; \
+ YY_RESTORE_YY_MORE_OFFSET \
+ yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ int yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
+ ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
+ : NULL)
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
+
+void yyrestart ( FILE *input_file , yyscan_t yyscanner );
+void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner );
+void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
+void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
+void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
+void yypop_buffer_state ( yyscan_t yyscanner );
+
+static void yyensure_buffer_stack ( yyscan_t yyscanner );
+static void yy_load_buffer_state ( yyscan_t yyscanner );
+static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file , yyscan_t yyscanner );
+#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER , yyscanner)
+
+YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner );
+
+void *yyalloc ( yy_size_t , yyscan_t yyscanner );
+void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner );
+void yyfree ( void * , yyscan_t yyscanner );
+
+#define yy_new_buffer yy_create_buffer
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ yyensure_buffer_stack (yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ yyensure_buffer_stack (yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+#define cmGccDepfile_yywrap(yyscanner) (/*CONSTCOND*/1)
+#define YY_SKIP_YYWRAP
+typedef flex_uint8_t YY_CHAR;
+
+typedef int yy_state_type;
+
+#define yytext_ptr yytext_r
+
+static yy_state_type yy_get_previous_state ( yyscan_t yyscanner );
+static yy_state_type yy_try_NUL_trans ( yy_state_type current_state , yyscan_t yyscanner);
+static int yy_get_next_buffer ( yyscan_t yyscanner );
+static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ yyg->yytext_ptr = yy_bp; \
+ yyleng = (int) (yy_cp - yy_bp); \
+ yyg->yy_hold_char = *yy_cp; \
+ *yy_cp = '\0'; \
+ yyg->yy_c_buf_p = yy_cp;
+#define YY_NUM_RULES 11
+#define YY_END_OF_BUFFER 12
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static const flex_int16_t yy_accept[26] =
+ { 0,
+ 0, 0, 12, 10, 8, 6, 10, 9, 10, 10,
+ 10, 8, 0, 6, 9, 1, 7, 5, 0, 3,
+ 2, 0, 4, 0, 0
+ } ;
+
+static const YY_CHAR yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 4, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 5, 6, 1, 7, 8, 6, 1, 1, 6,
+ 6, 1, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 9, 1, 1,
+ 6, 1, 1, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 10, 6, 1, 6, 1, 6, 6, 6, 6,
+
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 1, 6, 6, 1, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6
+ } ;
+
+static const YY_CHAR yy_meta[11] =
+ { 0,
+ 1, 2, 1, 1, 2, 1, 1, 1, 1, 3
+ } ;
+
+static const flex_int16_t yy_base[28] =
+ { 0,
+ 0, 0, 29, 35, 18, 35, 22, 18, 15, 0,
+ 8, 12, 16, 35, 11, 35, 0, 35, 13, 35,
+ 35, 16, 35, 22, 35, 31, 12
+ } ;
+
+static const flex_int16_t yy_def[28] =
+ { 0,
+ 25, 1, 25, 25, 26, 25, 25, 25, 25, 27,
+ 25, 26, 25, 25, 25, 25, 27, 25, 25, 25,
+ 25, 25, 25, 25, 0, 25, 25
+ } ;
+
+static const flex_int16_t yy_nxt[46] =
+ { 0,
+ 4, 5, 6, 7, 5, 8, 4, 9, 10, 11,
+ 18, 19, 20, 17, 21, 18, 15, 22, 18, 19,
+ 23, 13, 16, 15, 14, 24, 20, 13, 25, 25,
+ 25, 22, 12, 12, 3, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25
+ } ;
+
+static const flex_int16_t yy_chk[46] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 11, 11, 11, 27, 11, 19, 15, 11, 13, 13,
+ 22, 12, 9, 8, 7, 22, 24, 5, 3, 0,
+ 0, 24, 26, 26, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25
+ } ;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+/* IWYU pragma: no_forward_declare yyguts_t */
+
+#ifndef __clang_analyzer__ /* Suppress clang scan-build warnings */
+
+#include <cmGccDepfileLexerHelper.h>
+#include <string>
+
+#define INITIAL 0
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+/* Holds the entire state of the reentrant scanner. */
+struct yyguts_t
+ {
+
+ /* User-defined. Not touched by flex. */
+ YY_EXTRA_TYPE yyextra_r;
+
+ /* The rest are the same as the globals declared in the non-reentrant scanner. */
+ FILE *yyin_r, *yyout_r;
+ size_t yy_buffer_stack_top; /**< index of top of stack. */
+ size_t yy_buffer_stack_max; /**< capacity of stack. */
+ YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
+ char yy_hold_char;
+ int yy_n_chars;
+ int yyleng_r;
+ char *yy_c_buf_p;
+ int yy_init;
+ int yy_start;
+ int yy_did_buffer_switch_on_eof;
+ int yy_start_stack_ptr;
+ int yy_start_stack_depth;
+ int *yy_start_stack;
+ yy_state_type yy_last_accepting_state;
+ char* yy_last_accepting_cpos;
+
+ int yylineno_r;
+ int yy_flex_debug_r;
+
+ char *yytext_r;
+ int yy_more_flag;
+ int yy_more_len;
+
+ }; /* end struct yyguts_t */
+
+static int yy_init_globals ( yyscan_t yyscanner );
+
+int yylex_init (yyscan_t* scanner);
+
+int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner);
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy ( yyscan_t yyscanner );
+
+int yyget_debug ( yyscan_t yyscanner );
+
+void yyset_debug ( int debug_flag , yyscan_t yyscanner );
+
+YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner );
+
+void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner );
+
+FILE *yyget_in ( yyscan_t yyscanner );
+
+void yyset_in ( FILE * _in_str , yyscan_t yyscanner );
+
+FILE *yyget_out ( yyscan_t yyscanner );
+
+void yyset_out ( FILE * _out_str , yyscan_t yyscanner );
+
+ int yyget_leng ( yyscan_t yyscanner );
+
+char *yyget_text ( yyscan_t yyscanner );
+
+int yyget_lineno ( yyscan_t yyscanner );
+
+void yyset_lineno ( int _line_number , yyscan_t yyscanner );
+
+int yyget_column ( yyscan_t yyscanner );
+
+void yyset_column ( int _column_no , yyscan_t yyscanner );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap ( yyscan_t yyscanner );
+#else
+extern int yywrap ( yyscan_t yyscanner );
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+
+ static void yyunput ( int c, char *buf_ptr , yyscan_t yyscanner);
+
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner);
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen ( const char * , yyscan_t yyscanner);
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput ( yyscan_t yyscanner );
+#else
+static int input ( yyscan_t yyscanner );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
+#define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0)
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+ { \
+ int c = '*'; \
+ int n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(yyin); \
+ } \
+ }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner)
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int yylex (yyscan_t yyscanner);
+
+#define YY_DECL int yylex (yyscan_t yyscanner)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK /*LINTED*/break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ yy_state_type yy_current_state;
+ char *yy_cp, *yy_bp;
+ int yy_act;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if ( !yyg->yy_init )
+ {
+ yyg->yy_init = 1;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! yyg->yy_start )
+ yyg->yy_start = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ yyensure_buffer_stack (yyscanner);
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner);
+ }
+
+ yy_load_buffer_state( yyscanner );
+ }
+
+ {
+
+ while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = yyg->yy_c_buf_p;
+
+ /* Support of yytext. */
+ *yy_cp = yyg->yy_hold_char;
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = yyg->yy_start;
+yy_match:
+ do
+ {
+ YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
+ if ( yy_accept[yy_current_state] )
+ {
+ yyg->yy_last_accepting_state = yy_current_state;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ 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 >= 26 )
+ 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] != 35 );
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+ if ( yy_act == 0 )
+ { /* have to back up */
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
+ yy_act = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+do_action: /* This label is used only to access EOF actions. */
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = yyg->yy_hold_char;
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+{
+ // Unescape the dollar sign.
+ yyextra->addToCurrentPath("$");
+ }
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+{
+ // Unescape the hash.
+ yyextra->addToCurrentPath("#");
+ }
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+{
+ // 2N+1 backslashes plus space -> N backslashes plus space.
+ size_t c = (strlen(yytext) - 1) / 2;
+ std::string s(c, '\\');
+ s.push_back(' ');
+ yyextra->addToCurrentPath(s.c_str());
+ }
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+{
+ // 2N backslashes plus space -> 2N backslashes, end of filename.
+ yytext[strlen(yytext) - 1] = 0;
+ yyextra->addToCurrentPath(yytext);
+ yyextra->newDependency();
+ }
+ YY_BREAK
+case 5:
+/* rule 5 can match eol */
+YY_RULE_SETUP
+{
+ // A line continuation ends the current file name.
+ yyextra->newDependency();
+ }
+ YY_BREAK
+case 6:
+/* rule 6 can match eol */
+YY_RULE_SETUP
+{
+ // A newline ends the current file name and the current rule.
+ yyextra->newEntry();
+ }
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+{
+ // A colon followed by space ends the rules and starts a new dependency.
+ yyextra->newDependency();
+ }
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+{
+ // Rules and dependencies are separated by blocks of whitespace.
+ yyextra->newRuleOrDependency();
+ }
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+{
+ // Got a span of plain text.
+ yyextra->addToCurrentPath(yytext);
+ }
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+{
+ // Got an otherwise unmatched character.
+ yyextra->addToCurrentPath(yytext);
+ }
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+ECHO;
+ YY_BREAK
+case YY_STATE_EOF(INITIAL):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = yyg->yy_hold_char;
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( yyscanner );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner);
+
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++yyg->yy_c_buf_p;
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = yyg->yy_c_buf_p;
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( yyscanner ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ yyg->yy_did_buffer_switch_on_eof = 0;
+
+ if ( yywrap( yyscanner ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! yyg->yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yyg->yy_c_buf_p =
+ yyg->yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( yyscanner );
+
+ yy_cp = yyg->yy_c_buf_p;
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yyg->yy_c_buf_p =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars];
+
+ yy_current_state = yy_get_previous_state( yyscanner );
+
+ yy_cp = yyg->yy_c_buf_p;
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+ } /* end of user's declarations */
+} /* end of yylex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ char *source = yyg->yytext_ptr;
+ int number_to_move, i;
+ int ret_val;
+
+ if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr - 1);
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0;
+
+ else
+ {
+ int num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
+
+ int yy_c_buf_p_offset =
+ (int) (yyg->yy_c_buf_p - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yyrealloc( (void *) b->yy_ch_buf,
+ (yy_size_t) (b->yy_buf_size + 2) , yyscanner );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = NULL;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+ number_to_move - 1;
+
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ yyg->yy_n_chars, num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ if ( yyg->yy_n_chars == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart( yyin , yyscanner);
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if ((yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ /* Extend the array by 50%, plus the number we really need. */
+ int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc(
+ (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size , yyscanner );
+ if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ /* "- 2" to take care of EOB's */
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2);
+ }
+
+ yyg->yy_n_chars += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+ yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+ static yy_state_type yy_get_previous_state (yyscan_t yyscanner)
+{
+ yy_state_type yy_current_state;
+ char *yy_cp;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ yy_current_state = yyg->yy_start;
+
+ for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
+ {
+ YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ yyg->yy_last_accepting_state = yy_current_state;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ 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 >= 26 )
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner)
+{
+ int yy_is_jam;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */
+ char *yy_cp = yyg->yy_c_buf_p;
+
+ YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ yyg->yy_last_accepting_state = yy_current_state;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ 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 >= 26 )
+ yy_c = yy_meta[yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
+ yy_is_jam = (yy_current_state == 25);
+
+ (void)yyg;
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+#ifndef YY_NO_UNPUT
+
+ static void yyunput (int c, char * yy_bp , yyscan_t yyscanner)
+{
+ char *yy_cp;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ yy_cp = yyg->yy_c_buf_p;
+
+ /* undo effects of setting up yytext */
+ *yy_cp = yyg->yy_hold_char;
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ int number_to_move = yyg->yy_n_chars + 2;
+ char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+ char *source =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+ while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+ yyg->yy_n_chars = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+ yyg->yytext_ptr = yy_bp;
+ yyg->yy_hold_char = *yy_cp;
+ yyg->yy_c_buf_p = yy_cp;
+}
+
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput (yyscan_t yyscanner)
+#else
+ static int input (yyscan_t yyscanner)
+#endif
+
+{
+ int c;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+
+ if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
+ /* This was really a NUL. */
+ *yyg->yy_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ int offset = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr);
+ ++yyg->yy_c_buf_p;
+
+ switch ( yy_get_next_buffer( yyscanner ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart( yyin , yyscanner);
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap( yyscanner ) )
+ return 0;
+
+ if ( ! yyg->yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput(yyscanner);
+#else
+ return input(yyscanner);
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yyg->yy_c_buf_p = yyg->yytext_ptr + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */
+ *yyg->yy_c_buf_p = '\0'; /* preserve yytext */
+ yyg->yy_hold_char = *++yyg->yy_c_buf_p;
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * @param yyscanner The scanner object.
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+ void yyrestart (FILE * input_file , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if ( ! YY_CURRENT_BUFFER ){
+ yyensure_buffer_stack (yyscanner);
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner);
+ }
+
+ yy_init_buffer( YY_CURRENT_BUFFER, input_file , yyscanner);
+ yy_load_buffer_state( yyscanner );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * @param yyscanner The scanner object.
+ */
+ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * yypop_buffer_state();
+ * yypush_buffer_state(new_buffer);
+ */
+ yyensure_buffer_stack (yyscanner);
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ yy_load_buffer_state( yyscanner );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+static void yy_load_buffer_state (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ yyg->yy_hold_char = *yyg->yy_c_buf_p;
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * @param yyscanner The scanner object.
+ * @return the allocated buffer state.
+ */
+ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) , yyscanner );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer( b, file , yyscanner);
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ * @param yyscanner The scanner object.
+ */
+ void yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ yyfree( (void *) b->yy_ch_buf , yyscanner );
+
+ yyfree( (void *) b , yyscanner );
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner)
+
+{
+ int oerrno = errno;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ yy_flush_buffer( b , yyscanner);
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then yy_init_buffer was _probably_
+ * called from yyrestart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * @param yyscanner The scanner object.
+ */
+ void yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ yy_load_buffer_state( yyscanner );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ * @param yyscanner The scanner object.
+ */
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if (new_buffer == NULL)
+ return;
+
+ yyensure_buffer_stack(yyscanner);
+
+ /* This block is copied from yy_switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ yyg->yy_buffer_stack_top++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from yy_switch_to_buffer. */
+ yy_load_buffer_state( yyscanner );
+ yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ * @param yyscanner The scanner object.
+ */
+void yypop_buffer_state (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ yy_delete_buffer(YY_CURRENT_BUFFER , yyscanner);
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if (yyg->yy_buffer_stack_top > 0)
+ --yyg->yy_buffer_stack_top;
+
+ if (YY_CURRENT_BUFFER) {
+ yy_load_buffer_state( yyscanner );
+ yyg->yy_did_buffer_switch_on_eof = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void yyensure_buffer_stack (yyscan_t yyscanner)
+{
+ yy_size_t num_to_alloc;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if (!yyg->yy_buffer_stack) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ , yyscanner);
+ if ( ! yyg->yy_buffer_stack )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ yyg->yy_buffer_stack_max = num_to_alloc;
+ yyg->yy_buffer_stack_top = 0;
+ return;
+ }
+
+ if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ yy_size_t grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc
+ (yyg->yy_buffer_stack,
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ , yyscanner);
+ if ( ! yyg->yy_buffer_stack )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ /* zero only the new slots.*/
+ memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
+ yyg->yy_buffer_stack_max = num_to_alloc;
+ }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return NULL;
+
+ b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+ b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = NULL;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer( b , yyscanner );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string (const char * yystr , yyscan_t yyscanner)
+{
+
+ return yy_scan_bytes( yystr, (int) strlen(yystr) , yyscanner);
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = (yy_size_t) (_yybytes_len + 2);
+ buf = (char *) yyalloc( n , yyscanner );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer( buf, n , yyscanner);
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yynoreturn yy_fatal_error (const char* msg , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ (void)yyg;
+ fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ yytext[yyleng] = yyg->yy_hold_char; \
+ yyg->yy_c_buf_p = yytext + yyless_macro_arg; \
+ yyg->yy_hold_char = *yyg->yy_c_buf_p; \
+ *yyg->yy_c_buf_p = '\0'; \
+ yyleng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the user-defined data for this scanner.
+ * @param yyscanner The scanner object.
+ */
+YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyextra;
+}
+
+/** Get the current line number.
+ * @param yyscanner The scanner object.
+ */
+int yyget_lineno (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if (! YY_CURRENT_BUFFER)
+ return 0;
+
+ return yylineno;
+}
+
+/** Get the current column number.
+ * @param yyscanner The scanner object.
+ */
+int yyget_column (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if (! YY_CURRENT_BUFFER)
+ return 0;
+
+ return yycolumn;
+}
+
+/** Get the input stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *yyget_in (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyin;
+}
+
+/** Get the output stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *yyget_out (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyout;
+}
+
+/** Get the length of the current token.
+ * @param yyscanner The scanner object.
+ */
+int yyget_leng (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyleng;
+}
+
+/** Get the current token.
+ * @param yyscanner The scanner object.
+ */
+
+char *yyget_text (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yytext;
+}
+
+/** Set the user-defined data. This data is never touched by the scanner.
+ * @param user_defined The data to be associated with this scanner.
+ * @param yyscanner The scanner object.
+ */
+void yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyextra = user_defined ;
+}
+
+/** Set the current line number.
+ * @param _line_number line number
+ * @param yyscanner The scanner object.
+ */
+void yyset_lineno (int _line_number , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* lineno is only valid if an input buffer exists. */
+ if (! YY_CURRENT_BUFFER )
+ YY_FATAL_ERROR( "yyset_lineno called with no buffer" );
+
+ yylineno = _line_number;
+}
+
+/** Set the current column.
+ * @param _column_no column number
+ * @param yyscanner The scanner object.
+ */
+void yyset_column (int _column_no , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* column is only valid if an input buffer exists. */
+ if (! YY_CURRENT_BUFFER )
+ YY_FATAL_ERROR( "yyset_column called with no buffer" );
+
+ yycolumn = _column_no;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param _in_str A readable stream.
+ * @param yyscanner The scanner object.
+ * @see yy_switch_to_buffer
+ */
+void yyset_in (FILE * _in_str , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyin = _in_str ;
+}
+
+void yyset_out (FILE * _out_str , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyout = _out_str ;
+}
+
+int yyget_debug (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yy_flex_debug;
+}
+
+void yyset_debug (int _bdebug , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yy_flex_debug = _bdebug ;
+}
+
+/* Accessor methods for yylval and yylloc */
+
+/* User-visible API */
+
+/* yylex_init is special because it creates the scanner itself, so it is
+ * the ONLY reentrant function that doesn't take the scanner as the last argument.
+ * That's why we explicitly handle the declaration, instead of using our macros.
+ */
+int yylex_init(yyscan_t* ptr_yy_globals)
+{
+ if (ptr_yy_globals == NULL){
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL );
+
+ if (*ptr_yy_globals == NULL){
+ errno = ENOMEM;
+ return 1;
+ }
+
+ /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */
+ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+
+ return yy_init_globals ( *ptr_yy_globals );
+}
+
+/* yylex_init_extra has the same functionality as yylex_init, but follows the
+ * convention of taking the scanner as the last argument. Note however, that
+ * this is a *pointer* to a scanner, as it will be allocated by this call (and
+ * is the reason, too, why this function also must handle its own declaration).
+ * The user defined value in the first argument will be available to yyalloc in
+ * the yyextra field.
+ */
+int yylex_init_extra( YY_EXTRA_TYPE yy_user_defined, yyscan_t* ptr_yy_globals )
+{
+ struct yyguts_t dummy_yyguts;
+
+ yyset_extra (yy_user_defined, &dummy_yyguts);
+
+ if (ptr_yy_globals == NULL){
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
+
+ if (*ptr_yy_globals == NULL){
+ errno = ENOMEM;
+ return 1;
+ }
+
+ /* By setting to 0xAA, we expose bugs in
+ yy_init_globals. Leave at 0x00 for releases. */
+ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+
+ yyset_extra (yy_user_defined, *ptr_yy_globals);
+
+ return yy_init_globals ( *ptr_yy_globals );
+}
+
+static int yy_init_globals (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from yylex_destroy(), so don't allocate here.
+ */
+
+ yyg->yy_buffer_stack = NULL;
+ yyg->yy_buffer_stack_top = 0;
+ yyg->yy_buffer_stack_max = 0;
+ yyg->yy_c_buf_p = NULL;
+ yyg->yy_init = 0;
+ yyg->yy_start = 0;
+
+ yyg->yy_start_stack_ptr = 0;
+ yyg->yy_start_stack_depth = 0;
+ yyg->yy_start_stack = NULL;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ yyin = stdin;
+ yyout = stdout;
+#else
+ yyin = NULL;
+ yyout = NULL;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * yylex_init()
+ */
+ return 0;
+}
+
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ yy_delete_buffer( YY_CURRENT_BUFFER , yyscanner );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ yypop_buffer_state(yyscanner);
+ }
+
+ /* Destroy the stack itself. */
+ yyfree(yyg->yy_buffer_stack , yyscanner);
+ yyg->yy_buffer_stack = NULL;
+
+ /* Destroy the start condition stack. */
+ yyfree( yyg->yy_start_stack , yyscanner );
+ yyg->yy_start_stack = NULL;
+
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * yylex() is called, initialization will occur. */
+ yy_init_globals( yyscanner);
+
+ /* Destroy the main struct (reentrant only). */
+ yyfree ( yyscanner , yyscanner );
+ yyscanner = NULL;
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, const char * s2, int n , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ (void)yyg;
+
+ int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (const char * s , yyscan_t yyscanner)
+{
+ int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *yyalloc (yy_size_t size , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ (void)yyg;
+ return malloc(size);
+}
+
+void *yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ (void)yyg;
+
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return realloc(ptr, size);
+}
+
+void yyfree (void * ptr , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ (void)yyg;
+ free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+/*--------------------------------------------------------------------------*/
+
+#endif /* __clang_analyzer__ */
diff --git a/Source/LexerParser/cmGccDepfileLexer.h b/Source/LexerParser/cmGccDepfileLexer.h
new file mode 100644
index 0000000..7d34060
--- /dev/null
+++ b/Source/LexerParser/cmGccDepfileLexer.h
@@ -0,0 +1,687 @@
+#ifndef cmGccDepfile_yyHEADER_H
+#define cmGccDepfile_yyHEADER_H 1
+#define cmGccDepfile_yyIN_HEADER 1
+
+#define FLEXINT_H 1
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 6
+#define YY_FLEX_SUBMINOR_VERSION 4
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+#ifdef yy_create_buffer
+#define cmGccDepfile_yy_create_buffer_ALREADY_DEFINED
+#else
+#define yy_create_buffer cmGccDepfile_yy_create_buffer
+#endif
+
+#ifdef yy_delete_buffer
+#define cmGccDepfile_yy_delete_buffer_ALREADY_DEFINED
+#else
+#define yy_delete_buffer cmGccDepfile_yy_delete_buffer
+#endif
+
+#ifdef yy_scan_buffer
+#define cmGccDepfile_yy_scan_buffer_ALREADY_DEFINED
+#else
+#define yy_scan_buffer cmGccDepfile_yy_scan_buffer
+#endif
+
+#ifdef yy_scan_string
+#define cmGccDepfile_yy_scan_string_ALREADY_DEFINED
+#else
+#define yy_scan_string cmGccDepfile_yy_scan_string
+#endif
+
+#ifdef yy_scan_bytes
+#define cmGccDepfile_yy_scan_bytes_ALREADY_DEFINED
+#else
+#define yy_scan_bytes cmGccDepfile_yy_scan_bytes
+#endif
+
+#ifdef yy_init_buffer
+#define cmGccDepfile_yy_init_buffer_ALREADY_DEFINED
+#else
+#define yy_init_buffer cmGccDepfile_yy_init_buffer
+#endif
+
+#ifdef yy_flush_buffer
+#define cmGccDepfile_yy_flush_buffer_ALREADY_DEFINED
+#else
+#define yy_flush_buffer cmGccDepfile_yy_flush_buffer
+#endif
+
+#ifdef yy_load_buffer_state
+#define cmGccDepfile_yy_load_buffer_state_ALREADY_DEFINED
+#else
+#define yy_load_buffer_state cmGccDepfile_yy_load_buffer_state
+#endif
+
+#ifdef yy_switch_to_buffer
+#define cmGccDepfile_yy_switch_to_buffer_ALREADY_DEFINED
+#else
+#define yy_switch_to_buffer cmGccDepfile_yy_switch_to_buffer
+#endif
+
+#ifdef yypush_buffer_state
+#define cmGccDepfile_yypush_buffer_state_ALREADY_DEFINED
+#else
+#define yypush_buffer_state cmGccDepfile_yypush_buffer_state
+#endif
+
+#ifdef yypop_buffer_state
+#define cmGccDepfile_yypop_buffer_state_ALREADY_DEFINED
+#else
+#define yypop_buffer_state cmGccDepfile_yypop_buffer_state
+#endif
+
+#ifdef yyensure_buffer_stack
+#define cmGccDepfile_yyensure_buffer_stack_ALREADY_DEFINED
+#else
+#define yyensure_buffer_stack cmGccDepfile_yyensure_buffer_stack
+#endif
+
+#ifdef yylex
+#define cmGccDepfile_yylex_ALREADY_DEFINED
+#else
+#define yylex cmGccDepfile_yylex
+#endif
+
+#ifdef yyrestart
+#define cmGccDepfile_yyrestart_ALREADY_DEFINED
+#else
+#define yyrestart cmGccDepfile_yyrestart
+#endif
+
+#ifdef yylex_init
+#define cmGccDepfile_yylex_init_ALREADY_DEFINED
+#else
+#define yylex_init cmGccDepfile_yylex_init
+#endif
+
+#ifdef yylex_init_extra
+#define cmGccDepfile_yylex_init_extra_ALREADY_DEFINED
+#else
+#define yylex_init_extra cmGccDepfile_yylex_init_extra
+#endif
+
+#ifdef yylex_destroy
+#define cmGccDepfile_yylex_destroy_ALREADY_DEFINED
+#else
+#define yylex_destroy cmGccDepfile_yylex_destroy
+#endif
+
+#ifdef yyget_debug
+#define cmGccDepfile_yyget_debug_ALREADY_DEFINED
+#else
+#define yyget_debug cmGccDepfile_yyget_debug
+#endif
+
+#ifdef yyset_debug
+#define cmGccDepfile_yyset_debug_ALREADY_DEFINED
+#else
+#define yyset_debug cmGccDepfile_yyset_debug
+#endif
+
+#ifdef yyget_extra
+#define cmGccDepfile_yyget_extra_ALREADY_DEFINED
+#else
+#define yyget_extra cmGccDepfile_yyget_extra
+#endif
+
+#ifdef yyset_extra
+#define cmGccDepfile_yyset_extra_ALREADY_DEFINED
+#else
+#define yyset_extra cmGccDepfile_yyset_extra
+#endif
+
+#ifdef yyget_in
+#define cmGccDepfile_yyget_in_ALREADY_DEFINED
+#else
+#define yyget_in cmGccDepfile_yyget_in
+#endif
+
+#ifdef yyset_in
+#define cmGccDepfile_yyset_in_ALREADY_DEFINED
+#else
+#define yyset_in cmGccDepfile_yyset_in
+#endif
+
+#ifdef yyget_out
+#define cmGccDepfile_yyget_out_ALREADY_DEFINED
+#else
+#define yyget_out cmGccDepfile_yyget_out
+#endif
+
+#ifdef yyset_out
+#define cmGccDepfile_yyset_out_ALREADY_DEFINED
+#else
+#define yyset_out cmGccDepfile_yyset_out
+#endif
+
+#ifdef yyget_leng
+#define cmGccDepfile_yyget_leng_ALREADY_DEFINED
+#else
+#define yyget_leng cmGccDepfile_yyget_leng
+#endif
+
+#ifdef yyget_text
+#define cmGccDepfile_yyget_text_ALREADY_DEFINED
+#else
+#define yyget_text cmGccDepfile_yyget_text
+#endif
+
+#ifdef yyget_lineno
+#define cmGccDepfile_yyget_lineno_ALREADY_DEFINED
+#else
+#define yyget_lineno cmGccDepfile_yyget_lineno
+#endif
+
+#ifdef yyset_lineno
+#define cmGccDepfile_yyset_lineno_ALREADY_DEFINED
+#else
+#define yyset_lineno cmGccDepfile_yyset_lineno
+#endif
+
+#ifdef yyget_column
+#define cmGccDepfile_yyget_column_ALREADY_DEFINED
+#else
+#define yyget_column cmGccDepfile_yyget_column
+#endif
+
+#ifdef yyset_column
+#define cmGccDepfile_yyset_column_ALREADY_DEFINED
+#else
+#define yyset_column cmGccDepfile_yyset_column
+#endif
+
+#ifdef yywrap
+#define cmGccDepfile_yywrap_ALREADY_DEFINED
+#else
+#define yywrap cmGccDepfile_yywrap
+#endif
+
+#ifdef yyalloc
+#define cmGccDepfile_yyalloc_ALREADY_DEFINED
+#else
+#define yyalloc cmGccDepfile_yyalloc
+#endif
+
+#ifdef yyrealloc
+#define cmGccDepfile_yyrealloc_ALREADY_DEFINED
+#else
+#define yyrealloc cmGccDepfile_yyrealloc
+#endif
+
+#ifdef yyfree
+#define cmGccDepfile_yyfree_ALREADY_DEFINED
+#else
+#define yyfree cmGccDepfile_yyfree
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#ifndef SIZE_MAX
+#define SIZE_MAX (~(size_t)0)
+#endif
+
+#endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+/* begin standard C++ headers. */
+
+/* TODO: this is always defined, so inline it */
+#define yyconst const
+
+#if defined(__GNUC__) && __GNUC__ >= 3
+#define yynoreturn __attribute__((__noreturn__))
+#else
+#define yynoreturn
+#endif
+
+/* An opaque pointer. */
+#ifndef YY_TYPEDEF_YY_SCANNER_T
+#define YY_TYPEDEF_YY_SCANNER_T
+typedef void* yyscan_t;
+#endif
+
+/* For convenience, these vars (plus the bison vars far below)
+ are macros in the reentrant scanner. */
+#define yyin yyg->yyin_r
+#define yyout yyg->yyout_r
+#define yyextra yyg->yyextra_r
+#define yyleng yyg->yyleng_r
+#define yytext yyg->yytext_r
+#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
+#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
+#define yy_flex_debug yyg->yy_flex_debug_r
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
+#define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
+#endif
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ int yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+void yyrestart ( FILE *input_file , yyscan_t yyscanner );
+void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner );
+void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
+void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
+void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
+void yypop_buffer_state ( yyscan_t yyscanner );
+
+YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner );
+
+void *yyalloc ( yy_size_t , yyscan_t yyscanner );
+void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner );
+void yyfree ( void * , yyscan_t yyscanner );
+
+/* Begin user sect3 */
+
+#define cmGccDepfile_yywrap(yyscanner) (/*CONSTCOND*/1)
+#define YY_SKIP_YYWRAP
+
+#define yytext_ptr yytext_r
+
+#ifdef YY_HEADER_EXPORT_START_CONDITIONS
+#define INITIAL 0
+
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+int yylex_init (yyscan_t* scanner);
+
+int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner);
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy ( yyscan_t yyscanner );
+
+int yyget_debug ( yyscan_t yyscanner );
+
+void yyset_debug ( int debug_flag , yyscan_t yyscanner );
+
+YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner );
+
+void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner );
+
+FILE *yyget_in ( yyscan_t yyscanner );
+
+void yyset_in ( FILE * _in_str , yyscan_t yyscanner );
+
+FILE *yyget_out ( yyscan_t yyscanner );
+
+void yyset_out ( FILE * _out_str , yyscan_t yyscanner );
+
+ int yyget_leng ( yyscan_t yyscanner );
+
+char *yyget_text ( yyscan_t yyscanner );
+
+int yyget_lineno ( yyscan_t yyscanner );
+
+void yyset_lineno ( int _line_number , yyscan_t yyscanner );
+
+int yyget_column ( yyscan_t yyscanner );
+
+void yyset_column ( int _column_no , yyscan_t yyscanner );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap ( yyscan_t yyscanner );
+#else
+extern int yywrap ( yyscan_t yyscanner );
+#endif
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner);
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen ( const char * , yyscan_t yyscanner);
+#endif
+
+#ifndef YY_NO_INPUT
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
+#define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int yylex (yyscan_t yyscanner);
+
+#define YY_DECL int yylex (yyscan_t yyscanner)
+#endif /* !YY_DECL */
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+#undef YY_NEW_FILE
+#undef YY_FLUSH_BUFFER
+#undef yy_set_bol
+#undef yy_new_buffer
+#undef yy_set_interactive
+#undef YY_DO_BEFORE_ACTION
+
+#ifdef YY_DECL_IS_OURS
+#undef YY_DECL_IS_OURS
+#undef YY_DECL
+#endif
+
+#ifndef cmGccDepfile_yy_create_buffer_ALREADY_DEFINED
+#undef yy_create_buffer
+#endif
+#ifndef cmGccDepfile_yy_delete_buffer_ALREADY_DEFINED
+#undef yy_delete_buffer
+#endif
+#ifndef cmGccDepfile_yy_scan_buffer_ALREADY_DEFINED
+#undef yy_scan_buffer
+#endif
+#ifndef cmGccDepfile_yy_scan_string_ALREADY_DEFINED
+#undef yy_scan_string
+#endif
+#ifndef cmGccDepfile_yy_scan_bytes_ALREADY_DEFINED
+#undef yy_scan_bytes
+#endif
+#ifndef cmGccDepfile_yy_init_buffer_ALREADY_DEFINED
+#undef yy_init_buffer
+#endif
+#ifndef cmGccDepfile_yy_flush_buffer_ALREADY_DEFINED
+#undef yy_flush_buffer
+#endif
+#ifndef cmGccDepfile_yy_load_buffer_state_ALREADY_DEFINED
+#undef yy_load_buffer_state
+#endif
+#ifndef cmGccDepfile_yy_switch_to_buffer_ALREADY_DEFINED
+#undef yy_switch_to_buffer
+#endif
+#ifndef cmGccDepfile_yypush_buffer_state_ALREADY_DEFINED
+#undef yypush_buffer_state
+#endif
+#ifndef cmGccDepfile_yypop_buffer_state_ALREADY_DEFINED
+#undef yypop_buffer_state
+#endif
+#ifndef cmGccDepfile_yyensure_buffer_stack_ALREADY_DEFINED
+#undef yyensure_buffer_stack
+#endif
+#ifndef cmGccDepfile_yylex_ALREADY_DEFINED
+#undef yylex
+#endif
+#ifndef cmGccDepfile_yyrestart_ALREADY_DEFINED
+#undef yyrestart
+#endif
+#ifndef cmGccDepfile_yylex_init_ALREADY_DEFINED
+#undef yylex_init
+#endif
+#ifndef cmGccDepfile_yylex_init_extra_ALREADY_DEFINED
+#undef yylex_init_extra
+#endif
+#ifndef cmGccDepfile_yylex_destroy_ALREADY_DEFINED
+#undef yylex_destroy
+#endif
+#ifndef cmGccDepfile_yyget_debug_ALREADY_DEFINED
+#undef yyget_debug
+#endif
+#ifndef cmGccDepfile_yyset_debug_ALREADY_DEFINED
+#undef yyset_debug
+#endif
+#ifndef cmGccDepfile_yyget_extra_ALREADY_DEFINED
+#undef yyget_extra
+#endif
+#ifndef cmGccDepfile_yyset_extra_ALREADY_DEFINED
+#undef yyset_extra
+#endif
+#ifndef cmGccDepfile_yyget_in_ALREADY_DEFINED
+#undef yyget_in
+#endif
+#ifndef cmGccDepfile_yyset_in_ALREADY_DEFINED
+#undef yyset_in
+#endif
+#ifndef cmGccDepfile_yyget_out_ALREADY_DEFINED
+#undef yyget_out
+#endif
+#ifndef cmGccDepfile_yyset_out_ALREADY_DEFINED
+#undef yyset_out
+#endif
+#ifndef cmGccDepfile_yyget_leng_ALREADY_DEFINED
+#undef yyget_leng
+#endif
+#ifndef cmGccDepfile_yyget_text_ALREADY_DEFINED
+#undef yyget_text
+#endif
+#ifndef cmGccDepfile_yyget_lineno_ALREADY_DEFINED
+#undef yyget_lineno
+#endif
+#ifndef cmGccDepfile_yyset_lineno_ALREADY_DEFINED
+#undef yyset_lineno
+#endif
+#ifndef cmGccDepfile_yyget_column_ALREADY_DEFINED
+#undef yyget_column
+#endif
+#ifndef cmGccDepfile_yyset_column_ALREADY_DEFINED
+#undef yyset_column
+#endif
+#ifndef cmGccDepfile_yywrap_ALREADY_DEFINED
+#undef yywrap
+#endif
+#ifndef cmGccDepfile_yyget_lval_ALREADY_DEFINED
+#undef yyget_lval
+#endif
+#ifndef cmGccDepfile_yyset_lval_ALREADY_DEFINED
+#undef yyset_lval
+#endif
+#ifndef cmGccDepfile_yyget_lloc_ALREADY_DEFINED
+#undef yyget_lloc
+#endif
+#ifndef cmGccDepfile_yyset_lloc_ALREADY_DEFINED
+#undef yyset_lloc
+#endif
+#ifndef cmGccDepfile_yyalloc_ALREADY_DEFINED
+#undef yyalloc
+#endif
+#ifndef cmGccDepfile_yyrealloc_ALREADY_DEFINED
+#undef yyrealloc
+#endif
+#ifndef cmGccDepfile_yyfree_ALREADY_DEFINED
+#undef yyfree
+#endif
+#ifndef cmGccDepfile_yytext_ALREADY_DEFINED
+#undef yytext
+#endif
+#ifndef cmGccDepfile_yyleng_ALREADY_DEFINED
+#undef yyleng
+#endif
+#ifndef cmGccDepfile_yyin_ALREADY_DEFINED
+#undef yyin
+#endif
+#ifndef cmGccDepfile_yyout_ALREADY_DEFINED
+#undef yyout
+#endif
+#ifndef cmGccDepfile_yy_flex_debug_ALREADY_DEFINED
+#undef yy_flex_debug
+#endif
+#ifndef cmGccDepfile_yylineno_ALREADY_DEFINED
+#undef yylineno
+#endif
+#ifndef cmGccDepfile_yytables_fload_ALREADY_DEFINED
+#undef yytables_fload
+#endif
+#ifndef cmGccDepfile_yytables_destroy_ALREADY_DEFINED
+#undef yytables_destroy
+#endif
+#ifndef cmGccDepfile_yyTABLES_NAME_ALREADY_DEFINED
+#undef yyTABLES_NAME
+#endif
+
+#undef cmGccDepfile_yyIN_HEADER
+#endif /* cmGccDepfile_yyHEADER_H */
diff --git a/Source/LexerParser/cmGccDepfileLexer.in.l b/Source/LexerParser/cmGccDepfileLexer.in.l
new file mode 100644
index 0000000..08f8577
--- /dev/null
+++ b/Source/LexerParser/cmGccDepfileLexer.in.l
@@ -0,0 +1,72 @@
+%{
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+/* IWYU pragma: no_forward_declare yyguts_t */
+
+#ifndef __clang_analyzer__ /* Suppress clang scan-build warnings */
+
+#include <cmGccDepfileLexerHelper.h>
+#include <string>
+%}
+
+%option prefix="cmGccDepfile_yy"
+%option noyywrap
+%option reentrant
+%pointer
+
+WSPACE [ \t]
+NEWLINE \r?\n
+
+%%
+\${2} {
+ // Unescape the dollar sign.
+ yyextra->addToCurrentPath("$");
+ }
+\\# {
+ // Unescape the hash.
+ yyextra->addToCurrentPath("#");
+ }
+(\\\\)*\\[ ] {
+ // 2N+1 backslashes plus space -> N backslashes plus space.
+ size_t c = (strlen(yytext) - 1) / 2;
+ std::string s(c, '\\');
+ s.push_back(' ');
+ yyextra->addToCurrentPath(s.c_str());
+ }
+(\\\\)+[ ] {
+ // 2N backslashes plus space -> 2N backslashes, end of filename.
+ yytext[strlen(yytext) - 1] = 0;
+ yyextra->addToCurrentPath(yytext);
+ yyextra->newDependency();
+ }
+{WSPACE}*\\{NEWLINE} {
+ // A line continuation ends the current file name.
+ yyextra->newDependency();
+ }
+{NEWLINE} {
+ // A newline ends the current file name and the current rule.
+ yyextra->newEntry();
+ }
+:{WSPACE}+ {
+ // A colon followed by space ends the rules and starts a new dependency.
+ yyextra->newDependency();
+ }
+{WSPACE}+ {
+ // Rules and dependencies are separated by blocks of whitespace.
+ yyextra->newRuleOrDependency();
+ }
+[a-zA-Z0-9+,/_.~()}{%=@\x5B\x5D!\x80-\xFF-]+ {
+ // Got a span of plain text.
+ yyextra->addToCurrentPath(yytext);
+ }
+. {
+ // Got an otherwise unmatched character.
+ yyextra->addToCurrentPath(yytext);
+ }
+
+%%
+
+/*--------------------------------------------------------------------------*/
+
+#endif /* __clang_analyzer__ */
diff --git a/Source/LexerParser/cmListFileLexer.c b/Source/LexerParser/cmListFileLexer.c
index 15dcda0..ec7424c 100644
--- a/Source/LexerParser/cmListFileLexer.c
+++ b/Source/LexerParser/cmListFileLexer.c
@@ -2787,7 +2787,7 @@ int cmListFileLexer_SetString(cmListFileLexer* lexer, const char* text)
/*--------------------------------------------------------------------------*/
cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer* lexer)
{
- if (!lexer->file) {
+ if (!lexer->file && !lexer->string_buffer) {
return 0;
}
if (cmListFileLexer_yylex(lexer->scanner, lexer)) {
@@ -2801,21 +2801,13 @@ cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer* lexer)
/*--------------------------------------------------------------------------*/
long cmListFileLexer_GetCurrentLine(cmListFileLexer* lexer)
{
- if (lexer->file) {
- return lexer->line;
- } else {
- return 0;
- }
+ return lexer->line;
}
/*--------------------------------------------------------------------------*/
long cmListFileLexer_GetCurrentColumn(cmListFileLexer* lexer)
{
- if (lexer->file) {
- return lexer->column;
- } else {
- return 0;
- }
+ return lexer->column;
}
/*--------------------------------------------------------------------------*/
diff --git a/Source/LexerParser/cmListFileLexer.in.l b/Source/LexerParser/cmListFileLexer.in.l
index fdf14d2..94cf8a5 100644
--- a/Source/LexerParser/cmListFileLexer.in.l
+++ b/Source/LexerParser/cmListFileLexer.in.l
@@ -500,7 +500,7 @@ int cmListFileLexer_SetString(cmListFileLexer* lexer, const char* text)
/*--------------------------------------------------------------------------*/
cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer* lexer)
{
- if (!lexer->file) {
+ if (!lexer->file && !lexer->string_buffer) {
return 0;
}
if (cmListFileLexer_yylex(lexer->scanner, lexer)) {
@@ -514,21 +514,13 @@ cmListFileLexer_Token* cmListFileLexer_Scan(cmListFileLexer* lexer)
/*--------------------------------------------------------------------------*/
long cmListFileLexer_GetCurrentLine(cmListFileLexer* lexer)
{
- if (lexer->file) {
- return lexer->line;
- } else {
- return 0;
- }
+ return lexer->line;
}
/*--------------------------------------------------------------------------*/
long cmListFileLexer_GetCurrentColumn(cmListFileLexer* lexer)
{
- if (lexer->file) {
- return lexer->column;
- } else {
- return 0;
- }
+ return lexer->column;
}
/*--------------------------------------------------------------------------*/
diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt
index cb89d19..98dd0e2 100644
--- a/Source/QtDialog/CMakeLists.txt
+++ b/Source/QtDialog/CMakeLists.txt
@@ -178,6 +178,10 @@ if(WIN32)
target_sources(cmake-gui PRIVATE $<TARGET_OBJECTS:CMakeVersion>)
endif()
+if(CMake_JOB_POOL_LINK_BIN)
+ set_property(TARGET cmake-gui PROPERTY JOB_POOL_LINK "link-bin")
+endif()
+
# cmake-gui has not been updated for `include-what-you-use`.
# Block the tool until this is done.
set_target_properties(cmake-gui PROPERTIES
diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx
index ee81a7d..9d928b2 100644
--- a/Source/QtDialog/CMakeSetup.cxx
+++ b/Source/QtDialog/CMakeSetup.cxx
@@ -201,8 +201,7 @@ int main(int argc, char** argv)
cmSystemTools::CollapseFullPath(args[1].toLocal8Bit().data());
// check if argument is a directory containing CMakeCache.txt
- std::string buildFilePath =
- cmSystemTools::CollapseFullPath("CMakeCache.txt", filePath.c_str());
+ std::string buildFilePath = cmStrCat(filePath, "/CMakeCache.txt");
// check if argument is a CMakeCache.txt file
if (cmSystemTools::GetFilenameName(filePath) == "CMakeCache.txt" &&
@@ -211,8 +210,7 @@ int main(int argc, char** argv)
}
// check if argument is a directory containing CMakeLists.txt
- std::string srcFilePath =
- cmSystemTools::CollapseFullPath("CMakeLists.txt", filePath.c_str());
+ std::string srcFilePath = cmStrCat(filePath, "/CMakeLists.txt");
if (cmSystemTools::FileExists(buildFilePath.c_str())) {
dialog.setBinaryDirectory(QString::fromLocal8Bit(
diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx
index 436a904..930f300 100644
--- a/Source/QtDialog/CMakeSetupDialog.cxx
+++ b/Source/QtDialog/CMakeSetupDialog.cxx
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "CMakeSetupDialog.h"
+#include <cm/memory>
+
#include <QCloseEvent>
#include <QCoreApplication>
#include <QDesktopServices>
@@ -39,23 +41,21 @@
QCMakeThread::QCMakeThread(QObject* p)
: QThread(p)
- , CMakeInstance(nullptr)
{
}
QCMake* QCMakeThread::cmakeInstance() const
{
- return this->CMakeInstance;
+ return this->CMakeInstance.get();
}
void QCMakeThread::run()
{
- this->CMakeInstance = new QCMake;
+ this->CMakeInstance = cm::make_unique<QCMake>();
// emit that this cmake thread is ready for use
emit this->cmakeInitialized();
this->exec();
- delete this->CMakeInstance;
- this->CMakeInstance = nullptr;
+ this->CMakeInstance.reset();
}
CMakeSetupDialog::CMakeSetupDialog()
@@ -804,12 +804,19 @@ bool CMakeSetupDialog::setupFirstConfigure()
QString systemVersion = dialog.getSystemVersion();
m->insertProperty(QCMakeProperty::STRING, "CMAKE_SYSTEM_VERSION",
tr("CMake System Version"), systemVersion, false);
+ QString systemProcessor = dialog.getSystemProcessor();
+ m->insertProperty(QCMakeProperty::STRING, "CMAKE_SYSTEM_PROCESSOR",
+ tr("CMake System Processor"), systemProcessor, false);
QString cxxCompiler = dialog.getCXXCompiler();
- m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_CXX_COMPILER",
- tr("CXX compiler."), cxxCompiler, false);
+ if (!cxxCompiler.isEmpty()) {
+ m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_CXX_COMPILER",
+ tr("CXX compiler."), cxxCompiler, false);
+ }
QString cCompiler = dialog.getCCompiler();
- m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_C_COMPILER",
- tr("C compiler."), cCompiler, false);
+ if (!cCompiler.isEmpty()) {
+ m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_C_COMPILER",
+ tr("C compiler."), cCompiler, false);
+ }
} else if (dialog.crossCompilerToolChainFile()) {
QString toolchainFile = dialog.getCrossCompilerToolChainFile();
m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_TOOLCHAIN_FILE",
@@ -1206,7 +1213,7 @@ void CMakeSetupDialog::setSearchFilter(const QString& str)
void CMakeSetupDialog::doOutputContextMenu(QPoint pt)
{
- QMenu* menu = this->Output->createStandardContextMenu();
+ std::unique_ptr<QMenu> menu(this->Output->createStandardContextMenu());
menu->addSeparator();
menu->addAction(tr("Find..."), this, SLOT(doOutputFindDialog()),
@@ -1220,7 +1227,6 @@ void CMakeSetupDialog::doOutputContextMenu(QPoint pt)
QKeySequence(Qt::Key_F8));
menu->exec(this->Output->mapToGlobal(pt));
- delete menu;
}
void CMakeSetupDialog::doOutputFindDialog()
diff --git a/Source/QtDialog/CMakeSetupDialog.h b/Source/QtDialog/CMakeSetupDialog.h
index f23aee6..d1e2035 100644
--- a/Source/QtDialog/CMakeSetupDialog.h
+++ b/Source/QtDialog/CMakeSetupDialog.h
@@ -3,6 +3,8 @@
#ifndef CMakeSetupDialog_h
#define CMakeSetupDialog_h
+#include <memory>
+
#include "QCMake.h"
#include <QEventLoop>
#include <QMainWindow>
@@ -143,7 +145,7 @@ signals:
protected:
virtual void run();
- QCMake* CMakeInstance;
+ std::unique_ptr<QCMake> CMakeInstance;
};
#endif // CMakeSetupDialog_h
diff --git a/Source/QtDialog/FirstConfigure.cxx b/Source/QtDialog/FirstConfigure.cxx
index ca28b19..3c24b9b 100644
--- a/Source/QtDialog/FirstConfigure.cxx
+++ b/Source/QtDialog/FirstConfigure.cxx
@@ -10,8 +10,12 @@
#include "Compilers.h"
-StartCompilerSetup::StartCompilerSetup(QWidget* p)
+StartCompilerSetup::StartCompilerSetup(QString defaultGeneratorPlatform,
+ QString defaultGeneratorToolset,
+ QWidget* p)
: QWizardPage(p)
+ , DefaultGeneratorPlatform(std::move(defaultGeneratorPlatform))
+ , DefaultGeneratorToolset(std::move(defaultGeneratorToolset))
{
QVBoxLayout* l = new QVBoxLayout(this);
l->addWidget(new QLabel(tr("Specify the generator for this project")));
@@ -68,6 +72,10 @@ QFrame* StartCompilerSetup::CreateToolsetWidgets()
Toolset = new QLineEdit(frame);
l->addWidget(Toolset);
+ // Default to CMAKE_GENERATOR_TOOLSET env var if set
+ if (!DefaultGeneratorToolset.isEmpty()) {
+ this->Toolset->setText(DefaultGeneratorToolset);
+ }
return frame;
}
@@ -199,6 +207,14 @@ void StartCompilerSetup::onGeneratorChanged(QString const& name)
this->PlatformOptions->addItems(platform_list);
PlatformFrame->show();
+
+ // Default to generator platform from environment
+ if (!DefaultGeneratorPlatform.isEmpty()) {
+ int platform_index = platforms.indexOf(DefaultGeneratorPlatform);
+ if (platform_index != -1) {
+ this->PlatformOptions->setCurrentIndex(platform_index);
+ }
+ }
} else {
PlatformFrame->hide();
}
@@ -421,8 +437,26 @@ void ToolchainCompilerSetup::setToolchainFile(const QString& t)
FirstConfigure::FirstConfigure()
{
+ const char* env_generator = std::getenv("CMAKE_GENERATOR");
+ const char* env_generator_platform = nullptr;
+ const char* env_generator_toolset = nullptr;
+ if (env_generator && std::strlen(env_generator)) {
+ mDefaultGenerator = env_generator;
+ env_generator_platform = std::getenv("CMAKE_GENERATOR_PLATFORM");
+ env_generator_toolset = std::getenv("CMAKE_GENERATOR_TOOLSET");
+ }
+
+ if (!env_generator_platform) {
+ env_generator_platform = "";
+ }
+
+ if (!env_generator_toolset) {
+ env_generator_toolset = "";
+ }
+
// this->setOption(QWizard::HaveFinishButtonOnEarlyPages, true);
- this->mStartCompilerSetupPage = new StartCompilerSetup(this);
+ this->mStartCompilerSetupPage = new StartCompilerSetup(
+ env_generator_platform, env_generator_toolset, this);
this->setPage(Start, this->mStartCompilerSetupPage);
QObject::connect(this->mStartCompilerSetupPage, SIGNAL(selectionChanged()),
this, SLOT(restart()));
@@ -504,6 +538,17 @@ void FirstConfigure::loadFromSettings()
this->mCrossCompilerSetupPage->setIncludeMode(
settings.value("IncludeMode", 0).toInt());
settings.endGroup();
+
+ // environment variables take precedence over application settings because...
+ // - they're harder to set
+ // - settings always exist after the program is run once, so the environment
+ // variables would never be used otherwise
+ // - platform and toolset are populated only from environment variables, so
+ // this prevents them from being taken from environment, while the
+ // generator is taken from application settings
+ if (!mDefaultGenerator.isEmpty()) {
+ this->mStartCompilerSetupPage->setCurrentGenerator(mDefaultGenerator);
+ }
}
void FirstConfigure::saveToSettings()
diff --git a/Source/QtDialog/FirstConfigure.h b/Source/QtDialog/FirstConfigure.h
index d1db5bf..c26f489 100644
--- a/Source/QtDialog/FirstConfigure.h
+++ b/Source/QtDialog/FirstConfigure.h
@@ -29,7 +29,8 @@ class StartCompilerSetup : public QWizardPage
{
Q_OBJECT
public:
- StartCompilerSetup(QWidget* p);
+ StartCompilerSetup(QString defaultGeneratorPlatform,
+ QString defaultGeneratorToolset, QWidget* p);
~StartCompilerSetup();
void setGenerators(std::vector<cmake::GeneratorInfo> const& gens);
void setCurrentGenerator(const QString& gen);
@@ -64,6 +65,7 @@ protected:
QStringList GeneratorsSupportingPlatform;
QMultiMap<QString, QString> GeneratorSupportedPlatforms;
QMap<QString, QString> GeneratorDefaultPlatform;
+ QString DefaultGeneratorPlatform, DefaultGeneratorToolset;
private:
QFrame* CreateToolsetWidgets();
@@ -197,6 +199,7 @@ protected:
NativeCompilerSetup* mNativeCompilerSetupPage;
CrossCompilerSetup* mCrossCompilerSetupPage;
ToolchainCompilerSetup* mToolchainCompilerSetupPage;
+ QString mDefaultGenerator;
};
#endif // FirstConfigure_h
diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx
index b608fcb..776af81 100644
--- a/Source/QtDialog/QCMake.cxx
+++ b/Source/QtDialog/QCMake.cxx
@@ -2,10 +2,13 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "QCMake.h"
+#include <cm/memory>
+
#include <QCoreApplication>
#include <QDir>
#include "cmExternalMakefileProjectGenerator.h"
+#include "cmGlobalGenerator.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -34,7 +37,8 @@ QCMake::QCMake(QObject* p)
cmSystemTools::SetStderrCallback(
[this](std::string const& msg) { this->stderrCallback(msg); });
- this->CMakeInstance = new cmake(cmake::RoleProject, cmState::Project);
+ this->CMakeInstance =
+ cm::make_unique<cmake>(cmake::RoleProject, cmState::Project);
this->CMakeInstance->SetCMakeEditCommand(
cmSystemTools::GetCMakeGUICommand());
this->CMakeInstance->SetProgressCallback(
@@ -54,11 +58,7 @@ QCMake::QCMake(QObject* p)
}
}
-QCMake::~QCMake()
-{
- delete this->CMakeInstance;
- // cmDynamicLoader::FlushCache();
-}
+QCMake::~QCMake() = default;
void QCMake::loadCache(const QString& dir)
{
@@ -100,29 +100,28 @@ void QCMake::setBinaryDirectory(const QString& _dir)
QCMakePropertyList props = this->properties();
emit this->propertiesChanged(props);
- const char* homeDir = state->GetCacheEntryValue("CMAKE_HOME_DIRECTORY");
+ cmProp homeDir = state->GetCacheEntryValue("CMAKE_HOME_DIRECTORY");
if (homeDir) {
- setSourceDirectory(QString::fromLocal8Bit(homeDir));
+ setSourceDirectory(QString::fromLocal8Bit(homeDir->c_str()));
}
- const char* gen = state->GetCacheEntryValue("CMAKE_GENERATOR");
+ cmProp gen = state->GetCacheEntryValue("CMAKE_GENERATOR");
if (gen) {
const std::string* extraGen =
state->GetInitializedCacheValue("CMAKE_EXTRA_GENERATOR");
std::string curGen =
cmExternalMakefileProjectGenerator::CreateFullGeneratorName(
- gen, extraGen ? *extraGen : "");
+ *gen, extraGen ? *extraGen : "");
this->setGenerator(QString::fromLocal8Bit(curGen.c_str()));
}
- const char* platform =
- state->GetCacheEntryValue("CMAKE_GENERATOR_PLATFORM");
+ cmProp platform = state->GetCacheEntryValue("CMAKE_GENERATOR_PLATFORM");
if (platform) {
- this->setPlatform(QString::fromLocal8Bit(platform));
+ this->setPlatform(QString::fromLocal8Bit(platform->c_str()));
}
- const char* toolset = state->GetCacheEntryValue("CMAKE_GENERATOR_TOOLSET");
+ cmProp toolset = state->GetCacheEntryValue("CMAKE_GENERATOR_TOOLSET");
if (toolset) {
- this->setToolset(QString::fromLocal8Bit(toolset));
+ this->setToolset(QString::fromLocal8Bit(toolset->c_str()));
}
checkOpenPossible();
@@ -303,27 +302,28 @@ QCMakePropertyList QCMake::properties() const
continue;
}
- const char* cachedValue = state->GetCacheEntryValue(key);
+ cmProp cachedValue = state->GetCacheEntryValue(key);
QCMakeProperty prop;
prop.Key = QString::fromLocal8Bit(key.c_str());
- prop.Help =
- QString::fromLocal8Bit(state->GetCacheEntryProperty(key, "HELPSTRING"));
- prop.Value = QString::fromLocal8Bit(cachedValue);
+ if (cmProp hs = state->GetCacheEntryProperty(key, "HELPSTRING")) {
+ prop.Help = QString::fromLocal8Bit(hs->c_str());
+ }
+ prop.Value = QString::fromLocal8Bit(cachedValue->c_str());
prop.Advanced = state->GetCacheEntryPropertyAsBool(key, "ADVANCED");
if (t == cmStateEnums::BOOL) {
prop.Type = QCMakeProperty::BOOL;
- prop.Value = cmIsOn(cachedValue);
+ prop.Value = cmIsOn(*cachedValue);
} else if (t == cmStateEnums::PATH) {
prop.Type = QCMakeProperty::PATH;
} else if (t == cmStateEnums::FILEPATH) {
prop.Type = QCMakeProperty::FILEPATH;
} else if (t == cmStateEnums::STRING) {
prop.Type = QCMakeProperty::STRING;
- const char* stringsProperty =
- state->GetCacheEntryProperty(key, "STRINGS");
+ cmProp stringsProperty = state->GetCacheEntryProperty(key, "STRINGS");
if (stringsProperty) {
- prop.Strings = QString::fromLocal8Bit(stringsProperty).split(";");
+ prop.Strings =
+ QString::fromLocal8Bit(stringsProperty->c_str()).split(";");
}
}
@@ -485,7 +485,7 @@ void QCMake::setWarnUnusedMode(bool value)
void QCMake::checkOpenPossible()
{
- auto data = this->BinaryDirectory.toLocal8Bit().data();
+ std::string data = this->BinaryDirectory.toLocal8Bit().data();
auto possible = this->CMakeInstance->Open(data, true);
emit openPossible(possible);
}
diff --git a/Source/QtDialog/QCMake.h b/Source/QtDialog/QCMake.h
index fa4451b..110a971 100644
--- a/Source/QtDialog/QCMake.h
+++ b/Source/QtDialog/QCMake.h
@@ -12,6 +12,7 @@
# pragma warning(disable : 4512)
#endif
+#include <memory>
#include <vector>
#include <QAtomicInt>
@@ -165,7 +166,7 @@ signals:
void openPossible(bool possible);
protected:
- cmake* CMakeInstance;
+ std::unique_ptr<cmake> CMakeInstance;
bool interruptCallback();
void progressCallback(std::string const& msg, float percent);
diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx
index b85cc33..8435740 100644
--- a/Source/bindexplib.cxx
+++ b/Source/bindexplib.cxx
@@ -64,32 +64,36 @@
*/
#include "bindexplib.h"
-#include <iostream>
+#include <cstddef> // IWYU pragma: keep
#include <sstream>
#include <vector>
-#include <windows.h>
+#ifdef _WIN32
+# include <windows.h>
+
+# include "cmsys/Encoding.hxx"
+#endif
-#include "cmsys/Encoding.hxx"
#include "cmsys/FStream.hxx"
#include "cmSystemTools.h"
-#ifndef IMAGE_FILE_MACHINE_ARM
-# define IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM Little-Endian
-#endif
+#ifdef _WIN32
+# ifndef IMAGE_FILE_MACHINE_ARM
+# define IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM Little-Endian
+# endif
-#ifndef IMAGE_FILE_MACHINE_THUMB
-# define IMAGE_FILE_MACHINE_THUMB 0x01c2 // ARM Thumb/Thumb-2 Little-Endian
-#endif
+# ifndef IMAGE_FILE_MACHINE_THUMB
+# define IMAGE_FILE_MACHINE_THUMB 0x01c2 // ARM Thumb/Thumb-2 Little-Endian
+# endif
-#ifndef IMAGE_FILE_MACHINE_ARMNT
-# define IMAGE_FILE_MACHINE_ARMNT 0x01c4 // ARM Thumb-2 Little-Endian
-#endif
+# ifndef IMAGE_FILE_MACHINE_ARMNT
+# define IMAGE_FILE_MACHINE_ARMNT 0x01c4 // ARM Thumb-2 Little-Endian
+# endif
-#ifndef IMAGE_FILE_MACHINE_ARM64
-# define IMAGE_FILE_MACHINE_ARM64 0xaa64 // ARM64 Little-Endian
-#endif
+# ifndef IMAGE_FILE_MACHINE_ARM64
+# define IMAGE_FILE_MACHINE_ARM64 0xaa64 // ARM64 Little-Endian
+# endif
typedef struct cmANON_OBJECT_HEADER_BIGOBJ
{
@@ -272,8 +276,9 @@ public:
symbol.compare(0, 4, vectorPrefix)) {
SectChar = this->SectionHeaders[pSymbolTable->SectionNumber - 1]
.Characteristics;
- // skip symbols containing a dot
- if (symbol.find('.') == std::string::npos) {
+ // skip symbols containing a dot or are from managed code
+ if (symbol.find('.') == std::string::npos &&
+ !SymbolIsFromManagedCode(symbol)) {
if (!pSymbolTable->Type && (SectChar & IMAGE_SCN_MEM_WRITE)) {
// Read only (i.e. constants) must be excluded
this->DataSymbols.insert(symbol);
@@ -298,6 +303,13 @@ public:
}
private:
+ bool SymbolIsFromManagedCode(std::string const& symbol)
+ {
+ return symbol == "__t2m" || symbol == "__m2mep" || symbol == "__mep" ||
+ symbol.find("$$F") != std::string::npos ||
+ symbol.find("$$J") != std::string::npos;
+ }
+
std::set<std::string>& Symbols;
std::set<std::string>& DataSymbols;
DWORD_PTR SymbolCount;
@@ -306,6 +318,7 @@ private:
SymbolTableType* SymbolTable;
bool IsI386;
};
+#endif
bool DumpFileWithLlvmNm(std::string const& nmPath, const char* filename,
std::set<std::string>& symbols,
@@ -315,15 +328,15 @@ bool DumpFileWithLlvmNm(std::string const& nmPath, const char* filename,
// break up command line into a vector
std::vector<std::string> command;
command.push_back(nmPath);
- command.push_back("--no-weak");
- command.push_back("--defined-only");
- command.push_back("--format=posix");
- command.push_back(filename);
+ command.emplace_back("--no-weak");
+ command.emplace_back("--defined-only");
+ command.emplace_back("--format=posix");
+ command.emplace_back(filename);
// run the command
int exit_code = 0;
- cmSystemTools::RunSingleCommand(command, &output, &output, &exit_code, "",
- cmSystemTools::OUTPUT_NONE);
+ cmSystemTools::RunSingleCommand(command, &output, &output, &exit_code,
+ nullptr, cmSystemTools::OUTPUT_NONE);
if (exit_code != 0) {
fprintf(stderr, "llvm-nm returned an error: %s\n", output.c_str());
@@ -336,7 +349,7 @@ bool DumpFileWithLlvmNm(std::string const& nmPath, const char* filename,
if (line.empty()) { // last line
continue;
}
- size_t sym_end = line.find(" ");
+ size_t sym_end = line.find(' ');
if (sym_end == std::string::npos) {
fprintf(stderr, "Couldn't parse llvm-nm output line: %s\n",
line.c_str());
@@ -347,14 +360,14 @@ bool DumpFileWithLlvmNm(std::string const& nmPath, const char* filename,
line.c_str());
return false;
}
- const std::string sym = line.substr(0, sym_end);
const char sym_type = line[sym_end + 1];
+ line.resize(sym_end);
switch (sym_type) {
case 'D':
- dataSymbols.insert(sym);
+ dataSymbols.insert(line);
break;
case 'T':
- symbols.insert(sym);
+ symbols.insert(line);
break;
}
}
@@ -366,6 +379,9 @@ bool DumpFile(std::string const& nmPath, const char* filename,
std::set<std::string>& symbols,
std::set<std::string>& dataSymbols)
{
+#ifndef _WIN32
+ return DumpFileWithLlvmNm(nmPath, filename, symbols, dataSymbols);
+#else
HANDLE hFile;
HANDLE hFileMapping;
LPVOID lpFileBase;
@@ -446,6 +462,7 @@ bool DumpFile(std::string const& nmPath, const char* filename,
CloseHandle(hFileMapping);
CloseHandle(hFile);
return true;
+#endif
}
bool bindexplib::AddObjectFile(const char* filename)
diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx
index 6e04ce5..231a2d6 100644
--- a/Source/cmAddCustomCommandCommand.cxx
+++ b/Source/cmAddCustomCommandCommand.cxx
@@ -174,7 +174,7 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args,
doing = doing_comment;
} else if (copy == keyDEPFILE) {
doing = doing_depfile;
- if (mf.GetGlobalGenerator()->GetName() != "Ninja") {
+ if (!mf.GetGlobalGenerator()->SupportsCustomCommandDepfile()) {
status.SetError("Option DEPFILE not supported by " +
mf.GetGlobalGenerator()->GetName());
return false;
@@ -215,7 +215,8 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args,
}
if (cmSystemTools::FileIsFullPath(filename)) {
- filename = cmSystemTools::CollapseFullPath(filename);
+ filename = cmSystemTools::CollapseFullPath(
+ filename, status.GetMakefile().GetHomeOutputDirectory());
}
switch (doing) {
case doing_depfile:
@@ -261,9 +262,9 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args,
case doing_target:
target = copy;
break;
- case doing_depends: {
+ case doing_depends:
depends.push_back(copy);
- } break;
+ break;
case doing_outputs:
outputs.push_back(filename);
break;
@@ -343,7 +344,7 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args,
// Target is empty, use the output.
mf.AddCustomCommandToOutput(
output, byproducts, depends, main_dependency, implicit_depends,
- commandLines, comment, working.c_str(), false, escapeOldStyle,
+ commandLines, comment, working.c_str(), nullptr, false, escapeOldStyle,
uses_terminal, command_expand_lists, depfile, job_pool);
} else if (!byproducts.empty()) {
status.SetError("BYPRODUCTS may not be specified with SOURCE signatures");
diff --git a/Source/cmAddCustomTargetCommand.cxx b/Source/cmAddCustomTargetCommand.cxx
index e27b126..aa98d89 100644
--- a/Source/cmAddCustomTargetCommand.cxx
+++ b/Source/cmAddCustomTargetCommand.cxx
@@ -6,7 +6,6 @@
#include "cmCheckCustomOutputs.h"
#include "cmCustomCommandLines.h"
-#include "cmCustomCommandTypes.h"
#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
@@ -215,9 +214,9 @@ bool cmAddCustomTargetCommand(std::vector<std::string> const& args,
// Add the utility target to the makefile.
bool escapeOldStyle = !verbatim;
cmTarget* target = mf.AddUtilityCommand(
- targetName, cmCommandOrigin::Project, excludeFromAll,
- working_directory.c_str(), byproducts, depends, commandLines,
- escapeOldStyle, comment, uses_terminal, command_expand_lists, job_pool);
+ targetName, excludeFromAll, working_directory.c_str(), byproducts, depends,
+ commandLines, escapeOldStyle, comment, uses_terminal, command_expand_lists,
+ job_pool);
// Add additional user-specified source files to the target.
target->AddSources(sources);
diff --git a/Source/cmAddDependenciesCommand.cxx b/Source/cmAddDependenciesCommand.cxx
index b1fc893..2d55a5a 100644
--- a/Source/cmAddDependenciesCommand.cxx
+++ b/Source/cmAddDependenciesCommand.cxx
@@ -29,7 +29,7 @@ bool cmAddDependenciesCommand(std::vector<std::string> const& args,
// skip over target_name
for (std::string const& arg : cmMakeRange(args).advance(1)) {
- target->AddUtility(arg, &mf);
+ target->AddUtility(arg, false, &mf);
}
} else {
mf.IssueMessage(
diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx
index 0439c51..f443fc6 100644
--- a/Source/cmAddLibraryCommand.cxx
+++ b/Source/cmAddLibraryCommand.cxx
@@ -2,7 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmAddLibraryCommand.h"
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
@@ -309,7 +310,7 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
return true;
}
- cmAppend(srclists, s, args.end());
+ cm::append(srclists, s, args.end());
mf.AddLibrary(libName, type, srclists, excludeFromAll);
diff --git a/Source/cmAddSubDirectoryCommand.cxx b/Source/cmAddSubDirectoryCommand.cxx
index 6a1a514..83d6306 100644
--- a/Source/cmAddSubDirectoryCommand.cxx
+++ b/Source/cmAddSubDirectoryCommand.cxx
@@ -4,6 +4,8 @@
#include <cstring>
+#include <cm/string_view>
+
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmRange.h"
@@ -53,7 +55,8 @@ bool cmAddSubDirectoryCommand(std::vector<std::string> const& args,
status.SetError(error);
return false;
}
- srcPath = cmSystemTools::CollapseFullPath(srcPath);
+ srcPath =
+ cmSystemTools::CollapseFullPath(srcPath, mf.GetHomeOutputDirectory());
// Compute the full path to the binary directory.
std::string binPath;
@@ -85,7 +88,8 @@ bool cmAddSubDirectoryCommand(std::vector<std::string> const& args,
if (binLen > 0 && bin.back() == '/') {
--binLen;
}
- binPath = bin.substr(0, binLen) + srcPath.substr(srcLen);
+ binPath = cmStrCat(cm::string_view(bin).substr(0, binLen),
+ cm::string_view(srcPath).substr(srcLen));
} else {
// Use the binary directory specified.
// Interpret a relative path with respect to the current binary directory.
diff --git a/Source/cmAddTestCommand.cxx b/Source/cmAddTestCommand.cxx
index 8942113..205c1c7 100644
--- a/Source/cmAddTestCommand.cxx
+++ b/Source/cmAddTestCommand.cxx
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmAddTestCommand.h"
+#include <cm/memory>
+
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
@@ -44,7 +46,7 @@ bool cmAddTestCommand(std::vector<std::string> const& args,
} else {
test = mf.CreateTest(args[0]);
test->SetOldStyle(true);
- mf.AddTestGenerator(new cmTestGenerator(test));
+ mf.AddTestGenerator(cm::make_unique<cmTestGenerator>(test));
}
test->SetCommand(command);
@@ -141,7 +143,7 @@ bool cmAddTestCommandHandleNameMode(std::vector<std::string> const& args,
test->SetProperty("WORKING_DIRECTORY", working_directory.c_str());
}
test->SetCommandExpandLists(command_expand_lists);
- mf.AddTestGenerator(new cmTestGenerator(test, configurations));
+ mf.AddTestGenerator(cm::make_unique<cmTestGenerator>(test, configurations));
return true;
}
diff --git a/Source/cmAffinity.cxx b/Source/cmAffinity.cxx
index 8f9fe2a..35443e7 100644
--- a/Source/cmAffinity.cxx
+++ b/Source/cmAffinity.cxx
@@ -2,7 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmAffinity.h"
-#include "cm_uv.h"
+#include <cm3p/uv.h>
#ifndef CMAKE_USE_SYSTEM_LIBUV
# ifdef _WIN32
diff --git a/Source/cmAlgorithms.h b/Source/cmAlgorithms.h
index e0d27ee..c8e8dcb 100644
--- a/Source/cmAlgorithms.h
+++ b/Source/cmAlgorithms.h
@@ -8,24 +8,15 @@
#include <algorithm>
#include <functional>
#include <iterator>
+#include <memory>
#include <unordered_set>
#include <utility>
#include <vector>
-#include "cm_kwiml.h"
+#include <cmext/algorithm>
#include "cmRange.h"
-template <std::size_t N>
-struct cmOverloadPriority : cmOverloadPriority<N - 1>
-{
-};
-
-template <>
-struct cmOverloadPriority<0>
-{
-};
-
template <typename FwdIt>
FwdIt cmRotate(FwdIt first, FwdIt middle, FwdIt last)
{
@@ -36,76 +27,8 @@ FwdIt cmRotate(FwdIt first, FwdIt middle, FwdIt last)
return first;
}
-template <typename Container, typename Predicate>
-void cmEraseIf(Container& cont, Predicate pred)
-{
- cont.erase(std::remove_if(cont.begin(), cont.end(), pred), cont.end());
-}
-
-template <typename Range, typename Key>
-auto cmContainsImpl(Range const& range, Key const& key, cmOverloadPriority<2>)
- -> decltype(range.exists(key))
-{
- return range.exists(key);
-}
-
-template <typename Range, typename Key>
-auto cmContainsImpl(Range const& range, Key const& key, cmOverloadPriority<1>)
- -> decltype(range.find(key) != range.end())
-{
- return range.find(key) != range.end();
-}
-
-template <typename Range, typename Key>
-bool cmContainsImpl(Range const& range, Key const& key, cmOverloadPriority<0>)
-{
- using std::begin;
- using std::end;
- return std::find(begin(range), end(range), key) != end(range);
-}
-
-template <typename Range, typename Key>
-bool cmContains(Range const& range, Key const& key)
-{
- return cmContainsImpl(range, key, cmOverloadPriority<2>{});
-}
-
namespace ContainerAlgorithms {
-template <typename T>
-struct cmIsPair
-{
- enum
- {
- value = false
- };
-};
-
-template <typename K, typename V>
-struct cmIsPair<std::pair<K, V>>
-{
- enum
- {
- value = true
- };
-};
-
-template <typename Range,
- bool valueTypeIsPair = cmIsPair<typename Range::value_type>::value>
-struct DefaultDeleter
-{
- void operator()(typename Range::value_type value) const { delete value; }
-};
-
-template <typename Range>
-struct DefaultDeleter<Range, /* valueTypeIsPair = */ true>
-{
- void operator()(typename Range::value_type value) const
- {
- delete value.second;
- }
-};
-
template <typename FwdIt>
FwdIt RemoveN(FwdIt i1, FwdIt i2, size_t n)
{
@@ -138,25 +61,6 @@ using cmBacktraceRange =
cmRange<std::vector<cmListFileBacktrace>::const_iterator>;
template <typename Range>
-void cmDeleteAll(Range const& r)
-{
- std::for_each(r.begin(), r.end(),
- ContainerAlgorithms::DefaultDeleter<Range>());
-}
-
-template <typename T, typename Range>
-void cmAppend(std::vector<T>& v, Range const& r)
-{
- v.insert(v.end(), r.begin(), r.end());
-}
-
-template <typename T, typename InputIt>
-void cmAppend(std::vector<T>& v, InputIt first, InputIt last)
-{
- v.insert(v.end(), first, last);
-}
-
-template <typename Range>
typename Range::const_iterator cmRemoveN(Range& r, size_t n)
{
return ContainerAlgorithms::RemoveN(r.begin(), r.end(), n);
@@ -197,7 +101,7 @@ template <typename ForwardIterator>
ForwardIterator cmRemoveDuplicates(ForwardIterator first, ForwardIterator last)
{
using Value = typename std::iterator_traits<ForwardIterator>::value_type;
- using Hash = struct
+ struct Hash
{
std::size_t operator()(ForwardIterator it) const
{
@@ -205,7 +109,7 @@ ForwardIterator cmRemoveDuplicates(ForwardIterator first, ForwardIterator last)
}
};
- using Equal = struct
+ struct Equal
{
bool operator()(ForwardIterator it1, ForwardIterator it2) const
{
@@ -216,7 +120,7 @@ ForwardIterator cmRemoveDuplicates(ForwardIterator first, ForwardIterator last)
ForwardIterator result = first;
while (first != last) {
- if (!cmContains(uniq, first)) {
+ if (!cm::contains(uniq, first)) {
if (result != first) {
*result = std::move(*first);
}
diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx
index e5eea79..78bb6e0 100644
--- a/Source/cmArchiveWrite.cxx
+++ b/Source/cmArchiveWrite.cxx
@@ -7,12 +7,14 @@
#include <iostream>
#include <sstream>
+#include <cm3p/archive.h>
+#include <cm3p/archive_entry.h>
+
#include "cmsys/Directory.hxx"
#include "cmsys/Encoding.hxx"
#include "cmsys/FStream.hxx"
#include "cm_get_date.h"
-#include "cm_libarchive.h"
#include "cmLocale.h"
#include "cmStringAlgorithms.h"
@@ -170,15 +172,19 @@ cmArchiveWrite::cmArchiveWrite(std::ostream& os, Compress c,
cm_archive_error_string(this->Archive));
return;
}
+}
+bool cmArchiveWrite::Open()
+{
if (archive_write_open(
this->Archive, this, nullptr,
reinterpret_cast<archive_write_callback*>(&Callback::Write),
nullptr) != ARCHIVE_OK) {
this->Error =
cmStrCat("archive_write_open: ", cm_archive_error_string(this->Archive));
- return;
+ return false;
}
+ return true;
}
cmArchiveWrite::~cmArchiveWrite()
@@ -200,8 +206,11 @@ bool cmArchiveWrite::Add(std::string path, size_t skip, const char* prefix,
bool cmArchiveWrite::AddPath(const char* path, size_t skip, const char* prefix,
bool recursive)
{
- if (!this->AddFile(path, skip, prefix)) {
- return false;
+ if (strcmp(path, ".") != 0 ||
+ (this->Format != "zip" && this->Format != "7zip")) {
+ if (!this->AddFile(path, skip, prefix)) {
+ return false;
+ }
}
if ((!cmSystemTools::FileIsDirectory(path) || !recursive) ||
cmSystemTools::FileIsSymlink(path)) {
@@ -210,6 +219,9 @@ bool cmArchiveWrite::AddPath(const char* path, size_t skip, const char* prefix,
cmsys::Directory d;
if (d.Load(path)) {
std::string next = cmStrCat(path, '/');
+ if (next == "./" && (this->Format == "zip" || this->Format == "7zip")) {
+ next.clear();
+ }
std::string::size_type end = next.size();
unsigned long n = d.GetNumberOfFiles();
for (unsigned long i = 0; i < n; ++i) {
@@ -359,3 +371,16 @@ bool cmArchiveWrite::AddData(const char* file, size_t size)
}
return true;
}
+
+bool cmArchiveWrite::SetFilterOption(const char* module, const char* key,
+ const char* value)
+{
+ if (archive_write_set_filter_option(this->Archive, module, key, value) !=
+ ARCHIVE_OK) {
+ this->Error = "archive_write_set_filter_option: ";
+ this->Error += cm_archive_error_string(this->Archive);
+ return false;
+ }
+
+ return true;
+}
diff --git a/Source/cmArchiveWrite.h b/Source/cmArchiveWrite.h
index e791761..b643bce 100644
--- a/Source/cmArchiveWrite.h
+++ b/Source/cmArchiveWrite.h
@@ -62,6 +62,8 @@ public:
cmArchiveWrite(const cmArchiveWrite&) = delete;
cmArchiveWrite& operator=(const cmArchiveWrite&) = delete;
+ bool Open();
+
/**
* Add a path (file or directory) to the archive. Directories are
* added recursively. The "path" must be readable on disk, either
@@ -139,6 +141,9 @@ public:
this->Gname = "";
}
+ //! Set an option on a filter;
+ bool SetFilterOption(const char* module, const char* key, const char* value);
+
private:
bool Okay() const { return this->Error.empty(); }
bool AddPath(const char* path, size_t skip, const char* prefix,
diff --git a/Source/cmArgumentParser.cxx b/Source/cmArgumentParser.cxx
index 4c87177..4624f1c 100644
--- a/Source/cmArgumentParser.cxx
+++ b/Source/cmArgumentParser.cxx
@@ -3,7 +3,6 @@
#include "cmArgumentParser.h"
#include <algorithm>
-#include <type_traits>
namespace ArgumentParser {
diff --git a/Source/cmArgumentParser.h b/Source/cmArgumentParser.h
index 9426537..5d2dfa2 100644
--- a/Source/cmArgumentParser.h
+++ b/Source/cmArgumentParser.h
@@ -12,8 +12,7 @@
#include <vector>
#include <cm/string_view>
-
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
namespace ArgumentParser {
diff --git a/Source/cmAuxSourceDirectoryCommand.cxx b/Source/cmAuxSourceDirectoryCommand.cxx
index 289bb72..d6f7500e 100644
--- a/Source/cmAuxSourceDirectoryCommand.cxx
+++ b/Source/cmAuxSourceDirectoryCommand.cxx
@@ -6,6 +6,8 @@
#include <cstddef>
#include <utility>
+#include <cm/string_view>
+
#include "cmsys/Directory.hxx"
#include "cmExecutionStatus.h"
@@ -50,11 +52,10 @@ bool cmAuxSourceDirectoryCommand(std::vector<std::string> const& args,
// Split the filename into base and extension
std::string::size_type dotpos = file.rfind('.');
if (dotpos != std::string::npos) {
- std::string ext = file.substr(dotpos + 1);
- std::string base = file.substr(0, dotpos);
+ auto ext = cm::string_view(file).substr(dotpos + 1);
// Process only source files
auto cm = mf.GetCMakeInstance();
- if (!base.empty() && cm->IsSourceExtension(ext)) {
+ if (dotpos > 0 && cm->IsSourceExtension(ext)) {
std::string fullname = cmStrCat(templateDirectory, '/', file);
// add the file as a class file so
// depends can be done
diff --git a/Source/cmBinUtilsLinuxELFLinker.cxx b/Source/cmBinUtilsLinuxELFLinker.cxx
index 0dea825..9ce403d 100644
--- a/Source/cmBinUtilsLinuxELFLinker.cxx
+++ b/Source/cmBinUtilsLinuxELFLinker.cxx
@@ -6,6 +6,7 @@
#include <sstream>
#include <cm/memory>
+#include <cm/string_view>
#include <cmsys/RegularExpression.hxx>
@@ -26,14 +27,16 @@ static std::string ReplaceOrigin(const std::string& rpath,
cmsys::RegularExpressionMatch match;
if (originRegex.find(rpath.c_str(), match)) {
- std::string begin = rpath.substr(0, match.start(1));
- std::string end = rpath.substr(match.end(1));
- return begin + origin + end;
+ cm::string_view pathv(rpath);
+ auto begin = pathv.substr(0, match.start(1));
+ auto end = pathv.substr(match.end(1));
+ return cmStrCat(begin, origin, end);
}
if (originCurlyRegex.find(rpath.c_str(), match)) {
- std::string begin = rpath.substr(0, match.start());
- std::string end = rpath.substr(match.end());
- return begin + origin + end;
+ cm::string_view pathv(rpath);
+ auto begin = pathv.substr(0, match.start());
+ auto end = pathv.substr(match.end());
+ return cmStrCat(begin, origin, end);
}
return rpath;
}
diff --git a/Source/cmBuildCommand.cxx b/Source/cmBuildCommand.cxx
index 49c9439..b82fb9a 100644
--- a/Source/cmBuildCommand.cxx
+++ b/Source/cmBuildCommand.cxx
@@ -108,7 +108,7 @@ bool TwoArgsSignature(std::vector<std::string> const& args,
if (cacheValue) {
return true;
}
- mf.AddCacheDefinition(define, makecommand.c_str(),
+ mf.AddCacheDefinition(define, makecommand,
"Command used to build entire project "
"from the command line.",
cmStateEnums::STRING);
diff --git a/Source/cmBuildNameCommand.cxx b/Source/cmBuildNameCommand.cxx
index 3e517dc..ad4d665 100644
--- a/Source/cmBuildNameCommand.cxx
+++ b/Source/cmBuildNameCommand.cxx
@@ -28,7 +28,7 @@ bool cmBuildNameCommand(std::vector<std::string> const& args,
std::replace(cv.begin(), cv.end(), '/', '_');
std::replace(cv.begin(), cv.end(), '(', '_');
std::replace(cv.begin(), cv.end(), ')', '_');
- mf.AddCacheDefinition(args[0], cv.c_str(), "Name of build.",
+ mf.AddCacheDefinition(args[0], cv, "Name of build.",
cmStateEnums::STRING);
}
return true;
@@ -54,7 +54,7 @@ bool cmBuildNameCommand(std::vector<std::string> const& args,
std::replace(buildname.begin(), buildname.end(), '(', '_');
std::replace(buildname.begin(), buildname.end(), ')', '_');
- mf.AddCacheDefinition(args[0], buildname.c_str(), "Name of build.",
+ mf.AddCacheDefinition(args[0], buildname, "Name of build.",
cmStateEnums::STRING);
return true;
}
diff --git a/Source/cmCMakeCommand.cxx b/Source/cmCMakeCommand.cxx
new file mode 100644
index 0000000..da15b1a
--- /dev/null
+++ b/Source/cmCMakeCommand.cxx
@@ -0,0 +1,81 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmCMakeCommand.h"
+
+#include <algorithm>
+#include <cstddef>
+#include <iosfwd>
+#include <memory>
+#include <string>
+
+#include "cmExecutionStatus.h"
+#include "cmListFileCache.h"
+#include "cmMakefile.h"
+#include "cmRange.h"
+#include "cmStringAlgorithms.h"
+
+inline std::ostream& operator<<(std::ostream& os,
+ cmListFileArgument const& arg)
+{
+ os << arg.Value;
+ return os;
+}
+
+bool cmCMakeCommand(std::vector<cmListFileArgument> const& args,
+ cmExecutionStatus& status)
+{
+ if (args.empty()) {
+ status.SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ cmMakefile& makefile = status.GetMakefile();
+ cmListFileContext context = makefile.GetExecutionContext();
+
+ bool result = false;
+
+ if (args[0].Value == "INVOKE") {
+ if (args.size() == 1) {
+ status.SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ // First argument is the name of the function to call
+ cmListFileFunction func;
+ func.Name = args[1].Value;
+ func.Line = context.Line;
+
+ // The rest of the arguments are passed to the function call above
+ func.Arguments.resize(args.size() - 1);
+ for (size_t i = 2; i < args.size(); ++i) {
+ cmListFileArgument lfarg;
+ lfarg.Delim = args[i].Delim;
+ lfarg.Line = context.Line;
+ lfarg.Value = args[i].Value;
+ func.Arguments.emplace_back(lfarg);
+ }
+
+ result = makefile.ExecuteCommand(func, status);
+ } else if (args[0].Value == "EVAL") {
+ if (args.size() < 2) {
+ status.SetError("called with incorrect number of arguments");
+ return false;
+ }
+
+ auto code_iter = std::find_if(
+ args.begin(), args.end(),
+ [](cmListFileArgument const& arg) { return arg.Value == "CODE"; });
+ if (code_iter == args.end()) {
+ status.SetError("called without CODE argument");
+ return false;
+ }
+
+ const std::string code = cmJoin(cmMakeRange(++code_iter, args.end()), " ");
+ result = makefile.ReadListFileAsString(
+ code, cmStrCat(context.FilePath, ":", context.Line, ":EVAL"));
+ } else {
+ status.SetError("called with unknown meta-operation");
+ }
+
+ return result;
+}
diff --git a/Source/cmCMakeCommand.h b/Source/cmCMakeCommand.h
new file mode 100644
index 0000000..7dbecff
--- /dev/null
+++ b/Source/cmCMakeCommand.h
@@ -0,0 +1,20 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmCMakeCommand_h
+#define cmCMakeCommand_h
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <vector>
+
+class cmExecutionStatus;
+struct cmListFileArgument;
+
+/**
+ * \brief Calls a scripted or build-in command
+ *
+ */
+bool cmCMakeCommand(std::vector<cmListFileArgument> const& args,
+ cmExecutionStatus& status);
+
+#endif
diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx
index 177bca8..697d435 100644
--- a/Source/cmCPluginAPI.cxx
+++ b/Source/cmCPluginAPI.cxx
@@ -221,10 +221,10 @@ void CCONV cmAddUtilityCommand(void* arg, const char* utilityName,
// Pass the call to the makefile instance.
std::vector<std::string> no_byproducts;
- mf->AddUtilityCommand(utilityName, cmCommandOrigin::Project,
- (all ? false : true), nullptr, no_byproducts, depends2,
- commandLines);
+ mf->AddUtilityCommand(utilityName, (all ? false : true), nullptr,
+ no_byproducts, depends2, commandLines);
}
+
void CCONV cmAddCustomCommand(void* arg, const char* source,
const char* command, int numArgs,
const char** args, int numDepends,
@@ -488,24 +488,8 @@ struct cmCPluginAPISourceFile
// Keep a map from real cmSourceFile instances stored in a makefile to
// the CPluginAPI proxy source file.
-class cmCPluginAPISourceFileMap
- : public std::map<cmSourceFile*, cmCPluginAPISourceFile*>
-{
-public:
- using derived = std::map<cmSourceFile*, cmCPluginAPISourceFile*>;
- using iterator = derived::iterator;
- using value_type = derived::value_type;
- cmCPluginAPISourceFileMap() = default;
- ~cmCPluginAPISourceFileMap()
- {
- for (auto const& i : *this) {
- delete i.second;
- }
- }
- cmCPluginAPISourceFileMap(const cmCPluginAPISourceFileMap&) = delete;
- cmCPluginAPISourceFileMap& operator=(const cmCPluginAPISourceFileMap&) =
- delete;
-};
+using cmCPluginAPISourceFileMap =
+ std::map<cmSourceFile*, std::unique_ptr<cmCPluginAPISourceFile>>;
cmCPluginAPISourceFileMap cmCPluginAPISourceFiles;
void* CCONV cmCreateSourceFile(void)
@@ -536,7 +520,7 @@ void CCONV* cmGetSource(void* arg, const char* name)
auto i = cmCPluginAPISourceFiles.find(rsf);
if (i == cmCPluginAPISourceFiles.end()) {
// Create a proxy source file object for this source.
- cmCPluginAPISourceFile* sf = new cmCPluginAPISourceFile;
+ auto sf = cm::make_unique<cmCPluginAPISourceFile>();
sf->RealSourceFile = rsf;
sf->FullPath = rsf->ResolveFullPath();
sf->SourceName =
@@ -545,10 +529,9 @@ void CCONV* cmGetSource(void* arg, const char* name)
cmSystemTools::GetFilenameLastExtension(sf->FullPath);
// Store the proxy in the map so it can be re-used and deleted later.
- cmCPluginAPISourceFileMap::value_type entry(rsf, sf);
- i = cmCPluginAPISourceFiles.insert(entry).first;
+ i = cmCPluginAPISourceFiles.emplace(rsf, std::move(sf)).first;
}
- return i->second;
+ return i->second.get();
}
return nullptr;
}
@@ -569,15 +552,16 @@ void* CCONV cmAddSource(void* arg, void* arg2)
}
// Create the proxy for the real source file.
- cmCPluginAPISourceFile* sf = new cmCPluginAPISourceFile;
+ auto sf = cm::make_unique<cmCPluginAPISourceFile>();
sf->RealSourceFile = rsf;
sf->FullPath = osf->FullPath;
sf->SourceName = osf->SourceName;
sf->SourceExtension = osf->SourceExtension;
// Store the proxy in the map so it can be re-used and deleted later.
- cmCPluginAPISourceFiles[rsf] = sf;
- return sf;
+ auto value = sf.get();
+ cmCPluginAPISourceFiles[rsf] = std::move(sf);
+ return value;
}
const char* CCONV cmSourceFileGetSourceName(void* arg)
@@ -596,12 +580,14 @@ const char* CCONV cmSourceFileGetProperty(void* arg, const char* prop)
{
cmCPluginAPISourceFile* sf = static_cast<cmCPluginAPISourceFile*>(arg);
if (cmSourceFile* rsf = sf->RealSourceFile) {
- return rsf->GetProperty(prop);
+ cmProp p = rsf->GetProperty(prop);
+ return p ? p->c_str() : nullptr;
}
if (!strcmp(prop, "LOCATION")) {
return sf->FullPath.c_str();
}
- return sf->Properties.GetPropertyValue(prop);
+ cmProp retVal = sf->Properties.GetPropertyValue(prop);
+ return retVal ? retVal->c_str() : nullptr;
}
int CCONV cmSourceFileGetPropertyAsBool(void* arg, const char* prop)
@@ -791,8 +777,9 @@ void CCONV DefineSourceFileProperty(void* arg, const char* name,
const char* longDocs, int chained)
{
cmMakefile* mf = static_cast<cmMakefile*>(arg);
- mf->GetState()->DefineProperty(name, cmProperty::SOURCE_FILE, briefDocs,
- longDocs, chained != 0);
+ mf->GetState()->DefineProperty(name, cmProperty::SOURCE_FILE,
+ briefDocs ? briefDocs : "",
+ longDocs ? longDocs : "", chained != 0);
}
} // close the extern "C" scope
diff --git a/Source/cmCPluginAPI.h b/Source/cmCPluginAPI.h
index 6a95148..19626f0 100644
--- a/Source/cmCPluginAPI.h
+++ b/Source/cmCPluginAPI.h
@@ -36,7 +36,7 @@ typedef struct
of functions are utility functions that are specific to the plugin API
=========================================================================*/
/* set/Get the ClientData in the cmLoadedCommandInfo structure, this is how
- information is passed from the InitialPass to FInalPass for commands
+ information is passed from the InitialPass to FinalPass for commands
that need a FinalPass and need information from the InitialPass */
void*(CCONV* GetClientData)(void* info);
/* return the summed size in characters of all the arguments */
@@ -44,7 +44,7 @@ typedef struct
/* free all the memory associated with an argc, argv pair */
void(CCONV* FreeArguments)(int argc, char** argv);
/* set/Get the ClientData in the cmLoadedCommandInfo structure, this is how
- information is passed from the InitialPass to FInalPass for commands
+ information is passed from the InitialPass to FinalPass for commands
that need a FinalPass and need information from the InitialPass */
void(CCONV* SetClientData)(void* info, void* cd);
/* when an error occurs, call this function to set the error string */
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 6eae26e..9b023d9 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -16,24 +16,27 @@
#include <utility>
#include <vector>
+#include <cm/memory>
+#include <cm/string_view>
+#include <cmext/algorithm>
+#include <cmext/string_view>
+
+#include <cm3p/curl/curl.h>
+#include <cm3p/zlib.h>
+
#include "cmsys/Base64.h"
#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
#include "cmsys/Glob.hxx"
#include "cmsys/Process.h"
+#include "cmsys/RegularExpression.hxx"
#include "cmsys/SystemInformation.hxx"
-
-#include "cm_curl.h"
-#include "cm_zlib.h"
#if defined(_WIN32)
# include <windows.h> // IWYU pragma: keep
#else
# include <unistd.h> // IWYU pragma: keep
#endif
-#include <cm/memory>
-
-#include "cmAlgorithms.h"
#include "cmCTestBuildAndTestHandler.h"
#include "cmCTestBuildHandler.h"
#include "cmCTestConfigureHandler.h"
@@ -83,11 +86,12 @@ struct cmCTest::Private
std::string Name;
};
- int RepeatTests = 1; // default to run each test once
- bool RepeatUntilFail = false;
+ int RepeatCount = 1; // default to run each test once
+ cmCTest::Repeat RepeatMode = cmCTest::Repeat::Never;
std::string ConfigType;
std::string ScheduleType;
std::chrono::system_clock::time_point StopTime;
+ bool StopOnFailure = false;
bool TestProgressOutput = false;
bool Verbose = false;
bool ExtraVerbose = false;
@@ -200,13 +204,15 @@ struct cmCTest::Private
int SubmitIndex = 0;
- cmGeneratedFileStream* OutputLogFile = nullptr;
+ std::unique_ptr<cmGeneratedFileStream> OutputLogFile;
int OutputLogFileLastTag = -1;
bool OutputTestOutputOnTestFailure = false;
bool OutputColorCode = cmCTest::ColoredOutputSupportedByConsole();
std::map<std::string, std::string> Definitions;
+
+ cmCTest::NoTests NoTestsMode = cmCTest::NoTests::Legacy;
};
struct tm* cmCTest::GetNightlyTime(std::string const& str, bool tomorrowtag)
@@ -268,9 +274,10 @@ bool cmCTest::GetTomorrowTag() const
return this->Impl->TomorrowTag;
}
-std::string cmCTest::CleanString(const std::string& str)
+std::string cmCTest::CleanString(const std::string& str,
+ std::string::size_type spos)
{
- std::string::size_type spos = str.find_first_not_of(" \n\t\r\f\v");
+ spos = str.find_first_not_of(" \n\t\r\f\v", spos);
std::string::size_type epos = str.find_last_not_of(" \n\t\r\f\v");
if (spos == std::string::npos) {
return std::string();
@@ -359,10 +366,7 @@ cmCTest::cmCTest()
cmSystemTools::EnableVSConsoleOutput();
}
-cmCTest::~cmCTest()
-{
- delete this->Impl->OutputLogFile;
-}
+cmCTest::~cmCTest() = default;
int cmCTest::GetParallelLevel() const
{
@@ -724,7 +728,7 @@ bool cmCTest::UpdateCTestConfiguration()
continue;
}
while (fin && (line.back() == '\\')) {
- line = line.substr(0, line.size() - 1);
+ line.resize(line.size() - 1);
buffer[0] = 0;
fin.getline(buffer, 1023);
buffer[1023] = 0;
@@ -738,7 +742,7 @@ bool cmCTest::UpdateCTestConfiguration()
continue;
}
std::string key = line.substr(0, cpos);
- std::string value = cmCTest::CleanString(line.substr(cpos + 1));
+ std::string value = cmCTest::CleanString(line, cpos + 1);
this->Impl->CTestConfiguration[key] = value;
}
fin.close();
@@ -1279,7 +1283,7 @@ int cmCTest::RunTest(std::vector<const char*> argv, std::string* output,
while (cmsysProcess_WaitForData(cp, &data, &length, nullptr)) {
processOutput.DecodeText(data, length, strdata);
if (output) {
- cmAppend(tempOutput, data, data + length);
+ cm::append(tempOutput, data, data + length);
}
cmCTestLog(this, HANDLER_VERBOSE_OUTPUT,
cmCTestLogWrite(strdata.c_str(), strdata.size()));
@@ -1439,16 +1443,15 @@ void cmCTest::AddSiteProperties(cmXMLWriter& xml)
return;
}
// This code should go when cdash is changed to use labels only
- const char* subproject = cm->GetState()->GetGlobalProperty("SubProject");
+ cmProp subproject = cm->GetState()->GetGlobalProperty("SubProject");
if (subproject) {
xml.StartElement("Subproject");
- xml.Attribute("name", subproject);
- const char* labels =
+ xml.Attribute("name", *subproject);
+ cmProp labels =
ch->GetCMake()->GetState()->GetGlobalProperty("SubProjectLabels");
if (labels) {
xml.StartElement("Labels");
- std::string l = labels;
- std::vector<std::string> args = cmExpandedList(l);
+ std::vector<std::string> args = cmExpandedList(*labels);
for (std::string const& i : args) {
xml.Element("Label", i);
}
@@ -1458,10 +1461,10 @@ void cmCTest::AddSiteProperties(cmXMLWriter& xml)
}
// This code should stay when cdash only does label based sub-projects
- const char* label = cm->GetState()->GetGlobalProperty("Label");
+ cmProp label = cm->GetState()->GetGlobalProperty("Label");
if (label) {
xml.StartElement("Labels");
- xml.Element("Label", label);
+ xml.Element("Label", *label);
xml.EndElement();
}
}
@@ -1813,10 +1816,10 @@ void cmCTest::ErrorMessageUnknownDashDValue(std::string& val)
<< " ctest -D NightlyMemoryCheck" << std::endl);
}
-bool cmCTest::CheckArgument(const std::string& arg, const char* varg1,
+bool cmCTest::CheckArgument(const std::string& arg, cm::string_view varg1,
const char* varg2)
{
- return (varg1 && arg == varg1) || (varg2 && arg == varg2);
+ return (arg == varg1) || (varg2 && arg == varg2);
}
// Processes one command line argument (and its arguments if any)
@@ -1826,38 +1829,76 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
std::string& errormsg)
{
std::string arg = args[i];
- if (this->CheckArgument(arg, "-F")) {
+ if (this->CheckArgument(arg, "-F"_s)) {
this->Impl->Failover = true;
- }
- if (this->CheckArgument(arg, "-j", "--parallel") && i < args.size() - 1) {
+ } else if (this->CheckArgument(arg, "-j"_s, "--parallel") &&
+ i < args.size() - 1) {
i++;
int plevel = atoi(args[i].c_str());
this->SetParallelLevel(plevel);
this->Impl->ParallelLevelSetInCli = true;
- } else if (arg.find("-j") == 0) {
+ } else if (cmHasPrefix(arg, "-j")) {
int plevel = atoi(arg.substr(2).c_str());
this->SetParallelLevel(plevel);
this->Impl->ParallelLevelSetInCli = true;
}
- if (this->CheckArgument(arg, "--repeat-until-fail")) {
+
+ else if (this->CheckArgument(arg, "--repeat-until-fail"_s)) {
if (i >= args.size() - 1) {
errormsg = "'--repeat-until-fail' requires an argument";
return false;
}
+ if (this->Impl->RepeatMode != cmCTest::Repeat::Never) {
+ errormsg = "At most one '--repeat' option may be used.";
+ return false;
+ }
i++;
long repeat = 1;
if (!cmStrToLong(args[i], &repeat)) {
- errormsg =
- "'--repeat-until-fail' given non-integer value '" + args[i] + "'";
+ errormsg = cmStrCat("'--repeat-until-fail' given non-integer value '",
+ args[i], "'");
return false;
}
- this->Impl->RepeatTests = static_cast<int>(repeat);
+ this->Impl->RepeatCount = static_cast<int>(repeat);
if (repeat > 1) {
- this->Impl->RepeatUntilFail = true;
+ this->Impl->RepeatMode = cmCTest::Repeat::UntilFail;
+ }
+ }
+
+ else if (this->CheckArgument(arg, "--repeat"_s)) {
+ if (i >= args.size() - 1) {
+ errormsg = "'--repeat' requires an argument";
+ return false;
+ }
+ if (this->Impl->RepeatMode != cmCTest::Repeat::Never) {
+ errormsg = "At most one '--repeat' option may be used.";
+ return false;
+ }
+ i++;
+ cmsys::RegularExpression repeatRegex(
+ "^(until-fail|until-pass|after-timeout):([0-9]+)$");
+ if (repeatRegex.find(args[i])) {
+ std::string const& count = repeatRegex.match(2);
+ unsigned long n = 1;
+ cmStrToULong(count, &n); // regex guarantees success
+ this->Impl->RepeatCount = static_cast<int>(n);
+ if (this->Impl->RepeatCount > 1) {
+ std::string const& mode = repeatRegex.match(1);
+ if (mode == "until-fail") {
+ this->Impl->RepeatMode = cmCTest::Repeat::UntilFail;
+ } else if (mode == "until-pass") {
+ this->Impl->RepeatMode = cmCTest::Repeat::UntilPass;
+ } else if (mode == "after-timeout") {
+ this->Impl->RepeatMode = cmCTest::Repeat::AfterTimeout;
+ }
+ }
+ } else {
+ errormsg = cmStrCat("'--repeat' given invalid value '", args[i], "'");
+ return false;
}
}
- if (this->CheckArgument(arg, "--test-load") && i < args.size() - 1) {
+ else if (this->CheckArgument(arg, "--test-load"_s) && i < args.size() - 1) {
i++;
unsigned long load;
if (cmStrToULong(args[i], &load)) {
@@ -1868,76 +1909,68 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
}
}
- if (this->CheckArgument(arg, "--no-compress-output")) {
+ else if (this->CheckArgument(arg, "--no-compress-output"_s)) {
this->Impl->CompressTestOutput = false;
}
- if (this->CheckArgument(arg, "--print-labels")) {
+ else if (this->CheckArgument(arg, "--print-labels"_s)) {
this->Impl->PrintLabels = true;
}
- if (this->CheckArgument(arg, "--http1.0")) {
+ else if (this->CheckArgument(arg, "--http1.0"_s)) {
this->Impl->UseHTTP10 = true;
}
- if (this->CheckArgument(arg, "--timeout") && i < args.size() - 1) {
+ else if (this->CheckArgument(arg, "--timeout"_s) && i < args.size() - 1) {
i++;
auto timeout = cmDuration(atof(args[i].c_str()));
this->Impl->GlobalTimeout = timeout;
}
- if (this->CheckArgument(arg, "--stop-time") && i < args.size() - 1) {
+ else if (this->CheckArgument(arg, "--stop-time"_s) && i < args.size() - 1) {
i++;
this->SetStopTime(args[i]);
}
- if (this->CheckArgument(arg, "-C", "--build-config") &&
- i < args.size() - 1) {
+ else if (this->CheckArgument(arg, "--stop-on-failure"_s)) {
+ this->Impl->StopOnFailure = true;
+ }
+
+ else if (this->CheckArgument(arg, "-C"_s, "--build-config") &&
+ i < args.size() - 1) {
i++;
this->SetConfigType(args[i].c_str());
}
- if (this->CheckArgument(arg, "--debug")) {
+ else if (this->CheckArgument(arg, "--debug"_s)) {
this->Impl->Debug = true;
this->Impl->ShowLineNumbers = true;
- }
- if (this->CheckArgument(arg, "--group") && i < args.size() - 1) {
- i++;
- this->Impl->SpecificGroup = args[i];
- }
- // This is an undocumented / deprecated option.
- // "Track" has been renamed to "Group".
- if (this->CheckArgument(arg, "--track") && i < args.size() - 1) {
+ } else if ((this->CheckArgument(arg, "--group"_s) ||
+ // This is an undocumented / deprecated option.
+ // "Track" has been renamed to "Group".
+ this->CheckArgument(arg, "--track"_s)) &&
+ i < args.size() - 1) {
i++;
this->Impl->SpecificGroup = args[i];
- }
- if (this->CheckArgument(arg, "--show-line-numbers")) {
+ } else if (this->CheckArgument(arg, "--show-line-numbers"_s)) {
this->Impl->ShowLineNumbers = true;
- }
- if (this->CheckArgument(arg, "--no-label-summary")) {
+ } else if (this->CheckArgument(arg, "--no-label-summary"_s)) {
this->Impl->LabelSummary = false;
- }
- if (this->CheckArgument(arg, "--no-subproject-summary")) {
+ } else if (this->CheckArgument(arg, "--no-subproject-summary"_s)) {
this->Impl->SubprojectSummary = false;
- }
- if (this->CheckArgument(arg, "-Q", "--quiet")) {
+ } else if (this->CheckArgument(arg, "-Q"_s, "--quiet")) {
this->Impl->Quiet = true;
- }
- if (this->CheckArgument(arg, "--progress")) {
+ } else if (this->CheckArgument(arg, "--progress"_s)) {
this->Impl->TestProgressOutput = true;
- }
- if (this->CheckArgument(arg, "-V", "--verbose")) {
+ } else if (this->CheckArgument(arg, "-V"_s, "--verbose")) {
this->Impl->Verbose = true;
- }
- if (this->CheckArgument(arg, "-VV", "--extra-verbose")) {
+ } else if (this->CheckArgument(arg, "-VV"_s, "--extra-verbose")) {
this->Impl->ExtraVerbose = true;
this->Impl->Verbose = true;
- }
- if (this->CheckArgument(arg, "--output-on-failure")) {
+ } else if (this->CheckArgument(arg, "--output-on-failure"_s)) {
this->Impl->OutputTestOutputOnTestFailure = true;
- }
- if (this->CheckArgument(arg, "--test-output-size-passed") &&
- i < args.size() - 1) {
+ } else if (this->CheckArgument(arg, "--test-output-size-passed"_s) &&
+ i < args.size() - 1) {
i++;
long outputSize;
if (cmStrToLong(args[i], &outputSize)) {
@@ -1947,9 +1980,8 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
"Invalid value for '--test-output-size-passed': " << args[i]
<< "\n");
}
- }
- if (this->CheckArgument(arg, "--test-output-size-failed") &&
- i < args.size() - 1) {
+ } else if (this->CheckArgument(arg, "--test-output-size-failed"_s) &&
+ i < args.size() - 1) {
i++;
long outputSize;
if (cmStrToLong(args[i], &outputSize)) {
@@ -1959,11 +1991,9 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
"Invalid value for '--test-output-size-failed': " << args[i]
<< "\n");
}
- }
- if (this->CheckArgument(arg, "-N", "--show-only")) {
+ } else if (this->CheckArgument(arg, "-N"_s, "--show-only")) {
this->Impl->ShowOnly = true;
- }
- if (cmHasLiteralPrefix(arg, "--show-only=")) {
+ } else if (cmHasLiteralPrefix(arg, "--show-only=")) {
this->Impl->ShowOnly = true;
// Check if a specific format is requested. Defaults to human readable
@@ -1981,27 +2011,26 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
}
}
- if (this->CheckArgument(arg, "-O", "--output-log") && i < args.size() - 1) {
+ else if (this->CheckArgument(arg, "-O"_s, "--output-log") &&
+ i < args.size() - 1) {
i++;
this->SetOutputLogFileName(args[i].c_str());
}
- if (this->CheckArgument(arg, "--tomorrow-tag")) {
+ else if (this->CheckArgument(arg, "--tomorrow-tag"_s)) {
this->Impl->TomorrowTag = true;
- }
- if (this->CheckArgument(arg, "--force-new-ctest-process")) {
+ } else if (this->CheckArgument(arg, "--force-new-ctest-process"_s)) {
this->Impl->ForceNewCTestProcess = true;
- }
- if (this->CheckArgument(arg, "-W", "--max-width") && i < args.size() - 1) {
+ } else if (this->CheckArgument(arg, "-W"_s, "--max-width") &&
+ i < args.size() - 1) {
i++;
this->Impl->MaxTestNameWidth = atoi(args[i].c_str());
- }
- if (this->CheckArgument(arg, "--interactive-debug-mode") &&
- i < args.size() - 1) {
+ } else if (this->CheckArgument(arg, "--interactive-debug-mode"_s) &&
+ i < args.size() - 1) {
i++;
this->Impl->InteractiveDebugMode = cmIsOn(args[i]);
- }
- if (this->CheckArgument(arg, "--submit-index") && i < args.size() - 1) {
+ } else if (this->CheckArgument(arg, "--submit-index"_s) &&
+ i < args.size() - 1) {
i++;
this->Impl->SubmitIndex = atoi(args[i].c_str());
if (this->Impl->SubmitIndex < 0) {
@@ -2009,46 +2038,60 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
}
}
- if (this->CheckArgument(arg, "--overwrite") && i < args.size() - 1) {
+ else if (this->CheckArgument(arg, "--overwrite"_s) && i < args.size() - 1) {
i++;
this->AddCTestConfigurationOverwrite(args[i]);
- }
- if (this->CheckArgument(arg, "-A", "--add-notes") && i < args.size() - 1) {
+ } else if (this->CheckArgument(arg, "-A"_s, "--add-notes") &&
+ i < args.size() - 1) {
this->Impl->ProduceXML = true;
this->SetTest("Notes");
i++;
this->SetNotesFiles(args[i].c_str());
+ return true;
+ }
+
+ cm::string_view noTestsPrefix = "--no-tests=";
+ if (cmHasPrefix(arg, noTestsPrefix)) {
+ cm::string_view noTestsMode =
+ cm::string_view(arg).substr(noTestsPrefix.length());
+ if (noTestsMode == "error") {
+ this->Impl->NoTestsMode = cmCTest::NoTests::Error;
+ } else if (noTestsMode != "ignore") {
+ errormsg =
+ cmStrCat("'--no-tests=' given unknown value '", noTestsMode, '\'');
+ return false;
+ } else {
+ this->Impl->NoTestsMode = cmCTest::NoTests::Ignore;
+ }
}
// options that control what tests are run
- if (this->CheckArgument(arg, "-I", "--tests-information") &&
- i < args.size() - 1) {
+ else if (this->CheckArgument(arg, "-I"_s, "--tests-information") &&
+ i < args.size() - 1) {
i++;
this->GetTestHandler()->SetPersistentOption("TestsToRunInformation",
args[i].c_str());
this->GetMemCheckHandler()->SetPersistentOption("TestsToRunInformation",
args[i].c_str());
- }
- if (this->CheckArgument(arg, "-U", "--union")) {
+ } else if (this->CheckArgument(arg, "-U"_s, "--union")) {
this->GetTestHandler()->SetPersistentOption("UseUnion", "true");
this->GetMemCheckHandler()->SetPersistentOption("UseUnion", "true");
- }
- if (this->CheckArgument(arg, "-R", "--tests-regex") && i < args.size() - 1) {
+ } else if (this->CheckArgument(arg, "-R"_s, "--tests-regex") &&
+ i < args.size() - 1) {
i++;
this->GetTestHandler()->SetPersistentOption("IncludeRegularExpression",
args[i].c_str());
this->GetMemCheckHandler()->SetPersistentOption("IncludeRegularExpression",
args[i].c_str());
- }
- if (this->CheckArgument(arg, "-L", "--label-regex") && i < args.size() - 1) {
+ } else if (this->CheckArgument(arg, "-L"_s, "--label-regex") &&
+ i < args.size() - 1) {
i++;
this->GetTestHandler()->SetPersistentOption("LabelRegularExpression",
args[i].c_str());
this->GetMemCheckHandler()->SetPersistentOption("LabelRegularExpression",
args[i].c_str());
- }
- if (this->CheckArgument(arg, "-LE", "--label-exclude") &&
- i < args.size() - 1) {
+ } else if (this->CheckArgument(arg, "-LE"_s, "--label-exclude") &&
+ i < args.size() - 1) {
i++;
this->GetTestHandler()->SetPersistentOption(
"ExcludeLabelRegularExpression", args[i].c_str());
@@ -2056,8 +2099,8 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
"ExcludeLabelRegularExpression", args[i].c_str());
}
- if (this->CheckArgument(arg, "-E", "--exclude-regex") &&
- i < args.size() - 1) {
+ else if (this->CheckArgument(arg, "-E"_s, "--exclude-regex") &&
+ i < args.size() - 1) {
i++;
this->GetTestHandler()->SetPersistentOption("ExcludeRegularExpression",
args[i].c_str());
@@ -2065,24 +2108,22 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
args[i].c_str());
}
- if (this->CheckArgument(arg, "-FA", "--fixture-exclude-any") &&
- i < args.size() - 1) {
+ else if (this->CheckArgument(arg, "-FA"_s, "--fixture-exclude-any") &&
+ i < args.size() - 1) {
i++;
this->GetTestHandler()->SetPersistentOption(
"ExcludeFixtureRegularExpression", args[i].c_str());
this->GetMemCheckHandler()->SetPersistentOption(
"ExcludeFixtureRegularExpression", args[i].c_str());
- }
- if (this->CheckArgument(arg, "-FS", "--fixture-exclude-setup") &&
- i < args.size() - 1) {
+ } else if (this->CheckArgument(arg, "-FS"_s, "--fixture-exclude-setup") &&
+ i < args.size() - 1) {
i++;
this->GetTestHandler()->SetPersistentOption(
"ExcludeFixtureSetupRegularExpression", args[i].c_str());
this->GetMemCheckHandler()->SetPersistentOption(
"ExcludeFixtureSetupRegularExpression", args[i].c_str());
- }
- if (this->CheckArgument(arg, "-FC", "--fixture-exclude-cleanup") &&
- i < args.size() - 1) {
+ } else if (this->CheckArgument(arg, "-FC"_s, "--fixture-exclude-cleanup") &&
+ i < args.size() - 1) {
i++;
this->GetTestHandler()->SetPersistentOption(
"ExcludeFixtureCleanupRegularExpression", args[i].c_str());
@@ -2090,8 +2131,8 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
"ExcludeFixtureCleanupRegularExpression", args[i].c_str());
}
- if (this->CheckArgument(arg, "--resource-spec-file") &&
- i < args.size() - 1) {
+ else if (this->CheckArgument(arg, "--resource-spec-file"_s) &&
+ i < args.size() - 1) {
i++;
this->GetTestHandler()->SetPersistentOption("ResourceSpecFile",
args[i].c_str());
@@ -2099,7 +2140,7 @@ bool cmCTest::HandleCommandLineArguments(size_t& i,
args[i].c_str());
}
- if (this->CheckArgument(arg, "--rerun-failed")) {
+ else if (this->CheckArgument(arg, "--rerun-failed"_s)) {
this->GetTestHandler()->SetPersistentOption("RerunFailed", "true");
this->GetMemCheckHandler()->SetPersistentOption("RerunFailed", "true");
}
@@ -2151,7 +2192,7 @@ void cmCTest::HandleScriptArguments(size_t& i, std::vector<std::string>& args,
bool& SRArgumentSpecified)
{
std::string arg = args[i];
- if (this->CheckArgument(arg, "-SP", "--script-new-process") &&
+ if (this->CheckArgument(arg, "-SP"_s, "--script-new-process") &&
i < args.size() - 1) {
this->Impl->RunConfigurationScript = true;
i++;
@@ -2162,7 +2203,8 @@ void cmCTest::HandleScriptArguments(size_t& i, std::vector<std::string>& args,
}
}
- if (this->CheckArgument(arg, "-SR", "--script-run") && i < args.size() - 1) {
+ if (this->CheckArgument(arg, "-SR"_s, "--script-run") &&
+ i < args.size() - 1) {
SRArgumentSpecified = true;
this->Impl->RunConfigurationScript = true;
i++;
@@ -2170,7 +2212,7 @@ void cmCTest::HandleScriptArguments(size_t& i, std::vector<std::string>& args,
ch->AddConfigurationScript(args[i].c_str(), true);
}
- if (this->CheckArgument(arg, "-S", "--script") && i < args.size() - 1) {
+ if (this->CheckArgument(arg, "-S"_s, "--script") && i < args.size() - 1) {
this->Impl->RunConfigurationScript = true;
i++;
cmCTestScriptHandler* ch = this->GetScriptHandler();
@@ -2204,7 +2246,7 @@ int cmCTest::Run(std::vector<std::string>& args, std::string* output)
bool SRArgumentSpecified = false;
// copy the command line
- cmAppend(this->Impl->InitialCommandLineArguments, args);
+ cm::append(this->Impl->InitialCommandLineArguments, args);
// process the command line arguments
for (size_t i = 1; i < args.size(); ++i) {
@@ -2220,7 +2262,8 @@ int cmCTest::Run(std::vector<std::string>& args, std::string* output)
// --dashboard: handle a request for a dashboard
std::string arg = args[i];
- if (this->CheckArgument(arg, "-D", "--dashboard") && i < args.size() - 1) {
+ if (this->CheckArgument(arg, "-D"_s, "--dashboard") &&
+ i < args.size() - 1) {
this->Impl->ProduceXML = true;
i++;
std::string targ = args[i];
@@ -2256,7 +2299,7 @@ int cmCTest::Run(std::vector<std::string>& args, std::string* output)
}
// --extra-submit
- if (this->CheckArgument(arg, "--extra-submit") && i < args.size() - 1) {
+ if (this->CheckArgument(arg, "--extra-submit"_s) && i < args.size() - 1) {
this->Impl->ProduceXML = true;
this->SetTest("Submit");
i++;
@@ -2266,12 +2309,13 @@ int cmCTest::Run(std::vector<std::string>& args, std::string* output)
}
// --build-and-test options
- if (this->CheckArgument(arg, "--build-and-test") && i < args.size() - 1) {
+ if (this->CheckArgument(arg, "--build-and-test"_s) &&
+ i < args.size() - 1) {
cmakeAndTest = true;
}
// --schedule-random
- if (this->CheckArgument(arg, "--schedule-random")) {
+ if (this->CheckArgument(arg, "--schedule-random"_s)) {
this->Impl->ScheduleType = "Random";
}
@@ -2326,7 +2370,7 @@ bool cmCTest::HandleTestActionArgument(const char* ctestExec, size_t& i,
{
bool success = true;
std::string arg = args[i];
- if (this->CheckArgument(arg, "-T", "--test-action") &&
+ if (this->CheckArgument(arg, "-T"_s, "--test-action") &&
(i < args.size() - 1)) {
this->Impl->ProduceXML = true;
i++;
@@ -2358,15 +2402,15 @@ bool cmCTest::HandleTestModelArgument(const char* ctestExec, size_t& i,
{
bool success = true;
std::string arg = args[i];
- if (this->CheckArgument(arg, "-M", "--test-model") &&
+ if (this->CheckArgument(arg, "-M"_s, "--test-model") &&
(i < args.size() - 1)) {
i++;
std::string const& str = args[i];
- if (cmSystemTools::LowerCase(str) == "nightly") {
+ if (cmSystemTools::LowerCase(str) == "nightly"_s) {
this->SetTestModel(cmCTest::NIGHTLY);
- } else if (cmSystemTools::LowerCase(str) == "continuous") {
+ } else if (cmSystemTools::LowerCase(str) == "continuous"_s) {
this->SetTestModel(cmCTest::CONTINUOUS);
- } else if (cmSystemTools::LowerCase(str) == "experimental") {
+ } else if (cmSystemTools::LowerCase(str) == "experimental"_s) {
this->SetTestModel(cmCTest::EXPERIMENTAL);
} else {
success = false;
@@ -2453,6 +2497,16 @@ void cmCTest::SetNotesFiles(const char* notes)
this->Impl->NotesFiles = notes;
}
+bool cmCTest::GetStopOnFailure() const
+{
+ return this->Impl->StopOnFailure;
+}
+
+void cmCTest::SetStopOnFailure(bool stop)
+{
+ this->Impl->StopOnFailure = stop;
+}
+
std::chrono::system_clock::time_point cmCTest::GetStopTime() const
{
return this->Impl->StopTime;
@@ -2633,7 +2687,7 @@ std::string cmCTest::GetShortPathToFile(const char* cfname)
path = "./" + *res;
if (path.back() == '/') {
- path = path.substr(0, path.size() - 1);
+ path.resize(path.size() - 1);
}
}
@@ -2684,7 +2738,7 @@ std::string cmCTest::GetSubmitURL()
std::string site = this->GetCTestConfiguration("DropSite");
std::string location = this->GetCTestConfiguration("DropLocation");
- url = cmStrCat(method.empty() ? "http" : method, "://");
+ url = cmStrCat(method.empty() ? "http" : method, "://"_s);
if (!user.empty()) {
url += user;
if (!password.empty()) {
@@ -2847,14 +2901,19 @@ const std::map<std::string, std::string>& cmCTest::GetDefinitions() const
return this->Impl->Definitions;
}
-int cmCTest::GetTestRepeat() const
+int cmCTest::GetRepeatCount() const
+{
+ return this->Impl->RepeatCount;
+}
+
+cmCTest::Repeat cmCTest::GetRepeatMode() const
{
- return this->Impl->RepeatTests;
+ return this->Impl->RepeatMode;
}
-bool cmCTest::GetRepeatUntilFail() const
+cmCTest::NoTests cmCTest::GetNoTestsMode() const
{
- return this->Impl->RepeatUntilFail;
+ return this->Impl->NoTestsMode;
}
void cmCTest::SetBuildID(const std::string& id)
@@ -2964,10 +3023,10 @@ bool cmCTest::RunCommand(std::vector<std::string> const& args,
res = cmsysProcess_WaitForData(cp, &data, &length, nullptr);
switch (res) {
case cmsysProcess_Pipe_STDOUT:
- cmAppend(tempOutput, data, data + length);
+ cm::append(tempOutput, data, data + length);
break;
case cmsysProcess_Pipe_STDERR:
- cmAppend(tempError, data, data + length);
+ cm::append(tempError, data, data + length);
break;
default:
done = true;
@@ -3027,12 +3086,10 @@ bool cmCTest::RunCommand(std::vector<std::string> const& args,
void cmCTest::SetOutputLogFileName(const char* name)
{
- if (this->Impl->OutputLogFile) {
- delete this->Impl->OutputLogFile;
- this->Impl->OutputLogFile = nullptr;
- }
if (name) {
- this->Impl->OutputLogFile = new cmGeneratedFileStream(name);
+ this->Impl->OutputLogFile = cm::make_unique<cmGeneratedFileStream>(name);
+ } else {
+ this->Impl->OutputLogFile.reset();
}
}
diff --git a/Source/cmCTest.h b/Source/cmCTest.h
index 82a6f4c..a39b8fe 100644
--- a/Source/cmCTest.h
+++ b/Source/cmCTest.h
@@ -13,6 +13,8 @@
#include <string>
#include <vector>
+#include <cm/string_view>
+
#include "cmDuration.h"
#include "cmProcessOutput.h"
@@ -140,7 +142,8 @@ public:
std::string GetTestModelString();
static int GetTestModelFromString(const char* str);
- static std::string CleanString(const std::string& str);
+ static std::string CleanString(const std::string& str,
+ std::string::size_type spos = 0);
std::string GetCTestConfiguration(const std::string& name);
void SetCTestConfiguration(const char* name, const char* value,
bool suppress = false);
@@ -201,6 +204,9 @@ public:
bool ShouldCompressTestOutput();
bool CompressString(std::string& str);
+ bool GetStopOnFailure() const;
+ void SetStopOnFailure(bool stop);
+
std::chrono::system_clock::time_point GetStopTime() const;
void SetStopTime(std::string const& time);
@@ -431,10 +437,24 @@ public:
const std::map<std::string, std::string>& GetDefinitions() const;
/** Return the number of times a test should be run */
- int GetTestRepeat() const;
+ int GetRepeatCount() const;
- /** Return true if test should run until fail */
- bool GetRepeatUntilFail() const;
+ enum class Repeat
+ {
+ Never,
+ UntilFail,
+ UntilPass,
+ AfterTimeout,
+ };
+ Repeat GetRepeatMode() const;
+
+ enum class NoTests
+ {
+ Legacy,
+ Error,
+ Ignore
+ };
+ NoTests GetNoTestsMode() const;
void GenerateSubprojectsOutput(cmXMLWriter& xml);
std::vector<std::string> GetLabelsForSubprojects();
@@ -492,8 +512,8 @@ private:
std::vector<std::string> const& files);
/** Check if the argument is the one specified */
- bool CheckArgument(const std::string& arg, const char* varg1,
- const char* varg2 = nullptr);
+ static bool CheckArgument(const std::string& arg, cm::string_view varg1,
+ const char* varg2 = nullptr);
/** Output errors from a test */
void OutputTestErrors(std::vector<char> const& process_output);
diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx
index d627465..35bd681 100644
--- a/Source/cmCacheManager.cxx
+++ b/Source/cmCacheManager.cxx
@@ -19,12 +19,6 @@
#include "cmSystemTools.h"
#include "cmVersion.h"
-cmCacheManager::cmCacheManager()
-{
- this->CacheMajorVersion = 0;
- this->CacheMinorVersion = 0;
-}
-
void cmCacheManager::CleanCMakeFiles(const std::string& path)
{
std::string glob = cmStrCat(path, "/CMakeFiles/*.cmake");
@@ -77,7 +71,7 @@ bool cmCacheManager::LoadCache(const std::string& path, bool internal,
}
while (realbuffer[0] == '/' && realbuffer[1] == '/') {
if ((realbuffer[2] == '\\') && (realbuffer[3] == 'n')) {
- helpString += "\n";
+ helpString += '\n';
helpString += &realbuffer[4];
} else {
helpString += &realbuffer[2];
@@ -117,20 +111,20 @@ bool cmCacheManager::LoadCache(const std::string& path, bool internal,
}
} else {
std::ostringstream error;
- error << "Parse error in cache file " << cacheFile;
- error << " on line " << lineno << ". Offending entry: " << realbuffer;
+ error << "Parse error in cache file " << cacheFile << " on line "
+ << lineno << ". Offending entry: " << realbuffer;
cmSystemTools::Error(error.str());
}
}
this->CacheMajorVersion = 0;
this->CacheMinorVersion = 0;
- if (const std::string* cmajor =
+ if (cmProp cmajor =
this->GetInitializedCacheValue("CMAKE_CACHE_MAJOR_VERSION")) {
unsigned int v = 0;
if (sscanf(cmajor->c_str(), "%u", &v) == 1) {
this->CacheMajorVersion = v;
}
- if (const std::string* cminor =
+ if (cmProp cminor =
this->GetInitializedCacheValue("CMAKE_CACHE_MINOR_VERSION")) {
if (sscanf(cminor->c_str(), "%u", &v) == 1) {
this->CacheMinorVersion = v;
@@ -150,8 +144,7 @@ bool cmCacheManager::LoadCache(const std::string& path, bool internal,
}
// check to make sure the cache directory has not
// been moved
- const std::string* oldDir =
- this->GetInitializedCacheValue("CMAKE_CACHEFILE_DIR");
+ cmProp oldDir = this->GetInitializedCacheValue("CMAKE_CACHEFILE_DIR");
if (internal && oldDir) {
std::string currentcwd = path;
std::string oldcwd = *oldDir;
@@ -159,8 +152,7 @@ bool cmCacheManager::LoadCache(const std::string& path, bool internal,
currentcwd += "/CMakeCache.txt";
oldcwd += "/CMakeCache.txt";
if (!cmSystemTools::SameFile(oldcwd, currentcwd)) {
- const std::string* dir =
- this->GetInitializedCacheValue("CMAKE_CACHEFILE_DIR");
+ cmProp dir = this->GetInitializedCacheValue("CMAKE_CACHEFILE_DIR");
std::ostringstream message;
message << "The current CMakeCache.txt directory " << currentcwd
<< " is different than the directory " << (dir ? *dir : "")
@@ -174,10 +166,10 @@ bool cmCacheManager::LoadCache(const std::string& path, bool internal,
}
const char* cmCacheManager::PersistentProperties[] = { "ADVANCED", "MODIFIED",
- "STRINGS", nullptr };
+ "STRINGS" };
-bool cmCacheManager::ReadPropertyEntry(std::string const& entryKey,
- CacheEntry& e)
+bool cmCacheManager::ReadPropertyEntry(const std::string& entryKey,
+ const CacheEntry& e)
{
// All property entries are internal.
if (e.Type != cmStateEnums::INTERNAL) {
@@ -185,20 +177,18 @@ bool cmCacheManager::ReadPropertyEntry(std::string const& entryKey,
}
const char* end = entryKey.c_str() + entryKey.size();
- for (const char** p = cmCacheManager::PersistentProperties; *p; ++p) {
- std::string::size_type plen = strlen(*p) + 1;
+ for (const char* p : cmCacheManager::PersistentProperties) {
+ std::string::size_type plen = strlen(p) + 1;
if (entryKey.size() > plen && *(end - plen) == '-' &&
- strcmp(end - plen + 1, *p) == 0) {
+ strcmp(end - plen + 1, p) == 0) {
std::string key = entryKey.substr(0, entryKey.size() - plen);
- cmCacheManager::CacheIterator it = this->GetCacheIterator(key.c_str());
- if (it.IsAtEnd()) {
+ if (auto entry = this->GetCacheEntry(key)) {
+ // Store this property on its entry.
+ entry->SetProperty(p, e.Value.c_str());
+ } else {
// Create an entry and store the property.
CacheEntry& ne = this->Cache[key];
- ne.Type = cmStateEnums::UNINITIALIZED;
- ne.SetProperty(*p, e.Value.c_str());
- } else {
- // Store this property on its entry.
- it.SetProperty(*p, e.Value.c_str());
+ ne.SetProperty(p, e.Value.c_str());
}
return true;
}
@@ -206,21 +196,23 @@ bool cmCacheManager::ReadPropertyEntry(std::string const& entryKey,
return false;
}
-void cmCacheManager::WritePropertyEntries(std::ostream& os, CacheIterator i,
- cmMessenger* messenger)
+void cmCacheManager::WritePropertyEntries(std::ostream& os,
+ const std::string& entryKey,
+ const CacheEntry& e,
+ cmMessenger* messenger) const
{
- for (const char** p = cmCacheManager::PersistentProperties; *p; ++p) {
- if (const char* value = i.GetProperty(*p)) {
+ for (const char* p : cmCacheManager::PersistentProperties) {
+ if (cmProp value = e.GetProperty(p)) {
std::string helpstring =
- cmStrCat(*p, " property for variable: ", i.GetName());
+ cmStrCat(p, " property for variable: ", entryKey);
cmCacheManager::OutputHelpString(os, helpstring);
- std::string key = cmStrCat(i.GetName(), '-', *p);
+ std::string key = cmStrCat(entryKey, '-', p);
cmCacheManager::OutputKey(os, key);
os << ":INTERNAL=";
- cmCacheManager::OutputValue(os, value);
- os << "\n";
- cmCacheManager::OutputNewlineTruncationWarning(os, key, value,
+ cmCacheManager::OutputValue(os, *value);
+ os << '\n';
+ cmCacheManager::OutputNewlineTruncationWarning(os, key, *value,
messenger);
}
}
@@ -270,31 +262,29 @@ bool cmCacheManager::SaveCache(const std::string& path, cmMessenger* messenger)
/* clang-format off */
fout << "# This is the CMakeCache file.\n"
- << "# For build in directory: " << currentcwd << "\n"
- << "# It was generated by CMake: "
- << cmSystemTools::GetCMakeCommand() << std::endl;
- /* clang-format on */
-
- /* clang-format off */
- fout << "# You can edit this file to change values found and used by cmake."
- << std::endl
- << "# If you do not want to change any of the values, simply exit the "
- "editor." << std::endl
- << "# If you do want to change a value, simply edit, save, and exit "
- "the editor." << std::endl
- << "# The syntax for the file is as follows:\n"
- << "# KEY:TYPE=VALUE\n"
- << "# KEY is the name of a variable in the cache.\n"
- << "# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT "
- "TYPE!." << std::endl
- << "# VALUE is the current value for the KEY.\n\n";
+ "# For build in directory: " << currentcwd << "\n"
+ "# It was generated by CMake: "
+ << cmSystemTools::GetCMakeCommand()
+ << "\n"
+ "# You can edit this file to change values found and used by cmake."
+ "\n"
+ "# If you do not want to change any of the values, simply exit the "
+ "editor.\n"
+ "# If you do want to change a value, simply edit, save, and exit "
+ "the editor.\n"
+ "# The syntax for the file is as follows:\n"
+ "# KEY:TYPE=VALUE\n"
+ "# KEY is the name of a variable in the cache.\n"
+ "# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!."
+ "\n"
+ "# VALUE is the current value for the KEY.\n"
+ "\n"
+ "########################\n"
+ "# EXTERNAL cache entries\n"
+ "########################\n"
+ "\n";
/* clang-format on */
- fout << "########################\n";
- fout << "# EXTERNAL cache entries\n";
- fout << "########################\n";
- fout << "\n";
-
for (auto const& i : this->Cache) {
CacheEntry const& ce = i.second;
cmStateEnums::CacheEntryType t = ce.Type;
@@ -305,49 +295,48 @@ bool cmCacheManager::SaveCache(const std::string& path, cmMessenger* messenger)
*/
} else if (t != cmStateEnums::INTERNAL) {
// Format is key:type=value
- if (const char* help = ce.GetProperty("HELPSTRING")) {
- cmCacheManager::OutputHelpString(fout, help);
+ if (cmProp help = ce.GetProperty("HELPSTRING")) {
+ cmCacheManager::OutputHelpString(fout, *help);
} else {
cmCacheManager::OutputHelpString(fout, "Missing description");
}
cmCacheManager::OutputKey(fout, i.first);
- fout << ":" << cmState::CacheEntryTypeToString(t) << "=";
+ fout << ':' << cmState::CacheEntryTypeToString(t) << '=';
cmCacheManager::OutputValue(fout, ce.Value);
- fout << "\n";
+ fout << '\n';
cmCacheManager::OutputNewlineTruncationWarning(fout, i.first, ce.Value,
messenger);
- fout << "\n";
+ fout << '\n';
}
}
- fout << "\n";
- fout << "########################\n";
- fout << "# INTERNAL cache entries\n";
- fout << "########################\n";
- fout << "\n";
+ fout << "\n"
+ "########################\n"
+ "# INTERNAL cache entries\n"
+ "########################\n"
+ "\n";
- for (cmCacheManager::CacheIterator i = this->NewIterator(); !i.IsAtEnd();
- i.Next()) {
- if (!i.Initialized()) {
+ for (auto const& i : this->Cache) {
+ if (!i.second.Initialized) {
continue;
}
- cmStateEnums::CacheEntryType t = i.GetType();
- this->WritePropertyEntries(fout, i, messenger);
+ cmStateEnums::CacheEntryType t = i.second.GetType();
+ this->WritePropertyEntries(fout, i.first, i.second, messenger);
if (t == cmStateEnums::INTERNAL) {
// Format is key:type=value
- if (const char* help = i.GetProperty("HELPSTRING")) {
- cmCacheManager::OutputHelpString(fout, help);
+ if (cmProp help = i.second.GetProperty("HELPSTRING")) {
+ cmCacheManager::OutputHelpString(fout, *help);
}
- cmCacheManager::OutputKey(fout, i.GetName());
- fout << ":" << cmState::CacheEntryTypeToString(t) << "=";
- cmCacheManager::OutputValue(fout, i.GetValue());
- fout << "\n";
- cmCacheManager::OutputNewlineTruncationWarning(fout, i.GetName(),
- i.GetValue(), messenger);
+ cmCacheManager::OutputKey(fout, i.first);
+ fout << ':' << cmState::CacheEntryTypeToString(t) << '=';
+ cmCacheManager::OutputValue(fout, i.second.GetValue());
+ fout << '\n';
+ cmCacheManager::OutputNewlineTruncationWarning(
+ fout, i.first, i.second.GetValue(), messenger);
}
}
- fout << "\n";
+ fout << '\n';
fout.Close();
std::string checkCacheFile = cmStrCat(path, "/CMakeFiles");
cmSystemTools::MakeDirectory(checkCacheFile);
@@ -385,7 +374,9 @@ void cmCacheManager::OutputKey(std::ostream& fout, std::string const& key)
{
// support : in key name by double quoting
const char* q =
- (key.find(':') != std::string::npos || key.find("//") == 0) ? "\"" : "";
+ (key.find(':') != std::string::npos || cmHasLiteralPrefix(key, "//"))
+ ? "\""
+ : "";
fout << q << key << q;
}
@@ -430,7 +421,7 @@ void cmCacheManager::OutputHelpString(std::ostream& fout,
fout << "\\n";
}
oneLine = helpString.substr(pos, i - pos);
- fout << oneLine << "\n";
+ fout << oneLine << '\n';
pos = i;
}
}
@@ -452,7 +443,7 @@ void cmCacheManager::OutputWarningComment(std::ostream& fout,
fout << "\\n";
}
oneLine = message.substr(pos, i - pos);
- fout << oneLine << "\n";
+ fout << oneLine << '\n';
pos = i;
}
}
@@ -481,10 +472,7 @@ void cmCacheManager::OutputNewlineTruncationWarning(std::ostream& fout,
void cmCacheManager::RemoveCacheEntry(const std::string& key)
{
- auto i = this->Cache.find(key);
- if (i != this->Cache.end()) {
- this->Cache.erase(i);
- }
+ this->Cache.erase(key);
}
cmCacheManager::CacheEntry* cmCacheManager::GetCacheEntry(
@@ -497,34 +485,39 @@ cmCacheManager::CacheEntry* cmCacheManager::GetCacheEntry(
return nullptr;
}
-cmCacheManager::CacheIterator cmCacheManager::GetCacheIterator(const char* key)
+const cmCacheManager::CacheEntry* cmCacheManager::GetCacheEntry(
+ const std::string& key) const
{
- return { *this, key };
+ auto i = this->Cache.find(key);
+ if (i != this->Cache.end()) {
+ return &i->second;
+ }
+ return nullptr;
}
-const std::string* cmCacheManager::GetInitializedCacheValue(
- const std::string& key) const
+cmProp cmCacheManager::GetInitializedCacheValue(const std::string& key) const
{
- auto i = this->Cache.find(key);
- if (i != this->Cache.end() && i->second.Initialized) {
- return &i->second.Value;
+ if (auto entry = this->GetCacheEntry(key)) {
+ if (entry->Initialized) {
+ return &entry->GetValue();
+ }
}
return nullptr;
}
void cmCacheManager::PrintCache(std::ostream& out) const
{
- out << "=================================================" << std::endl;
- out << "CMakeCache Contents:" << std::endl;
+ out << "=================================================\n"
+ "CMakeCache Contents:\n";
for (auto const& i : this->Cache) {
if (i.second.Type != cmStateEnums::INTERNAL) {
- out << i.first << " = " << i.second.Value << std::endl;
+ out << i.first << " = " << i.second.Value << '\n';
}
}
- out << "\n\n";
- out << "To change values in the CMakeCache, " << std::endl
- << "edit CMakeCache.txt in your output directory.\n";
- out << "=================================================" << std::endl;
+ out << "\n\n"
+ "To change values in the CMakeCache, \n"
+ "edit CMakeCache.txt in your output directory.\n"
+ "=================================================\n";
}
void cmCacheManager::AddCacheEntry(const std::string& key, const char* value,
@@ -532,12 +525,7 @@ void cmCacheManager::AddCacheEntry(const std::string& key, const char* value,
cmStateEnums::CacheEntryType type)
{
CacheEntry& e = this->Cache[key];
- if (value) {
- e.Value = value;
- e.Initialized = true;
- } else {
- e.Value.clear();
- }
+ e.SetValue(value);
e.Type = type;
// make sure we only use unix style paths
if (type == cmStateEnums::FILEPATH || type == cmStateEnums::PATH) {
@@ -561,70 +549,41 @@ void cmCacheManager::AddCacheEntry(const std::string& key, const char* value,
: "(This variable does not exist and should not be used)");
}
-bool cmCacheManager::CacheIterator::IsAtEnd() const
-{
- return this->Position == this->Container.Cache.end();
-}
-
-void cmCacheManager::CacheIterator::Begin()
-{
- this->Position = this->Container.Cache.begin();
-}
-
-bool cmCacheManager::CacheIterator::Find(const std::string& key)
-{
- this->Position = this->Container.Cache.find(key);
- return !this->IsAtEnd();
-}
-
-void cmCacheManager::CacheIterator::Next()
-{
- if (!this->IsAtEnd()) {
- ++this->Position;
- }
-}
-
-std::vector<std::string> cmCacheManager::CacheIterator::GetPropertyList() const
-{
- return this->GetEntry().GetPropertyList();
-}
-
-void cmCacheManager::CacheIterator::SetValue(const char* value)
+void cmCacheManager::CacheEntry::SetValue(const char* value)
{
- if (this->IsAtEnd()) {
- return;
- }
- CacheEntry* entry = &this->GetEntry();
if (value) {
- entry->Value = value;
- entry->Initialized = true;
+ this->Value = value;
+ this->Initialized = true;
} else {
- entry->Value.clear();
+ this->Value.clear();
}
}
-bool cmCacheManager::CacheIterator::GetValueAsBool() const
-{
- return cmIsOn(this->GetEntry().Value);
-}
-
std::vector<std::string> cmCacheManager::CacheEntry::GetPropertyList() const
{
return this->Properties.GetKeys();
}
-const char* cmCacheManager::CacheEntry::GetProperty(
- const std::string& prop) const
+cmProp cmCacheManager::CacheEntry::GetProperty(const std::string& prop) const
{
if (prop == "TYPE") {
- return cmState::CacheEntryTypeToString(this->Type);
+ return &cmState::CacheEntryTypeToString(this->Type);
}
if (prop == "VALUE") {
- return this->Value.c_str();
+ return &this->Value;
}
return this->Properties.GetPropertyValue(prop);
}
+bool cmCacheManager::CacheEntry::GetPropertyAsBool(
+ const std::string& prop) const
+{
+ if (cmProp value = this->GetProperty(prop)) {
+ return cmIsOn(*value);
+ }
+ return false;
+}
+
void cmCacheManager::CacheEntry::SetProperty(const std::string& prop,
const char* value)
{
@@ -637,15 +596,21 @@ void cmCacheManager::CacheEntry::SetProperty(const std::string& prop,
}
}
+void cmCacheManager::CacheEntry::SetProperty(const std::string& p, bool v)
+{
+ this->SetProperty(p, v ? "ON" : "OFF");
+}
+
void cmCacheManager::CacheEntry::AppendProperty(const std::string& prop,
- const char* value,
+ const std::string& value,
bool asString)
{
if (prop == "TYPE") {
- this->Type = cmState::StringToCacheEntryType(value ? value : "STRING");
+ this->Type =
+ cmState::StringToCacheEntryType(!value.empty() ? value : "STRING");
} else if (prop == "VALUE") {
- if (value) {
- if (!this->Value.empty() && *value && !asString) {
+ if (!value.empty()) {
+ if (!this->Value.empty() && !asString) {
this->Value += ";";
}
this->Value += value;
@@ -654,49 +619,3 @@ void cmCacheManager::CacheEntry::AppendProperty(const std::string& prop,
this->Properties.AppendProperty(prop, value, asString);
}
}
-
-const char* cmCacheManager::CacheIterator::GetProperty(
- const std::string& prop) const
-{
- if (!this->IsAtEnd()) {
- return this->GetEntry().GetProperty(prop);
- }
- return nullptr;
-}
-
-void cmCacheManager::CacheIterator::SetProperty(const std::string& p,
- const char* v)
-{
- if (!this->IsAtEnd()) {
- this->GetEntry().SetProperty(p, v);
- }
-}
-
-void cmCacheManager::CacheIterator::AppendProperty(const std::string& p,
- const char* v,
- bool asString)
-{
- if (!this->IsAtEnd()) {
- this->GetEntry().AppendProperty(p, v, asString);
- }
-}
-
-bool cmCacheManager::CacheIterator::GetPropertyAsBool(
- const std::string& prop) const
-{
- if (const char* value = this->GetProperty(prop)) {
- return cmIsOn(value);
- }
- return false;
-}
-
-void cmCacheManager::CacheIterator::SetProperty(const std::string& p, bool v)
-{
- this->SetProperty(p, v ? "ON" : "OFF");
-}
-
-bool cmCacheManager::CacheIterator::PropertyExists(
- const std::string& prop) const
-{
- return this->GetProperty(prop) != nullptr;
-}
diff --git a/Source/cmCacheManager.h b/Source/cmCacheManager.h
index faa60c5..3d946b4 100644
--- a/Source/cmCacheManager.h
+++ b/Source/cmCacheManager.h
@@ -25,77 +25,33 @@ class cmMessenger;
*/
class cmCacheManager
{
-public:
- cmCacheManager();
- class CacheIterator;
- friend class cmCacheManager::CacheIterator;
-
-private:
- struct CacheEntry
+ class CacheEntry
{
- std::string Value;
- cmStateEnums::CacheEntryType Type = cmStateEnums::UNINITIALIZED;
- cmPropertyMap Properties;
- std::vector<std::string> GetPropertyList() const;
- const char* GetProperty(const std::string&) const;
- void SetProperty(const std::string& property, const char* value);
- void AppendProperty(const std::string& property, const char* value,
- bool asString = false);
- bool Initialized = false;
- };
+ friend class cmCacheManager;
-public:
- class CacheIterator
- {
public:
- void Begin();
- bool Find(const std::string&);
- bool IsAtEnd() const;
- void Next();
- std::string GetName() const { return this->Position->first; }
+ const std::string& GetValue() const { return this->Value; }
+ void SetValue(const char*);
+
+ cmStateEnums::CacheEntryType GetType() const { return this->Type; }
+ void SetType(cmStateEnums::CacheEntryType ty) { this->Type = ty; }
+
std::vector<std::string> GetPropertyList() const;
- const char* GetProperty(const std::string&) const;
- bool GetPropertyAsBool(const std::string&) const;
- bool PropertyExists(const std::string&) const;
+ cmProp GetProperty(const std::string& property) const;
+ bool GetPropertyAsBool(const std::string& property) const;
void SetProperty(const std::string& property, const char* value);
- void AppendProperty(const std::string& property, const char* value,
- bool asString = false);
void SetProperty(const std::string& property, bool value);
- const char* GetValue() const { return this->GetEntry().Value.c_str(); }
- bool GetValueAsBool() const;
- void SetValue(const char*);
- cmStateEnums::CacheEntryType GetType() const
- {
- return this->GetEntry().Type;
- }
- void SetType(cmStateEnums::CacheEntryType ty)
- {
- this->GetEntry().Type = ty;
- }
- bool Initialized() { return this->GetEntry().Initialized; }
- cmCacheManager& Container;
- std::map<std::string, CacheEntry>::iterator Position;
- CacheIterator(cmCacheManager& cm)
- : Container(cm)
- {
- this->Begin();
- }
- CacheIterator(cmCacheManager& cm, const char* key)
- : Container(cm)
- {
- if (key) {
- this->Find(key);
- }
- }
+ void AppendProperty(const std::string& property, const std::string& value,
+ bool asString = false);
private:
- CacheEntry const& GetEntry() const { return this->Position->second; }
- CacheEntry& GetEntry() { return this->Position->second; }
+ std::string Value;
+ cmStateEnums::CacheEntryType Type = cmStateEnums::UNINITIALIZED;
+ cmPropertyMap Properties;
+ bool Initialized = false;
};
- //! return an iterator to iterate through the cache map
- cmCacheManager::CacheIterator NewIterator() { return { *this }; }
-
+public:
//! Load a cache for given makefile. Loads from path/CMakeCache.txt.
bool LoadCache(const std::string& path, bool internal,
std::set<std::string>& excludes,
@@ -110,66 +66,82 @@ public:
//! Print the cache to a stream
void PrintCache(std::ostream&) const;
- //! Get the iterator for an entry with a given key.
- cmCacheManager::CacheIterator GetCacheIterator(const char* key = nullptr);
-
- //! Remove an entry from the cache
- void RemoveCacheEntry(const std::string& key);
+ //! Get a value from the cache given a key
+ cmProp GetInitializedCacheValue(const std::string& key) const;
- //! Get the number of entries in the cache
- int GetSize() { return static_cast<int>(this->Cache.size()); }
+ cmProp GetCacheEntryValue(const std::string& key) const
+ {
+ if (auto entry = this->GetCacheEntry(key)) {
+ return &entry->GetValue();
+ }
+ return nullptr;
+ }
- //! Get a value from the cache given a key
- const std::string* GetInitializedCacheValue(const std::string& key) const;
+ void SetCacheEntryValue(std::string const& key, std::string const& value)
+ {
+ if (auto entry = this->GetCacheEntry(key)) {
+ entry->SetValue(value.c_str());
+ }
+ }
- const char* GetCacheEntryValue(const std::string& key)
+ cmStateEnums::CacheEntryType GetCacheEntryType(std::string const& key) const
{
- cmCacheManager::CacheIterator it = this->GetCacheIterator(key.c_str());
- if (it.IsAtEnd()) {
- return nullptr;
+ if (auto entry = this->GetCacheEntry(key)) {
+ return entry->GetType();
}
- return it.GetValue();
+ return cmStateEnums::UNINITIALIZED;
}
- const char* GetCacheEntryProperty(std::string const& key,
- std::string const& propName)
+ std::vector<std::string> GetCacheEntryPropertyList(
+ std::string const& key) const
{
- return this->GetCacheIterator(key.c_str()).GetProperty(propName);
+ if (auto entry = this->GetCacheEntry(key)) {
+ return entry->GetPropertyList();
+ }
+ return {};
}
- cmStateEnums::CacheEntryType GetCacheEntryType(std::string const& key)
+ cmProp GetCacheEntryProperty(std::string const& key,
+ std::string const& propName) const
{
- return this->GetCacheIterator(key.c_str()).GetType();
+ if (auto entry = this->GetCacheEntry(key)) {
+ return entry->GetProperty(propName);
+ }
+ return nullptr;
}
bool GetCacheEntryPropertyAsBool(std::string const& key,
- std::string const& propName)
+ std::string const& propName) const
{
- return this->GetCacheIterator(key.c_str()).GetPropertyAsBool(propName);
+ if (auto entry = this->GetCacheEntry(key)) {
+ return entry->GetPropertyAsBool(propName);
+ }
+ return false;
}
void SetCacheEntryProperty(std::string const& key,
std::string const& propName,
std::string const& value)
{
- this->GetCacheIterator(key.c_str()).SetProperty(propName, value.c_str());
+ if (auto entry = this->GetCacheEntry(key)) {
+ entry->SetProperty(propName, value.c_str());
+ }
}
void SetCacheEntryBoolProperty(std::string const& key,
std::string const& propName, bool value)
{
- this->GetCacheIterator(key.c_str()).SetProperty(propName, value);
- }
-
- void SetCacheEntryValue(std::string const& key, std::string const& value)
- {
- this->GetCacheIterator(key.c_str()).SetValue(value.c_str());
+ if (auto entry = this->GetCacheEntry(key)) {
+ entry->SetProperty(propName, value);
+ }
}
void RemoveCacheEntryProperty(std::string const& key,
std::string const& propName)
{
- this->GetCacheIterator(key.c_str()).SetProperty(propName, nullptr);
+ if (auto entry = this->GetCacheEntry(key)) {
+ entry->SetProperty(propName, nullptr);
+ }
}
void AppendCacheEntryProperty(std::string const& key,
@@ -177,17 +149,17 @@ public:
std::string const& value,
bool asString = false)
{
- this->GetCacheIterator(key.c_str())
- .AppendProperty(propName, value.c_str(), asString);
+ if (auto entry = this->GetCacheEntry(key)) {
+ entry->AppendProperty(propName, value, asString);
+ }
}
- std::vector<std::string> GetCacheEntryKeys()
+ std::vector<std::string> GetCacheEntryKeys() const
{
std::vector<std::string> definitions;
- definitions.reserve(this->GetSize());
- cmCacheManager::CacheIterator cit = this->GetCacheIterator();
- for (cit.Begin(); !cit.IsAtEnd(); cit.Next()) {
- definitions.push_back(cit.GetName());
+ definitions.reserve(this->Cache.size());
+ for (auto const& i : this->Cache) {
+ definitions.push_back(i.first);
}
return definitions;
}
@@ -196,23 +168,22 @@ public:
unsigned int GetCacheMajorVersion() const { return this->CacheMajorVersion; }
unsigned int GetCacheMinorVersion() const { return this->CacheMinorVersion; }
-protected:
//! Add an entry into the cache
void AddCacheEntry(const std::string& key, const char* value,
const char* helpString,
cmStateEnums::CacheEntryType type);
+ //! Remove an entry from the cache
+ void RemoveCacheEntry(const std::string& key);
+
+private:
//! Get a cache entry object for a key
CacheEntry* GetCacheEntry(const std::string& key);
+ const CacheEntry* GetCacheEntry(const std::string& key) const;
+
//! Clean out the CMakeFiles directory if no CMakeCache.txt
void CleanCMakeFiles(const std::string& path);
- // Cache version info
- unsigned int CacheMajorVersion;
- unsigned int CacheMinorVersion;
-
-private:
- using CacheEntryMap = std::map<std::string, CacheEntry>;
static void OutputHelpString(std::ostream& fout,
const std::string& helpString);
static void OutputWarningComment(std::ostream& fout,
@@ -228,15 +199,15 @@ private:
std::string const& value);
static const char* PersistentProperties[];
- bool ReadPropertyEntry(std::string const& key, CacheEntry& e);
- void WritePropertyEntries(std::ostream& os, CacheIterator i,
- cmMessenger* messenger);
-
- CacheEntryMap Cache;
- // Only cmake and cmState should be able to add cache values
- // the commands should never use the cmCacheManager directly
- friend class cmState; // allow access to add cache values
- friend class cmake; // allow access to add cache values
+ bool ReadPropertyEntry(const std::string& key, const CacheEntry& e);
+ void WritePropertyEntries(std::ostream& os, const std::string& entryKey,
+ const CacheEntry& e, cmMessenger* messenger) const;
+
+ std::map<std::string, CacheEntry> Cache;
+
+ // Cache version info
+ unsigned int CacheMajorVersion = 0;
+ unsigned int CacheMinorVersion = 0;
};
#endif
diff --git a/Source/cmCallVisualStudioMacro.cxx b/Source/cmCallVisualStudioMacro.cxx
index 9e152ff..94b6e18 100644
--- a/Source/cmCallVisualStudioMacro.cxx
+++ b/Source/cmCallVisualStudioMacro.cxx
@@ -43,8 +43,7 @@ static bool LogErrorsAsMessages;
if (LogErrorsAsMessages) { \
std::ostringstream _hresult_oss; \
_hresult_oss.flags(std::ios::hex); \
- _hresult_oss << context << " failed HRESULT, hr = 0x" << hr \
- << std::endl; \
+ _hresult_oss << context << " failed HRESULT, hr = 0x" << hr << '\n'; \
_hresult_oss.flags(std::ios::dec); \
_hresult_oss << __FILE__ << "(" << __LINE__ << ")"; \
cmSystemTools::Message(_hresult_oss.str()); \
@@ -98,32 +97,37 @@ HRESULT InstanceCallMacro(IDispatch* vsIDE, const std::string& macro,
DISPATCH_METHOD, &params, &result, &excep, &arg);
std::ostringstream oss;
- oss << std::endl;
- oss << "Invoke(ExecuteCommand)" << std::endl;
- oss << " Macro: " << macro << std::endl;
- oss << " Args: " << args << std::endl;
+ /* clang-format off */
+ oss << "\nInvoke(ExecuteCommand)\n"
+ " Macro: " << macro << "\n"
+ " Args: " << args << '\n';
+ /* clang-format on */
if (DISP_E_EXCEPTION == hr) {
- oss << "DISP_E_EXCEPTION EXCEPINFO:" << excep.wCode << std::endl;
- oss << " wCode: " << excep.wCode << std::endl;
- oss << " wReserved: " << excep.wReserved << std::endl;
+ /* clang-format off */
+ oss << "DISP_E_EXCEPTION EXCEPINFO:" << excep.wCode << "\n"
+ " wCode: " << excep.wCode << "\n"
+ " wReserved: " << excep.wReserved << '\n';
+ /* clang-format on */
if (excep.bstrSource) {
oss << " bstrSource: " << (const char*)(_bstr_t)excep.bstrSource
- << std::endl;
+ << '\n';
}
if (excep.bstrDescription) {
oss << " bstrDescription: "
- << (const char*)(_bstr_t)excep.bstrDescription << std::endl;
+ << (const char*)(_bstr_t)excep.bstrDescription << '\n';
}
if (excep.bstrHelpFile) {
oss << " bstrHelpFile: " << (const char*)(_bstr_t)excep.bstrHelpFile
- << std::endl;
+ << '\n';
}
- oss << " dwHelpContext: " << excep.dwHelpContext << std::endl;
- oss << " pvReserved: " << excep.pvReserved << std::endl;
- oss << " pfnDeferredFillIn: "
- << reinterpret_cast<void*>(excep.pfnDeferredFillIn) << std::endl;
- oss << " scode: " << excep.scode << std::endl;
+ /* clang-format off */
+ oss << " dwHelpContext: " << excep.dwHelpContext << "\n"
+ " pvReserved: " << excep.pvReserved << "\n"
+ " pfnDeferredFillIn: "
+ << reinterpret_cast<void*>(excep.pfnDeferredFillIn) << "\n"
+ " scode: " << excep.scode << '\n';
+ /* clang-format on */
}
std::string exstr(oss.str());
diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx
index 613ae06..0516d26 100644
--- a/Source/cmCommandArgumentParserHelper.cxx
+++ b/Source/cmCommandArgumentParserHelper.cxx
@@ -5,6 +5,9 @@
#include <cstring>
#include <iostream>
#include <sstream>
+#include <utility>
+
+#include <cm/memory>
#include "cmCommandArgumentLexer.h"
#include "cmMakefile.h"
@@ -40,10 +43,10 @@ const char* cmCommandArgumentParserHelper::AddString(const std::string& str)
if (str.empty()) {
return "";
}
- char* stVal = new char[str.size() + 1];
- strcpy(stVal, str.c_str());
- this->Variables.push_back(stVal);
- return stVal;
+ auto stVal = cm::make_unique<char[]>(str.size() + 1);
+ strcpy(stVal.get(), str.c_str());
+ this->Variables.push_back(std::move(stVal));
+ return this->Variables.back().get();
}
const char* cmCommandArgumentParserHelper::ExpandSpecialVariable(
@@ -66,8 +69,7 @@ const char* cmCommandArgumentParserHelper::ExpandSpecialVariable(
return "";
}
if (strcmp(key, "CACHE") == 0) {
- if (const std::string* c =
- this->Makefile->GetState()->GetInitializedCacheValue(var)) {
+ if (cmProp c = this->Makefile->GetState()->GetInitializedCacheValue(var)) {
if (this->EscapeQuotes) {
return this->AddString(cmEscapeQuotes(*c));
}
@@ -136,11 +138,11 @@ const char* cmCommandArgumentParserHelper::CombineUnions(const char* in1,
return in1;
}
size_t len = strlen(in1) + strlen(in2) + 1;
- char* out = new char[len];
- strcpy(out, in1);
- strcat(out, in2);
- this->Variables.push_back(out);
- return out;
+ auto out = cm::make_unique<char[]>(len);
+ strcpy(out.get(), in1);
+ strcat(out.get(), in2);
+ this->Variables.push_back(std::move(out));
+ return this->Variables.back().get();
}
void cmCommandArgumentParserHelper::AllocateParserType(
@@ -153,11 +155,11 @@ void cmCommandArgumentParserHelper::AllocateParserType(
if (len == 0) {
return;
}
- char* out = new char[len + 1];
- memcpy(out, str, len);
- out[len] = 0;
- pt->str = out;
- this->Variables.push_back(out);
+ auto out = cm::make_unique<char[]>(len + 1);
+ memcpy(out.get(), str, len);
+ out.get()[len] = 0;
+ pt->str = out.get();
+ this->Variables.push_back(std::move(out));
}
bool cmCommandArgumentParserHelper::HandleEscapeSymbol(
@@ -235,10 +237,7 @@ int cmCommandArgumentParserHelper::ParseString(const char* str, int verb)
void cmCommandArgumentParserHelper::CleanupParser()
{
- for (char* var : this->Variables) {
- delete[] var;
- }
- this->Variables.erase(this->Variables.begin(), this->Variables.end());
+ this->Variables.clear();
}
int cmCommandArgumentParserHelper::LexInput(char* buf, int maxlen)
diff --git a/Source/cmCommandArgumentParserHelper.h b/Source/cmCommandArgumentParserHelper.h
index 25e6892..b46edcb 100644
--- a/Source/cmCommandArgumentParserHelper.h
+++ b/Source/cmCommandArgumentParserHelper.h
@@ -5,6 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <memory>
#include <string>
#include <vector>
@@ -69,7 +70,7 @@ private:
void CleanupParser();
void SetError(std::string const& msg);
- std::vector<char*> Variables;
+ std::vector<std::unique_ptr<char[]>> Variables;
const cmMakefile* Makefile;
std::string Result;
std::string ErrorString;
diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index 6f19697..28b4267 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -91,6 +91,7 @@
# include "cmAddLinkOptionsCommand.h"
# include "cmAuxSourceDirectoryCommand.h"
# include "cmBuildNameCommand.h"
+# include "cmCMakeCommand.h"
# include "cmCMakeHostSystemInformationCommand.h"
# include "cmExportCommand.h"
# include "cmExportLibraryDependenciesCommand.h"
@@ -196,8 +197,10 @@ void GetScriptingCommands(cmState* state)
"match the opening WHILE command.");
#if !defined(CMAKE_BOOTSTRAP)
+ state->AddBuiltinCommand("cmake_command", cmCMakeCommand);
state->AddBuiltinCommand("cmake_host_system_information",
cmCMakeHostSystemInformationCommand);
+ state->AddBuiltinCommand("load_cache", cmLoadCacheCommand);
state->AddBuiltinCommand("remove", cmRemoveCommand);
state->AddBuiltinCommand("variable_watch", cmVariableWatchCommand);
state->AddBuiltinCommand("write_file", cmWriteFileCommand);
@@ -279,7 +282,6 @@ void GetProjectCommands(cmState* state)
state->AddBuiltinCommand("link_libraries", cmLinkLibrariesCommand);
state->AddBuiltinCommand("target_link_directories",
cmTargetLinkDirectoriesCommand);
- state->AddBuiltinCommand("load_cache", cmLoadCacheCommand);
state->AddBuiltinCommand("qt_wrap_cpp", cmQTWrapCPPCommand);
state->AddBuiltinCommand("qt_wrap_ui", cmQTWrapUICommand);
state->AddBuiltinCommand("remove_definitions", cmRemoveDefinitionsCommand);
@@ -339,7 +341,6 @@ void GetProjectCommandsInScriptMode(cmState* state)
CM_UNEXPECTED_PROJECT_COMMAND("install");
CM_UNEXPECTED_PROJECT_COMMAND("link_directories");
CM_UNEXPECTED_PROJECT_COMMAND("link_libraries");
- CM_UNEXPECTED_PROJECT_COMMAND("load_cache");
CM_UNEXPECTED_PROJECT_COMMAND("project");
CM_UNEXPECTED_PROJECT_COMMAND("qt_wrap_cpp");
CM_UNEXPECTED_PROJECT_COMMAND("qt_wrap_ui");
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
index 19a096b..5414409 100644
--- a/Source/cmCommonTargetGenerator.cxx
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -17,6 +17,7 @@
#include "cmSourceFile.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
+#include "cmTarget.h"
cmCommonTargetGenerator::cmCommonTargetGenerator(cmGeneratorTarget* gt)
: GeneratorTarget(gt)
@@ -25,27 +26,29 @@ cmCommonTargetGenerator::cmCommonTargetGenerator(cmGeneratorTarget* gt)
static_cast<cmLocalCommonGenerator*>(gt->LocalGenerator))
, GlobalCommonGenerator(static_cast<cmGlobalCommonGenerator*>(
gt->LocalGenerator->GetGlobalGenerator()))
- , ConfigName(LocalCommonGenerator->GetConfigName())
+ , ConfigNames(LocalCommonGenerator->GetConfigNames())
{
}
cmCommonTargetGenerator::~cmCommonTargetGenerator() = default;
-std::string const& cmCommonTargetGenerator::GetConfigName() const
+std::vector<std::string> const& cmCommonTargetGenerator::GetConfigNames() const
{
- return this->ConfigName;
+ return this->ConfigNames;
}
-const char* cmCommonTargetGenerator::GetFeature(const std::string& feature)
+const char* cmCommonTargetGenerator::GetFeature(const std::string& feature,
+ const std::string& config)
{
- return this->GeneratorTarget->GetFeature(feature, this->ConfigName);
+ return this->GeneratorTarget->GetFeature(feature, config);
}
void cmCommonTargetGenerator::AddModuleDefinitionFlag(
- cmLinkLineComputer* linkLineComputer, std::string& flags)
+ cmLinkLineComputer* linkLineComputer, std::string& flags,
+ const std::string& config)
{
cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
- this->GeneratorTarget->GetModuleDefinitionInfo(this->GetConfigName());
+ this->GeneratorTarget->GetModuleDefinitionInfo(config);
if (!mdi || mdi->DefFile.empty()) {
return;
}
@@ -70,11 +73,12 @@ void cmCommonTargetGenerator::AddModuleDefinitionFlag(
void cmCommonTargetGenerator::AppendFortranFormatFlags(
std::string& flags, cmSourceFile const& source)
{
- const char* srcfmt = source.GetProperty("Fortran_FORMAT");
+ const std::string srcfmt = source.GetSafeProperty("Fortran_FORMAT");
cmOutputConverter::FortranFormat format =
cmOutputConverter::GetFortranFormat(srcfmt);
if (format == cmOutputConverter::FortranFormatNone) {
- const char* tgtfmt = this->GeneratorTarget->GetProperty("Fortran_FORMAT");
+ std::string const& tgtfmt =
+ this->GeneratorTarget->GetSafeProperty("Fortran_FORMAT");
format = cmOutputConverter::GetFortranFormat(tgtfmt);
}
const char* var = nullptr;
@@ -94,57 +98,63 @@ void cmCommonTargetGenerator::AppendFortranFormatFlags(
}
}
-std::string cmCommonTargetGenerator::GetFlags(const std::string& l)
+std::string cmCommonTargetGenerator::GetFlags(const std::string& l,
+ const std::string& config,
+ const std::string& arch)
{
- auto i = this->FlagsByLanguage.find(l);
- if (i == this->FlagsByLanguage.end()) {
+ const std::string key = config + arch;
+
+ auto i = this->Configs[key].FlagsByLanguage.find(l);
+ if (i == this->Configs[key].FlagsByLanguage.end()) {
std::string flags;
- this->LocalCommonGenerator->GetTargetCompileFlags(
- this->GeneratorTarget, this->ConfigName, l, flags);
+ this->LocalCommonGenerator->GetTargetCompileFlags(this->GeneratorTarget,
+ config, l, flags, arch);
ByLanguageMap::value_type entry(l, flags);
- i = this->FlagsByLanguage.insert(entry).first;
+ i = this->Configs[key].FlagsByLanguage.insert(entry).first;
}
return i->second;
}
-std::string cmCommonTargetGenerator::GetDefines(const std::string& l)
+std::string cmCommonTargetGenerator::GetDefines(const std::string& l,
+ const std::string& config)
{
- auto i = this->DefinesByLanguage.find(l);
- if (i == this->DefinesByLanguage.end()) {
+ auto i = this->Configs[config].DefinesByLanguage.find(l);
+ if (i == this->Configs[config].DefinesByLanguage.end()) {
std::set<std::string> defines;
- this->LocalCommonGenerator->GetTargetDefines(this->GeneratorTarget,
- this->ConfigName, l, defines);
+ this->LocalCommonGenerator->GetTargetDefines(this->GeneratorTarget, config,
+ l, defines);
std::string definesString;
this->LocalCommonGenerator->JoinDefines(defines, definesString, l);
ByLanguageMap::value_type entry(l, definesString);
- i = this->DefinesByLanguage.insert(entry).first;
+ i = this->Configs[config].DefinesByLanguage.insert(entry).first;
}
return i->second;
}
-std::string cmCommonTargetGenerator::GetIncludes(std::string const& l)
+std::string cmCommonTargetGenerator::GetIncludes(std::string const& l,
+ const std::string& config)
{
- auto i = this->IncludesByLanguage.find(l);
- if (i == this->IncludesByLanguage.end()) {
+ auto i = this->Configs[config].IncludesByLanguage.find(l);
+ if (i == this->Configs[config].IncludesByLanguage.end()) {
std::string includes;
- this->AddIncludeFlags(includes, l);
+ this->AddIncludeFlags(includes, l, config);
ByLanguageMap::value_type entry(l, includes);
- i = this->IncludesByLanguage.insert(entry).first;
+ i = this->Configs[config].IncludesByLanguage.insert(entry).first;
}
return i->second;
}
-std::vector<std::string> cmCommonTargetGenerator::GetLinkedTargetDirectories()
- const
+std::vector<std::string> cmCommonTargetGenerator::GetLinkedTargetDirectories(
+ const std::string& config) const
{
std::vector<std::string> dirs;
std::set<cmGeneratorTarget const*> emitted;
if (cmComputeLinkInformation* cli =
- this->GeneratorTarget->GetLinkInformation(this->ConfigName)) {
+ this->GeneratorTarget->GetLinkInformation(config)) {
cmComputeLinkInformation::ItemVector const& items = cli->GetItems();
for (auto const& item : items) {
cmGeneratorTarget const* linkee = item.Target;
@@ -165,19 +175,24 @@ std::vector<std::string> cmCommonTargetGenerator::GetLinkedTargetDirectories()
return dirs;
}
-std::string cmCommonTargetGenerator::ComputeTargetCompilePDB() const
+std::string cmCommonTargetGenerator::ComputeTargetCompilePDB(
+ const std::string& config) const
{
std::string compilePdbPath;
if (this->GeneratorTarget->GetType() > cmStateEnums::OBJECT_LIBRARY) {
return compilePdbPath;
}
- compilePdbPath =
- this->GeneratorTarget->GetCompilePDBPath(this->GetConfigName());
+ compilePdbPath = this->GeneratorTarget->GetCompilePDBPath(config);
if (compilePdbPath.empty()) {
// Match VS default: `$(IntDir)vc$(PlatformToolsetVersion).pdb`.
// A trailing slash tells the toolchain to add its default file name.
- compilePdbPath = this->GeneratorTarget->GetSupportDirectory() + "/";
+ compilePdbPath = this->GeneratorTarget->GetSupportDirectory();
+ if (this->GlobalCommonGenerator->IsMultiConfig()) {
+ compilePdbPath += "/";
+ compilePdbPath += config;
+ }
+ compilePdbPath += "/";
if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY) {
// Match VS default for static libs: `$(IntDir)$(ProjectName).pdb`.
compilePdbPath += this->GeneratorTarget->GetName();
@@ -188,10 +203,10 @@ std::string cmCommonTargetGenerator::ComputeTargetCompilePDB() const
return compilePdbPath;
}
-std::string cmCommonTargetGenerator::GetManifests()
+std::string cmCommonTargetGenerator::GetManifests(const std::string& config)
{
std::vector<cmSourceFile const*> manifest_srcs;
- this->GeneratorTarget->GetManifests(manifest_srcs, this->ConfigName);
+ this->GeneratorTarget->GetManifests(manifest_srcs, config);
std::vector<std::string> manifests;
manifests.reserve(manifest_srcs.size());
@@ -206,6 +221,20 @@ std::string cmCommonTargetGenerator::GetManifests()
return cmJoin(manifests, " ");
}
+std::string cmCommonTargetGenerator::GetAIXExports(std::string const&)
+{
+ std::string aixExports;
+ if (this->GeneratorTarget->Target->IsAIX()) {
+ if (cmProp exportAll =
+ this->GeneratorTarget->GetProperty("AIX_EXPORT_ALL_SYMBOLS")) {
+ if (cmIsOff(*exportAll)) {
+ aixExports = "-n";
+ }
+ }
+ }
+ return aixExports;
+}
+
void cmCommonTargetGenerator::AppendOSXVerFlag(std::string& flags,
const std::string& lang,
const char* name, bool so)
@@ -223,7 +252,10 @@ void cmCommonTargetGenerator::AppendOSXVerFlag(std::string& flags,
int major;
int minor;
int patch;
- this->GeneratorTarget->GetTargetVersion(so, major, minor, patch);
+ std::string prop = cmStrCat("MACHO_", name, "_VERSION");
+ std::string fallback_prop = so ? "SOVERSION" : "VERSION";
+ this->GeneratorTarget->GetTargetVersionFallback(prop, fallback_prop, major,
+ minor, patch);
if (major > 0 || minor > 0 || patch > 0) {
// Append the flag since a non-zero version is specified.
std::ostringstream vflag;
diff --git a/Source/cmCommonTargetGenerator.h b/Source/cmCommonTargetGenerator.h
index 17792d6..78cedf5 100644
--- a/Source/cmCommonTargetGenerator.h
+++ b/Source/cmCommonTargetGenerator.h
@@ -25,42 +25,52 @@ public:
cmCommonTargetGenerator(cmGeneratorTarget* gt);
virtual ~cmCommonTargetGenerator();
- std::string const& GetConfigName() const;
+ std::vector<std::string> const& GetConfigNames() const;
protected:
// Feature query methods.
- const char* GetFeature(const std::string& feature);
+ const char* GetFeature(const std::string& feature,
+ const std::string& config);
// Helper to add flag for windows .def file.
void AddModuleDefinitionFlag(cmLinkLineComputer* linkLineComputer,
- std::string& flags);
+ std::string& flags, const std::string& config);
cmGeneratorTarget* GeneratorTarget;
cmMakefile* Makefile;
cmLocalCommonGenerator* LocalCommonGenerator;
cmGlobalCommonGenerator* GlobalCommonGenerator;
- std::string ConfigName;
+ std::vector<std::string> ConfigNames;
void AppendFortranFormatFlags(std::string& flags,
cmSourceFile const& source);
- virtual void AddIncludeFlags(std::string& flags,
- std::string const& lang) = 0;
+ virtual void AddIncludeFlags(std::string& flags, std::string const& lang,
+ const std::string& config) = 0;
void AppendOSXVerFlag(std::string& flags, const std::string& lang,
const char* name, bool so);
- using ByLanguageMap = std::map<std::string, std::string>;
- std::string GetFlags(const std::string& l);
- ByLanguageMap FlagsByLanguage;
- std::string GetDefines(const std::string& l);
- ByLanguageMap DefinesByLanguage;
- std::string GetIncludes(std::string const& l);
- ByLanguageMap IncludesByLanguage;
- std::string GetManifests();
+ std::string GetFlags(const std::string& l, const std::string& config,
+ const std::string& arch = std::string());
+ std::string GetDefines(const std::string& l, const std::string& config);
+ std::string GetIncludes(std::string const& l, const std::string& config);
+ std::string GetManifests(const std::string& config);
+ std::string GetAIXExports(std::string const& config);
+
+ std::vector<std::string> GetLinkedTargetDirectories(
+ const std::string& config) const;
+ std::string ComputeTargetCompilePDB(const std::string& config) const;
- std::vector<std::string> GetLinkedTargetDirectories() const;
- std::string ComputeTargetCompilePDB() const;
+private:
+ using ByLanguageMap = std::map<std::string, std::string>;
+ struct ByConfig
+ {
+ ByLanguageMap FlagsByLanguage;
+ ByLanguageMap DefinesByLanguage;
+ ByLanguageMap IncludesByLanguage;
+ };
+ std::map<std::string, ByConfig> Configs;
};
#endif
diff --git a/Source/cmComputeComponentGraph.cxx b/Source/cmComputeComponentGraph.cxx
index af257ee..81cd878 100644
--- a/Source/cmComputeComponentGraph.cxx
+++ b/Source/cmComputeComponentGraph.cxx
@@ -123,7 +123,7 @@ void cmComputeComponentGraph::TransferEdges()
// We do not attempt to combine duplicate edges, but instead
// store the inter-component edges with suitable multiplicity.
this->ComponentGraph[i_component].emplace_back(
- j_component, ni.IsStrong(), ni.GetBacktrace());
+ j_component, ni.IsStrong(), ni.IsCross(), ni.GetBacktrace());
}
}
}
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index ccef9c8..e9bf5a5 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -412,7 +412,7 @@ void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep)
// This shared library dependency must follow the item that listed
// it.
this->EntryConstraintGraph[dep.DependerIndex].emplace_back(
- index, true, cmListFileBacktrace());
+ index, true, false, cmListFileBacktrace());
// Target items may have their own dependencies.
if (entry.Target) {
@@ -514,7 +514,7 @@ void cmComputeLinkDepends::AddLinkEntries(int depender_index,
// The dependee must come after the depender.
if (depender_index >= 0) {
this->EntryConstraintGraph[depender_index].emplace_back(
- dependee_index, false, cmListFileBacktrace());
+ dependee_index, false, false, cmListFileBacktrace());
} else {
// This is a direct dependency of the target being linked.
this->OriginalEntries.push_back(dependee_index);
@@ -587,7 +587,7 @@ void cmComputeLinkDepends::InferDependencies()
cmGraphEdgeList& edges = this->EntryConstraintGraph[depender_index];
edges.reserve(edges.size() + common.size());
for (auto const& c : common) {
- edges.emplace_back(c, true, cmListFileBacktrace());
+ edges.emplace_back(c, true, false, cmListFileBacktrace());
}
}
}
diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h
index 43bfd1d..e806dff 100644
--- a/Source/cmComputeLinkDepends.h
+++ b/Source/cmComputeLinkDepends.h
@@ -7,12 +7,11 @@
#include <map>
#include <memory>
+#include <queue>
#include <set>
#include <string>
#include <vector>
-#include <queue>
-
#include "cmGraphAdjacencyList.h"
#include "cmLinkItem.h"
#include "cmListFileCache.h"
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index f3dd840..ea7ede4 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -8,8 +8,11 @@
#include <sstream>
#include <utility>
-#include "cmAlgorithms.h"
+#include <cm/memory>
+#include <cmext/algorithm>
+
#include "cmComputeLinkDepends.h"
+#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmListFileCache.h"
@@ -256,11 +259,10 @@ cmComputeLinkInformation::cmComputeLinkInformation(
"FIND_LIBRARY_USE_OPENBSD_VERSIONING");
// Allocate internals.
- this->OrderLinkerSearchPath = new cmOrderDirectories(
+ this->OrderLinkerSearchPath = cm::make_unique<cmOrderDirectories>(
this->GlobalGenerator, target, "linker search path");
- this->OrderRuntimeSearchPath = new cmOrderDirectories(
+ this->OrderRuntimeSearchPath = cm::make_unique<cmOrderDirectories>(
this->GlobalGenerator, target, "runtime search path");
- this->OrderDependentRPath = nullptr;
// Get the language used for linking this target.
this->LinkLanguage = this->Target->GetLinkerLanguage(config);
@@ -358,7 +360,7 @@ cmComputeLinkInformation::cmComputeLinkInformation(
this->SharedDependencyMode = SharedDepModeLibDir;
} else if (!this->RPathLinkFlag.empty()) {
this->SharedDependencyMode = SharedDepModeDir;
- this->OrderDependentRPath = new cmOrderDirectories(
+ this->OrderDependentRPath = cm::make_unique<cmOrderDirectories>(
this->GlobalGenerator, target, "dependent library path");
}
@@ -400,12 +402,7 @@ cmComputeLinkInformation::cmComputeLinkInformation(
"CMAKE_POLICY_WARNING_CMP0060");
}
-cmComputeLinkInformation::~cmComputeLinkInformation()
-{
- delete this->OrderLinkerSearchPath;
- delete this->OrderRuntimeSearchPath;
- delete this->OrderDependentRPath;
-}
+cmComputeLinkInformation::~cmComputeLinkInformation() = default;
void cmComputeLinkInformation::AppendValues(
std::string& result, std::vector<BT<std::string>>& values)
@@ -517,8 +514,8 @@ bool cmComputeLinkInformation::Compute()
// Restore the target link type so the correct system runtime
// libraries are found.
- const char* lss = this->Target->GetProperty("LINK_SEARCH_END_STATIC");
- if (cmIsOn(lss)) {
+ cmProp lss = this->Target->GetProperty("LINK_SEARCH_END_STATIC");
+ if (lss && cmIsOn(*lss)) {
this->SetCurrentLinkType(LinkStatic);
} else {
this->SetCurrentLinkType(this->StartLinkType);
@@ -573,6 +570,15 @@ void cmComputeLinkInformation::AddImplicitLinkInfo()
cmGeneratorTarget::LinkClosure const* lc =
this->Target->GetLinkClosure(this->Config);
for (std::string const& li : lc->Languages) {
+
+ if (li == "CUDA") {
+ // These need to go before the other implicit link information
+ // as they could require symbols from those other library
+ // Currently restricted to CUDA as it is the only language
+ // we have documented runtime behavior controls for
+ this->AddRuntimeLinkLibrary(li);
+ }
+
// Skip those of the linker language. They are implicit.
if (li != this->LinkLanguage) {
this->AddImplicitLinkInfo(li);
@@ -580,6 +586,38 @@ void cmComputeLinkInformation::AddImplicitLinkInfo()
}
}
+void cmComputeLinkInformation::AddRuntimeLinkLibrary(std::string const& lang)
+{ // Add the lang runtime library flags. This is activated by the presence
+ // of a default selection whether or not it is overridden by a property.
+ std::string defaultVar =
+ cmStrCat("CMAKE_", lang, "_RUNTIME_LIBRARY_DEFAULT");
+ cmProp langRuntimeLibraryDefault = this->Makefile->GetDef(defaultVar);
+ if (langRuntimeLibraryDefault && !langRuntimeLibraryDefault->empty()) {
+ cmProp runtimeLibraryValue =
+ this->Target->GetProperty(cmStrCat(lang, "_RUNTIME_LIBRARY"));
+ if (!runtimeLibraryValue) {
+ runtimeLibraryValue = langRuntimeLibraryDefault;
+ }
+
+ std::string runtimeLibrary =
+ cmSystemTools::UpperCase(cmGeneratorExpression::Evaluate(
+ *runtimeLibraryValue, this->Target->GetLocalGenerator(), this->Config,
+ this->Target));
+ if (!runtimeLibrary.empty()) {
+ if (const char* runtimeLinkOptions = this->Makefile->GetDefinition(
+ "CMAKE_" + lang + "_RUNTIME_LIBRARY_LINK_OPTIONS_" +
+ runtimeLibrary)) {
+ std::vector<std::string> libsVec = cmExpandedList(runtimeLinkOptions);
+ for (std::string const& i : libsVec) {
+ if (!cm::contains(this->ImplicitLinkLibs, i)) {
+ this->AddItem(i, nullptr);
+ }
+ }
+ }
+ }
+ }
+}
+
void cmComputeLinkInformation::AddImplicitLinkInfo(std::string const& lang)
{
// Add libraries for this language that are not implied by the
@@ -588,7 +626,7 @@ void cmComputeLinkInformation::AddImplicitLinkInfo(std::string const& lang)
if (const char* libs = this->Makefile->GetDefinition(libVar)) {
std::vector<std::string> libsVec = cmExpandedList(libs);
for (std::string const& i : libsVec) {
- if (!cmContains(this->ImplicitLinkLibs, i)) {
+ if (!cm::contains(this->ImplicitLinkLibs, i)) {
this->AddItem(i, nullptr);
}
}
@@ -749,10 +787,10 @@ void cmComputeLinkInformation::AddSharedDepItem(BT<std::string> const& item,
if (this->SharedDependencyMode == SharedDepModeLibDir &&
!this->LinkWithRuntimePath /* AddLibraryRuntimeInfo adds it */) {
// Add the item to the linker search path.
- order = this->OrderLinkerSearchPath;
+ order = this->OrderLinkerSearchPath.get();
} else if (this->SharedDependencyMode == SharedDepModeDir) {
// Add the item to the separate dependent library search path.
- order = this->OrderDependentRPath;
+ order = this->OrderDependentRPath.get();
}
if (order) {
if (tgt) {
@@ -816,8 +854,8 @@ void cmComputeLinkInformation::ComputeLinkTypeInfo()
}
// Lookup the starting link type from the target (linked statically?).
- const char* lss = this->Target->GetProperty("LINK_SEARCH_START_STATIC");
- this->StartLinkType = cmIsOn(lss) ? LinkStatic : LinkShared;
+ cmProp lss = this->Target->GetProperty("LINK_SEARCH_START_STATIC");
+ this->StartLinkType = (lss && cmIsOn(*lss)) ? LinkStatic : LinkShared;
this->CurrentLinkType = this->StartLinkType;
}
@@ -959,15 +997,16 @@ std::string cmComputeLinkInformation::CreateExtensionRegex(
std::string cmComputeLinkInformation::NoCaseExpression(const char* str)
{
std::string ret;
+ ret.reserve(strlen(str) * 4);
const char* s = str;
while (*s) {
if (*s == '.') {
ret += *s;
} else {
- ret += "[";
+ ret += '[';
ret += static_cast<char>(tolower(*s));
ret += static_cast<char>(toupper(*s));
- ret += "]";
+ ret += ']';
}
s++;
}
@@ -1024,8 +1063,8 @@ void cmComputeLinkInformation::AddTargetItem(BT<std::string> const& item,
// For compatibility with CMake 2.4 include the item's directory in
// the linker search path.
if (this->OldLinkDirMode && !target->IsFrameworkOnApple() &&
- !cmContains(this->OldLinkDirMask,
- cmSystemTools::GetFilenamePath(item.Value))) {
+ !cm::contains(this->OldLinkDirMask,
+ cmSystemTools::GetFilenamePath(item.Value))) {
this->OldLinkDirItems.push_back(item.Value);
}
@@ -1078,8 +1117,8 @@ void cmComputeLinkInformation::AddFullItem(BT<std::string> const& item)
// For compatibility with CMake 2.4 include the item's directory in
// the linker search path.
if (this->OldLinkDirMode &&
- !cmContains(this->OldLinkDirMask,
- cmSystemTools::GetFilenamePath(item.Value))) {
+ !cm::contains(this->OldLinkDirMask,
+ cmSystemTools::GetFilenamePath(item.Value))) {
this->OldLinkDirItems.push_back(item.Value);
}
@@ -1098,7 +1137,7 @@ bool cmComputeLinkInformation::CheckImplicitDirItem(std::string const& item)
// Check if this item is in an implicit link directory.
std::string dir = cmSystemTools::GetFilenamePath(item);
- if (!cmContains(this->ImplicitLinkDirs, dir)) {
+ if (!cm::contains(this->ImplicitLinkDirs, dir)) {
// Only libraries in implicit link directories are converted to
// pathless items.
return false;
@@ -1161,7 +1200,8 @@ void cmComputeLinkInformation::AddUserItem(BT<std::string> const& item,
// CMP0003 so put it in OldUserFlagItems, if it is not a -l
// or -Wl,-l (-framework -pthread), then allow it without a
// CMP0003 as -L will not affect those other linker flags
- if (item.Value.find("-l") == 0 || item.Value.find("-Wl,-l") == 0) {
+ if (cmHasLiteralPrefix(item.Value, "-l") ||
+ cmHasLiteralPrefix(item.Value, "-Wl,-l")) {
// This is a linker option provided by the user.
this->OldUserFlagItems.push_back(item.Value);
}
@@ -1400,7 +1440,6 @@ void cmComputeLinkInformation::HandleBadFullItem(std::string const& item,
}
case cmPolicies::OLD:
// OLD behavior does not warn.
- break;
case cmPolicies::NEW:
// NEW behavior will not get here.
break;
@@ -1757,11 +1796,11 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
// support or if using the link path as an rpath.
if (use_build_rpath) {
std::string d = ri;
- if (!rootPath.empty() && d.find(rootPath) == 0) {
- d = d.substr(rootPath.size());
- } else if (stagePath && *stagePath && d.find(stagePath) == 0) {
- std::string suffix = d.substr(strlen(stagePath));
- d = cmStrCat(installPrefix, '/', suffix);
+ if (!rootPath.empty() && cmHasPrefix(d, rootPath)) {
+ d.erase(0, rootPath.size());
+ } else if (stagePath && *stagePath && cmHasPrefix(d, stagePath)) {
+ d.erase(0, strlen(stagePath));
+ d = cmStrCat(installPrefix, '/', d);
cmSystemTools::ConvertToUnixSlashes(d);
} else if (use_relative_build_rpath) {
// If expansion of the $ORIGIN token is supported and permitted per
@@ -1788,11 +1827,11 @@ void cmComputeLinkInformation::GetRPath(std::vector<std::string>& runtimeDirs,
!cmSystemTools::IsSubDirectory(ri, topSourceDir) &&
!cmSystemTools::IsSubDirectory(ri, topBinaryDir)) {
std::string d = ri;
- if (!rootPath.empty() && d.find(rootPath) == 0) {
- d = d.substr(rootPath.size());
- } else if (stagePath && *stagePath && d.find(stagePath) == 0) {
- std::string suffix = d.substr(strlen(stagePath));
- d = cmStrCat(installPrefix, '/', suffix);
+ if (!rootPath.empty() && cmHasPrefix(d, rootPath)) {
+ d.erase(0, rootPath.size());
+ } else if (stagePath && *stagePath && cmHasPrefix(d, stagePath)) {
+ d.erase(0, strlen(stagePath));
+ d = cmStrCat(installPrefix, '/', d);
cmSystemTools::ConvertToUnixSlashes(d);
}
if (emitted.insert(d).second) {
diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h
index ee74ccd..e50d369 100644
--- a/Source/cmComputeLinkInformation.h
+++ b/Source/cmComputeLinkInformation.h
@@ -6,6 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <iosfwd>
+#include <memory>
#include <set>
#include <string>
#include <utility>
@@ -29,6 +30,9 @@ class cmComputeLinkInformation
public:
cmComputeLinkInformation(cmGeneratorTarget const* target,
const std::string& config);
+ cmComputeLinkInformation(const cmComputeLinkInformation&) = delete;
+ cmComputeLinkInformation& operator=(const cmComputeLinkInformation&) =
+ delete;
~cmComputeLinkInformation();
bool Compute();
@@ -166,7 +170,7 @@ private:
cmsys::RegularExpression SplitFramework;
// Linker search path computation.
- cmOrderDirectories* OrderLinkerSearchPath;
+ std::unique_ptr<cmOrderDirectories> OrderLinkerSearchPath;
bool FinishLinkerSearchDirectories();
void PrintLinkPolicyDiagnosis(std::ostream&);
@@ -174,6 +178,7 @@ private:
void LoadImplicitLinkInfo();
void AddImplicitLinkInfo();
void AddImplicitLinkInfo(std::string const& lang);
+ void AddRuntimeLinkLibrary(std::string const& lang);
std::set<std::string> ImplicitLinkDirs;
std::set<std::string> ImplicitLinkLibs;
@@ -186,9 +191,9 @@ private:
std::vector<std::string> OldUserFlagItems;
std::set<std::string> CMP0060WarnItems;
// Dependent library path computation.
- cmOrderDirectories* OrderDependentRPath;
+ std::unique_ptr<cmOrderDirectories> OrderDependentRPath;
// Runtime path computation.
- cmOrderDirectories* OrderRuntimeSearchPath;
+ std::unique_ptr<cmOrderDirectories> OrderRuntimeSearchPath;
bool OldLinkDirMode;
bool OpenBSD;
diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx
index 162bab2..41f5346 100644
--- a/Source/cmComputeTargetDepends.cxx
+++ b/Source/cmComputeTargetDepends.cxx
@@ -4,6 +4,7 @@
#include <cassert>
#include <cstdio>
+#include <memory>
#include <sstream>
#include <utility>
@@ -150,6 +151,7 @@ void cmComputeTargetDepends::GetTargetDirectDepends(cmGeneratorTarget const* t,
cmGeneratorTarget const* dep = this->Targets[ni];
auto di = deps.insert(dep).first;
di->SetType(ni.IsStrong());
+ di->SetCross(ni.IsCross());
di->SetBacktrace(ni.GetBacktrace());
}
}
@@ -157,15 +159,12 @@ void cmComputeTargetDepends::GetTargetDirectDepends(cmGeneratorTarget const* t,
void cmComputeTargetDepends::CollectTargets()
{
// Collect all targets from all generators.
- std::vector<cmLocalGenerator*> const& lgens =
- this->GlobalGenerator->GetLocalGenerators();
- for (cmLocalGenerator* lgen : lgens) {
- const std::vector<cmGeneratorTarget*>& targets =
- lgen->GetGeneratorTargets();
- for (cmGeneratorTarget const* ti : targets) {
+ auto const& lgens = this->GlobalGenerator->GetLocalGenerators();
+ for (const auto& lgen : lgens) {
+ for (const auto& ti : lgen->GetGeneratorTargets()) {
int index = static_cast<int>(this->Targets.size());
- this->TargetIndex[ti] = index;
- this->Targets.push_back(ti);
+ this->TargetIndex[ti.get()] = index;
+ this->Targets.push_back(ti.get());
}
}
}
@@ -199,6 +198,20 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
std::vector<std::string> const& configs =
depender->Makefile->GetGeneratorConfigs();
for (std::string const& it : configs) {
+ cmLinkImplementation const* impl = depender->GetLinkImplementation(it);
+
+ // A target should not depend on itself.
+ emitted.insert(cmLinkItem(depender, false, cmListFileBacktrace()));
+ emitted.insert(cmLinkItem(depender, true, cmListFileBacktrace()));
+ for (cmLinkImplItem const& lib : impl->Libraries) {
+ // Don't emit the same library twice for this target.
+ if (emitted.insert(lib).second) {
+ this->AddTargetDepend(depender_index, lib, true, false);
+ this->AddInterfaceDepends(depender_index, lib, it, emitted);
+ }
+ }
+
+ // Add dependencies on object libraries not otherwise handled above.
std::vector<cmSourceFile const*> objectFiles;
depender->GetExternalObjects(objectFiles, it);
for (cmSourceFile const* o : objectFiles) {
@@ -219,22 +232,10 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
return;
}
const_cast<cmGeneratorTarget*>(depender)->Target->AddUtility(
- objLib);
+ objLib, false);
}
}
}
-
- cmLinkImplementation const* impl = depender->GetLinkImplementation(it);
-
- // A target should not depend on itself.
- emitted.insert(cmLinkItem(depender, cmListFileBacktrace()));
- for (cmLinkImplItem const& lib : impl->Libraries) {
- // Don't emit the same library twice for this target.
- if (emitted.insert(lib).second) {
- this->AddTargetDepend(depender_index, lib, true);
- this->AddInterfaceDepends(depender_index, lib, it, emitted);
- }
- }
}
}
@@ -243,11 +244,12 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
std::set<cmLinkItem> const& tutils = depender->GetUtilityItems();
std::set<cmLinkItem> emitted;
// A target should not depend on itself.
- emitted.insert(cmLinkItem(depender, cmListFileBacktrace()));
+ emitted.insert(cmLinkItem(depender, false, cmListFileBacktrace()));
+ emitted.insert(cmLinkItem(depender, true, cmListFileBacktrace()));
for (cmLinkItem const& litem : tutils) {
// Don't emit the same utility twice for this target.
if (emitted.insert(litem).second) {
- this->AddTargetDepend(depender_index, litem, false);
+ this->AddTargetDepend(depender_index, litem, false, litem.Cross);
}
}
}
@@ -269,7 +271,7 @@ void cmComputeTargetDepends::AddInterfaceDepends(
// code in the project that caused this dependency to be added.
cmLinkItem libBT = lib;
libBT.Backtrace = dependee_backtrace;
- this->AddTargetDepend(depender_index, libBT, true);
+ this->AddTargetDepend(depender_index, libBT, true, false);
this->AddInterfaceDepends(depender_index, libBT, config, emitted);
}
}
@@ -292,7 +294,8 @@ void cmComputeTargetDepends::AddInterfaceDepends(
if (dependee) {
// A target should not depend on itself.
- emitted.insert(cmLinkItem(depender, cmListFileBacktrace()));
+ emitted.insert(cmLinkItem(depender, false, cmListFileBacktrace()));
+ emitted.insert(cmLinkItem(depender, true, cmListFileBacktrace()));
this->AddInterfaceDepends(depender_index, dependee,
dependee_name.Backtrace, config, emitted);
}
@@ -300,7 +303,7 @@ void cmComputeTargetDepends::AddInterfaceDepends(
void cmComputeTargetDepends::AddTargetDepend(int depender_index,
cmLinkItem const& dependee_name,
- bool linking)
+ bool linking, bool cross)
{
// Get the depender.
cmGeneratorTarget const* depender = this->Targets[depender_index];
@@ -345,13 +348,13 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index,
if (dependee) {
this->AddTargetDepend(depender_index, dependee, dependee_name.Backtrace,
- linking);
+ linking, cross);
}
}
void cmComputeTargetDepends::AddTargetDepend(
int depender_index, cmGeneratorTarget const* dependee,
- cmListFileBacktrace const& dependee_backtrace, bool linking)
+ cmListFileBacktrace const& dependee_backtrace, bool linking, bool cross)
{
if (dependee->IsImported() ||
dependee->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
@@ -361,7 +364,7 @@ void cmComputeTargetDepends::AddTargetDepend(
for (cmLinkItem const& i : utils) {
if (cmGeneratorTarget const* transitive_dependee = i.Target) {
this->AddTargetDepend(depender_index, transitive_dependee, i.Backtrace,
- false);
+ false, i.Cross);
}
}
} else {
@@ -373,7 +376,7 @@ void cmComputeTargetDepends::AddTargetDepend(
// Add this entry to the dependency graph.
this->InitialGraph[depender_index].emplace_back(dependee_index, !linking,
- dependee_backtrace);
+ cross, dependee_backtrace);
}
}
@@ -507,7 +510,8 @@ bool cmComputeTargetDepends::IntraComponent(std::vector<int> const& cmap,
for (cmGraphEdge const& edge : el) {
int j = edge;
if (cmap[j] == c && edge.IsStrong()) {
- this->FinalGraph[i].emplace_back(j, true, edge.GetBacktrace());
+ this->FinalGraph[i].emplace_back(j, true, edge.IsCross(),
+ edge.GetBacktrace());
if (!this->IntraComponent(cmap, c, j, head, emitted, visited)) {
return false;
}
@@ -516,7 +520,8 @@ bool cmComputeTargetDepends::IntraComponent(std::vector<int> const& cmap,
// Prepend to a linear linked-list of intra-component edges.
if (*head >= 0) {
- this->FinalGraph[i].emplace_back(*head, false, cmListFileBacktrace());
+ this->FinalGraph[i].emplace_back(*head, false, false,
+ cmListFileBacktrace());
} else {
this->ComponentTail[c] = i;
}
@@ -566,7 +571,8 @@ bool cmComputeTargetDepends::ComputeFinalDepends(
int dependee_component = ni;
int dependee_component_head = this->ComponentHead[dependee_component];
this->FinalGraph[depender_component_tail].emplace_back(
- dependee_component_head, ni.IsStrong(), ni.GetBacktrace());
+ dependee_component_head, ni.IsStrong(), ni.IsCross(),
+ ni.GetBacktrace());
}
}
return true;
diff --git a/Source/cmComputeTargetDepends.h b/Source/cmComputeTargetDepends.h
index d8060ae..e0d625f 100644
--- a/Source/cmComputeTargetDepends.h
+++ b/Source/cmComputeTargetDepends.h
@@ -46,10 +46,10 @@ private:
void CollectDepends();
void CollectTargetDepends(int depender_index);
void AddTargetDepend(int depender_index, cmLinkItem const& dependee_name,
- bool linking);
+ bool linking, bool cross);
void AddTargetDepend(int depender_index, cmGeneratorTarget const* dependee,
cmListFileBacktrace const& dependee_backtrace,
- bool linking);
+ bool linking, bool cross);
bool ComputeFinalDepends(cmComputeComponentGraph const& ccg);
void AddInterfaceDepends(int depender_index, cmLinkItem const& dependee_name,
const std::string& config,
diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx
index 003e60d..7a3a3e8 100644
--- a/Source/cmConditionEvaluator.cxx
+++ b/Source/cmConditionEvaluator.cxx
@@ -9,9 +9,10 @@
#include <sstream>
#include <utility>
+#include <cmext/algorithm>
+
#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmState.h"
@@ -396,7 +397,7 @@ bool cmConditionEvaluator::HandleLevel0(cmArgumentList& newArgs,
// copy to the list structure
auto argP1 = arg;
argP1++;
- cmAppend(newArgs2, argP1, argClose);
+ cm::append(newArgs2, argP1, argClose);
newArgs2.pop_back();
// now recursively invoke IsTrue to handle the values inside the
// parenthetical expression
@@ -492,12 +493,12 @@ bool cmConditionEvaluator::HandleLevel1(cmArgumentList& newArgs, std::string&,
if (this->IsKeyword(keyDEFINED, *arg) && argP1 != newArgs.end()) {
size_t argP1len = argP1->GetValue().size();
bool bdef = false;
- if (argP1len > 4 && argP1->GetValue().substr(0, 4) == "ENV{" &&
+ if (argP1len > 4 && cmHasLiteralPrefix(argP1->GetValue(), "ENV{") &&
argP1->GetValue().operator[](argP1len - 1) == '}') {
std::string env = argP1->GetValue().substr(4, argP1len - 5);
bdef = cmSystemTools::HasEnv(env);
} else if (argP1len > 6 &&
- argP1->GetValue().substr(0, 6) == "CACHE{" &&
+ cmHasLiteralPrefix(argP1->GetValue(), "CACHE{") &&
argP1->GetValue().operator[](argP1len - 1) == '}') {
std::string cache = argP1->GetValue().substr(6, argP1len - 7);
bdef =
@@ -671,7 +672,7 @@ bool cmConditionEvaluator::HandleLevel2(cmArgumentList& newArgs,
if (def2) {
std::vector<std::string> list = cmExpandedList(def2, true);
- result = cmContains(list, def);
+ result = cm::contains(list, def);
}
this->HandleBinaryOp(result, reducible, arg, newArgs, argP1, argP2);
diff --git a/Source/cmConfigureFileCommand.cxx b/Source/cmConfigureFileCommand.cxx
index 8767386..5b3045d 100644
--- a/Source/cmConfigureFileCommand.cxx
+++ b/Source/cmConfigureFileCommand.cxx
@@ -2,6 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmConfigureFileCommand.h"
+#include <set>
+
+#include <cm/string_view>
+#include <cmext/string_view>
+
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -56,6 +61,18 @@ bool cmConfigureFileCommand(std::vector<std::string> const& args,
bool copyOnly = false;
bool escapeQuotes = false;
+ static std::set<cm::string_view> noopOptions = {
+ /* Legacy. */
+ "IMMEDIATE"_s,
+ /* Handled by NewLineStyle member. */
+ "NEWLINE_STYLE"_s,
+ "LF"_s,
+ "UNIX"_s,
+ "CRLF"_s,
+ "WIN32"_s,
+ "DOS"_s,
+ };
+
std::string unknown_args;
bool atOnly = false;
for (unsigned int i = 2; i < args.size(); ++i) {
@@ -70,12 +87,8 @@ bool cmConfigureFileCommand(std::vector<std::string> const& args,
escapeQuotes = true;
} else if (args[i] == "@ONLY") {
atOnly = true;
- } else if (args[i] == "IMMEDIATE") {
- /* Ignore legacy option. */
- } else if (args[i] == "NEWLINE_STYLE" || args[i] == "LF" ||
- args[i] == "UNIX" || args[i] == "CRLF" || args[i] == "WIN32" ||
- args[i] == "DOS") {
- /* Options handled by NewLineStyle member above. */
+ } else if (noopOptions.find(args[i]) != noopOptions.end()) {
+ /* Ignore no-op options. */
} else {
unknown_args += " ";
unknown_args += args[i];
diff --git a/Source/cmConnection.cxx b/Source/cmConnection.cxx
index 884e314..e4d0cf1 100644
--- a/Source/cmConnection.cxx
+++ b/Source/cmConnection.cxx
@@ -5,7 +5,7 @@
#include <cassert>
#include <cstring>
-#include "cm_uv.h"
+#include <cm3p/uv.h>
#include "cmServer.h"
@@ -20,8 +20,13 @@ void cmEventBasedConnection::on_alloc_buffer(uv_handle_t* handle,
uv_buf_t* buf)
{
(void)(handle);
+#ifndef __clang_analyzer__
char* rawBuffer = new char[suggested_size];
*buf = uv_buf_init(rawBuffer, static_cast<unsigned int>(suggested_size));
+#else
+ (void)(suggested_size);
+ (void)(buf);
+#endif /* __clang_analyzer__ */
}
void cmEventBasedConnection::on_read(uv_stream_t* stream, ssize_t nread,
@@ -76,6 +81,7 @@ void cmEventBasedConnection::WriteData(const std::string& _data)
assert(uv_thread_equal(&curr_thread_id, &this->Server->ServeThreadId));
#endif
+#ifndef __clang_analyzer__
auto data = _data;
assert(this->WriteStream.get());
if (BufferStrategy) {
@@ -90,6 +96,9 @@ void cmEventBasedConnection::WriteData(const std::string& _data)
memcpy(req->buf.base, data.c_str(), ds);
uv_write(reinterpret_cast<uv_write_t*>(req), this->WriteStream, &req->buf, 1,
on_write);
+#else
+ (void)(_data);
+#endif /* __clang_analyzer__ */
}
void cmEventBasedConnection::ReadData(const std::string& data)
diff --git a/Source/cmConnection.h b/Source/cmConnection.h
index 7bb2494..5335a7f 100644
--- a/Source/cmConnection.h
+++ b/Source/cmConnection.h
@@ -9,7 +9,7 @@
#include <memory>
#include <string>
-#include "cm_uv.h"
+#include <cm3p/uv.h>
#include "cmUVHandlePtr.h"
diff --git a/Source/cmConvertMSBuildXMLToJSON.py b/Source/cmConvertMSBuildXMLToJSON.py
index 02074ba..2be3781 100644
--- a/Source/cmConvertMSBuildXMLToJSON.py
+++ b/Source/cmConvertMSBuildXMLToJSON.py
@@ -35,12 +35,14 @@ def vsflags(*args):
return values
-def read_msbuild_xml(path, values={}):
+def read_msbuild_xml(path, values=None):
"""Reads the MS Build XML file at the path and returns its contents.
Keyword arguments:
values -- The map to append the contents to (default {})
"""
+ if values is None:
+ values = {}
# Attempt to read the file contents
try:
@@ -76,12 +78,15 @@ def read_msbuild_xml(path, values={}):
return values
-def read_msbuild_json(path, values=[]):
+def read_msbuild_json(path, values=None):
"""Reads the MS Build JSON file at the path and returns its contents.
Keyword arguments:
values -- The list to append the contents to (default [])
"""
+ if values is None:
+ values = []
+
if not os.path.exists(path):
logging.info('Could not find MS Build JSON file at %s', path)
return values
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index 5711cae..4e2caed 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -8,9 +8,9 @@
#include <sstream>
#include <utility>
-#include "cmsys/Directory.hxx"
+#include <cmext/string_view>
-#include "cm_static_string_view.hxx"
+#include "cmsys/Directory.hxx"
#include "cmExportTryCompileFileGenerator.h"
#include "cmGlobalGenerator.h"
@@ -40,6 +40,10 @@ static std::string const kCMAKE_CXX_LINK_NO_PIE_SUPPORTED =
"CMAKE_CXX_LINK_NO_PIE_SUPPORTED";
static std::string const kCMAKE_CXX_LINK_PIE_SUPPORTED =
"CMAKE_CXX_LINK_PIE_SUPPORTED";
+static std::string const kCMAKE_CUDA_ARCHITECTURES =
+ "CMAKE_CUDA_ARCHITECTURES";
+static std::string const kCMAKE_CUDA_COMPILER_TARGET =
+ "CMAKE_CUDA_COMPILER_TARGET";
static std::string const kCMAKE_ENABLE_EXPORTS = "CMAKE_ENABLE_EXPORTS";
static std::string const kCMAKE_LINK_SEARCH_END_STATIC =
"CMAKE_LINK_SEARCH_END_STATIC";
@@ -51,6 +55,8 @@ static std::string const kCMAKE_OSX_ARCHITECTURES = "CMAKE_OSX_ARCHITECTURES";
static std::string const kCMAKE_OSX_DEPLOYMENT_TARGET =
"CMAKE_OSX_DEPLOYMENT_TARGET";
static std::string const kCMAKE_OSX_SYSROOT = "CMAKE_OSX_SYSROOT";
+static std::string const kCMAKE_APPLE_ARCH_SYSROOTS =
+ "CMAKE_APPLE_ARCH_SYSROOTS";
static std::string const kCMAKE_POSITION_INDEPENDENT_CODE =
"CMAKE_POSITION_INDEPENDENT_CODE";
static std::string const kCMAKE_SYSROOT = "CMAKE_SYSROOT";
@@ -99,29 +105,23 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
this->SrcFileSignature = true;
cmStateEnums::TargetType targetType = cmStateEnums::EXECUTABLE;
- const char* tt =
- this->Makefile->GetDefinition("CMAKE_TRY_COMPILE_TARGET_TYPE");
- if (!isTryRun && tt && *tt) {
- if (strcmp(tt, cmState::GetTargetTypeName(cmStateEnums::EXECUTABLE)) ==
- 0) {
+ const std::string* tt =
+ this->Makefile->GetDef("CMAKE_TRY_COMPILE_TARGET_TYPE");
+ if (!isTryRun && tt && !tt->empty()) {
+ if (*tt == cmState::GetTargetTypeName(cmStateEnums::EXECUTABLE)) {
targetType = cmStateEnums::EXECUTABLE;
- } else if (strcmp(tt,
- cmState::GetTargetTypeName(
- cmStateEnums::STATIC_LIBRARY)) == 0) {
+ } else if (*tt ==
+ cmState::GetTargetTypeName(cmStateEnums::STATIC_LIBRARY)) {
targetType = cmStateEnums::STATIC_LIBRARY;
} else {
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
- std::string("Invalid value '") + tt +
- "' for "
- "CMAKE_TRY_COMPILE_TARGET_TYPE. Only "
- "'" +
- cmState::GetTargetTypeName(cmStateEnums::EXECUTABLE) +
- "' and "
- "'" +
- cmState::GetTargetTypeName(cmStateEnums::STATIC_LIBRARY) +
- "' "
- "are allowed.");
+ 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;
}
}
@@ -294,12 +294,10 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
default:
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
- "Only libraries may be used as try_compile or try_run IMPORTED "
- "LINK_LIBRARIES. Got " +
- std::string(tgt->GetName()) +
- " of "
- "type " +
- cmState::GetTargetTypeName(tgt->GetType()) + ".");
+ cmStrCat("Only libraries may be used as try_compile or try_run "
+ "IMPORTED LINK_LIBRARIES. Got ",
+ tgt->GetName(), " of type ",
+ cmState::GetTargetTypeName(tgt->GetType()), "."));
return -1;
}
if (tgt->IsImported()) {
@@ -717,12 +715,15 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
vars.insert(kCMAKE_C_COMPILER_TARGET);
vars.insert(kCMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN);
vars.insert(kCMAKE_CXX_COMPILER_TARGET);
+ vars.insert(kCMAKE_CUDA_ARCHITECTURES);
+ vars.insert(kCMAKE_CUDA_COMPILER_TARGET);
vars.insert(kCMAKE_ENABLE_EXPORTS);
vars.insert(kCMAKE_LINK_SEARCH_END_STATIC);
vars.insert(kCMAKE_LINK_SEARCH_START_STATIC);
vars.insert(kCMAKE_OSX_ARCHITECTURES);
vars.insert(kCMAKE_OSX_DEPLOYMENT_TARGET);
vars.insert(kCMAKE_OSX_SYSROOT);
+ vars.insert(kCMAKE_APPLE_ARCH_SYSROOTS);
vars.insert(kCMAKE_POSITION_INDEPENDENT_CODE);
vars.insert(kCMAKE_SYSROOT);
vars.insert(kCMAKE_SYSROOT_COMPILE);
@@ -1042,7 +1043,9 @@ void cmCoreTryCompile::CleanupFiles(std::string const& binDir)
if (deletedFiles.insert(fileName).second) {
std::string const fullPath =
std::string(binDir).append("/").append(fileName);
- if (cmSystemTools::FileIsDirectory(fullPath)) {
+ if (cmSystemTools::FileIsSymlink(fullPath)) {
+ cmSystemTools::RemoveFile(fullPath);
+ } else if (cmSystemTools::FileIsDirectory(fullPath)) {
this->CleanupFiles(fullPath);
cmSystemTools::RemoveADirectory(fullPath);
} else {
diff --git a/Source/cmCryptoHash.cxx b/Source/cmCryptoHash.cxx
index dc7d939..b1e63ba 100644
--- a/Source/cmCryptoHash.cxx
+++ b/Source/cmCryptoHash.cxx
@@ -4,10 +4,10 @@
#include <cm/memory>
-#include "cmsys/FStream.hxx"
+#include <cm3p/kwiml/int.h>
+#include <cm3p/rhash.h>
-#include "cm_kwiml.h"
-#include "cm_rhash.h"
+#include "cmsys/FStream.hxx"
static unsigned int const cmCryptoHashAlgoToId[] = {
/* clang-format needs this comment to break after the opening brace */
diff --git a/Source/cmCurl.h b/Source/cmCurl.h
index cb73ce6..7bd036e 100644
--- a/Source/cmCurl.h
+++ b/Source/cmCurl.h
@@ -7,7 +7,7 @@
#include <string>
-#include "cm_curl.h"
+#include <cm3p/curl/curl.h>
std::string cmCurlSetCAInfo(::CURL* curl, const char* cafile = nullptr);
std::string cmCurlSetNETRCOption(::CURL* curl, const std::string& netrc_level,
diff --git a/Source/cmCustomCommand.cxx b/Source/cmCustomCommand.cxx
index 09d269b..149f5e9 100644
--- a/Source/cmCustomCommand.cxx
+++ b/Source/cmCustomCommand.cxx
@@ -4,27 +4,25 @@
#include <utility>
-#include "cmAlgorithms.h"
-#include "cmMakefile.h"
+#include <cmext/algorithm>
-cmCustomCommand::cmCustomCommand(cmMakefile const* mf,
- std::vector<std::string> outputs,
+cmCustomCommand::cmCustomCommand(std::vector<std::string> outputs,
std::vector<std::string> byproducts,
std::vector<std::string> depends,
cmCustomCommandLines commandLines,
- const char* comment,
- const char* workingDirectory)
+ cmListFileBacktrace lfbt, const char* comment,
+ const char* workingDirectory,
+ bool stdPipesUTF8)
: Outputs(std::move(outputs))
, Byproducts(std::move(byproducts))
, Depends(std::move(depends))
, CommandLines(std::move(commandLines))
+ , Backtrace(std::move(lfbt))
, Comment(comment ? comment : "")
, WorkingDirectory(workingDirectory ? workingDirectory : "")
, HaveComment(comment != nullptr)
+ , StdPipesUTF8(stdPipesUTF8)
{
- if (mf) {
- this->Backtrace = mf->GetBacktrace();
- }
}
const std::vector<std::string>& cmCustomCommand::GetOutputs() const
@@ -55,12 +53,12 @@ const char* cmCustomCommand::GetComment() const
void cmCustomCommand::AppendCommands(const cmCustomCommandLines& commandLines)
{
- cmAppend(this->CommandLines, commandLines);
+ cm::append(this->CommandLines, commandLines);
}
void cmCustomCommand::AppendDepends(const std::vector<std::string>& depends)
{
- cmAppend(this->Depends, depends);
+ cm::append(this->Depends, depends);
}
bool cmCustomCommand::GetEscapeOldStyle() const
@@ -100,7 +98,7 @@ void cmCustomCommand::SetImplicitDepends(cmImplicitDependsList const& l)
void cmCustomCommand::AppendImplicitDepends(cmImplicitDependsList const& l)
{
- cmAppend(this->ImplicitDepends, l);
+ cm::append(this->ImplicitDepends, l);
}
bool cmCustomCommand::GetUsesTerminal() const
diff --git a/Source/cmCustomCommand.h b/Source/cmCustomCommand.h
index 4689ace..aa572ad 100644
--- a/Source/cmCustomCommand.h
+++ b/Source/cmCustomCommand.h
@@ -12,8 +12,6 @@
#include "cmCustomCommandLines.h"
#include "cmListFileCache.h"
-class cmMakefile;
-
class cmImplicitDependsList
: public std::vector<std::pair<std::string, std::string>>
{
@@ -28,11 +26,12 @@ class cmCustomCommand
{
public:
/** Main constructor specifies all information for the command. */
- cmCustomCommand(cmMakefile const* mf, std::vector<std::string> outputs,
+ cmCustomCommand(std::vector<std::string> outputs,
std::vector<std::string> byproducts,
std::vector<std::string> depends,
- cmCustomCommandLines commandLines, const char* comment,
- const char* workingDirectory);
+ cmCustomCommandLines commandLines, cmListFileBacktrace lfbt,
+ const char* comment, const char* workingDirectory,
+ bool stdPipesUTF8);
/** Get the output file produced by the command. */
const std::vector<std::string>& GetOutputs() const;
@@ -55,6 +54,9 @@ public:
/** Get the comment string for the command. */
const char* GetComment() const;
+ /** Get a value indicating if the command uses UTF-8 output pipes. */
+ bool GetStdPipesUTF8() const { return this->StdPipesUTF8; }
+
/** Append to the list of command lines. */
void AppendCommands(const cmCustomCommandLines& commandLines);
@@ -110,6 +112,7 @@ private:
bool EscapeOldStyle = true;
bool UsesTerminal = false;
bool CommandExpandLists = false;
+ bool StdPipesUTF8 = false;
};
#endif
diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx
index c1f412d..0fe19b6 100644
--- a/Source/cmCustomCommandGenerator.cxx
+++ b/Source/cmCustomCommandGenerator.cxx
@@ -6,7 +6,8 @@
#include <memory>
#include <utility>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmCustomCommand.h"
#include "cmCustomCommandLines.h"
#include "cmGeneratorExpression.h"
@@ -29,10 +30,11 @@ void AppendPaths(const std::vector<std::string>& inputs,
for (std::string& it : result) {
cmSystemTools::ConvertToUnixSlashes(it);
if (cmSystemTools::FileIsFullPath(it)) {
- it = cmSystemTools::CollapseFullPath(it);
+ it = cmSystemTools::CollapseFullPath(
+ it, lg->GetMakefile()->GetHomeOutputDirectory());
}
}
- cmAppend(output, result);
+ cm::append(output, result);
}
}
}
@@ -56,7 +58,7 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(cmCustomCommand const& cc,
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(clarg);
std::string parsed_arg = cge->Evaluate(this->LG, this->Config);
if (this->CC.GetCommandExpandLists()) {
- cmAppend(argv, cmExpandedList(parsed_arg));
+ cm::append(argv, cmExpandedList(parsed_arg));
} else {
argv.push_back(std::move(parsed_arg));
}
@@ -109,13 +111,13 @@ void cmCustomCommandGenerator::FillEmulatorsWithArguments()
if (target && target->GetType() == cmStateEnums::EXECUTABLE &&
!target->IsImported()) {
- const char* emulator_property =
+ cmProp emulator_property =
target->GetProperty("CROSSCOMPILING_EMULATOR");
if (!emulator_property) {
continue;
}
- cmExpandList(emulator_property, this->EmulatorsWithArguments[c]);
+ cmExpandList(*emulator_property, this->EmulatorsWithArguments[c]);
}
}
}
@@ -137,7 +139,7 @@ const char* cmCustomCommandGenerator::GetArgv0Location(unsigned int c) const
(target->IsImported() ||
target->GetProperty("CROSSCOMPILING_EMULATOR") ||
!this->LG->GetMakefile()->IsOn("CMAKE_CROSSCOMPILING"))) {
- return target->GetLocation(this->Config);
+ return target->GetLocation(this->Config).c_str();
}
return nullptr;
}
@@ -201,7 +203,9 @@ void cmCustomCommandGenerator::AppendArguments(unsigned int c,
if (this->OldStyle) {
cmd += escapeForShellOldStyle(emulator[j]);
} else {
- cmd += this->LG->EscapeForShell(emulator[j], this->MakeVars);
+ cmd +=
+ this->LG->EscapeForShell(emulator[j], this->MakeVars, false, false,
+ this->MakeVars && this->LG->IsNinjaMulti());
}
}
@@ -222,7 +226,9 @@ void cmCustomCommandGenerator::AppendArguments(unsigned int c,
if (this->OldStyle) {
cmd += escapeForShellOldStyle(arg);
} else {
- cmd += this->LG->EscapeForShell(arg, this->MakeVars);
+ cmd +=
+ this->LG->EscapeForShell(arg, this->MakeVars, false, false,
+ this->MakeVars && this->LG->IsNinjaMulti());
}
}
}
diff --git a/Source/cmDefinePropertyCommand.cxx b/Source/cmDefinePropertyCommand.cxx
index f4e4fda..4e2d9b0 100644
--- a/Source/cmDefinePropertyCommand.cxx
+++ b/Source/cmDefinePropertyCommand.cxx
@@ -95,7 +95,7 @@ bool cmDefinePropertyCommand(std::vector<std::string> const& args,
// Actually define the property.
status.GetMakefile().GetState()->DefineProperty(
- PropertyName, scope, BriefDocs.c_str(), FullDocs.c_str(), inherited);
+ PropertyName, scope, BriefDocs, FullDocs, inherited);
return true;
}
diff --git a/Source/cmDepends.cxx b/Source/cmDepends.cxx
index 129a5f7..d8aa730 100644
--- a/Source/cmDepends.cxx
+++ b/Source/cmDepends.cxx
@@ -2,7 +2,6 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmDepends.h"
-#include <sstream>
#include <utility>
#include "cmsys/FStream.hxx"
@@ -10,12 +9,12 @@
#include "cmFileTime.h"
#include "cmFileTimeCache.h"
#include "cmGeneratedFileStream.h"
-#include "cmLocalGenerator.h"
+#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-cmDepends::cmDepends(cmLocalGenerator* lg, std::string targetDir)
+cmDepends::cmDepends(cmLocalUnixMakefileGenerator3* lg, std::string targetDir)
: LocalGenerator(lg)
, TargetDirectory(std::move(targetDir))
{
@@ -81,16 +80,14 @@ void cmDepends::Clear(const std::string& file)
{
// Print verbose output.
if (this->Verbose) {
- std::ostringstream msg;
- msg << "Clearing dependencies in \"" << file << "\"." << std::endl;
- cmSystemTools::Stdout(msg.str());
+ cmSystemTools::Stdout(
+ cmStrCat("Clearing dependencies in \"", file, "\".\n"));
}
// Write an empty dependency file.
cmGeneratedFileStream depFileStream(file);
depFileStream << "# Empty dependencies file\n"
- << "# This may be replaced when dependencies are built."
- << std::endl;
+ "# This may be replaced when dependencies are built.\n";
}
bool cmDepends::WriteDependencies(const std::set<std::string>& /*unused*/,
@@ -172,10 +169,9 @@ bool cmDepends::CheckDependencies(std::istream& internalDepends,
// Print verbose output.
if (this->Verbose) {
- std::ostringstream msg;
- msg << "Dependee \"" << dependee << "\" does not exist for depender \""
- << depender << "\"." << std::endl;
- cmSystemTools::Stdout(msg.str());
+ cmSystemTools::Stdout(cmStrCat("Dependee \"", dependee,
+ "\" does not exist for depender \"",
+ depender, "\".\n"));
}
} else if (dependerExists) {
// The dependee and depender both exist. Compare file times.
@@ -185,10 +181,9 @@ bool cmDepends::CheckDependencies(std::istream& internalDepends,
// Print verbose output.
if (this->Verbose) {
- std::ostringstream msg;
- msg << "Dependee \"" << dependee << "\" is newer than depender \""
- << depender << "\"." << std::endl;
- cmSystemTools::Stdout(msg.str());
+ cmSystemTools::Stdout(cmStrCat("Dependee \"", dependee,
+ "\" is newer than depender \"",
+ depender, "\".\n"));
}
}
} else {
@@ -200,11 +195,9 @@ bool cmDepends::CheckDependencies(std::istream& internalDepends,
// Print verbose output.
if (this->Verbose) {
- std::ostringstream msg;
- msg << "Dependee \"" << dependee
- << "\" is newer than depends file \"" << internalDependsFileName
- << "\"." << std::endl;
- cmSystemTools::Stdout(msg.str());
+ cmSystemTools::Stdout(cmStrCat("Dependee \"", dependee,
+ "\" is newer than depends file \"",
+ internalDependsFileName, "\".\n"));
}
}
}
diff --git a/Source/cmDepends.h b/Source/cmDepends.h
index d938775..8cf528f 100644
--- a/Source/cmDepends.h
+++ b/Source/cmDepends.h
@@ -12,7 +12,7 @@
#include <vector>
class cmFileTimeCache;
-class cmLocalGenerator;
+class cmLocalUnixMakefileGenerator3;
/** \class cmDepends
* \brief Dependency scanner superclass.
@@ -29,7 +29,8 @@ public:
public:
/** Instances need to know the build directory name and the relative
path from the build directory to the target file. */
- cmDepends(cmLocalGenerator* lg = nullptr, std::string targetDir = "");
+ cmDepends(cmLocalUnixMakefileGenerator3* lg = nullptr,
+ std::string targetDir = "");
cmDepends(cmDepends const&) = delete;
cmDepends& operator=(cmDepends const&) = delete;
@@ -38,7 +39,10 @@ public:
scanning dependencies. This is not a full local generator; it
has been setup to do relative path conversions for the current
directory. */
- void SetLocalGenerator(cmLocalGenerator* lg) { this->LocalGenerator = lg; }
+ void SetLocalGenerator(cmLocalUnixMakefileGenerator3* lg)
+ {
+ this->LocalGenerator = lg;
+ }
/** Set the specific language to be scanned. */
void SetLanguage(const std::string& lang) { this->Language = lang; }
@@ -92,7 +96,7 @@ protected:
std::ostream& internalDepends);
// The local generator.
- cmLocalGenerator* LocalGenerator;
+ cmLocalUnixMakefileGenerator3* LocalGenerator;
// Flag for verbose output.
bool Verbose = false;
diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx
index e30d959..4499a66 100644
--- a/Source/cmDependsC.cxx
+++ b/Source/cmDependsC.cxx
@@ -7,7 +7,7 @@
#include "cmsys/FStream.hxx"
#include "cmFileTime.h"
-#include "cmLocalGenerator.h"
+#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -22,8 +22,9 @@
cmDependsC::cmDependsC() = default;
-cmDependsC::cmDependsC(cmLocalGenerator* lg, const std::string& targetDir,
- const std::string& lang, const DependencyMap* validDeps)
+cmDependsC::cmDependsC(cmLocalUnixMakefileGenerator3* lg,
+ const std::string& targetDir, const std::string& lang,
+ const DependencyMap* validDeps)
: cmDepends(lg, targetDir)
, ValidDeps(validDeps)
{
@@ -211,18 +212,18 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources,
// written by the original local generator for this directory
// convert the dependencies to paths relative to the home output
// directory. We must do the same here.
- std::string obj_m = cmSystemTools::ConvertToOutputPath(obj_i);
- internalDepends << obj_i << std::endl;
+ std::string obj_m = this->LocalGenerator->ConvertToMakefilePath(obj_i);
+ internalDepends << obj_i << '\n';
for (std::string const& dep : dependencies) {
makeDepends << obj_m << ": "
- << cmSystemTools::ConvertToOutputPath(
+ << this->LocalGenerator->ConvertToMakefilePath(
this->LocalGenerator->MaybeConvertToRelativePath(binDir,
dep))
- << std::endl;
- internalDepends << " " << dep << std::endl;
+ << '\n';
+ internalDepends << ' ' << dep << '\n';
}
- makeDepends << std::endl;
+ makeDepends << '\n';
return true;
}
@@ -264,19 +265,19 @@ void cmDependsC::ReadCacheFile()
// file doesn't exist, check that the regular expressions
// haven't changed
else if (!res) {
- if (line.find(INCLUDE_REGEX_LINE_MARKER) == 0) {
+ if (cmHasLiteralPrefix(line, INCLUDE_REGEX_LINE_MARKER)) {
if (line != this->IncludeRegexLineString) {
return;
}
- } else if (line.find(INCLUDE_REGEX_SCAN_MARKER) == 0) {
+ } else if (cmHasLiteralPrefix(line, INCLUDE_REGEX_SCAN_MARKER)) {
if (line != this->IncludeRegexScanString) {
return;
}
- } else if (line.find(INCLUDE_REGEX_COMPLAIN_MARKER) == 0) {
+ } else if (cmHasLiteralPrefix(line, INCLUDE_REGEX_COMPLAIN_MARKER)) {
if (line != this->IncludeRegexComplainString) {
return;
}
- } else if (line.find(INCLUDE_REGEX_TRANSFORM_MARKER) == 0) {
+ } else if (cmHasLiteralPrefix(line, INCLUDE_REGEX_TRANSFORM_MARKER)) {
if (line != this->IncludeRegexTransformString) {
return;
}
@@ -312,17 +313,17 @@ void cmDependsC::WriteCacheFile() const
for (auto const& fileIt : this->FileCache) {
if (fileIt.second.Used) {
- cacheOut << fileIt.first << std::endl;
+ cacheOut << fileIt.first << '\n';
for (UnscannedEntry const& inc : fileIt.second.UnscannedEntries) {
- cacheOut << inc.FileName << std::endl;
+ cacheOut << inc.FileName << '\n';
if (inc.QuotedLocation.empty()) {
- cacheOut << "-" << std::endl;
+ cacheOut << '-' << '\n';
} else {
- cacheOut << inc.QuotedLocation << std::endl;
+ cacheOut << inc.QuotedLocation << '\n';
}
}
- cacheOut << std::endl;
+ cacheOut << '\n';
}
}
}
diff --git a/Source/cmDependsC.h b/Source/cmDependsC.h
index 3bb6e36..e01faa4 100644
--- a/Source/cmDependsC.h
+++ b/Source/cmDependsC.h
@@ -7,17 +7,16 @@
#include <iosfwd>
#include <map>
+#include <queue>
#include <set>
#include <string>
#include <vector>
-#include <queue>
-
#include "cmsys/RegularExpression.hxx"
#include "cmDepends.h"
-class cmLocalGenerator;
+class cmLocalUnixMakefileGenerator3;
/** \class cmDependsC
* \brief Dependency scanner for C and C++ object files.
@@ -28,7 +27,7 @@ public:
/** Checking instances need to know the build directory name and the
relative path from the build directory to the target file. */
cmDependsC();
- cmDependsC(cmLocalGenerator* lg, const std::string& targetDir,
+ cmDependsC(cmLocalUnixMakefileGenerator3* lg, const std::string& targetDir,
const std::string& lang, const DependencyMap* validDeps);
/** Virtual destructor to cleanup subclasses properly. */
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx
index 3692202..95dfc4e 100644
--- a/Source/cmDependsFortran.cxx
+++ b/Source/cmDependsFortran.cxx
@@ -12,7 +12,7 @@
#include "cmFortranParser.h" /* Interface to parser object. */
#include "cmGeneratedFileStream.h"
-#include "cmLocalGenerator.h"
+#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmOutputConverter.h"
#include "cmStateDirectory.h"
@@ -29,12 +29,10 @@ static void cmFortranModuleAppendUpperLower(std::string const& mod,
std::string& mod_lower)
{
std::string::size_type ext_len = 0;
- if (cmHasLiteralSuffix(mod, ".mod")) {
+ if (cmHasLiteralSuffix(mod, ".mod") || cmHasLiteralSuffix(mod, ".sub")) {
ext_len = 4;
} else if (cmHasLiteralSuffix(mod, ".smod")) {
ext_len = 5;
- } else if (cmHasLiteralSuffix(mod, ".sub")) {
- ext_len = 4;
}
std::string const& name = mod.substr(0, mod.size() - ext_len);
std::string const& ext = mod.substr(mod.size() - ext_len);
@@ -72,7 +70,7 @@ public:
cmDependsFortran::cmDependsFortran() = default;
-cmDependsFortran::cmDependsFortran(cmLocalGenerator* lg)
+cmDependsFortran::cmDependsFortran(cmLocalUnixMakefileGenerator3* lg)
: cmDepends(lg)
, Internal(new cmDependsFortranInternals)
{
@@ -102,10 +100,7 @@ cmDependsFortran::cmDependsFortran(cmLocalGenerator* lg)
this->SModExt = mf->GetSafeDefinition("CMAKE_Fortran_SUBMODULE_EXT");
}
-cmDependsFortran::~cmDependsFortran()
-{
- delete this->Internal;
-}
+cmDependsFortran::~cmDependsFortran() = default;
bool cmDependsFortran::WriteDependencies(const std::set<std::string>& sources,
const std::string& obj,
@@ -188,7 +183,7 @@ bool cmDependsFortran::Finalize(std::ostream& makeDepends,
fiStream << "provides\n";
std::set<std::string> const& provides = this->Internal->TargetProvides;
for (std::string const& i : provides) {
- fiStream << " " << i << "\n";
+ fiStream << ' ' << i << '\n';
}
// Create a script to clean the modules.
@@ -205,14 +200,14 @@ bool cmDependsFortran::Finalize(std::ostream& makeDepends,
std::string mod_lower = cmStrCat(mod_dir, '/');
cmFortranModuleAppendUpperLower(i, mod_upper, mod_lower);
std::string stamp = cmStrCat(stamp_dir, '/', i, ".stamp");
- fcStream << "\n";
- fcStream << " \""
+ fcStream << "\n"
+ " \""
<< this->MaybeConvertToRelativePath(currentBinDir, mod_lower)
- << "\"\n";
- fcStream << " \""
+ << "\"\n"
+ " \""
<< this->MaybeConvertToRelativePath(currentBinDir, mod_upper)
- << "\"\n";
- fcStream << " \""
+ << "\"\n"
+ " \""
<< this->MaybeConvertToRelativePath(currentBinDir, stamp)
<< "\"\n";
}
@@ -329,16 +324,15 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj,
std::string binDir = this->LocalGenerator->GetBinaryDirectory();
std::string obj_i = this->MaybeConvertToRelativePath(binDir, obj);
std::string obj_m = cmSystemTools::ConvertToOutputPath(obj_i);
- internalDepends << obj_i << std::endl;
- internalDepends << " " << src << std::endl;
+ internalDepends << obj_i << "\n " << src << '\n';
for (std::string const& i : info.Includes) {
makeDepends << obj_m << ": "
<< cmSystemTools::ConvertToOutputPath(
this->MaybeConvertToRelativePath(binDir, i))
- << std::endl;
- internalDepends << " " << i << std::endl;
+ << '\n';
+ internalDepends << ' ' << i << '\n';
}
- makeDepends << std::endl;
+ makeDepends << '\n';
// Write module requirements to the output stream.
for (std::string const& i : info.Requires) {
@@ -357,7 +351,7 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj,
// This module is known. Depend on its timestamp file.
std::string stampFile = cmSystemTools::ConvertToOutputPath(
this->MaybeConvertToRelativePath(binDir, required->second));
- makeDepends << obj_m << ": " << stampFile << "\n";
+ makeDepends << obj_m << ": " << stampFile << '\n';
} else {
// This module is not known to CMake. Try to locate it where
// the compiler will and depend on that.
@@ -365,7 +359,7 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj,
if (this->FindModule(i, module)) {
module = cmSystemTools::ConvertToOutputPath(
this->MaybeConvertToRelativePath(binDir, module));
- makeDepends << obj_m << ": " << module << "\n";
+ makeDepends << obj_m << ": " << module << '\n';
}
}
}
@@ -394,7 +388,7 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj,
cmSystemTools::ConvertToOutputPath(stampFile);
makeDepends << obj_m << ".provides.build"
- << ": " << stampFileForMake << "\n";
+ << ": " << stampFileForMake << '\n';
// Note that when cmake_copy_f90_mod finds that a module file
// and the corresponding stamp file have no differences, the stamp
// file is not updated. In such case the stamp file will be always
@@ -402,15 +396,15 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj,
// on each new build. This is expected behavior for incremental
// builds and can not be changed without preforming recursive make
// calls that would considerably slow down the building process.
- makeDepends << stampFileForMake << ": " << obj_m << "\n";
+ makeDepends << stampFileForMake << ": " << obj_m << '\n';
makeDepends << "\t$(CMAKE_COMMAND) -E cmake_copy_f90_mod " << modFile
- << " " << stampFileForShell;
+ << ' ' << stampFileForShell;
cmMakefile* mf = this->LocalGenerator->GetMakefile();
const char* cid = mf->GetDefinition("CMAKE_Fortran_COMPILER_ID");
if (cid && *cid) {
- makeDepends << " " << cid;
+ makeDepends << ' ' << cid;
}
- makeDepends << "\n";
+ makeDepends << '\n';
}
makeDepends << obj_m << ".provides.build:\n";
// After copying the modules update the timestamp file.
diff --git a/Source/cmDependsFortran.h b/Source/cmDependsFortran.h
index 0485115..3e306dd 100644
--- a/Source/cmDependsFortran.h
+++ b/Source/cmDependsFortran.h
@@ -6,6 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <iosfwd>
+#include <memory>
#include <set>
#include <string>
#include <vector>
@@ -14,7 +15,7 @@
class cmDependsFortranInternals;
class cmFortranSourceInfo;
-class cmLocalGenerator;
+class cmLocalUnixMakefileGenerator3;
/** \class cmDependsFortran
* \brief Dependency scanner for Fortran object files.
@@ -30,7 +31,7 @@ public:
path from the build directory to the target file, the source
file from which to start scanning, the include file search
path, and the target directory. */
- cmDependsFortran(cmLocalGenerator* lg);
+ cmDependsFortran(cmLocalUnixMakefileGenerator3* lg);
/** Virtual destructor to cleanup subclasses properly. */
~cmDependsFortran() override;
@@ -84,7 +85,7 @@ protected:
std::set<std::string> PPDefinitions;
// Internal implementation details.
- cmDependsFortranInternals* Internal = nullptr;
+ std::unique_ptr<cmDependsFortranInternals> Internal;
private:
std::string MaybeConvertToRelativePath(std::string const& base,
diff --git a/Source/cmDependsJavaParserHelper.cxx b/Source/cmDependsJavaParserHelper.cxx
index 516bbbf..fc1bbdd 100644
--- a/Source/cmDependsJavaParserHelper.cxx
+++ b/Source/cmDependsJavaParserHelper.cxx
@@ -8,6 +8,7 @@
#include <iostream>
#include <utility>
+#include <cm/memory>
#include <cm/string_view>
#include "cmsys/FStream.hxx"
@@ -169,10 +170,11 @@ void cmDependsJavaParserHelper::AllocateParserType(
return;
}
this->UnionsAvailable++;
- pt->str = new char[len + 1];
+ auto up = cm::make_unique<char[]>(len + 1);
+ pt->str = up.get();
strncpy(pt->str, str, len);
pt->str[len] = 0;
- this->Allocates.push_back(pt->str);
+ this->Allocates.push_back(std::move(up));
}
void cmDependsJavaParserHelper::StartClass(const char* cls)
@@ -275,10 +277,7 @@ int cmDependsJavaParserHelper::ParseString(const char* str, int verb)
void cmDependsJavaParserHelper::CleanupParser()
{
- for (char* allocate : this->Allocates) {
- delete[] allocate;
- }
- this->Allocates.erase(this->Allocates.begin(), this->Allocates.end());
+ this->Allocates.clear();
}
int cmDependsJavaParserHelper::LexInput(char* buf, int maxlen)
diff --git a/Source/cmDependsJavaParserHelper.h b/Source/cmDependsJavaParserHelper.h
index a673b5b..c545ee2 100644
--- a/Source/cmDependsJavaParserHelper.h
+++ b/Source/cmDependsJavaParserHelper.h
@@ -5,6 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <memory>
#include <string>
#include <vector>
@@ -81,7 +82,7 @@ private:
int CurrentDepth;
int Verbose;
- std::vector<char*> Allocates;
+ std::vector<std::unique_ptr<char[]>> Allocates;
void PrintClasses();
diff --git a/Source/cmDocumentationSection.h b/Source/cmDocumentationSection.h
index 15cada6..641263d 100644
--- a/Source/cmDocumentationSection.h
+++ b/Source/cmDocumentationSection.h
@@ -8,7 +8,8 @@
#include <string>
#include <vector>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmDocumentationEntry.h"
// Low-level interface for custom documents:
@@ -47,7 +48,7 @@ public:
}
void Append(const std::vector<cmDocumentationEntry>& entries)
{
- cmAppend(this->Entries, entries);
+ cm::append(this->Entries, entries);
}
/** Append an entry to this section using NULL terminated chars */
diff --git a/Source/cmDynamicLoader.cxx b/Source/cmDynamicLoader.cxx
index 0b72a94..a3731c1 100644
--- a/Source/cmDynamicLoader.cxx
+++ b/Source/cmDynamicLoader.cxx
@@ -6,6 +6,7 @@
#include <string>
#include <utility>
+namespace {
class cmDynamicLoaderCache
{
public:
@@ -15,14 +16,15 @@ public:
cmsys::DynamicLoader::LibraryHandle& /*p*/);
bool FlushCache(const char* path);
void FlushCache();
- static cmDynamicLoaderCache* GetInstance();
+ static cmDynamicLoaderCache& GetInstance();
private:
std::map<std::string, cmsys::DynamicLoader::LibraryHandle> CacheMap;
- static cmDynamicLoaderCache* Instance;
+ static cmDynamicLoaderCache Instance;
};
-cmDynamicLoaderCache* cmDynamicLoaderCache::Instance = nullptr;
+cmDynamicLoaderCache cmDynamicLoaderCache::Instance;
+}
cmDynamicLoaderCache::~cmDynamicLoaderCache() = default;
@@ -64,15 +66,11 @@ void cmDynamicLoaderCache::FlushCache()
for (auto const& it : this->CacheMap) {
cmsys::DynamicLoader::CloseLibrary(it.second);
}
- delete cmDynamicLoaderCache::Instance;
- cmDynamicLoaderCache::Instance = nullptr;
+ this->CacheMap.clear();
}
-cmDynamicLoaderCache* cmDynamicLoaderCache::GetInstance()
+cmDynamicLoaderCache& cmDynamicLoaderCache::GetInstance()
{
- if (!cmDynamicLoaderCache::Instance) {
- cmDynamicLoaderCache::Instance = new cmDynamicLoaderCache;
- }
return cmDynamicLoaderCache::Instance;
}
@@ -80,15 +78,15 @@ cmsys::DynamicLoader::LibraryHandle cmDynamicLoader::OpenLibrary(
const char* libname)
{
cmsys::DynamicLoader::LibraryHandle lh;
- if (cmDynamicLoaderCache::GetInstance()->GetCacheFile(libname, lh)) {
+ if (cmDynamicLoaderCache::GetInstance().GetCacheFile(libname, lh)) {
return lh;
}
lh = cmsys::DynamicLoader::OpenLibrary(libname);
- cmDynamicLoaderCache::GetInstance()->CacheFile(libname, lh);
+ cmDynamicLoaderCache::GetInstance().CacheFile(libname, lh);
return lh;
}
void cmDynamicLoader::FlushCache()
{
- cmDynamicLoaderCache::GetInstance()->FlushCache();
+ cmDynamicLoaderCache::GetInstance().FlushCache();
}
diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx
index 5976b2f..a8d81f7 100644
--- a/Source/cmELF.cxx
+++ b/Source/cmELF.cxx
@@ -3,6 +3,7 @@
#include "cmELF.h"
#include <cstddef>
+#include <cstdint>
#include <map>
#include <memory>
#include <sstream>
@@ -10,17 +11,15 @@
#include <vector>
#include <cm/memory>
+#include <cmext/algorithm>
-#include "cmsys/FStream.hxx"
-
-#include "cm_kwiml.h"
+#include <cm3p/kwiml/abi.h>
-#include "cmAlgorithms.h"
+#include "cmsys/FStream.hxx"
// Include the ELF format information system header.
#if defined(__OpenBSD__)
# include <elf_abi.h>
-# include <stdint.h>
#elif defined(__HAIKU__)
# include <elf32.h>
# include <elf64.h>
@@ -578,7 +577,7 @@ std::vector<char> cmELFInternalImpl<Types>::EncodeDynamicEntries(
}
char* pdyn = reinterpret_cast<char*>(&dyn);
- cmAppend(result, pdyn, pdyn + sizeof(ELF_Dyn));
+ cm::append(result, pdyn, pdyn + sizeof(ELF_Dyn));
}
return result;
diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx
index 80e4bcd..9c53bdf 100644
--- a/Source/cmExecuteProcessCommand.cxx
+++ b/Source/cmExecuteProcessCommand.cxx
@@ -9,11 +9,11 @@
#include <memory>
#include <vector>
-#include "cmsys/Process.h"
+#include <cmext/algorithm>
+#include <cmext/string_view>
-#include "cm_static_string_view.hxx"
+#include "cmsys/Process.h"
-#include "cmAlgorithms.h"
#include "cmArgumentParser.h"
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
@@ -60,6 +60,8 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args,
bool ErrorQuiet = false;
bool OutputStripTrailingWhitespace = false;
bool ErrorStripTrailingWhitespace = false;
+ bool EchoOutputVariable = false;
+ bool EchoErrorVariable = false;
std::string Encoding;
};
@@ -82,7 +84,9 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args,
&Arguments::OutputStripTrailingWhitespace)
.Bind("ERROR_STRIP_TRAILING_WHITESPACE"_s,
&Arguments::ErrorStripTrailingWhitespace)
- .Bind("ENCODING"_s, &Arguments::Encoding);
+ .Bind("ENCODING"_s, &Arguments::Encoding)
+ .Bind("ECHO_OUTPUT_VARIABLE"_s, &Arguments::EchoOutputVariable)
+ .Bind("ECHO_ERROR_VARIABLE"_s, &Arguments::EchoErrorVariable);
std::vector<std::string> unparsedArguments;
std::vector<std::string> keywordsMissingValue;
@@ -240,28 +244,32 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args,
while ((p = cmsysProcess_WaitForData(cp, &data, &length, nullptr))) {
// Put the output in the right place.
if (p == cmsysProcess_Pipe_STDOUT && !arguments.OutputQuiet) {
- if (arguments.OutputVariable.empty()) {
+ if (arguments.OutputVariable.empty() || arguments.EchoOutputVariable) {
processOutput.DecodeText(data, length, strdata, 1);
cmSystemTools::Stdout(strdata);
- } else {
+ }
+ if (!arguments.OutputVariable.empty()) {
cmExecuteProcessCommandAppend(tempOutput, data, length);
}
} else if (p == cmsysProcess_Pipe_STDERR && !arguments.ErrorQuiet) {
- if (arguments.ErrorVariable.empty()) {
+ if (arguments.ErrorVariable.empty() || arguments.EchoErrorVariable) {
processOutput.DecodeText(data, length, strdata, 2);
cmSystemTools::Stderr(strdata);
- } else {
+ }
+ if (!arguments.ErrorVariable.empty()) {
cmExecuteProcessCommandAppend(tempError, data, length);
}
}
}
- if (!arguments.OutputQuiet && arguments.OutputVariable.empty()) {
+ if (!arguments.OutputQuiet &&
+ (arguments.OutputVariable.empty() || arguments.EchoOutputVariable)) {
processOutput.DecodeText(std::string(), strdata, 1);
if (!strdata.empty()) {
cmSystemTools::Stdout(strdata);
}
}
- if (!arguments.ErrorQuiet && arguments.ErrorVariable.empty()) {
+ if (!arguments.ErrorQuiet &&
+ (arguments.ErrorVariable.empty() || arguments.EchoErrorVariable)) {
processOutput.DecodeText(std::string(), strdata, 2);
if (!strdata.empty()) {
cmSystemTools::Stderr(strdata);
@@ -402,6 +410,6 @@ void cmExecuteProcessCommandAppend(std::vector<char>& output, const char* data,
--length;
}
#endif
- cmAppend(output, data, data + length);
+ cm::append(output, data, data + length);
}
}
diff --git a/Source/cmExportBuildAndroidMKGenerator.cxx b/Source/cmExportBuildAndroidMKGenerator.cxx
index 561e830..0ee1259 100644
--- a/Source/cmExportBuildAndroidMKGenerator.cxx
+++ b/Source/cmExportBuildAndroidMKGenerator.cxx
@@ -5,7 +5,8 @@
#include <sstream>
#include <utility>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmGeneratorTarget.h"
#include "cmLinkItem.h"
#include "cmMakefile.h"
@@ -118,13 +119,13 @@ void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
} else {
bool relpath = false;
if (type == cmExportBuildAndroidMKGenerator::INSTALL) {
- relpath = lib.substr(0, 3) == "../";
+ relpath = cmHasLiteralPrefix(lib, "../");
}
// check for full path or if it already has a -l, or
// in the case of an install check for relative paths
// if it is full or a link library then use string directly
if (cmSystemTools::FileIsFullPath(lib) ||
- lib.substr(0, 2) == "-l" || relpath) {
+ cmHasLiteralPrefix(lib, "-l") || relpath) {
ldlibs += " " + lib;
// if it is not a path and does not have a -l then add -l
} else if (!lib.empty()) {
@@ -165,7 +166,7 @@ void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
// Tell the NDK build system if prebuilt static libraries use C++.
if (target->GetType() == cmStateEnums::STATIC_LIBRARY) {
cmLinkImplementation const* li = target->GetLinkImplementation(config);
- if (cmContains(li->Languages, "CXX")) {
+ if (cm::contains(li->Languages, "CXX")) {
os << "LOCAL_HAS_CPP := true\n";
}
}
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index 7e9a987..dd700c5 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -8,6 +8,8 @@
#include <sstream>
#include <utility>
+#include <cmext/algorithm>
+
#include "cmExportSet.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
@@ -300,14 +302,13 @@ cmExportBuildFileGenerator::FindBuildExportInfo(cmGlobalGenerator* gg,
std::vector<std::string> exportFiles;
std::string ns;
- std::map<std::string, cmExportBuildFileGenerator*>& exportSets =
- gg->GetBuildExportSets();
+ auto& exportSets = gg->GetBuildExportSets();
for (auto const& exp : exportSets) {
- const cmExportBuildFileGenerator* exportSet = exp.second;
+ const auto& exportSet = exp.second;
std::vector<std::string> targets;
exportSet->GetTargets(targets);
- if (cmContains(targets, name)) {
+ if (cm::contains(targets, name)) {
exportFiles.push_back(exp.first);
ns = exportSet->GetNamespace();
}
diff --git a/Source/cmExportBuildFileGenerator.h b/Source/cmExportBuildFileGenerator.h
index 11fbd02..66e8cbb 100644
--- a/Source/cmExportBuildFileGenerator.h
+++ b/Source/cmExportBuildFileGenerator.h
@@ -10,7 +10,8 @@
#include <utility>
#include <vector>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmExportFileGenerator.h"
#include "cmStateTypes.h"
@@ -41,7 +42,7 @@ public:
void GetTargets(std::vector<std::string>& targets) const;
void AppendTargets(std::vector<std::string> const& targets)
{
- cmAppend(this->Targets, targets);
+ cm::append(this->Targets, targets);
}
void SetExportSet(cmExportSet*);
diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx
index 2a6bf5d..9f8a821 100644
--- a/Source/cmExportCommand.cxx
+++ b/Source/cmExportCommand.cxx
@@ -6,11 +6,12 @@
#include <sstream>
#include <utility>
-#include "cmsys/RegularExpression.hxx"
+#include <cm/memory>
+#include <cmext/algorithm>
+#include <cmext/string_view>
-#include "cm_static_string_view.hxx"
+#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
#include "cmArgumentParser.h"
#include "cmExecutionStatus.h"
#include "cmExportBuildAndroidMKGenerator.h"
@@ -22,6 +23,7 @@
#include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
@@ -144,7 +146,7 @@ bool cmExportCommand(std::vector<std::string> const& args,
}
exportSet = &it->second;
} else if (!arguments.Targets.empty() ||
- cmContains(keywordsMissingValue, "TARGETS")) {
+ cm::contains(keywordsMissingValue, "TARGETS")) {
for (std::string const& currentTarget : arguments.Targets) {
if (mf.IsAlias(currentTarget)) {
std::ostringstream e;
@@ -181,12 +183,34 @@ bool cmExportCommand(std::vector<std::string> const& args,
return false;
}
+ // if cmExportBuildFileGenerator is already defined for the file
+ // and APPEND is not specified, if CMP0103 is OLD ignore previous definition
+ // else raise an error
+ if (gg->GetExportedTargetsFile(fname) != nullptr) {
+ switch (mf.GetPolicyStatus(cmPolicies::CMP0103)) {
+ case cmPolicies::WARN:
+ mf.IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0103), '\n',
+ "export() command already specified for the file\n ",
+ arguments.Filename, "\nDid you miss 'APPEND' keyword?"));
+ CM_FALLTHROUGH;
+ case cmPolicies::OLD:
+ break;
+ default:
+ status.SetError(cmStrCat("command already specified for the file\n ",
+ arguments.Filename,
+ "\nDid you miss 'APPEND' keyword?"));
+ return false;
+ }
+ }
+
// Setup export file generation.
- cmExportBuildFileGenerator* ebfg = nullptr;
+ std::unique_ptr<cmExportBuildFileGenerator> ebfg = nullptr;
if (android) {
- ebfg = new cmExportBuildAndroidMKGenerator;
+ ebfg = cm::make_unique<cmExportBuildAndroidMKGenerator>();
} else {
- ebfg = new cmExportBuildFileGenerator;
+ ebfg = cm::make_unique<cmExportBuildFileGenerator>();
}
ebfg->SetExportFile(fname.c_str());
ebfg->SetNamespace(arguments.Namespace);
@@ -196,7 +220,6 @@ bool cmExportCommand(std::vector<std::string> const& args,
} else {
ebfg->SetTargets(targets);
}
- mf.AddExportBuildFileGenerator(ebfg);
ebfg->SetExportOld(arguments.ExportOld);
// Compute the set of configurations exported.
@@ -209,10 +232,11 @@ bool cmExportCommand(std::vector<std::string> const& args,
ebfg->AddConfiguration(ct);
}
if (exportSet != nullptr) {
- gg->AddBuildExportExportSet(ebfg);
+ gg->AddBuildExportExportSet(ebfg.get());
} else {
- gg->AddBuildExportSet(ebfg);
+ gg->AddBuildExportSet(ebfg.get());
}
+ mf.AddExportBuildFileGenerator(std::move(ebfg));
return true;
}
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index aeef602..28037c6 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -14,6 +14,7 @@
#include "cmComputeLinkInformation.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
+#include "cmGlobalGenerator.h"
#include "cmLinkItem.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
@@ -60,9 +61,9 @@ void cmExportFileGenerator::SetExportFile(const char* mainFile)
cmSystemTools::GetFilenameLastExtension(this->MainImportFile);
}
-const char* cmExportFileGenerator::GetMainExportFileName() const
+const std::string& cmExportFileGenerator::GetMainExportFileName() const
{
- return this->MainImportFile.c_str();
+ return this->MainImportFile;
}
bool cmExportFileGenerator::GenerateImportFile()
@@ -124,9 +125,9 @@ void cmExportFileGenerator::PopulateInterfaceProperty(
const std::string& propName, cmGeneratorTarget* target,
ImportPropertyMap& properties)
{
- const char* input = target->GetProperty(propName);
+ cmProp input = target->GetProperty(propName);
if (input) {
- properties[propName] = input;
+ properties[propName] = *input;
}
}
@@ -136,16 +137,16 @@ void cmExportFileGenerator::PopulateInterfaceProperty(
cmGeneratorExpression::PreprocessContext preprocessRule,
ImportPropertyMap& properties, std::vector<std::string>& missingTargets)
{
- const char* input = target->GetProperty(propName);
+ cmProp input = target->GetProperty(propName);
if (input) {
- if (!*input) {
+ if (input->empty()) {
// Set to empty
properties[outputName].clear();
return;
}
std::string prepro =
- cmGeneratorExpression::Preprocess(input, preprocessRule);
+ cmGeneratorExpression::Preprocess(*input, preprocessRule);
if (!prepro.empty()) {
this->ResolveTargetsInGeneratorExpressions(prepro, target,
missingTargets);
@@ -173,10 +174,10 @@ bool cmExportFileGenerator::PopulateInterfaceLinkLibrariesProperty(
if (!target->IsLinkable()) {
return false;
}
- const char* input = target->GetProperty("INTERFACE_LINK_LIBRARIES");
+ cmProp input = target->GetProperty("INTERFACE_LINK_LIBRARIES");
if (input) {
std::string prepro =
- cmGeneratorExpression::Preprocess(input, preprocessRule);
+ cmGeneratorExpression::Preprocess(*input, preprocessRule);
if (!prepro.empty()) {
this->ResolveTargetsInGeneratorExpressions(
prepro, target, missingTargets, ReplaceFreeTargets);
@@ -275,8 +276,7 @@ static bool checkInterfaceDirs(const std::string& prepro,
<< "\"\nhowever it is also "
"a subdirectory of the "
<< (inBinary ? "build" : "source") << " tree:\n \""
- << (inBinary ? topBinaryDir : topSourceDir) << "\""
- << std::endl;
+ << (inBinary ? topBinaryDir : topSourceDir) << "\"\n";
target->GetLocalGenerator()->IssueMessage(
MessageType::AUTHOR_WARNING, s.str());
CM_FALLTHROUGH;
@@ -341,19 +341,19 @@ void cmExportFileGenerator::PopulateSourcesInterface(
assert(preprocessRule == cmGeneratorExpression::InstallInterface);
const char* propName = "INTERFACE_SOURCES";
- const char* input = gt->GetProperty(propName);
+ cmProp input = gt->GetProperty(propName);
if (!input) {
return;
}
- if (!*input) {
+ if (input->empty()) {
properties[propName].clear();
return;
}
std::string prepro =
- cmGeneratorExpression::Preprocess(input, preprocessRule, true);
+ cmGeneratorExpression::Preprocess(*input, preprocessRule, true);
if (!prepro.empty()) {
this->ResolveTargetsInGeneratorExpressions(prepro, gt, missingTargets);
@@ -372,7 +372,7 @@ void cmExportFileGenerator::PopulateIncludeDirectoriesInterface(
assert(preprocessRule == cmGeneratorExpression::InstallInterface);
const char* propName = "INTERFACE_INCLUDE_DIRECTORIES";
- const char* input = target->GetProperty(propName);
+ cmProp input = target->GetProperty(propName);
cmGeneratorExpression ge;
@@ -399,7 +399,7 @@ void cmExportFileGenerator::PopulateIncludeDirectoriesInterface(
if (!input && exportDirs.empty()) {
return;
}
- if ((input && !*input) && exportDirs.empty()) {
+ if ((input && input->empty()) && exportDirs.empty()) {
// Set to empty
properties[propName].clear();
return;
@@ -407,7 +407,7 @@ void cmExportFileGenerator::PopulateIncludeDirectoriesInterface(
prefixItems(exportDirs);
- std::string includes = (input ? input : "");
+ std::string includes = (input ? *input : "");
const char* sep = input ? ";" : "";
includes += sep + exportDirs;
std::string prepro =
@@ -430,19 +430,19 @@ void cmExportFileGenerator::PopulateLinkDependsInterface(
assert(preprocessRule == cmGeneratorExpression::InstallInterface);
const char* propName = "INTERFACE_LINK_DEPENDS";
- const char* input = gt->GetProperty(propName);
+ cmProp input = gt->GetProperty(propName);
if (!input) {
return;
}
- if (!*input) {
+ if (input->empty()) {
properties[propName].clear();
return;
}
std::string prepro =
- cmGeneratorExpression::Preprocess(input, preprocessRule, true);
+ cmGeneratorExpression::Preprocess(*input, preprocessRule, true);
if (!prepro.empty()) {
this->ResolveTargetsInGeneratorExpressions(prepro, gt, missingTargets);
@@ -461,19 +461,19 @@ void cmExportFileGenerator::PopulateLinkDirectoriesInterface(
assert(preprocessRule == cmGeneratorExpression::InstallInterface);
const char* propName = "INTERFACE_LINK_DIRECTORIES";
- const char* input = gt->GetProperty(propName);
+ cmProp input = gt->GetProperty(propName);
if (!input) {
return;
}
- if (!*input) {
+ if (input->empty()) {
properties[propName].clear();
return;
}
std::string prepro =
- cmGeneratorExpression::Preprocess(input, preprocessRule, true);
+ cmGeneratorExpression::Preprocess(*input, preprocessRule, true);
if (!prepro.empty()) {
this->ResolveTargetsInGeneratorExpressions(prepro, gt, missingTargets);
@@ -496,11 +496,11 @@ void cmExportFileGenerator::PopulateInterfaceProperty(
void getPropertyContents(cmGeneratorTarget const* tgt, const std::string& prop,
std::set<std::string>& ifaceProperties)
{
- const char* p = tgt->GetProperty(prop);
+ cmProp p = tgt->GetProperty(prop);
if (!p) {
return;
}
- std::vector<std::string> content = cmExpandedList(p);
+ std::vector<std::string> content = cmExpandedList(*p);
ifaceProperties.insert(content.begin(), content.end());
}
@@ -640,6 +640,9 @@ void cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
std::string sep;
input.clear();
for (std::string& li : parts) {
+ if (cmHasLiteralPrefix(li, CMAKE_DIRECTORY_ID_SEP)) {
+ continue;
+ }
if (cmGeneratorExpression::Find(li) == std::string::npos) {
this->AddTargetNamespace(li, target, missingTargets);
} else {
@@ -758,13 +761,12 @@ void cmExportFileGenerator::SetImportLinkInterface(
return;
}
- const char* propContent;
+ cmProp propContent;
- if (const char* prop_suffixed =
+ if (cmProp prop_suffixed =
target->GetProperty("LINK_INTERFACE_LIBRARIES" + suffix)) {
propContent = prop_suffixed;
- } else if (const char* prop =
- target->GetProperty("LINK_INTERFACE_LIBRARIES")) {
+ } else if (cmProp prop = target->GetProperty("LINK_INTERFACE_LIBRARIES")) {
propContent = prop;
} else {
return;
@@ -786,13 +788,13 @@ void cmExportFileGenerator::SetImportLinkInterface(
return;
}
- if (!*propContent) {
+ if (propContent->empty()) {
properties["IMPORTED_LINK_INTERFACE_LIBRARIES" + suffix].clear();
return;
}
std::string prepro =
- cmGeneratorExpression::Preprocess(propContent, preprocessRule);
+ cmGeneratorExpression::Preprocess(*propContent, preprocessRule);
if (!prepro.empty()) {
this->ResolveTargetsInGeneratorExpressions(prepro, target, missingTargets,
ReplaceFreeTargets);
@@ -852,8 +854,8 @@ void cmExportFileGenerator::SetImportDetailProperties(
cmGeneratorTarget::ManagedType::Native) {
std::string prop = cmStrCat("IMPORTED_COMMON_LANGUAGE_RUNTIME", suffix);
std::string propval;
- if (auto* p = target->GetProperty("COMMON_LANGUAGE_RUNTIME")) {
- propval = p;
+ if (cmProp p = target->GetProperty("COMMON_LANGUAGE_RUNTIME")) {
+ propval = *p;
} else if (target->IsCSharpOnly()) {
// C# projects do not have the /clr flag, so we set the property
// here to mark the target as (only) managed (i.e. no .lib file
@@ -1062,6 +1064,12 @@ void cmExportFileGenerator::GenerateImportTargetCode(
if (target->IsCFBundleOnApple()) {
os << "set_property(TARGET " << targetName << " PROPERTY BUNDLE 1)\n";
}
+
+ // generate DEPRECATION
+ if (target->IsDeprecated()) {
+ os << "set_property(TARGET " << targetName << " PROPERTY DEPRECATION "
+ << cmExportFileGeneratorEscape(target->GetDeprecation()) << ")\n";
+ }
os << "\n";
}
@@ -1106,7 +1114,7 @@ void cmExportFileGenerator::GenerateMissingTargetsCheckCode(
return;
}
/* clang-format off */
- os << "# Make sure the targets which have been exported in some other \n"
+ os << "# Make sure the targets which have been exported in some other\n"
"# export set exist.\n"
"unset(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets)\n"
"foreach(_target ";
@@ -1205,9 +1213,9 @@ bool cmExportFileGenerator::PopulateExportProperties(
std::string& errorMessage)
{
auto& targetProperties = gte->Target->GetProperties();
- if (const char* exportProperties =
+ if (cmProp exportProperties =
targetProperties.GetPropertyValue("EXPORT_PROPERTIES")) {
- for (auto& prop : cmExpandedList(exportProperties)) {
+ for (auto& prop : cmExpandedList(*exportProperties)) {
/* Black list reserved properties */
if (cmHasLiteralPrefix(prop, "IMPORTED_") ||
cmHasLiteralPrefix(prop, "INTERFACE_")) {
@@ -1218,15 +1226,15 @@ bool cmExportFileGenerator::PopulateExportProperties(
errorMessage = e.str();
return false;
}
- auto propertyValue = targetProperties.GetPropertyValue(prop);
+ cmProp propertyValue = targetProperties.GetPropertyValue(prop);
if (propertyValue == nullptr) {
// Asked to export a property that isn't defined on the target. Do not
// consider this an error, there's just nothing to export.
continue;
}
std::string evaluatedValue = cmGeneratorExpression::Preprocess(
- propertyValue, cmGeneratorExpression::StripAllGeneratorExpressions);
- if (evaluatedValue != propertyValue) {
+ *propertyValue, cmGeneratorExpression::StripAllGeneratorExpressions);
+ if (evaluatedValue != *propertyValue) {
std::ostringstream e;
e << "Target \"" << gte->Target->GetName() << "\" contains property \""
<< prop << "\" in EXPORT_PROPERTIES but this property contains a "
@@ -1234,7 +1242,7 @@ bool cmExportFileGenerator::PopulateExportProperties(
errorMessage = e.str();
return false;
}
- properties[prop] = propertyValue;
+ properties[prop] = *propertyValue;
}
}
return true;
diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h
index 0d69779..e9d0da7 100644
--- a/Source/cmExportFileGenerator.h
+++ b/Source/cmExportFileGenerator.h
@@ -46,7 +46,7 @@ public:
/** Set the full path to the export file to generate. */
void SetExportFile(const char* mainFile);
- const char* GetMainExportFileName() const;
+ const std::string& GetMainExportFileName() const;
/** Set the namespace in which to place exported target names. */
void SetNamespace(const std::string& ns) { this->Namespace = ns; }
diff --git a/Source/cmExportInstallAndroidMKGenerator.cxx b/Source/cmExportInstallAndroidMKGenerator.cxx
index 2d732c1..80f776e 100644
--- a/Source/cmExportInstallAndroidMKGenerator.cxx
+++ b/Source/cmExportInstallAndroidMKGenerator.cxx
@@ -49,7 +49,7 @@ void cmExportInstallAndroidMKGenerator::GenerateImportHeaderCode(
if (te->ArchiveGenerator) {
dest = te->ArchiveGenerator->GetDestination("");
}
- te->Target->Target->SetProperty("__dest", dest.c_str());
+ te->Target->Target->SetProperty("__dest", dest);
}
}
@@ -66,7 +66,7 @@ void cmExportInstallAndroidMKGenerator::GenerateImportTargetCode(
os << "LOCAL_MODULE := ";
os << targetName << "\n";
os << "LOCAL_SRC_FILES := $(_IMPORT_PREFIX)/";
- os << target->Target->GetProperty("__dest") << "/";
+ os << target->Target->GetSafeProperty("__dest") << "/";
std::string config;
if (!this->Configurations.empty()) {
config = this->Configurations[0];
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index 6d29c99..987ec9e 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -258,15 +258,7 @@ void cmExportInstallFileGenerator::LoadConfigFiles(std::ostream& os)
void cmExportInstallFileGenerator::ReplaceInstallPrefix(std::string& input)
{
- std::string::size_type pos = 0;
- std::string::size_type lastPos = pos;
-
- while ((pos = input.find("$<INSTALL_PREFIX>", lastPos)) !=
- std::string::npos) {
- std::string::size_type endPos = pos + sizeof("$<INSTALL_PREFIX>") - 1;
- input.replace(pos, endPos - pos, "${_IMPORT_PREFIX}");
- lastPos = endPos;
- }
+ cmGeneratorExpression::ReplaceInstallPrefix(input, "${_IMPORT_PREFIX}");
}
bool cmExportInstallFileGenerator::GenerateImportFileConfig(
@@ -525,13 +517,14 @@ void cmExportInstallFileGenerator::ComplainAboutMissingTarget(
}
std::string cmExportInstallFileGenerator::InstallNameDir(
- cmGeneratorTarget* target, const std::string& /*config*/)
+ cmGeneratorTarget* target, const std::string& config)
{
std::string install_name_dir;
cmMakefile* mf = target->Target->GetMakefile();
if (mf->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) {
- install_name_dir = target->GetInstallNameDirForInstallTree();
+ install_name_dir =
+ target->GetInstallNameDirForInstallTree(config, "${_IMPORT_PREFIX}");
}
return install_name_dir;
diff --git a/Source/cmExportLibraryDependenciesCommand.cxx b/Source/cmExportLibraryDependenciesCommand.cxx
index 89093e9..be63278 100644
--- a/Source/cmExportLibraryDependenciesCommand.cxx
+++ b/Source/cmExportLibraryDependenciesCommand.cxx
@@ -12,6 +12,7 @@
#include "cmExecutionStatus.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
+#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
@@ -20,6 +21,10 @@
#include "cmTargetLinkLibraryType.h"
#include "cmake.h"
+class cmListFileBacktrace;
+
+using cmProp = const std::string*;
+
static void FinalAction(cmMakefile& makefile, std::string const& filename,
bool append)
{
@@ -46,11 +51,11 @@ static void FinalAction(cmMakefile& makefile, std::string const& filename,
// the project.
cmake* cm = makefile.GetCMakeInstance();
cmGlobalGenerator* global = cm->GetGlobalGenerator();
- const std::vector<cmMakefile*>& locals = global->GetMakefiles();
+ const auto& locals = global->GetMakefiles();
std::map<std::string, std::string> libDepsOld;
std::map<std::string, std::string> libDepsNew;
std::map<std::string, std::string> libTypes;
- for (cmMakefile* local : locals) {
+ for (const auto& local : locals) {
for (auto const& tgt : local->GetTargets()) {
// Get the current target.
cmTarget const& target = tgt.second;
@@ -92,8 +97,8 @@ static void FinalAction(cmMakefile& makefile, std::string const& filename,
// Handle simple output name changes. This command is
// deprecated so we do not support full target name
// translation (which requires per-configuration info).
- if (const char* outname = libtgt->GetProperty("OUTPUT_NAME")) {
- lib = outname;
+ if (cmProp outname = libtgt->GetProperty("OUTPUT_NAME")) {
+ lib = *outname;
}
}
valueOld += lib;
@@ -150,9 +155,9 @@ bool cmExportLibraryDependenciesCommand(std::vector<std::string> const& args,
std::string const& filename = args[0];
bool const append = args.size() > 1 && args[1] == "APPEND";
- status.GetMakefile().AddFinalAction(
- [filename, append](cmMakefile& makefile) {
- FinalAction(makefile, filename, append);
+ status.GetMakefile().AddGeneratorAction(
+ [filename, append](cmLocalGenerator& lg, const cmListFileBacktrace&) {
+ FinalAction(*lg.GetMakefile(), filename, append);
});
return true;
diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx
index fafa51b..6212667 100644
--- a/Source/cmExportTryCompileFileGenerator.cxx
+++ b/Source/cmExportTryCompileFileGenerator.cxx
@@ -58,7 +58,7 @@ std::string cmExportTryCompileFileGenerator::FindTargets(
const std::string& propName, cmGeneratorTarget const* tgt,
std::string const& language, std::set<cmGeneratorTarget const*>& emitted)
{
- const char* prop = tgt->GetProperty(propName);
+ cmProp prop = tgt->GetProperty(propName);
if (!prop) {
return std::string();
}
@@ -67,10 +67,11 @@ std::string cmExportTryCompileFileGenerator::FindTargets(
cmGeneratorExpressionDAGChecker dagChecker(tgt, propName, nullptr, nullptr);
- std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
+ std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*prop);
cmTarget dummyHead("try_compile_dummy_exe", cmStateEnums::EXECUTABLE,
- cmTarget::VisibilityNormal, tgt->Target->GetMakefile());
+ cmTarget::VisibilityNormal, tgt->Target->GetMakefile(),
+ true);
cmGeneratorTarget gDummyHead(&dummyHead, tgt->GetLocalGenerator());
@@ -94,11 +95,11 @@ void cmExportTryCompileFileGenerator::PopulateProperties(
std::vector<std::string> props = target->GetPropertyKeys();
for (std::string const& p : props) {
- properties[p] = target->GetProperty(p);
+ properties[p] = *target->GetProperty(p);
- if (p.find("IMPORTED_LINK_INTERFACE_LIBRARIES") == 0 ||
- p.find("IMPORTED_LINK_DEPENDENT_LIBRARIES") == 0 ||
- p.find("INTERFACE_LINK_LIBRARIES") == 0) {
+ if (cmHasLiteralPrefix(p, "IMPORTED_LINK_INTERFACE_LIBRARIES") ||
+ cmHasLiteralPrefix(p, "IMPORTED_LINK_DEPENDENT_LIBRARIES") ||
+ cmHasLiteralPrefix(p, "INTERFACE_LINK_LIBRARIES")) {
std::string evalResult =
this->FindTargets(p, target, std::string(), emitted);
diff --git a/Source/cmExprParserHelper.h b/Source/cmExprParserHelper.h
index eaf5dc7..717acdc 100644
--- a/Source/cmExprParserHelper.h
+++ b/Source/cmExprParserHelper.h
@@ -8,7 +8,7 @@
#include <string>
#include <vector>
-#include "cm_kwiml.h"
+#include <cm3p/kwiml/int.h>
class cmExprParserHelper
{
diff --git a/Source/cmExternalMakefileProjectGenerator.h b/Source/cmExternalMakefileProjectGenerator.h
index a472a06..2b8d505 100644
--- a/Source/cmExternalMakefileProjectGenerator.h
+++ b/Source/cmExternalMakefileProjectGenerator.h
@@ -5,6 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <memory>
#include <string>
#include <vector>
@@ -78,7 +79,7 @@ public:
std::vector<std::string> GetSupportedGlobalGenerators() const;
std::vector<std::string> Aliases;
- virtual cmExternalMakefileProjectGenerator*
+ virtual std::unique_ptr<cmExternalMakefileProjectGenerator>
CreateExternalMakefileProjectGenerator() const = 0;
void AddSupportedGlobalGenerator(const std::string& base);
@@ -100,10 +101,10 @@ public:
{
}
- cmExternalMakefileProjectGenerator* CreateExternalMakefileProjectGenerator()
- const override
+ std::unique_ptr<cmExternalMakefileProjectGenerator>
+ CreateExternalMakefileProjectGenerator() const override
{
- T* p = new T;
+ std::unique_ptr<cmExternalMakefileProjectGenerator> p(new T);
p->SetName(GetName());
return p;
}
diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index 5a5d959..42fd0ea 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -3,10 +3,13 @@
#include "cmExtraCodeBlocksGenerator.h"
#include <map>
+#include <memory>
#include <ostream>
#include <set>
#include <utility>
+#include <cmext/algorithm>
+
#include "cmAlgorithms.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
@@ -209,13 +212,13 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile(
// Collect all files
std::vector<std::string> listFiles;
for (cmLocalGenerator* lg : it.second) {
- cmAppend(listFiles, lg->GetMakefile()->GetListFiles());
+ cm::append(listFiles, lg->GetMakefile()->GetListFiles());
}
// Convert
for (std::string const& listFile : listFiles) {
// don't put cmake's own files into the project (#12110):
- if (listFile.find(cmSystemTools::GetCMakeRoot()) == 0) {
+ if (cmHasPrefix(listFile, cmSystemTools::GetCMakeRoot())) {
continue;
}
@@ -283,8 +286,8 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile(
// add all executable and library targets and some of the GLOBAL
// and UTILITY targets
for (cmLocalGenerator* lg : lgs) {
- const std::vector<cmGeneratorTarget*>& targets = lg->GetGeneratorTargets();
- for (cmGeneratorTarget* target : targets) {
+ const auto& targets = lg->GetGeneratorTargets();
+ for (const auto& target : targets) {
std::string targetName = target->GetName();
switch (target->GetType()) {
case cmStateEnums::GLOBAL_TARGET: {
@@ -298,11 +301,11 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile(
case cmStateEnums::UTILITY:
// Add all utility targets, except the Nightly/Continuous/
// Experimental-"sub"targets as e.g. NightlyStart
- if (((targetName.find("Nightly") == 0) &&
+ if ((cmHasLiteralPrefix(targetName, "Nightly") &&
(targetName != "Nightly")) ||
- ((targetName.find("Continuous") == 0) &&
+ (cmHasLiteralPrefix(targetName, "Continuous") &&
(targetName != "Continuous")) ||
- ((targetName.find("Experimental") == 0) &&
+ (cmHasLiteralPrefix(targetName, "Experimental") &&
(targetName != "Experimental"))) {
break;
}
@@ -315,7 +318,7 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile(
case cmStateEnums::SHARED_LIBRARY:
case cmStateEnums::MODULE_LIBRARY:
case cmStateEnums::OBJECT_LIBRARY: {
- cmGeneratorTarget* gt = target;
+ cmGeneratorTarget* gt = target.get();
this->AppendTarget(xml, targetName, gt, make, lg, compiler,
makeArgs);
std::string fastTarget = cmStrCat(targetName, "/fast");
@@ -341,8 +344,8 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile(
for (cmLocalGenerator* lg : lgs) {
cmMakefile* makefile = lg->GetMakefile();
- const std::vector<cmGeneratorTarget*>& targets = lg->GetGeneratorTargets();
- for (cmGeneratorTarget* target : targets) {
+ const auto& targets = lg->GetGeneratorTargets();
+ for (const auto& target : targets) {
switch (target->GetType()) {
case cmStateEnums::EXECUTABLE:
case cmStateEnums::STATIC_LIBRARY:
@@ -352,13 +355,12 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile(
case cmStateEnums::UTILITY: // can have sources since 2.6.3
{
std::vector<cmSourceFile*> sources;
- cmGeneratorTarget* gt = target;
- gt->GetSourceFiles(sources,
- makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
+ target->GetSourceFiles(
+ sources, makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
for (cmSourceFile* s : sources) {
// don't add source files from UTILITY target which have the
// GENERATED property set:
- if (gt->GetType() == cmStateEnums::UTILITY &&
+ if (target->GetType() == cmStateEnums::UTILITY &&
s->GetIsGenerated()) {
continue;
}
@@ -391,7 +393,7 @@ void cmExtraCodeBlocksGenerator::CreateNewProjectFile(
}
CbpUnit& cbpUnit = allFiles[fullPath];
- cbpUnit.Targets.push_back(target);
+ cbpUnit.Targets.push_back(target.get());
}
}
default: // intended fallthrough
@@ -558,19 +560,19 @@ void cmExtraCodeBlocksGenerator::AppendTarget(
{
std::vector<std::string> includes;
lg->GetIncludeDirectories(includes, target, "C", buildType);
- cmAppend(allIncludeDirs, includes);
+ cm::append(allIncludeDirs, includes);
}
std::string systemIncludeDirs = makefile->GetSafeDefinition(
"CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS");
if (!systemIncludeDirs.empty()) {
- cmAppend(allIncludeDirs, cmExpandedList(systemIncludeDirs));
+ cm::append(allIncludeDirs, cmExpandedList(systemIncludeDirs));
}
systemIncludeDirs = makefile->GetSafeDefinition(
"CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS");
if (!systemIncludeDirs.empty()) {
- cmAppend(allIncludeDirs, cmExpandedList(systemIncludeDirs));
+ cm::append(allIncludeDirs, cmExpandedList(systemIncludeDirs));
}
auto end = cmRemoveDuplicates(allIncludeDirs);
diff --git a/Source/cmExtraCodeLiteGenerator.cxx b/Source/cmExtraCodeLiteGenerator.cxx
index c7b7457..bf7555d 100644
--- a/Source/cmExtraCodeLiteGenerator.cxx
+++ b/Source/cmExtraCodeLiteGenerator.cxx
@@ -4,6 +4,7 @@
#include <cstring>
#include <map>
+#include <memory>
#include <set>
#include <sstream>
#include <utility>
@@ -116,10 +117,9 @@ std::vector<std::string> cmExtraCodeLiteGenerator::CreateProjectsByTarget(
{
std::vector<std::string> retval;
// for each target in the workspace create a codelite project
- const std::vector<cmLocalGenerator*>& lgs =
- this->GlobalGenerator->GetLocalGenerators();
- for (cmLocalGenerator* lg : lgs) {
- for (cmGeneratorTarget* lt : lg->GetGeneratorTargets()) {
+ const auto& lgs = this->GlobalGenerator->GetLocalGenerators();
+ for (const auto& lg : lgs) {
+ for (const auto& lt : lg->GetGeneratorTargets()) {
cmStateEnums::TargetType type = lt->GetType();
std::string const& outputDir = lg->GetCurrentBinaryDirectory();
std::string targetName = lt->GetName();
@@ -142,7 +142,7 @@ std::vector<std::string> cmExtraCodeLiteGenerator::CreateProjectsByTarget(
xml->Attribute("Active", "No");
xml->EndElement();
- CreateNewProjectFile(lt, filename);
+ CreateNewProjectFile(lt.get(), filename);
break;
default:
break;
@@ -204,9 +204,7 @@ std::string cmExtraCodeLiteGenerator::CollectSourceFiles(
case cmStateEnums::STATIC_LIBRARY: {
projectType = "Static Library";
} break;
- case cmStateEnums::SHARED_LIBRARY: {
- projectType = "Dynamic Library";
- } break;
+ case cmStateEnums::SHARED_LIBRARY:
case cmStateEnums::MODULE_LIBRARY: {
projectType = "Dynamic Library";
} break;
@@ -269,9 +267,9 @@ void cmExtraCodeLiteGenerator::CreateNewProjectFile(
for (cmLocalGenerator* lg : lgs) {
cmMakefile* makefile = lg->GetMakefile();
- const std::vector<cmGeneratorTarget*>& targets = lg->GetGeneratorTargets();
- for (cmGeneratorTarget* target : targets) {
- projectType = CollectSourceFiles(makefile, target, cFiles, otherFiles);
+ for (const auto& target : lg->GetGeneratorTargets()) {
+ projectType =
+ CollectSourceFiles(makefile, target.get(), cFiles, otherFiles);
}
}
@@ -634,7 +632,10 @@ std::string cmExtraCodeLiteGenerator::GetBuildCommand(
if (generator == "NMake Makefiles" || generator == "Ninja") {
ss << make;
} else if (generator == "MinGW Makefiles" || generator == "Unix Makefiles") {
- ss << make << " -f$(ProjectPath)/Makefile -j " << this->CpuCount;
+ ss << make << " -f$(ProjectPath)/Makefile";
+ if (this->CpuCount > 0) {
+ ss << " -j " << this->CpuCount;
+ }
}
if (!targetName.empty()) {
ss << " " << targetName;
diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx
index b286acf..80d61c3 100644
--- a/Source/cmExtraEclipseCDT4Generator.cxx
+++ b/Source/cmExtraEclipseCDT4Generator.cxx
@@ -6,6 +6,7 @@
#include <cassert>
#include <cstdio>
#include <map>
+#include <memory>
#include <sstream>
#include <utility>
@@ -98,7 +99,7 @@ void cmExtraEclipseCDT4Generator::EnableLanguage(
void cmExtraEclipseCDT4Generator::Generate()
{
- cmLocalGenerator* lg = this->GlobalGenerator->GetLocalGenerators()[0];
+ const auto& lg = this->GlobalGenerator->GetLocalGenerators()[0];
const cmMakefile* mf = lg->GetMakefile();
std::string eclipseVersion = mf->GetSafeDefinition("CMAKE_ECLIPSE_VERSION");
@@ -175,7 +176,7 @@ void cmExtraEclipseCDT4Generator::Generate()
void cmExtraEclipseCDT4Generator::CreateSettingsResourcePrefsFile()
{
- cmLocalGenerator* lg = this->GlobalGenerator->GetLocalGenerators()[0];
+ const auto& lg = this->GlobalGenerator->GetLocalGenerators()[0];
cmMakefile* mf = lg->GetMakefile();
const std::string filename =
@@ -186,10 +187,10 @@ void cmExtraEclipseCDT4Generator::CreateSettingsResourcePrefsFile()
return;
}
- fout << "eclipse.preferences.version=1" << std::endl;
+ fout << "eclipse.preferences.version=1\n";
const char* encoding = mf->GetDefinition("CMAKE_ECLIPSE_RESOURCE_ENCODING");
if (encoding) {
- fout << "encoding/<project>=" << encoding << std::endl;
+ fout << "encoding/<project>=" << encoding << '\n';
}
}
@@ -198,7 +199,7 @@ void cmExtraEclipseCDT4Generator::CreateSourceProjectFile()
assert(this->HomeDirectory != this->HomeOutputDirectory);
// set up the project name: <project>-Source@<baseSourcePathName>
- cmLocalGenerator* lg = this->GlobalGenerator->GetLocalGenerators()[0];
+ const auto& lg = this->GlobalGenerator->GetLocalGenerators()[0];
std::string name = cmExtraEclipseCDT4Generator::GenerateProjectName(
lg->GetProjectName(), "Source",
cmExtraEclipseCDT4Generator::GetPathBasename(this->HomeDirectory));
@@ -231,9 +232,9 @@ void cmExtraEclipseCDT4Generator::CreateSourceProjectFile()
void cmExtraEclipseCDT4Generator::AddEnvVar(std::ostream& out,
const char* envVar,
- cmLocalGenerator* lg)
+ cmLocalGenerator& lg)
{
- cmMakefile* mf = lg->GetMakefile();
+ cmMakefile* mf = lg.GetMakefile();
// get the variables from the environment and from the cache and then
// figure out which one to use:
@@ -242,8 +243,7 @@ void cmExtraEclipseCDT4Generator::AddEnvVar(std::ostream& out,
const bool envVarSet = cmSystemTools::GetEnv(envVar, envVarValue);
std::string cacheEntryName = cmStrCat("CMAKE_ECLIPSE_ENVVAR_", envVar);
- const std::string* cacheValue =
- lg->GetState()->GetInitializedCacheValue(cacheEntryName);
+ cmProp cacheValue = lg.GetState()->GetInitializedCacheValue(cacheEntryName);
// now we have both, decide which one to use
std::string valueToUse;
@@ -254,9 +254,9 @@ void cmExtraEclipseCDT4Generator::AddEnvVar(std::ostream& out,
// The variable is in the env, but not in the cache. Use it and put it
// in the cache
valueToUse = envVarValue;
- mf->AddCacheDefinition(cacheEntryName, valueToUse.c_str(),
- cacheEntryName.c_str(), cmStateEnums::STRING, true);
- mf->GetCMakeInstance()->SaveCache(lg->GetBinaryDirectory());
+ mf->AddCacheDefinition(cacheEntryName, valueToUse, cacheEntryName.c_str(),
+ cmStateEnums::STRING, true);
+ mf->GetCMakeInstance()->SaveCache(lg.GetBinaryDirectory());
} else if (!envVarSet && cacheValue != nullptr) {
// It is already in the cache, but not in the env, so use it from the cache
valueToUse = *cacheValue;
@@ -269,10 +269,10 @@ void cmExtraEclipseCDT4Generator::AddEnvVar(std::ostream& out,
valueToUse = *cacheValue;
if (valueToUse.find(envVarValue) == std::string::npos) {
valueToUse = envVarValue;
- mf->AddCacheDefinition(cacheEntryName, valueToUse.c_str(),
+ mf->AddCacheDefinition(cacheEntryName, valueToUse,
cacheEntryName.c_str(), cmStateEnums::STRING,
true);
- mf->GetCMakeInstance()->SaveCache(lg->GetBinaryDirectory());
+ mf->GetCMakeInstance()->SaveCache(lg.GetBinaryDirectory());
}
}
@@ -283,7 +283,7 @@ void cmExtraEclipseCDT4Generator::AddEnvVar(std::ostream& out,
void cmExtraEclipseCDT4Generator::CreateProjectFile()
{
- cmLocalGenerator* lg = this->GlobalGenerator->GetLocalGenerators()[0];
+ const auto& lg = this->GlobalGenerator->GetLocalGenerators()[0];
cmMakefile* mf = lg->GetMakefile();
const std::string filename = this->HomeOutputDirectory + "/.project";
@@ -350,15 +350,15 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile()
// set vsvars32.bat environment available at CMake time,
// but not necessarily when eclipse is open
if (compilerId == "MSVC") {
- AddEnvVar(environment, "PATH", lg);
- AddEnvVar(environment, "INCLUDE", lg);
- AddEnvVar(environment, "LIB", lg);
- AddEnvVar(environment, "LIBPATH", lg);
+ AddEnvVar(environment, "PATH", *lg);
+ AddEnvVar(environment, "INCLUDE", *lg);
+ AddEnvVar(environment, "LIB", *lg);
+ AddEnvVar(environment, "LIBPATH", *lg);
} else if (compilerId == "Intel") {
// if the env.var is set, use this one and put it in the cache
// if the env.var is not set, but the value is in the cache,
// use it from the cache:
- AddEnvVar(environment, "INTEL_LICENSE_FILE", lg);
+ AddEnvVar(environment, "INTEL_LICENSE_FILE", *lg);
}
AppendDictionary(xml, "org.eclipse.cdt.make.core.environment",
environment.str());
@@ -414,9 +414,9 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile()
xml.Element("nature", n);
}
- if (const char* extraNaturesProp =
+ if (cmProp extraNaturesProp =
mf->GetState()->GetGlobalProperty("ECLIPSE_EXTRA_NATURES")) {
- std::vector<std::string> extraNatures = cmExpandedList(extraNaturesProp);
+ std::vector<std::string> extraNatures = cmExpandedList(*extraNaturesProp);
for (std::string const& n : extraNatures) {
xml.Element("nature", n);
}
@@ -494,11 +494,11 @@ void cmExtraEclipseCDT4Generator::CreateLinksForTargets(cmXMLWriter& xml)
cmExtraEclipseCDT4Generator::AppendLinkedResource(
xml, linkName, "virtual:/virtual", VirtualFolder);
- for (cmLocalGenerator* lg : this->GlobalGenerator->GetLocalGenerators()) {
+ for (const auto& lg : this->GlobalGenerator->GetLocalGenerators()) {
cmMakefile* makefile = lg->GetMakefile();
- const std::vector<cmGeneratorTarget*>& targets = lg->GetGeneratorTargets();
+ const auto& targets = lg->GetGeneratorTargets();
- for (cmGeneratorTarget* target : targets) {
+ for (const auto& target : targets) {
std::string linkName2 = cmStrCat(linkName, '/');
switch (target->GetType()) {
case cmStateEnums::EXECUTABLE:
@@ -519,10 +519,9 @@ void cmExtraEclipseCDT4Generator::CreateLinksForTargets(cmXMLWriter& xml)
std::vector<cmSourceGroup> sourceGroups =
makefile->GetSourceGroups();
// get the files from the source lists then add them to the groups
- cmGeneratorTarget* gt = const_cast<cmGeneratorTarget*>(target);
std::vector<cmSourceFile*> files;
- gt->GetSourceFiles(files,
- makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
+ target->GetSourceFiles(
+ files, makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
for (cmSourceFile* sf : files) {
// Add the file to the list of sources.
std::string const& source = sf->ResolveFullPath();
@@ -606,7 +605,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
{
std::set<std::string> emmited;
- cmLocalGenerator* lg = this->GlobalGenerator->GetLocalGenerators()[0];
+ const auto& lg = this->GlobalGenerator->GetLocalGenerators()[0];
const cmMakefile* mf = lg->GetMakefile();
const std::string filename = this->HomeOutputDirectory + "/.cproject";
@@ -752,13 +751,13 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
// add pre-processor definitions to allow eclipse to gray out sections
emmited.clear();
- for (cmLocalGenerator* lgen : this->GlobalGenerator->GetLocalGenerators()) {
+ for (const auto& lgen : this->GlobalGenerator->GetLocalGenerators()) {
- if (const char* cdefs =
+ if (cmProp cdefs =
lgen->GetMakefile()->GetProperty("COMPILE_DEFINITIONS")) {
// Expand the list.
std::vector<std::string> defs;
- cmGeneratorExpression::Split(cdefs, defs);
+ cmGeneratorExpression::Split(*cdefs, defs);
for (std::string const& d : defs) {
if (cmGeneratorExpression::Find(d) != std::string::npos) {
@@ -859,16 +858,15 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
// include dirs
emmited.clear();
- for (cmLocalGenerator* lgen : this->GlobalGenerator->GetLocalGenerators()) {
- const std::vector<cmGeneratorTarget*>& targets =
- lgen->GetGeneratorTargets();
- for (cmGeneratorTarget* target : targets) {
+ for (const auto& lgen : this->GlobalGenerator->GetLocalGenerators()) {
+ const auto& targets = lgen->GetGeneratorTargets();
+ for (const auto& target : targets) {
if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
std::vector<std::string> includeDirs;
std::string config = mf->GetSafeDefinition("CMAKE_BUILD_TYPE");
- lgen->GetIncludeDirectories(includeDirs, target, "C", config);
+ lgen->GetIncludeDirectories(includeDirs, target.get(), "C", config);
this->AppendIncludeDirectories(xml, includeDirs, emmited);
}
}
@@ -915,16 +913,15 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
// add all executable and library targets and some of the GLOBAL
// and UTILITY targets
- for (cmLocalGenerator* lgen : this->GlobalGenerator->GetLocalGenerators()) {
- const std::vector<cmGeneratorTarget*>& targets =
- lgen->GetGeneratorTargets();
+ for (const auto& lgen : this->GlobalGenerator->GetLocalGenerators()) {
+ const auto& targets = lgen->GetGeneratorTargets();
std::string subdir = lgen->MaybeConvertToRelativePath(
this->HomeOutputDirectory, lgen->GetCurrentBinaryDirectory());
if (subdir == ".") {
subdir.clear();
}
- for (cmGeneratorTarget* target : targets) {
+ for (const auto& target : targets) {
std::string targetName = target->GetName();
switch (target->GetType()) {
case cmStateEnums::GLOBAL_TARGET: {
@@ -938,11 +935,11 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
case cmStateEnums::UTILITY:
// Add all utility targets, except the Nightly/Continuous/
// Experimental-"sub"targets as e.g. NightlyStart
- if (((targetName.find("Nightly") == 0) &&
+ if ((cmHasLiteralPrefix(targetName, "Nightly") &&
(targetName != "Nightly")) ||
- ((targetName.find("Continuous") == 0) &&
+ (cmHasLiteralPrefix(targetName, "Continuous") &&
(targetName != "Continuous")) ||
- ((targetName.find("Experimental") == 0) &&
+ (cmHasLiteralPrefix(targetName, "Experimental") &&
(targetName != "Experimental"))) {
break;
}
@@ -975,8 +972,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
std::string cleanArgs =
cmStrCat("-E chdir \"", lgen->GetCurrentBinaryDirectory(),
"\" \"", cmSystemTools::GetCMakeCommand(), "\" -P \"");
- cmGeneratorTarget* gt = target;
- cleanArgs += lgen->GetTargetDirectory(gt);
+ cleanArgs += lgen->GetTargetDirectory(target.get());
cleanArgs += "/cmake_clean.cmake\"";
cmExtraEclipseCDT4Generator::AppendTarget(
xml, "Clean", cmSystemTools::GetCMakeCommand(), cleanArgs,
@@ -984,7 +980,6 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
}
} break;
case cmStateEnums::INTERFACE_LIBRARY:
- break;
default:
break;
}
@@ -1036,9 +1031,9 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
xml.EndElement(); // storageModule
// Append additional cproject contents without applying any XML formatting
- if (const char* extraCProjectContents =
+ if (cmProp extraCProjectContents =
mf->GetState()->GetGlobalProperty("ECLIPSE_EXTRA_CPROJECT_CONTENTS")) {
- fout << extraCProjectContents;
+ fout << *extraCProjectContents;
}
xml.EndElement(); // cproject
diff --git a/Source/cmExtraEclipseCDT4Generator.h b/Source/cmExtraEclipseCDT4Generator.h
index ff4c59e..a7aa549 100644
--- a/Source/cmExtraEclipseCDT4Generator.h
+++ b/Source/cmExtraEclipseCDT4Generator.h
@@ -86,7 +86,7 @@ private:
std::set<std::string>& emittedDirs);
static void AddEnvVar(std::ostream& out, const char* envVar,
- cmLocalGenerator* lg);
+ cmLocalGenerator& lg);
void WriteGroups(std::vector<cmSourceGroup> const& sourceGroups,
std::string& linkName, cmXMLWriter& xml);
diff --git a/Source/cmExtraKateGenerator.cxx b/Source/cmExtraKateGenerator.cxx
index e8c9dd0..01fac5a 100644
--- a/Source/cmExtraKateGenerator.cxx
+++ b/Source/cmExtraKateGenerator.cxx
@@ -3,6 +3,7 @@
#include "cmExtraKateGenerator.h"
#include <cstring>
+#include <memory>
#include <ostream>
#include <set>
#include <vector>
@@ -40,21 +41,21 @@ cmExternalMakefileProjectGeneratorFactory* cmExtraKateGenerator::GetFactory()
void cmExtraKateGenerator::Generate()
{
- cmLocalGenerator* lg = this->GlobalGenerator->GetLocalGenerators()[0];
+ const auto& lg = this->GlobalGenerator->GetLocalGenerators()[0];
const cmMakefile* mf = lg->GetMakefile();
this->ProjectName = this->GenerateProjectName(
lg->GetProjectName(), mf->GetSafeDefinition("CMAKE_BUILD_TYPE"),
this->GetPathBasename(lg->GetBinaryDirectory()));
this->UseNinja = (this->GlobalGenerator->GetName() == "Ninja");
- this->CreateKateProjectFile(lg);
- this->CreateDummyKateProjectFile(lg);
+ this->CreateKateProjectFile(*lg);
+ this->CreateDummyKateProjectFile(*lg);
}
void cmExtraKateGenerator::CreateKateProjectFile(
- const cmLocalGenerator* lg) const
+ const cmLocalGenerator& lg) const
{
- std::string filename = cmStrCat(lg->GetBinaryDirectory(), "/.kateproject");
+ std::string filename = cmStrCat(lg.GetBinaryDirectory(), "/.kateproject");
cmGeneratedFileStream fout(filename);
if (!fout) {
return;
@@ -64,21 +65,21 @@ void cmExtraKateGenerator::CreateKateProjectFile(
fout <<
"{\n"
"\t\"name\": \"" << this->ProjectName << "\",\n"
- "\t\"directory\": \"" << lg->GetSourceDirectory() << "\",\n"
+ "\t\"directory\": \"" << lg.GetSourceDirectory() << "\",\n"
"\t\"files\": [ { " << this->GenerateFilesString(lg) << "} ],\n";
/* clang-format on */
this->WriteTargets(lg, fout);
fout << "}\n";
}
-void cmExtraKateGenerator::WriteTargets(const cmLocalGenerator* lg,
+void cmExtraKateGenerator::WriteTargets(const cmLocalGenerator& lg,
cmGeneratedFileStream& fout) const
{
- cmMakefile const* mf = lg->GetMakefile();
+ cmMakefile const* mf = lg.GetMakefile();
const std::string& make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
const std::string& makeArgs =
mf->GetSafeDefinition("CMAKE_KATE_MAKE_ARGUMENTS");
- std::string const& homeOutputDir = lg->GetBinaryDirectory();
+ std::string const& homeOutputDir = lg.GetBinaryDirectory();
/* clang-format off */
fout <<
@@ -109,14 +110,12 @@ void cmExtraKateGenerator::WriteTargets(const cmLocalGenerator* lg,
// add all executable and library targets and some of the GLOBAL
// and UTILITY targets
- for (cmLocalGenerator* localGen :
- this->GlobalGenerator->GetLocalGenerators()) {
- const std::vector<cmGeneratorTarget*>& targets =
- localGen->GetGeneratorTargets();
+ for (const auto& localGen : this->GlobalGenerator->GetLocalGenerators()) {
+ const auto& targets = localGen->GetGeneratorTargets();
std::string currentDir = localGen->GetCurrentBinaryDirectory();
bool topLevel = (currentDir == localGen->GetBinaryDirectory());
- for (cmGeneratorTarget* target : targets) {
+ for (const auto& target : targets) {
std::string const& targetName = target->GetName();
switch (target->GetType()) {
case cmStateEnums::GLOBAL_TARGET: {
@@ -130,9 +129,8 @@ void cmExtraKateGenerator::WriteTargets(const cmLocalGenerator* lg,
if (targetName == "edit_cache") {
const char* editCommand =
localGen->GetMakefile()->GetDefinition("CMAKE_EDIT_COMMAND");
- if (editCommand == nullptr) {
- insertTarget = false;
- } else if (strstr(editCommand, "ccmake") != nullptr) {
+ if (editCommand == nullptr ||
+ strstr(editCommand, "ccmake") != nullptr) {
insertTarget = false;
}
}
@@ -145,11 +143,11 @@ void cmExtraKateGenerator::WriteTargets(const cmLocalGenerator* lg,
case cmStateEnums::UTILITY:
// Add all utility targets, except the Nightly/Continuous/
// Experimental-"sub"targets as e.g. NightlyStart
- if (((targetName.find("Nightly") == 0) &&
+ if ((cmHasLiteralPrefix(targetName, "Nightly") &&
(targetName != "Nightly")) ||
- ((targetName.find("Continuous") == 0) &&
+ (cmHasLiteralPrefix(targetName, "Continuous") &&
(targetName != "Continuous")) ||
- ((targetName.find("Experimental") == 0) &&
+ (cmHasLiteralPrefix(targetName, "Experimental") &&
(targetName != "Experimental"))) {
break;
}
@@ -205,10 +203,10 @@ void cmExtraKateGenerator::AppendTarget(cmGeneratedFileStream& fout,
}
void cmExtraKateGenerator::CreateDummyKateProjectFile(
- const cmLocalGenerator* lg) const
+ const cmLocalGenerator& lg) const
{
std::string filename =
- cmStrCat(lg->GetBinaryDirectory(), '/', this->ProjectName, ".kateproject");
+ cmStrCat(lg.GetBinaryDirectory(), '/', this->ProjectName, ".kateproject");
cmGeneratedFileStream fout(filename);
if (!fout) {
return;
@@ -219,26 +217,25 @@ void cmExtraKateGenerator::CreateDummyKateProjectFile(
}
std::string cmExtraKateGenerator::GenerateFilesString(
- const cmLocalGenerator* lg) const
+ const cmLocalGenerator& lg) const
{
- std::string s = cmStrCat(lg->GetSourceDirectory(), "/.git");
+ std::string s = cmStrCat(lg.GetSourceDirectory(), "/.git");
if (cmSystemTools::FileExists(s)) {
return "\"git\": 1 ";
}
- s = cmStrCat(lg->GetSourceDirectory(), "/.svn");
+ s = cmStrCat(lg.GetSourceDirectory(), "/.svn");
if (cmSystemTools::FileExists(s)) {
return "\"svn\": 1 ";
}
- s = cmStrCat(lg->GetSourceDirectory(), '/');
+ s = cmStrCat(lg.GetSourceDirectory(), '/');
std::set<std::string> files;
std::string tmp;
- const std::vector<cmLocalGenerator*>& lgs =
- this->GlobalGenerator->GetLocalGenerators();
+ const auto& lgs = this->GlobalGenerator->GetLocalGenerators();
- for (cmLocalGenerator* lgen : lgs) {
+ for (const auto& lgen : lgs) {
cmMakefile* makefile = lgen->GetMakefile();
const std::vector<std::string>& listFiles = makefile->GetListFiles();
for (std::string const& listFile : listFiles) {
@@ -248,8 +245,7 @@ std::string cmExtraKateGenerator::GenerateFilesString(
}
}
- const std::vector<cmSourceFile*>& sources = makefile->GetSourceFiles();
- for (cmSourceFile* sf : sources) {
+ for (const auto& sf : makefile->GetSourceFiles()) {
if (sf->GetIsGenerated()) {
continue;
}
@@ -277,7 +273,7 @@ std::string cmExtraKateGenerator::GenerateProjectName(
const std::string& name, const std::string& type,
const std::string& path) const
{
- return name + (type.empty() ? "" : "-") + type + "@" + path;
+ return name + (type.empty() ? "" : "-") + type + '@' + path;
}
std::string cmExtraKateGenerator::GetPathBasename(
diff --git a/Source/cmExtraKateGenerator.h b/Source/cmExtraKateGenerator.h
index be1376a..1fb81b4 100644
--- a/Source/cmExtraKateGenerator.h
+++ b/Source/cmExtraKateGenerator.h
@@ -25,16 +25,16 @@ public:
void Generate() override;
private:
- void CreateKateProjectFile(const cmLocalGenerator* lg) const;
- void CreateDummyKateProjectFile(const cmLocalGenerator* lg) const;
- void WriteTargets(const cmLocalGenerator* lg,
+ void CreateKateProjectFile(const cmLocalGenerator& lg) const;
+ void CreateDummyKateProjectFile(const cmLocalGenerator& lg) const;
+ void WriteTargets(const cmLocalGenerator& lg,
cmGeneratedFileStream& fout) const;
void AppendTarget(cmGeneratedFileStream& fout, const std::string& target,
const std::string& make, const std::string& makeArgs,
const std::string& path,
const std::string& homeOutputDir) const;
- std::string GenerateFilesString(const cmLocalGenerator* lg) const;
+ std::string GenerateFilesString(const cmLocalGenerator& lg) const;
std::string GetPathBasename(const std::string& path) const;
std::string GenerateProjectName(const std::string& name,
const std::string& type,
diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx
index 495324c..6dbc7b7 100644
--- a/Source/cmExtraSublimeTextGenerator.cxx
+++ b/Source/cmExtraSublimeTextGenerator.cxx
@@ -3,6 +3,7 @@
#include "cmExtraSublimeTextGenerator.h"
#include <cstring>
+#include <memory>
#include <set>
#include <sstream>
#include <utility>
@@ -22,6 +23,8 @@
#include "cmSystemTools.h"
#include "cmake.h"
+using cmProp = const std::string*; // just to silence IWYU
+
/*
Sublime Text 2 Generator
Author: Morné Chamberlain
@@ -182,8 +185,8 @@ void cmExtraSublimeTextGenerator::AppendAllTargets(
// and UTILITY targets
for (cmLocalGenerator* lg : lgs) {
cmMakefile* makefile = lg->GetMakefile();
- const std::vector<cmGeneratorTarget*>& targets = lg->GetGeneratorTargets();
- for (cmGeneratorTarget* target : targets) {
+ const auto& targets = lg->GetGeneratorTargets();
+ for (const auto& target : targets) {
std::string targetName = target->GetName();
switch (target->GetType()) {
case cmStateEnums::GLOBAL_TARGET: {
@@ -198,11 +201,11 @@ void cmExtraSublimeTextGenerator::AppendAllTargets(
case cmStateEnums::UTILITY:
// Add all utility targets, except the Nightly/Continuous/
// Experimental-"sub"targets as e.g. NightlyStart
- if (((targetName.find("Nightly") == 0) &&
+ if ((cmHasLiteralPrefix(targetName, "Nightly") &&
(targetName != "Nightly")) ||
- ((targetName.find("Continuous") == 0) &&
+ (cmHasLiteralPrefix(targetName, "Continuous") &&
(targetName != "Continuous")) ||
- ((targetName.find("Experimental") == 0) &&
+ (cmHasLiteralPrefix(targetName, "Experimental") &&
(targetName != "Experimental"))) {
break;
}
@@ -216,11 +219,11 @@ void cmExtraSublimeTextGenerator::AppendAllTargets(
case cmStateEnums::SHARED_LIBRARY:
case cmStateEnums::MODULE_LIBRARY:
case cmStateEnums::OBJECT_LIBRARY: {
- this->AppendTarget(fout, targetName, lg, target, make.c_str(),
+ this->AppendTarget(fout, targetName, lg, target.get(), make.c_str(),
makefile, compiler.c_str(), sourceFileFlags,
false);
std::string fastTarget = cmStrCat(targetName, "/fast");
- this->AppendTarget(fout, fastTarget, lg, target, make.c_str(),
+ this->AppendTarget(fout, fastTarget, lg, target.get(), make.c_str(),
makefile, compiler.c_str(), sourceFileFlags,
false);
} break;
@@ -296,8 +299,7 @@ void cmExtraSublimeTextGenerator::AppendTarget(
fout << "\t{\n\t\t\t\"name\": \"" << lg->GetProjectName() << " - "
<< targetName << "\",\n";
fout << "\t\t\t\"cmd\": ["
- << this->BuildMakeCommand(make, makefileName.c_str(), targetName)
- << "],\n";
+ << this->BuildMakeCommand(make, makefileName, targetName) << "],\n";
fout << "\t\t\t\"working_dir\": \"${project_path}\",\n";
fout << "\t\t\t\"file_regex\": \""
"^(..[^:]*)(?::|\\\\()([0-9]+)(?::|\\\\))(?:([0-9]+):)?\\\\s*(.*)"
@@ -308,7 +310,8 @@ void cmExtraSublimeTextGenerator::AppendTarget(
// Create the command line for building the given target using the selected
// make
std::string cmExtraSublimeTextGenerator::BuildMakeCommand(
- const std::string& make, const char* makefile, const std::string& target)
+ const std::string& make, const std::string& makefile,
+ const std::string& target)
{
std::string command = cmStrCat('"', make, '"');
std::string generator = this->GlobalGenerator->GetName();
@@ -357,14 +360,14 @@ std::string cmExtraSublimeTextGenerator::ComputeFlagsForObject(
language);
const std::string COMPILE_FLAGS("COMPILE_FLAGS");
- if (const char* cflags = source->GetProperty(COMPILE_FLAGS)) {
- lg->AppendFlags(flags, genexInterpreter.Evaluate(cflags, COMPILE_FLAGS));
+ if (cmProp cflags = source->GetProperty(COMPILE_FLAGS)) {
+ lg->AppendFlags(flags, genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS));
}
const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
- if (const char* coptions = source->GetProperty(COMPILE_OPTIONS)) {
+ if (cmProp coptions = source->GetProperty(COMPILE_OPTIONS)) {
lg->AppendCompileOptions(
- flags, genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS));
+ flags, genexInterpreter.Evaluate(*coptions, COMPILE_OPTIONS));
}
return flags;
@@ -386,17 +389,17 @@ std::string cmExtraSublimeTextGenerator::ComputeDefines(
// Add preprocessor definitions for this target and configuration.
lg->GetTargetDefines(target, config, language, defines);
const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS");
- if (const char* compile_defs = source->GetProperty(COMPILE_DEFINITIONS)) {
+ if (cmProp compile_defs = source->GetProperty(COMPILE_DEFINITIONS)) {
lg->AppendDefines(
- defines, genexInterpreter.Evaluate(compile_defs, COMPILE_DEFINITIONS));
+ defines, genexInterpreter.Evaluate(*compile_defs, COMPILE_DEFINITIONS));
}
std::string defPropName =
cmStrCat("COMPILE_DEFINITIONS_", cmSystemTools::UpperCase(config));
- if (const char* config_compile_defs = source->GetProperty(defPropName)) {
+ if (cmProp config_compile_defs = source->GetProperty(defPropName)) {
lg->AppendDefines(
defines,
- genexInterpreter.Evaluate(config_compile_defs, COMPILE_DEFINITIONS));
+ genexInterpreter.Evaluate(*config_compile_defs, COMPILE_DEFINITIONS));
}
std::string definesString;
@@ -418,9 +421,9 @@ std::string cmExtraSublimeTextGenerator::ComputeIncludes(
// Add include directories for this source file
const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
- if (const char* cincludes = source->GetProperty(INCLUDE_DIRECTORIES)) {
+ if (cmProp cincludes = source->GetProperty(INCLUDE_DIRECTORIES)) {
lg->AppendIncludeDirectories(
- includes, genexInterpreter.Evaluate(cincludes, INCLUDE_DIRECTORIES),
+ includes, genexInterpreter.Evaluate(*cincludes, INCLUDE_DIRECTORIES),
*source);
}
diff --git a/Source/cmExtraSublimeTextGenerator.h b/Source/cmExtraSublimeTextGenerator.h
index 7e8f2d4..078cfe7 100644
--- a/Source/cmExtraSublimeTextGenerator.h
+++ b/Source/cmExtraSublimeTextGenerator.h
@@ -44,7 +44,8 @@ private:
/** Returns the build command that needs to be executed to build the
* specified target.
*/
- std::string BuildMakeCommand(const std::string& make, const char* makefile,
+ std::string BuildMakeCommand(const std::string& make,
+ const std::string& makefile,
const std::string& target);
/** Appends the specified target to the generated project file as a Sublime
* Text build system.
diff --git a/Source/cmFLTKWrapUICommand.cxx b/Source/cmFLTKWrapUICommand.cxx
index 11844e4..d88617a 100644
--- a/Source/cmFLTKWrapUICommand.cxx
+++ b/Source/cmFLTKWrapUICommand.cxx
@@ -6,15 +6,20 @@
#include "cmCustomCommandLines.h"
#include "cmExecutionStatus.h"
+#include "cmListFileCache.h"
+#include "cmLocalGenerator.h"
#include "cmMakefile.h"
+#include "cmMessageType.h"
#include "cmRange.h"
#include "cmSourceFile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmake.h"
class cmTarget;
-static void FinalAction(cmMakefile& makefile, std::string const& name)
+static void FinalAction(cmMakefile& makefile, std::string const& name,
+ const cmListFileBacktrace& lfbt)
{
// people should add the srcs to the target themselves, but the old command
// didn't support that, so check and see if they added the files in and if
@@ -26,7 +31,8 @@ static void FinalAction(cmMakefile& makefile, std::string const& name)
". The problem was found while processing the source directory: ",
makefile.GetCurrentSourceDirectory(),
". This FLTK_WRAP_UI call will be ignored.");
- cmSystemTools::Message(msg, "Warning");
+ makefile.GetCMakeInstance()->IssueMessage(MessageType::AUTHOR_ERROR, msg,
+ lfbt);
}
}
@@ -116,7 +122,9 @@ bool cmFLTKWrapUICommand(std::vector<std::string> const& args,
std::string const varName = target + "_FLTK_UI_SRCS";
mf.AddDefinition(varName, sourceListValue);
- mf.AddFinalAction(
- [target](cmMakefile& makefile) { FinalAction(makefile, target); });
+ mf.AddGeneratorAction(
+ [target](cmLocalGenerator& lg, const cmListFileBacktrace& lfbt) {
+ FinalAction(*lg.GetMakefile(), target, lfbt);
+ });
return true;
}
diff --git a/Source/cmFileAPI.h b/Source/cmFileAPI.h
index e183e0d..ae07612 100644
--- a/Source/cmFileAPI.h
+++ b/Source/cmFileAPI.h
@@ -11,9 +11,9 @@
#include <unordered_set>
#include <vector>
-#include "cm_jsoncpp_reader.h"
-#include "cm_jsoncpp_value.h"
-#include "cm_jsoncpp_writer.h"
+#include <cm3p/json/reader.h>
+#include <cm3p/json/value.h>
+#include <cm3p/json/writer.h>
class cmake;
diff --git a/Source/cmFileAPICMakeFiles.cxx b/Source/cmFileAPICMakeFiles.cxx
index f419997..1e4f3b6 100644
--- a/Source/cmFileAPICMakeFiles.cxx
+++ b/Source/cmFileAPICMakeFiles.cxx
@@ -2,10 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmFileAPICMakeFiles.h"
+#include <memory>
#include <string>
#include <vector>
-#include "cm_jsoncpp_value.h"
+#include <cm3p/json/value.h>
#include "cmFileAPI.h"
#include "cmGlobalGenerator.h"
@@ -67,7 +68,7 @@ Json::Value CMakeFiles::DumpInputs()
cmGlobalGenerator* gg =
this->FileAPI.GetCMakeInstance()->GetGlobalGenerator();
- for (cmLocalGenerator const* lg : gg->GetLocalGenerators()) {
+ for (const auto& lg : gg->GetLocalGenerators()) {
cmMakefile const* mf = lg->GetMakefile();
for (std::string const& file : mf->GetListFiles()) {
inputs.append(this->DumpInput(file));
diff --git a/Source/cmFileAPICMakeFiles.h b/Source/cmFileAPICMakeFiles.h
index a851c32..1ae1e4f 100644
--- a/Source/cmFileAPICMakeFiles.h
+++ b/Source/cmFileAPICMakeFiles.h
@@ -5,7 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cm_jsoncpp_value.h"
+#include <cm3p/json/value.h>
class cmFileAPI;
diff --git a/Source/cmFileAPICache.cxx b/Source/cmFileAPICache.cxx
index ef77795..25e5916 100644
--- a/Source/cmFileAPICache.cxx
+++ b/Source/cmFileAPICache.cxx
@@ -7,7 +7,7 @@
#include <utility>
#include <vector>
-#include "cm_jsoncpp_value.h"
+#include <cm3p/json/value.h>
#include "cmFileAPI.h"
#include "cmState.h"
@@ -67,7 +67,7 @@ Json::Value Cache::DumpEntry(std::string const& name)
entry["name"] = name;
entry["type"] =
cmState::CacheEntryTypeToString(this->State->GetCacheEntryType(name));
- entry["value"] = this->State->GetCacheEntryValue(name);
+ entry["value"] = this->State->GetSafeCacheEntryValue(name);
Json::Value properties = this->DumpEntryProperties(name);
if (!properties.empty()) {
@@ -94,7 +94,8 @@ Json::Value Cache::DumpEntryProperty(std::string const& name,
{
Json::Value property = Json::objectValue;
property["name"] = prop;
- property["value"] = this->State->GetCacheEntryProperty(name, prop);
+ cmProp p = this->State->GetCacheEntryProperty(name, prop);
+ property["value"] = p ? *p : "";
return property;
}
}
diff --git a/Source/cmFileAPICache.h b/Source/cmFileAPICache.h
index 09d9e1c..2f30c76 100644
--- a/Source/cmFileAPICache.h
+++ b/Source/cmFileAPICache.h
@@ -5,7 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cm_jsoncpp_value.h"
+#include <cm3p/json/value.h>
class cmFileAPI;
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx
index d7993c7..b983b21 100644
--- a/Source/cmFileAPICodemodel.cxx
+++ b/Source/cmFileAPICodemodel.cxx
@@ -15,9 +15,10 @@
#include <utility>
#include <vector>
-#include "cm_jsoncpp_value.h"
+#include <cmext/algorithm>
+
+#include <cm3p/json/value.h>
-#include "cmAlgorithms.h"
#include "cmCryptoHash.h"
#include "cmFileAPI.h"
#include "cmGeneratorExpression.h"
@@ -426,7 +427,7 @@ Json::Value Codemodel::DumpConfigurations()
Json::Value configurations = Json::arrayValue;
cmGlobalGenerator* gg =
this->FileAPI.GetCMakeInstance()->GetGlobalGenerator();
- auto makefiles = gg->GetMakefiles();
+ const auto& makefiles = gg->GetMakefiles();
if (!makefiles.empty()) {
std::vector<std::string> const& configs =
makefiles[0]->GetGeneratorConfigs();
@@ -469,17 +470,17 @@ void CodemodelConfig::ProcessDirectories()
{
cmGlobalGenerator* gg =
this->FileAPI.GetCMakeInstance()->GetGlobalGenerator();
- std::vector<cmLocalGenerator*> const& localGens = gg->GetLocalGenerators();
+ auto const& localGens = gg->GetLocalGenerators();
// Add directories in forward order to process parents before children.
this->Directories.reserve(localGens.size());
- for (cmLocalGenerator* lg : localGens) {
+ for (const auto& lg : localGens) {
auto directoryIndex =
static_cast<Json::ArrayIndex>(this->Directories.size());
this->Directories.emplace_back();
Directory& d = this->Directories[directoryIndex];
d.Snapshot = lg->GetStateSnapshot().GetBuildsystemDirectory();
- d.LocalGenerator = lg;
+ d.LocalGenerator = lg.get();
this->DirectoryMap[d.Snapshot] = directoryIndex;
d.ProjectIndex = this->AddProject(d.Snapshot);
@@ -492,8 +493,9 @@ void CodemodelConfig::ProcessDirectories()
Directory& d = *di;
// Accumulate the presence of install rules on the way up.
- for (auto gen : d.LocalGenerator->GetMakefile()->GetInstallGenerators()) {
- if (!dynamic_cast<cmInstallSubdirectoryGenerator*>(gen)) {
+ for (const auto& gen :
+ d.LocalGenerator->GetMakefile()->GetInstallGenerators()) {
+ if (!dynamic_cast<cmInstallSubdirectoryGenerator*>(gen.get())) {
d.HasInstallRule = true;
break;
}
@@ -554,8 +556,8 @@ Json::Value CodemodelConfig::DumpTargets()
std::vector<cmGeneratorTarget*> targetList;
cmGlobalGenerator* gg =
this->FileAPI.GetCMakeInstance()->GetGlobalGenerator();
- for (cmLocalGenerator const* lg : gg->GetLocalGenerators()) {
- cmAppend(targetList, lg->GetGeneratorTargets());
+ for (const auto& lg : gg->GetLocalGenerators()) {
+ cm::append(targetList, lg->GetGeneratorTargets());
}
std::sort(targetList.begin(), targetList.end(),
[](cmGeneratorTarget* l, cmGeneratorTarget* r) {
@@ -853,8 +855,8 @@ CompileData Target::BuildCompileData(cmSourceFile* sf)
fd.Language);
const std::string COMPILE_FLAGS("COMPILE_FLAGS");
- if (const char* cflags = sf->GetProperty(COMPILE_FLAGS)) {
- std::string flags = genexInterpreter.Evaluate(cflags, COMPILE_FLAGS);
+ if (cmProp cflags = sf->GetProperty(COMPILE_FLAGS)) {
+ std::string flags = genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS);
fd.Flags.emplace_back(std::move(flags), JBTIndex());
}
const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
@@ -870,14 +872,27 @@ CompileData Target::BuildCompileData(cmSourceFile* sf)
}
// Add precompile headers compile options.
- const std::string pchSource =
- this->GT->GetPchSource(this->Config, fd.Language);
+ std::vector<std::string> architectures;
+ this->GT->GetAppleArchs(this->Config, architectures);
+ if (architectures.empty()) {
+ architectures.emplace_back();
+ }
+
+ std::unordered_map<std::string, std::string> pchSources;
+ for (const std::string& arch : architectures) {
+ const std::string pchSource =
+ this->GT->GetPchSource(this->Config, fd.Language, arch);
+ if (!pchSource.empty()) {
+ pchSources.insert(std::make_pair(pchSource, arch));
+ }
+ }
- if (!pchSource.empty() && !sf->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
+ if (!pchSources.empty() && !sf->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
std::string pchOptions;
- if (sf->ResolveFullPath() == pchSource) {
- pchOptions =
- this->GT->GetPchCreateCompileOptions(this->Config, fd.Language);
+ auto pchIt = pchSources.find(sf->ResolveFullPath());
+ if (pchIt != pchSources.end()) {
+ pchOptions = this->GT->GetPchCreateCompileOptions(
+ this->Config, fd.Language, pchIt->second);
} else {
pchOptions =
this->GT->GetPchUseCompileOptions(this->Config, fd.Language);
@@ -934,10 +949,10 @@ CompileData Target::BuildCompileData(cmSourceFile* sf)
std::set<std::string> configFileDefines;
const std::string defPropName =
"COMPILE_DEFINITIONS_" + cmSystemTools::UpperCase(this->Config);
- if (const char* config_defs = sf->GetProperty(defPropName)) {
+ if (cmProp config_defs = sf->GetProperty(defPropName)) {
lg->AppendDefines(
configFileDefines,
- genexInterpreter.Evaluate(config_defs, COMPILE_DEFINITIONS));
+ genexInterpreter.Evaluate(*config_defs, COMPILE_DEFINITIONS));
}
fd.Defines.reserve(fileDefines.size() + configFileDefines.size());
@@ -1409,9 +1424,9 @@ Json::Value Target::DumpDependency(cmTargetDepend const& td)
Json::Value Target::DumpFolder()
{
Json::Value folder;
- if (const char* f = this->GT->GetProperty("FOLDER")) {
+ if (cmProp f = this->GT->GetProperty("FOLDER")) {
folder = Json::objectValue;
- folder["name"] = f;
+ folder["name"] = *f;
}
return folder;
}
diff --git a/Source/cmFileAPICodemodel.h b/Source/cmFileAPICodemodel.h
index ffbd928..a6c6bdd 100644
--- a/Source/cmFileAPICodemodel.h
+++ b/Source/cmFileAPICodemodel.h
@@ -5,7 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cm_jsoncpp_value.h"
+#include <cm3p/json/value.h>
class cmFileAPI;
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index d45414f..f3d49c3 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -8,6 +8,7 @@
#include <cmath>
#include <cstdio>
#include <cstdlib>
+#include <iterator>
#include <map>
#include <set>
#include <sstream>
@@ -15,13 +16,15 @@
#include <vector>
#include <cm/memory>
+#include <cmext/algorithm>
+#include <cmext/string_view>
+
+#include <cm3p/kwiml/int.h>
#include "cmsys/FStream.hxx"
#include "cmsys/Glob.hxx"
#include "cmsys/RegularExpression.hxx"
-#include "cm_kwiml.h"
-#include "cm_static_string_view.hxx"
#include "cm_sys_stat.h"
#include "cmAlgorithms.h"
@@ -32,12 +35,14 @@
#include "cmFileInstaller.h"
#include "cmFileLockPool.h"
#include "cmFileTimes.h"
+#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
#include "cmHexFileConverter.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmNewLineStyle.h"
#include "cmPolicies.h"
#include "cmRange.h"
#include "cmRuntimeDependencyArchive.h"
@@ -46,10 +51,11 @@
#include "cmSubcommandTable.h"
#include "cmSystemTools.h"
#include "cmTimestamp.h"
+#include "cmWorkingDirectory.h"
#include "cmake.h"
#if !defined(CMAKE_BOOTSTRAP)
-# include "cm_curl.h"
+# include <cm3p/curl/curl.h>
# include "cmCurl.h"
# include "cmFileLockResult.h"
@@ -783,7 +789,7 @@ bool HandleGlobImpl(std::vector<std::string> const& args, bool recurse,
}
std::vector<std::string>& foundFiles = g.GetFiles();
- cmAppend(files, foundFiles);
+ cm::append(files, foundFiles);
if (configureDepends) {
std::sort(foundFiles.begin(), foundFiles.end());
@@ -1394,8 +1400,8 @@ size_t cmWriteToMemoryCallback(void* ptr, size_t size, size_t nmemb,
{
int realsize = static_cast<int>(size * nmemb);
const char* chPtr = static_cast<char*>(ptr);
- cmAppend(*static_cast<cmFileCommandVectorOfChar*>(data), chPtr,
- chPtr + realsize);
+ cm::append(*static_cast<cmFileCommandVectorOfChar*>(data), chPtr,
+ chPtr + realsize);
return realsize;
}
@@ -1408,7 +1414,7 @@ size_t cmFileCommandCurlDebugCallback(CURL*, curl_infotype type, char* chPtr,
case CURLINFO_TEXT:
case CURLINFO_HEADER_IN:
case CURLINFO_HEADER_OUT:
- cmAppend(vec, chPtr, chPtr + size);
+ cm::append(vec, chPtr, chPtr + size);
break;
case CURLINFO_DATA_IN:
case CURLINFO_DATA_OUT:
@@ -1418,7 +1424,7 @@ size_t cmFileCommandCurlDebugCallback(CURL*, curl_infotype type, char* chPtr,
int n = sprintf(buf, "[%" KWIML_INT_PRIu64 " bytes data]\n",
static_cast<KWIML_INT_uint64_t>(size));
if (n > 0) {
- cmAppend(vec, buf, buf + n);
+ cm::append(vec, buf, buf + n);
}
} break;
default:
@@ -1605,7 +1611,7 @@ bool HandleDownloadCommand(std::vector<std::string> const& args,
if (i != args.end()) {
tls_verify = cmIsOn(*i);
} else {
- status.SetError("TLS_VERIFY missing bool value.");
+ status.SetError("DOWNLOAD missing bool value for TLS_VERIFY.");
return false;
}
} else if (*i == "TLS_CAINFO") {
@@ -1613,7 +1619,7 @@ bool HandleDownloadCommand(std::vector<std::string> const& args,
if (i != args.end()) {
cainfo = i->c_str();
} else {
- status.SetError("TLS_CAFILE missing file value.");
+ status.SetError("DOWNLOAD missing file value for TLS_CAINFO.");
return false;
}
} else if (*i == "NETRC_FILE") {
@@ -1707,7 +1713,8 @@ bool HandleDownloadCommand(std::vector<std::string> const& args,
// as we receive downloaded bits from curl...
//
std::string dir = cmSystemTools::GetFilenamePath(file);
- if (!cmSystemTools::FileExists(dir) && !cmSystemTools::MakeDirectory(dir)) {
+ if (!dir.empty() && !cmSystemTools::FileExists(dir) &&
+ !cmSystemTools::MakeDirectory(dir)) {
std::string errstring = "DOWNLOAD error: cannot create directory '" + dir +
"' - Specify file by full path name and verify that you "
"have directory creation and file write privileges.";
@@ -1754,11 +1761,12 @@ bool HandleDownloadCommand(std::vector<std::string> const& args,
// check to see if TLS verification is requested
if (tls_verify) {
res = ::curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1);
- check_curl_result(res, "Unable to set TLS/SSL Verify on: ");
+ check_curl_result(res, "DOWNLOAD cannot set TLS/SSL Verify on: ");
} else {
res = ::curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
- check_curl_result(res, "Unable to set TLS/SSL Verify off: ");
+ check_curl_result(res, "DOWNLOAD cannot set TLS/SSL Verify off: ");
}
+
// check to see if a CAINFO file has been specified
// command arg comes first
std::string const& cainfo_err = cmCurlSetCAInfo(curl, cainfo);
@@ -1923,6 +1931,8 @@ bool HandleUploadCommand(std::vector<std::string> const& args,
std::string logVar;
std::string statusVar;
bool showProgress = false;
+ bool tls_verify = status.GetMakefile().IsOn("CMAKE_TLS_VERIFY");
+ const char* cainfo = status.GetMakefile().GetDefinition("CMAKE_TLS_CAINFO");
std::string userpwd;
std::string netrc_level =
status.GetMakefile().GetSafeDefinition("CMAKE_NETRC");
@@ -1964,6 +1974,22 @@ bool HandleUploadCommand(std::vector<std::string> const& args,
statusVar = *i;
} else if (*i == "SHOW_PROGRESS") {
showProgress = true;
+ } else if (*i == "TLS_VERIFY") {
+ ++i;
+ if (i != args.end()) {
+ tls_verify = cmIsOn(*i);
+ } else {
+ status.SetError("UPLOAD missing bool value for TLS_VERIFY.");
+ return false;
+ }
+ } else if (*i == "TLS_CAINFO") {
+ ++i;
+ if (i != args.end()) {
+ cainfo = i->c_str();
+ } else {
+ status.SetError("UPLOAD missing file value for TLS_CAINFO.");
+ return false;
+ }
} else if (*i == "NETRC_FILE") {
++i;
if (i != args.end()) {
@@ -2049,6 +2075,23 @@ bool HandleUploadCommand(std::vector<std::string> const& args,
cmFileCommandCurlDebugCallback);
check_curl_result(res, "UPLOAD cannot set debug function: ");
+ // check to see if TLS verification is requested
+ if (tls_verify) {
+ res = ::curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1);
+ check_curl_result(res, "UPLOAD cannot set TLS/SSL Verify on: ");
+ } else {
+ res = ::curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
+ check_curl_result(res, "UPLOAD cannot set TLS/SSL Verify off: ");
+ }
+
+ // check to see if a CAINFO file has been specified
+ // command arg comes first
+ std::string const& cainfo_err = cmCurlSetCAInfo(curl, cainfo);
+ if (!cainfo_err.empty()) {
+ status.SetError(cainfo_err);
+ return false;
+ }
+
cmFileCommandVectorOfChar chunkResponse;
cmFileCommandVectorOfChar chunkDebug;
@@ -2321,12 +2364,9 @@ bool HandleLockCommand(std::vector<std::string> const& args,
path += "/cmake.lock";
}
- if (!cmsys::SystemTools::FileIsFullPath(path)) {
- path = status.GetMakefile().GetCurrentSourceDirectory() + "/" + path;
- }
-
// Unify path (remove '//', '/../', ...)
- path = cmSystemTools::CollapseFullPath(path);
+ path = cmSystemTools::CollapseFullPath(
+ path, status.GetMakefile().GetCurrentSourceDirectory());
// Create file and directories if needed
std::string parentDir = cmSystemTools::GetParentDirectory(path);
@@ -2774,6 +2814,325 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args,
return true;
}
+bool HandleConfigureCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ if (args.size() < 5) {
+ status.SetError("Incorrect arguments to CONFIGURE subcommand.");
+ return false;
+ }
+ if (args[1] != "OUTPUT") {
+ status.SetError("Incorrect arguments to CONFIGURE subcommand.");
+ return false;
+ }
+ if (args[3] != "CONTENT") {
+ status.SetError("Incorrect arguments to CONFIGURE subcommand.");
+ return false;
+ }
+
+ std::string errorMessage;
+ cmNewLineStyle newLineStyle;
+ if (!newLineStyle.ReadFromArguments(args, errorMessage)) {
+ status.SetError(cmStrCat("CONFIGURE ", errorMessage));
+ return false;
+ }
+
+ bool escapeQuotes = false;
+ bool atOnly = false;
+ for (unsigned int i = 5; i < args.size(); ++i) {
+ if (args[i] == "@ONLY") {
+ atOnly = true;
+ } else if (args[i] == "ESCAPE_QUOTES") {
+ escapeQuotes = true;
+ } else if (args[i] == "NEWLINE_STYLE" || args[i] == "LF" ||
+ args[i] == "UNIX" || args[i] == "CRLF" || args[i] == "WIN32" ||
+ args[i] == "DOS") {
+ /* Options handled by NewLineStyle member above. */
+ } else {
+ status.SetError(
+ cmStrCat("CONFIGURE Unrecognized argument \"", args[i], "\""));
+ return false;
+ }
+ }
+
+ // Check for generator expressions
+ const std::string input = args[4];
+ std::string outputFile = args[2];
+
+ std::string::size_type pos = input.find_first_of("<>");
+ if (pos != std::string::npos) {
+ status.SetError(cmStrCat("CONFIGURE called with CONTENT containing a \"",
+ input[pos],
+ "\". This character is not allowed."));
+ return false;
+ }
+
+ pos = outputFile.find_first_of("<>");
+ if (pos != std::string::npos) {
+ status.SetError(cmStrCat("CONFIGURE called with OUTPUT containing a \"",
+ outputFile[pos],
+ "\". This character is not allowed."));
+ return false;
+ }
+
+ cmMakefile& makeFile = status.GetMakefile();
+ if (!makeFile.CanIWriteThisFile(outputFile)) {
+ cmSystemTools::Error("Attempt to write file: " + outputFile +
+ " into a source directory.");
+ return false;
+ }
+
+ cmSystemTools::ConvertToUnixSlashes(outputFile);
+
+ // Re-generate if non-temporary outputs are missing.
+ // when we finalize the configuration we will remove all
+ // output files that now don't exist.
+ makeFile.AddCMakeOutputFile(outputFile);
+
+ // Create output directory
+ const std::string::size_type slashPos = outputFile.rfind('/');
+ if (slashPos != std::string::npos) {
+ const std::string path = outputFile.substr(0, slashPos);
+ cmSystemTools::MakeDirectory(path);
+ }
+
+ std::string newLineCharacters;
+ bool open_with_binary_flag = false;
+ if (newLineStyle.IsValid()) {
+ open_with_binary_flag = true;
+ newLineCharacters = newLineStyle.GetCharacters();
+ }
+
+ cmGeneratedFileStream fout;
+ fout.Open(outputFile, false, open_with_binary_flag);
+ if (!fout) {
+ cmSystemTools::Error("Could not open file for write in copy operation " +
+ outputFile);
+ cmSystemTools::ReportLastSystemError("");
+ return false;
+ }
+ fout.SetCopyIfDifferent(true);
+
+ // copy intput to output and expand variables from input at the same time
+ std::stringstream sin(input, std::ios::in);
+ std::string inLine;
+ std::string outLine;
+ while (cmSystemTools::GetLineFromStream(sin, inLine)) {
+ outLine.clear();
+ makeFile.ConfigureString(inLine, outLine, atOnly, escapeQuotes);
+ fout << outLine << newLineCharacters;
+ }
+
+ // close file before attempting to copy
+ fout.close();
+
+ return true;
+}
+
+bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ struct Arguments
+ {
+ std::string Output;
+ std::string Format;
+ std::string Type;
+ std::string MTime;
+ bool Verbose = false;
+ std::vector<std::string> Files;
+ std::vector<std::string> Directories;
+ };
+
+ static auto const parser = cmArgumentParser<Arguments>{}
+ .Bind("OUTPUT"_s, &Arguments::Output)
+ .Bind("FORMAT"_s, &Arguments::Format)
+ .Bind("TYPE"_s, &Arguments::Type)
+ .Bind("MTIME"_s, &Arguments::MTime)
+ .Bind("VERBOSE"_s, &Arguments::Verbose)
+ .Bind("FILES"_s, &Arguments::Files)
+ .Bind("DIRECTORY"_s, &Arguments::Directories);
+
+ std::vector<std::string> unrecognizedArguments;
+ std::vector<std::string> keywordsMissingValues;
+ auto parsedArgs =
+ parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments,
+ &keywordsMissingValues);
+ auto argIt = unrecognizedArguments.begin();
+ if (argIt != unrecognizedArguments.end()) {
+ status.SetError(cmStrCat("Unrecognized argument: \"", *argIt, "\""));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ const std::vector<std::string> LIST_ARGS = {
+ "OUTPUT", "FORMAT", "TYPE", "MTIME", "FILES", "DIRECTORY",
+ };
+ 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 ")));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ const char* knownFormats[] = {
+ "7zip", "gnutar", "pax", "paxr", "raw", "zip"
+ };
+
+ if (!parsedArgs.Format.empty() &&
+ !cm::contains(knownFormats, parsedArgs.Format)) {
+ status.SetError(
+ cmStrCat("archive format ", parsedArgs.Format, " not supported"));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ const char* zipFileFormats[] = { "7zip", "zip" };
+ if (!parsedArgs.Type.empty() &&
+ cm::contains(zipFileFormats, parsedArgs.Format)) {
+ status.SetError(cmStrCat("archive format ", parsedArgs.Format,
+ " does not support TYPE arguments"));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ static std::map<std::string, cmSystemTools::cmTarCompression>
+ compressionTypeMap = { { "None", cmSystemTools::TarCompressNone },
+ { "BZip2", cmSystemTools::TarCompressBZip2 },
+ { "GZip", cmSystemTools::TarCompressGZip },
+ { "XZ", cmSystemTools::TarCompressXZ },
+ { "Zstd", cmSystemTools::TarCompressZstd } };
+
+ std::string const& outFile = parsedArgs.Output;
+ std::vector<std::string> files = parsedArgs.Files;
+ std::copy(parsedArgs.Directories.begin(), parsedArgs.Directories.end(),
+ std::back_inserter(files));
+
+ cmSystemTools::cmTarCompression compress = cmSystemTools::TarCompressNone;
+ auto typeIt = compressionTypeMap.find(parsedArgs.Type);
+ if (typeIt != compressionTypeMap.end()) {
+ compress = typeIt->second;
+ } else if (!parsedArgs.Type.empty()) {
+ status.SetError(
+ cmStrCat("compression type ", parsedArgs.Type, " is not supported"));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ if (files.empty()) {
+ status.GetMakefile().IssueMessage(MessageType::AUTHOR_WARNING,
+ "No files or directories specified");
+ }
+
+ if (!cmSystemTools::CreateTar(outFile, files, compress, parsedArgs.Verbose,
+ parsedArgs.MTime, parsedArgs.Format)) {
+ status.SetError(cmStrCat("failed to compress: ", outFile));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ return true;
+}
+
+bool HandleArchiveExtractCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ struct Arguments
+ {
+ std::string Input;
+ bool Verbose = false;
+ bool ListOnly = false;
+ std::string Destination;
+ std::vector<std::string> Files;
+ std::vector<std::string> Directories;
+ };
+
+ static auto const parser = cmArgumentParser<Arguments>{}
+ .Bind("INPUT"_s, &Arguments::Input)
+ .Bind("VERBOSE"_s, &Arguments::Verbose)
+ .Bind("LIST_ONLY"_s, &Arguments::ListOnly)
+ .Bind("DESTINATION"_s, &Arguments::Destination)
+ .Bind("FILES"_s, &Arguments::Files)
+ .Bind("DIRECTORY"_s, &Arguments::Directories);
+
+ std::vector<std::string> unrecognizedArguments;
+ std::vector<std::string> keywordsMissingValues;
+ auto parsedArgs =
+ parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments,
+ &keywordsMissingValues);
+ auto argIt = unrecognizedArguments.begin();
+ if (argIt != unrecognizedArguments.end()) {
+ status.SetError(cmStrCat("Unrecognized argument: \"", *argIt, "\""));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ const std::vector<std::string> LIST_ARGS = {
+ "INPUT",
+ "DESTINATION",
+ "FILES",
+ "DIRECTORY",
+ };
+ 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 ")));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ std::string inFile = parsedArgs.Input;
+ std::vector<std::string> files = parsedArgs.Files;
+ std::copy(parsedArgs.Directories.begin(), parsedArgs.Directories.end(),
+ std::back_inserter(files));
+
+ if (parsedArgs.ListOnly) {
+ if (!cmSystemTools::ListTar(inFile, files, parsedArgs.Verbose)) {
+ status.SetError(cmStrCat("failed to list: ", inFile));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+ } else {
+ std::string destDir = cmSystemTools::GetCurrentWorkingDirectory();
+ if (!parsedArgs.Destination.empty()) {
+ if (cmSystemTools::FileIsFullPath(parsedArgs.Destination)) {
+ destDir = parsedArgs.Destination;
+ } else {
+ destDir = cmStrCat(destDir, "/", parsedArgs.Destination);
+ }
+
+ if (!cmSystemTools::MakeDirectory(destDir)) {
+ status.SetError(cmStrCat("failed to create directory: ", destDir));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ if (!cmSystemTools::FileIsFullPath(inFile)) {
+ inFile =
+ cmStrCat(cmSystemTools::GetCurrentWorkingDirectory(), "/", inFile);
+ }
+ }
+
+ cmWorkingDirectory workdir(destDir);
+ if (workdir.Failed()) {
+ status.SetError(
+ cmStrCat("failed to change working directory to: ", destDir));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ if (!cmSystemTools::ExtractTar(inFile, files, parsedArgs.Verbose)) {
+ status.SetError(cmStrCat("failed to extract: ", inFile));
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+ }
+
+ return true;
+}
+
} // namespace
bool cmFileCommand(std::vector<std::string> const& args,
@@ -2827,6 +3186,9 @@ bool cmFileCommand(std::vector<std::string> const& args,
{ "READ_SYMLINK"_s, HandleReadSymlinkCommand },
{ "CREATE_LINK"_s, HandleCreateLinkCommand },
{ "GET_RUNTIME_DEPENDENCIES"_s, HandleGetRuntimeDependenciesCommand },
+ { "CONFIGURE"_s, HandleConfigureCommand },
+ { "ARCHIVE_CREATE"_s, HandleArchiveCreateCommand },
+ { "ARCHIVE_EXTRACT"_s, HandleArchiveExtractCommand },
};
return subcommand(args[0], args, status);
diff --git a/Source/cmFileLock.cxx b/Source/cmFileLock.cxx
index e90f571..6010233 100644
--- a/Source/cmFileLock.cxx
+++ b/Source/cmFileLock.cxx
@@ -3,11 +3,23 @@
#include "cmFileLock.h"
#include <cassert>
+#include <utility>
#include "cmFileLockResult.h"
// Common implementation
+cmFileLock::cmFileLock(cmFileLock&& other) noexcept
+{
+ this->File = other.File;
+#if defined(_WIN32)
+ other.File = INVALID_HANDLE_VALUE;
+#else
+ other.File = -1;
+#endif
+ this->Filename = std::move(other.Filename);
+}
+
cmFileLock::~cmFileLock()
{
if (!this->Filename.empty()) {
@@ -17,6 +29,19 @@ cmFileLock::~cmFileLock()
}
}
+cmFileLock& cmFileLock::operator=(cmFileLock&& other) noexcept
+{
+ this->File = other.File;
+#if defined(_WIN32)
+ other.File = INVALID_HANDLE_VALUE;
+#else
+ other.File = -1;
+#endif
+ this->Filename = std::move(other.Filename);
+
+ return *this;
+}
+
cmFileLockResult cmFileLock::Lock(const std::string& filename,
unsigned long timeout)
{
diff --git a/Source/cmFileLock.h b/Source/cmFileLock.h
index 2130d65..5fe068e 100644
--- a/Source/cmFileLock.h
+++ b/Source/cmFileLock.h
@@ -26,7 +26,9 @@ public:
~cmFileLock();
cmFileLock(cmFileLock const&) = delete;
+ cmFileLock(cmFileLock&&) noexcept;
cmFileLock& operator=(cmFileLock const&) = delete;
+ cmFileLock& operator=(cmFileLock&&) noexcept;
/**
* @brief Lock the file.
diff --git a/Source/cmFileLockPool.cxx b/Source/cmFileLockPool.cxx
index 8db2db2..e1f6e94 100644
--- a/Source/cmFileLockPool.cxx
+++ b/Source/cmFileLockPool.cxx
@@ -3,40 +3,34 @@
#include "cmFileLockPool.h"
#include <cassert>
+#include <utility>
-#include "cmAlgorithms.h"
#include "cmFileLock.h"
#include "cmFileLockResult.h"
cmFileLockPool::cmFileLockPool() = default;
-cmFileLockPool::~cmFileLockPool()
-{
- cmDeleteAll(this->FunctionScopes);
- cmDeleteAll(this->FileScopes);
-}
+cmFileLockPool::~cmFileLockPool() = default;
void cmFileLockPool::PushFunctionScope()
{
- this->FunctionScopes.push_back(new ScopePool());
+ this->FunctionScopes.push_back(ScopePool());
}
void cmFileLockPool::PopFunctionScope()
{
assert(!this->FunctionScopes.empty());
- delete this->FunctionScopes.back();
this->FunctionScopes.pop_back();
}
void cmFileLockPool::PushFileScope()
{
- this->FileScopes.push_back(new ScopePool());
+ this->FileScopes.push_back(ScopePool());
}
void cmFileLockPool::PopFileScope()
{
assert(!this->FileScopes.empty());
- delete this->FileScopes.back();
this->FileScopes.pop_back();
}
@@ -49,7 +43,7 @@ cmFileLockResult cmFileLockPool::LockFunctionScope(const std::string& filename,
if (this->FunctionScopes.empty()) {
return cmFileLockResult::MakeNoFunction();
}
- return this->FunctionScopes.back()->Lock(filename, timeoutSec);
+ return this->FunctionScopes.back().Lock(filename, timeoutSec);
}
cmFileLockResult cmFileLockPool::LockFileScope(const std::string& filename,
@@ -59,7 +53,7 @@ cmFileLockResult cmFileLockPool::LockFileScope(const std::string& filename,
return cmFileLockResult::MakeAlreadyLocked();
}
assert(!this->FileScopes.empty());
- return this->FileScopes.back()->Lock(filename, timeoutSec);
+ return this->FileScopes.back().Lock(filename, timeoutSec);
}
cmFileLockResult cmFileLockPool::LockProcessScope(const std::string& filename,
@@ -74,14 +68,14 @@ cmFileLockResult cmFileLockPool::LockProcessScope(const std::string& filename,
cmFileLockResult cmFileLockPool::Release(const std::string& filename)
{
for (auto& funcScope : this->FunctionScopes) {
- const cmFileLockResult result = funcScope->Release(filename);
+ const cmFileLockResult result = funcScope.Release(filename);
if (!result.IsOk()) {
return result;
}
}
for (auto& fileScope : this->FileScopes) {
- const cmFileLockResult result = fileScope->Release(filename);
+ const cmFileLockResult result = fileScope.Release(filename);
if (!result.IsOk()) {
return result;
}
@@ -93,14 +87,14 @@ cmFileLockResult cmFileLockPool::Release(const std::string& filename)
bool cmFileLockPool::IsAlreadyLocked(const std::string& filename) const
{
for (auto const& funcScope : this->FunctionScopes) {
- const bool result = funcScope->IsAlreadyLocked(filename);
+ const bool result = funcScope.IsAlreadyLocked(filename);
if (result) {
return true;
}
}
for (auto const& fileScope : this->FileScopes) {
- const bool result = fileScope->IsAlreadyLocked(filename);
+ const bool result = fileScope.IsAlreadyLocked(filename);
if (result) {
return true;
}
@@ -111,21 +105,29 @@ bool cmFileLockPool::IsAlreadyLocked(const std::string& filename) const
cmFileLockPool::ScopePool::ScopePool() = default;
-cmFileLockPool::ScopePool::~ScopePool()
+cmFileLockPool::ScopePool::~ScopePool() = default;
+
+cmFileLockPool::ScopePool::ScopePool(ScopePool&&) noexcept = default;
+
+cmFileLockPool::ScopePool& cmFileLockPool::ScopePool::operator=(
+ ScopePool&& other) noexcept
{
- cmDeleteAll(this->Locks);
+ if (this != &other) {
+ this->Locks = std::move(other.Locks);
+ }
+
+ return *this;
}
cmFileLockResult cmFileLockPool::ScopePool::Lock(const std::string& filename,
unsigned long timeoutSec)
{
- cmFileLock* lock = new cmFileLock();
- const cmFileLockResult result = lock->Lock(filename, timeoutSec);
+ cmFileLock lock;
+ const cmFileLockResult result = lock.Lock(filename, timeoutSec);
if (result.IsOk()) {
- this->Locks.push_back(lock);
+ this->Locks.push_back(std::move(lock));
return cmFileLockResult::MakeOk();
}
- delete lock;
return result;
}
@@ -133,8 +135,8 @@ cmFileLockResult cmFileLockPool::ScopePool::Release(
const std::string& filename)
{
for (auto& lock : this->Locks) {
- if (lock->IsLocked(filename)) {
- return lock->Release();
+ if (lock.IsLocked(filename)) {
+ return lock.Release();
}
}
return cmFileLockResult::MakeOk();
@@ -144,7 +146,7 @@ bool cmFileLockPool::ScopePool::IsAlreadyLocked(
const std::string& filename) const
{
for (auto const& lock : this->Locks) {
- if (lock->IsLocked(filename)) {
+ if (lock.IsLocked(filename)) {
return true;
}
}
diff --git a/Source/cmFileLockPool.h b/Source/cmFileLockPool.h
index dae68dd..d45c82c 100644
--- a/Source/cmFileLockPool.h
+++ b/Source/cmFileLockPool.h
@@ -8,7 +8,8 @@
#include <string>
#include <vector>
-class cmFileLock;
+#include "cmFileLock.h"
+
class cmFileLockResult;
class cmFileLockPool
@@ -64,7 +65,9 @@ private:
~ScopePool();
ScopePool(ScopePool const&) = delete;
+ ScopePool(ScopePool&&) noexcept;
ScopePool& operator=(ScopePool const&) = delete;
+ ScopePool& operator=(ScopePool&&) noexcept;
cmFileLockResult Lock(const std::string& filename,
unsigned long timeoutSec);
@@ -72,17 +75,12 @@ private:
bool IsAlreadyLocked(const std::string& filename) const;
private:
- using List = std::vector<cmFileLock*>;
- using It = List::iterator;
- using CIt = List::const_iterator;
+ using List = std::vector<cmFileLock>;
List Locks;
};
- using List = std::vector<ScopePool*>;
-
- using It = List::iterator;
- using CIt = List::const_iterator;
+ using List = std::vector<ScopePool>;
List FunctionScopes;
List FileScopes;
diff --git a/Source/cmFileMonitor.cxx b/Source/cmFileMonitor.cxx
index ac8a37e..8cfdb2d 100644
--- a/Source/cmFileMonitor.cxx
+++ b/Source/cmFileMonitor.cxx
@@ -7,9 +7,9 @@
#include <unordered_map>
#include <utility>
-#include "cmsys/SystemTools.hxx"
+#include <cm/memory>
-#include "cmAlgorithms.h"
+#include "cmsys/SystemTools.hxx"
namespace {
void on_directory_change(uv_fs_event_t* handle, const char* filename,
@@ -37,12 +37,12 @@ public:
class cmVirtualDirectoryWatcher : public cmIBaseWatcher
{
public:
- ~cmVirtualDirectoryWatcher() override { cmDeleteAll(this->Children); }
+ ~cmVirtualDirectoryWatcher() override = default;
cmIBaseWatcher* Find(const std::string& ps)
{
const auto i = this->Children.find(ps);
- return (i == this->Children.end()) ? nullptr : i->second;
+ return (i == this->Children.end()) ? nullptr : i->second.get();
}
void Trigger(const std::string& pathSegment, int events,
@@ -96,11 +96,7 @@ public:
return result;
}
- void Reset()
- {
- cmDeleteAll(this->Children);
- this->Children.clear();
- }
+ void Reset() { this->Children.clear(); }
void AddChildWatcher(const std::string& ps, cmIBaseWatcher* watcher)
{
@@ -108,11 +104,12 @@ public:
assert(this->Children.find(ps) == this->Children.end());
assert(watcher);
- this->Children.emplace(std::make_pair(ps, watcher));
+ this->Children.emplace(ps, std::unique_ptr<cmIBaseWatcher>(watcher));
}
private:
- std::unordered_map<std::string, cmIBaseWatcher*> Children; // owned!
+ std::unordered_map<std::string, std::unique_ptr<cmIBaseWatcher>>
+ Children; // owned!
};
// Root of all the different (on windows!) root directories:
@@ -295,14 +292,11 @@ void on_fs_close(uv_handle_t* handle)
} // namespace
cmFileMonitor::cmFileMonitor(uv_loop_t* l)
- : Root(new cmRootWatcher(l))
+ : Root(cm::make_unique<cmRootWatcher>(l))
{
}
-cmFileMonitor::~cmFileMonitor()
-{
- delete this->Root;
-}
+cmFileMonitor::~cmFileMonitor() = default;
void cmFileMonitor::MonitorPaths(const std::vector<std::string>& paths,
Callback const& cb)
@@ -316,7 +310,7 @@ void cmFileMonitor::MonitorPaths(const std::vector<std::string>& paths,
if (segmentCount < 2) { // Expect at least rootdir and filename
continue;
}
- cmVirtualDirectoryWatcher* currentWatcher = this->Root;
+ cmVirtualDirectoryWatcher* currentWatcher = this->Root.get();
for (size_t i = 0; i < segmentCount; ++i) {
assert(currentWatcher);
@@ -334,11 +328,12 @@ void cmFileMonitor::MonitorPaths(const std::vector<std::string>& paths,
cmIBaseWatcher* nextWatcher = currentWatcher->Find(currentSegment);
if (!nextWatcher) {
if (rootSegment) { // Root part
- assert(currentWatcher == this->Root);
- nextWatcher = new cmRootDirectoryWatcher(this->Root, currentSegment);
+ assert(currentWatcher == this->Root.get());
+ nextWatcher =
+ new cmRootDirectoryWatcher(this->Root.get(), currentSegment);
assert(currentWatcher->Find(currentSegment) == nextWatcher);
} else if (fileSegment) { // File part
- assert(currentWatcher != this->Root);
+ assert(currentWatcher != this->Root.get());
nextWatcher = new cmFileWatcher(
dynamic_cast<cmRealDirectoryWatcher*>(currentWatcher),
currentSegment, cb);
diff --git a/Source/cmFileMonitor.h b/Source/cmFileMonitor.h
index 7ffc929..fc75b0c 100644
--- a/Source/cmFileMonitor.h
+++ b/Source/cmFileMonitor.h
@@ -5,10 +5,11 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <functional>
+#include <memory>
#include <string>
#include <vector>
-#include "cm_uv.h"
+#include <cm3p/uv.h>
class cmRootWatcher;
@@ -30,5 +31,5 @@ public:
std::vector<std::string> WatchedDirectories() const;
private:
- cmRootWatcher* Root;
+ std::unique_ptr<cmRootWatcher> Root;
};
diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx
index 7d74118..b5553b8 100644
--- a/Source/cmFindBase.cxx
+++ b/Source/cmFindBase.cxx
@@ -4,10 +4,11 @@
#include <cstddef>
#include <deque>
-#include <iostream>
#include <map>
+#include <utility>
+
+#include <cmext/algorithm>
-#include "cmAlgorithms.h"
#include "cmMakefile.h"
#include "cmRange.h"
#include "cmSearchPath.h"
@@ -21,10 +22,6 @@ class cmExecutionStatus;
cmFindBase::cmFindBase(cmExecutionStatus& status)
: cmFindCommon(status)
{
- this->AlreadyInCache = false;
- this->AlreadyInCacheWithoutMetaInfo = false;
- this->NamesPerDir = false;
- this->NamesPerDirAllowed = false;
}
bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
@@ -114,19 +111,25 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
} else if (args[j] == "NO_SYSTEM_PATH") {
doing = DoingNone;
this->NoDefaultPath = true;
+ } else if (args[j] == "REQUIRED") {
+ doing = DoingNone;
+ this->Required = true;
+ newStyle = true;
} else if (this->CheckCommonArgument(args[j])) {
doing = DoingNone;
+ } else {
// Some common arguments were accidentally supported by CMake
// 2.4 and 2.6.0 in the short-hand form of the command, so we
// must support it even though it is not documented.
- } else if (doing == DoingNames) {
- this->Names.push_back(args[j]);
- } else if (doing == DoingPaths) {
- this->UserGuessArgs.push_back(args[j]);
- } else if (doing == DoingHints) {
- this->UserHintsArgs.push_back(args[j]);
- } else if (doing == DoingPathSuffixes) {
- this->AddPathSuffix(args[j]);
+ if (doing == DoingNames) {
+ this->Names.push_back(args[j]);
+ } else if (doing == DoingPaths) {
+ this->UserGuessArgs.push_back(args[j]);
+ } else if (doing == DoingHints) {
+ this->UserHintsArgs.push_back(args[j]);
+ } else if (doing == DoingPathSuffixes) {
+ this->AddPathSuffix(args[j]);
+ }
}
}
@@ -153,7 +156,7 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
std::vector<std::string> shortArgs = this->Names;
this->Names.clear(); // clear out any values in Names
this->Names.push_back(shortArgs[0]);
- cmAppend(this->UserGuessArgs, shortArgs.begin() + 1, shortArgs.end());
+ cm::append(this->UserGuessArgs, shortArgs.begin() + 1, shortArgs.end());
}
this->ExpandPaths();
@@ -288,39 +291,12 @@ void cmFindBase::FillUserGuessPath()
paths.AddSuffixes(this->SearchPathSuffixes);
}
-void cmFindBase::PrintFindStuff()
-{
- std::cerr << "SearchFrameworkLast: " << this->SearchFrameworkLast << "\n";
- std::cerr << "SearchFrameworkOnly: " << this->SearchFrameworkOnly << "\n";
- std::cerr << "SearchFrameworkFirst: " << this->SearchFrameworkFirst << "\n";
- std::cerr << "SearchAppBundleLast: " << this->SearchAppBundleLast << "\n";
- std::cerr << "SearchAppBundleOnly: " << this->SearchAppBundleOnly << "\n";
- std::cerr << "SearchAppBundleFirst: " << this->SearchAppBundleFirst << "\n";
- std::cerr << "VariableName " << this->VariableName << "\n";
- std::cerr << "VariableDocumentation " << this->VariableDocumentation << "\n";
- std::cerr << "NoDefaultPath " << this->NoDefaultPath << "\n";
- std::cerr << "NoCMakeEnvironmentPath " << this->NoCMakeEnvironmentPath
- << "\n";
- std::cerr << "NoCMakePath " << this->NoCMakePath << "\n";
- std::cerr << "NoSystemEnvironmentPath " << this->NoSystemEnvironmentPath
- << "\n";
- std::cerr << "NoCMakeSystemPath " << this->NoCMakeSystemPath << "\n";
- std::cerr << "EnvironmentPath " << this->EnvironmentPath << "\n";
- std::cerr << "CMakePathName " << this->CMakePathName << "\n";
- std::cerr << "Names " << cmJoin(this->Names, " ") << "\n";
- std::cerr << "\n";
- std::cerr << "SearchPathSuffixes ";
- std::cerr << cmJoin(this->SearchPathSuffixes, "\n") << "\n";
- std::cerr << "SearchPaths\n";
- std::cerr << cmWrap("[", this->SearchPaths, "]", "\n") << "\n";
-}
-
bool cmFindBase::CheckForVariableInCache()
{
if (const char* cacheValue =
this->Makefile->GetDefinition(this->VariableName)) {
cmState* state = this->Makefile->GetState();
- const char* cacheEntry = state->GetCacheEntryValue(this->VariableName);
+ cmProp cacheEntry = state->GetCacheEntryValue(this->VariableName);
bool found = !cmIsNOTFOUND(cacheValue);
bool cached = cacheEntry != nullptr;
if (found) {
@@ -336,10 +312,94 @@ bool cmFindBase::CheckForVariableInCache()
return true;
}
if (cached) {
- const char* hs =
+ cmProp hs =
state->GetCacheEntryProperty(this->VariableName, "HELPSTRING");
- this->VariableDocumentation = hs ? hs : "(none)";
+ this->VariableDocumentation = hs ? *hs : "(none)";
}
}
return false;
}
+
+cmFindBaseDebugState::cmFindBaseDebugState(std::string commandName,
+ cmFindBase const* findBase)
+ : FindCommand(findBase)
+ , CommandName(std::move(commandName))
+{
+}
+
+cmFindBaseDebugState::~cmFindBaseDebugState()
+{
+ if (this->FindCommand->DebugMode) {
+ std::string buffer =
+ cmStrCat(this->CommandName, " called with the following settings:\n");
+ buffer += cmStrCat(" VAR: ", this->FindCommand->VariableName, "\n");
+ buffer += cmStrCat(
+ " NAMES: ", cmWrap("\"", this->FindCommand->Names, "\"", "\n "),
+ "\n");
+ buffer += cmStrCat(
+ " Documentation: ", this->FindCommand->VariableDocumentation, "\n");
+ buffer += " Framework\n";
+ buffer += cmStrCat(" Only Search Frameworks: ",
+ this->FindCommand->SearchFrameworkOnly, "\n");
+
+ buffer += cmStrCat(" Search Frameworks Last: ",
+ this->FindCommand->SearchFrameworkLast, "\n");
+ buffer += cmStrCat(" Search Frameworks First: ",
+ this->FindCommand->SearchFrameworkFirst, "\n");
+ buffer += " AppBundle\n";
+ buffer += cmStrCat(" Only Search AppBundle: ",
+ this->FindCommand->SearchAppBundleOnly, "\n");
+ buffer += cmStrCat(" Search AppBundle Last: ",
+ this->FindCommand->SearchAppBundleLast, "\n");
+ buffer += cmStrCat(" Search AppBundle First: ",
+ this->FindCommand->SearchAppBundleFirst, "\n");
+
+ if (this->FindCommand->NoDefaultPath) {
+ buffer += " NO_DEFAULT_PATH Enabled\n";
+ } else {
+ buffer += cmStrCat(
+ " CMAKE_FIND_USE_CMAKE_PATH: ", !this->FindCommand->NoCMakePath, "\n",
+ " CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: ",
+ !this->FindCommand->NoCMakeEnvironmentPath, "\n",
+ " CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: ",
+ !this->FindCommand->NoSystemEnvironmentPath, "\n",
+ " CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: ",
+ !this->FindCommand->NoCMakeSystemPath, "\n");
+ }
+
+ buffer +=
+ cmStrCat(this->CommandName, " considered the following locations:\n");
+ for (auto const& state : this->FailedSearchLocations) {
+ std::string path = cmStrCat(" ", state.path);
+ if (!state.regexName.empty()) {
+ path = cmStrCat(path, "/", state.regexName);
+ }
+ buffer += cmStrCat(path, "\n");
+ }
+
+ if (!this->FoundSearchLocation.path.empty()) {
+ buffer += cmStrCat("The item was found at\n ",
+ this->FoundSearchLocation.path, "\n");
+ } else {
+ buffer += "The item was not found.\n";
+ }
+
+ this->FindCommand->DebugMessage(buffer);
+ }
+}
+
+void cmFindBaseDebugState::FoundAt(std::string const& path,
+ std::string regexName)
+{
+ if (this->FindCommand->DebugMode) {
+ this->FoundSearchLocation = DebugLibState{ std::move(regexName), path };
+ }
+}
+
+void cmFindBaseDebugState::FailedAt(std::string const& path,
+ std::string regexName)
+{
+ if (this->FindCommand->DebugMode) {
+ this->FailedSearchLocations.emplace_back(std::move(regexName), path);
+ }
+}
diff --git a/Source/cmFindBase.h b/Source/cmFindBase.h
index f75db5f..4cbf09e 100644
--- a/Source/cmFindBase.h
+++ b/Source/cmFindBase.h
@@ -6,6 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <string>
+#include <utility>
#include <vector>
#include "cmFindCommon.h"
@@ -31,7 +32,7 @@ public:
virtual bool ParseArguments(std::vector<std::string> const& args);
protected:
- void PrintFindStuff();
+ friend class cmFindBaseDebugState;
void ExpandPaths();
// see if the VariableName is already set in the cache,
@@ -43,14 +44,16 @@ protected:
std::string VariableDocumentation;
std::string VariableName;
std::vector<std::string> Names;
- bool NamesPerDir;
- bool NamesPerDirAllowed;
+ bool NamesPerDir = false;
+ bool NamesPerDirAllowed = false;
// CMAKE_*_PATH CMAKE_SYSTEM_*_PATH FRAMEWORK|LIBRARY|INCLUDE|PROGRAM
std::string EnvironmentPath; // LIB,INCLUDE
- bool AlreadyInCache;
- bool AlreadyInCacheWithoutMetaInfo;
+ bool AlreadyInCache = false;
+ bool AlreadyInCacheWithoutMetaInfo = false;
+
+ bool Required = false;
private:
// Add pieces of the search.
@@ -63,4 +66,33 @@ private:
void FillUserGuessPath();
};
+class cmFindBaseDebugState
+{
+public:
+ explicit cmFindBaseDebugState(std::string name, cmFindBase const* findBase);
+ ~cmFindBaseDebugState();
+
+ void FoundAt(std::string const& path, std::string regexName = std::string());
+ void FailedAt(std::string const& path,
+ std::string regexName = std::string());
+
+private:
+ struct DebugLibState
+ {
+ DebugLibState() = default;
+ DebugLibState(std::string&& n, std::string p)
+ : regexName(n)
+ , path(std::move(p))
+ {
+ }
+ std::string regexName;
+ std::string path;
+ };
+
+ cmFindBase const* FindCommand;
+ std::string CommandName;
+ std::vector<DebugLibState> FailedSearchLocations;
+ DebugLibState FoundSearchLocation;
+};
+
#endif
diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx
index badec55..82acfed 100644
--- a/Source/cmFindCommon.cxx
+++ b/Source/cmFindCommon.cxx
@@ -7,11 +7,14 @@
#include <cstring>
#include <utility>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
+#include "cmMessageType.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmake.h"
cmFindCommon::PathGroup cmFindCommon::PathGroup::All("ALL");
cmFindCommon::PathLabel cmFindCommon::PathLabel::PackageRoot(
@@ -52,6 +55,8 @@ cmFindCommon::cmFindCommon(cmExecutionStatus& status)
this->SearchAppBundleLast = false;
this->InitializeSearchPathGroups();
+
+ this->DebugMode = false;
}
void cmFindCommon::SetError(std::string const& e)
@@ -59,6 +64,19 @@ void cmFindCommon::SetError(std::string const& e)
this->Status.SetError(e);
}
+void cmFindCommon::DebugMessage(std::string const& msg) const
+{
+ if (this->Makefile) {
+ this->Makefile->IssueMessage(MessageType::LOG, msg);
+ }
+}
+
+bool cmFindCommon::ComputeIfDebugModeWanted()
+{
+ return this->Makefile->IsOn("CMAKE_FIND_DEBUG_MODE") ||
+ this->Makefile->GetCMakeInstance()->GetDebugFindOutput();
+}
+
void cmFindCommon::InitializeSearchPathGroups()
{
std::vector<PathLabel>* labels;
@@ -249,7 +267,7 @@ void cmFindCommon::RerootPaths(std::vector<std::string>& paths)
// If searching both rooted and unrooted paths add the original
// paths again.
if (this->FindRootPathMode == RootPathModeBoth) {
- cmAppend(paths, unrootedPaths);
+ cm::append(paths, unrootedPaths);
}
}
diff --git a/Source/cmFindCommon.h b/Source/cmFindCommon.h
index 8177eac..916f3bc 100644
--- a/Source/cmFindCommon.h
+++ b/Source/cmFindCommon.h
@@ -30,8 +30,11 @@ public:
void SetError(std::string const& e);
+ bool DebugModeEnabled() const { return this->DebugMode; }
+
protected:
friend class cmSearchPath;
+ friend class cmFindBaseDebugState;
/** Used to define groups of path labels */
class PathGroup : public cmPathLabel
@@ -96,6 +99,10 @@ protected:
/** Compute the current default search modes based on global variables. */
void SelectDefaultSearchModes();
+ /** The `InitialPass` functions of the child classes should set
+ this->DebugMode to the result of this. */
+ bool ComputeIfDebugModeWanted();
+
// Path arguments prior to path manipulation routines
std::vector<std::string> UserHintsArgs;
std::vector<std::string> UserGuessArgs;
@@ -106,6 +113,8 @@ protected:
bool CheckCommonArgument(std::string const& arg);
void AddPathSuffix(std::string const& arg);
+ void DebugMessage(std::string const& msg) const;
+ bool DebugMode;
bool NoDefaultPath;
bool NoPackageRootPath;
bool NoCMakePath;
diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx
index 20221b1..31f1201 100644
--- a/Source/cmFindLibraryCommand.cxx
+++ b/Source/cmFindLibraryCommand.cxx
@@ -12,6 +12,7 @@
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
+#include "cmMessageType.h"
#include "cmState.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
@@ -29,6 +30,7 @@ cmFindLibraryCommand::cmFindLibraryCommand(cmExecutionStatus& status)
// cmFindLibraryCommand
bool cmFindLibraryCommand::InitialPass(std::vector<std::string> const& argsIn)
{
+ this->DebugMode = ComputeIfDebugModeWanted();
this->VariableDocumentation = "Path to a library.";
this->CMakePathName = "LIBRARY";
if (!this->ParseArguments(argsIn)) {
@@ -74,15 +76,22 @@ bool cmFindLibraryCommand::InitialPass(std::vector<std::string> const& argsIn)
std::string const library = this->FindLibrary();
if (!library.empty()) {
// Save the value in the cache
- this->Makefile->AddCacheDefinition(this->VariableName, library.c_str(),
+ this->Makefile->AddCacheDefinition(this->VariableName, library,
this->VariableDocumentation.c_str(),
cmStateEnums::FILEPATH);
return true;
}
std::string notfound = this->VariableName + "-NOTFOUND";
- this->Makefile->AddCacheDefinition(this->VariableName, notfound.c_str(),
+ this->Makefile->AddCacheDefinition(this->VariableName, notfound,
this->VariableDocumentation.c_str(),
cmStateEnums::FILEPATH);
+ if (this->Required) {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ "Could not find " + this->VariableName +
+ " using the following names: " + cmJoin(this->Names, ", "));
+ cmSystemTools::SetFatalErrorOccured();
+ }
return true;
}
@@ -92,6 +101,13 @@ void cmFindLibraryCommand::AddArchitecturePaths(const char* suffix)
original.swap(this->SearchPaths);
for (std::string const& o : original) {
this->AddArchitecturePath(o, 0, suffix);
+ if (this->DebugMode) {
+ std::string msg = cmStrCat(
+ "find_library(", this->VariableName, ") removed original suffix ", o,
+ " from PATH_SUFFIXES while adding architecture paths for suffix '",
+ suffix, "'");
+ this->DebugMessage(msg);
+ }
}
}
@@ -153,11 +169,23 @@ void cmFindLibraryCommand::AddArchitecturePath(
if (use_dirX) {
dirX += "/";
+ if (this->DebugMode) {
+ std::string msg = cmStrCat(
+ "find_library(", this->VariableName, ") added replacement path ",
+ dirX, " to PATH_SUFFIXES for architecture suffix '", suffix, "'");
+ this->DebugMessage(msg);
+ }
this->SearchPaths.push_back(std::move(dirX));
}
if (use_dir) {
this->SearchPaths.push_back(dir);
+ if (this->DebugMode) {
+ std::string msg = cmStrCat(
+ "find_library(", this->VariableName, ") added replacement path ",
+ dir, " to PATH_SUFFIXES for architecture suffix '", suffix, "'");
+ this->DebugMessage(msg);
+ }
}
}
}
@@ -179,7 +207,7 @@ std::string cmFindLibraryCommand::FindLibrary()
struct cmFindLibraryHelper
{
- cmFindLibraryHelper(cmMakefile* mf);
+ cmFindLibraryHelper(cmMakefile* mf, cmFindBase const* findBase);
// Context information.
cmMakefile* Makefile;
@@ -198,6 +226,8 @@ struct cmFindLibraryHelper
// Support for OpenBSD shared library naming: lib<name>.so.<major>.<minor>
bool OpenBSD;
+ bool DebugMode;
+
// Current names under consideration.
struct Name
{
@@ -227,10 +257,33 @@ struct cmFindLibraryHelper
void SetName(std::string const& name);
bool CheckDirectory(std::string const& path);
bool CheckDirectoryForName(std::string const& path, Name& name);
+
+ cmFindBaseDebugState DebugSearches;
+
+ void DebugLibraryFailed(std::string const& name, std::string const& path)
+ {
+ if (this->DebugMode) {
+ auto regexName =
+ cmStrCat(this->PrefixRegexStr, name, this->SuffixRegexStr);
+ this->DebugSearches.FailedAt(path, regexName);
+ }
+ };
+
+ void DebugLibraryFound(std::string const& name, std::string const& path)
+ {
+ if (this->DebugMode) {
+ auto regexName =
+ cmStrCat(this->PrefixRegexStr, name, this->SuffixRegexStr);
+ this->DebugSearches.FoundAt(path, regexName);
+ }
+ };
};
-cmFindLibraryHelper::cmFindLibraryHelper(cmMakefile* mf)
+cmFindLibraryHelper::cmFindLibraryHelper(cmMakefile* mf,
+ cmFindBase const* base)
: Makefile(mf)
+ , DebugMode(base->DebugModeEnabled())
+ , DebugSearches("find_library", base)
{
this->GG = this->Makefile->GetGlobalGenerator();
@@ -350,7 +403,12 @@ bool cmFindLibraryHelper::CheckDirectoryForName(std::string const& path,
// library or an import library).
if (name.TryRaw) {
this->TestPath = cmStrCat(path, name.Raw);
- if (cmSystemTools::FileExists(this->TestPath, true)) {
+
+ const bool exists = cmSystemTools::FileExists(this->TestPath, true);
+ 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;
@@ -376,6 +434,8 @@ bool cmFindLibraryHelper::CheckDirectoryForName(std::string const& path,
if (name.Regex.find(testName)) {
this->TestPath = cmStrCat(path, origName);
if (!cmSystemTools::FileIsDirectory(this->TestPath)) {
+ 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
@@ -402,6 +462,12 @@ bool cmFindLibraryHelper::CheckDirectoryForName(std::string const& path,
}
}
+ if (this->BestPath.empty()) {
+ this->DebugLibraryFailed(name.Raw, dir);
+ } else {
+ this->DebugLibraryFound(name.Raw, this->BestPath);
+ }
+
// Use the best candidate found in this directory, if any.
return !this->BestPath.empty();
}
@@ -417,7 +483,7 @@ std::string cmFindLibraryCommand::FindNormalLibrary()
std::string cmFindLibraryCommand::FindNormalLibraryNamesPerDir()
{
// Search for all names in each directory.
- cmFindLibraryHelper helper(this->Makefile);
+ cmFindLibraryHelper helper(this->Makefile, this);
for (std::string const& n : this->Names) {
helper.AddName(n);
}
@@ -434,7 +500,7 @@ std::string cmFindLibraryCommand::FindNormalLibraryNamesPerDir()
std::string cmFindLibraryCommand::FindNormalLibraryDirsPerName()
{
// Search the entire path for each name.
- cmFindLibraryHelper helper(this->Makefile);
+ cmFindLibraryHelper helper(this->Makefile, this);
for (std::string const& n : this->Names) {
// Switch to searching for this name.
helper.SetName(n);
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 2b11b62..d1517fe 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -160,8 +160,8 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
this->RequiredCMakeVersion = CMake_VERSION_ENCODE(v[0], v[1], v[2]);
}
- // Check for debug mode.
- this->DebugMode = this->Makefile->IsOn("CMAKE_FIND_DEBUG_MODE");
+ this->DebugMode = ComputeIfDebugModeWanted();
+ this->DebugBuffer.clear();
// Lookup target architecture, if any.
if (const char* arch =
@@ -279,9 +279,13 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
} else if (args[i] == "MODULE") {
moduleArgs.insert(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);
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);
doing = DoingNone;
@@ -318,6 +322,8 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
this->NoSystemRegistry = true;
configArgs.insert(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);
@@ -576,6 +582,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
}
this->AppendSuccessInformation();
+
return loadedPackage;
}
@@ -695,8 +702,23 @@ void cmFindPackageCommand::RestoreFindDefinitions()
bool cmFindPackageCommand::FindModule(bool& found)
{
std::string module = cmStrCat("Find", this->Name, ".cmake");
+
bool system = false;
- std::string mfile = this->Makefile->GetModulesFile(module, system);
+ std::string debugBuffer =
+ cmStrCat("find_package considered the following paths for ", this->Name,
+ ".cmake\n");
+ std::string mfile = this->Makefile->GetModulesFile(
+ module, system, this->DebugMode, debugBuffer);
+ if (this->DebugMode) {
+ if (mfile.empty()) {
+ debugBuffer = cmStrCat(debugBuffer, "The file was not found.");
+ } else {
+ debugBuffer =
+ cmStrCat(debugBuffer, "The file was found at\n ", mfile, "\n");
+ }
+ this->DebugBuffer = cmStrCat(this->DebugBuffer, debugBuffer, "\n");
+ }
+
if (!mfile.empty()) {
if (system) {
auto it = this->DeprecatedFindModules.find(this->Name);
@@ -827,6 +849,11 @@ bool cmFindPackageCommand::HandlePackageMode(
result = false;
}
+ if (this->DebugMode) {
+ this->DebugMessage(this->DebugBuffer);
+ this->DebugBuffer.clear();
+ }
+
// package not found
if (result && !found) {
// warn if package required or neither quiet nor in config mode
@@ -987,6 +1014,11 @@ bool cmFindPackageCommand::FindConfig()
// Look for the project's configuration file.
bool found = false;
+ if (this->DebugMode) {
+ this->DebugBuffer = cmStrCat(this->DebugBuffer,
+ "find_package considered the following "
+ "locations for the Config module:\n");
+ }
// Search for frameworks.
if (!found && (this->SearchFrameworkFirst || this->SearchFrameworkOnly)) {
@@ -1013,6 +1045,16 @@ bool cmFindPackageCommand::FindConfig()
found = this->FindAppBundleConfig();
}
+ if (this->DebugMode) {
+ if (found) {
+ this->DebugBuffer = cmStrCat(
+ this->DebugBuffer, "The file was found at\n ", this->FileFound, "\n");
+ } else {
+ this->DebugBuffer =
+ cmStrCat(this->DebugBuffer, "The file was not found.\n");
+ }
+ }
+
// Store the entry in the cache so it can be set by the user.
std::string init;
if (found) {
@@ -1024,8 +1066,9 @@ bool cmFindPackageCommand::FindConfig()
cmStrCat("The directory containing a CMake configuration file for ",
this->Name, '.');
// We force the value since we do not get here if it was already set.
- this->Makefile->AddCacheDefinition(this->Variable, init.c_str(),
- help.c_str(), cmStateEnums::PATH, true);
+ this->Makefile->AddCacheDefinition(this->Variable, init, help.c_str(),
+ cmStateEnums::PATH, true);
+
return found;
}
@@ -1077,12 +1120,10 @@ bool cmFindPackageCommand::ReadListFile(const std::string& f,
void cmFindPackageCommand::AppendToFoundProperty(bool found)
{
std::vector<std::string> foundContents;
- const char* foundProp =
+ cmProp foundProp =
this->Makefile->GetState()->GetGlobalProperty("PACKAGES_FOUND");
- if (foundProp && *foundProp) {
- std::string tmp = foundProp;
-
- cmExpandList(tmp, foundContents, false);
+ if (foundProp && !foundProp->empty()) {
+ cmExpandList(*foundProp, foundContents, false);
auto nameIt =
std::find(foundContents.begin(), foundContents.end(), this->Name);
if (nameIt != foundContents.end()) {
@@ -1091,12 +1132,10 @@ void cmFindPackageCommand::AppendToFoundProperty(bool found)
}
std::vector<std::string> notFoundContents;
- const char* notFoundProp =
+ cmProp notFoundProp =
this->Makefile->GetState()->GetGlobalProperty("PACKAGES_NOT_FOUND");
- if (notFoundProp && *notFoundProp) {
- std::string tmp = notFoundProp;
-
- cmExpandList(tmp, notFoundContents, false);
+ if (notFoundProp && !notFoundProp->empty()) {
+ cmExpandList(*notFoundProp, notFoundContents, false);
auto nameIt =
std::find(notFoundContents.begin(), notFoundContents.end(), this->Name);
if (nameIt != notFoundContents.end()) {
@@ -1164,6 +1203,21 @@ void cmFindPackageCommand::AppendSuccessInformation()
this->Makefile->FindPackageRootPathStack.pop_back();
}
+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";
+ return 0;
+ }
+ for (std::size_t i = startIndex; i < paths.size(); i++) {
+ buffer += " " + paths[i] + "\n";
+ }
+ return paths.size();
+}
+
void cmFindPackageCommand::ComputePrefixes()
{
if (!this->NoDefaultPath) {
@@ -1177,7 +1231,9 @@ void cmFindPackageCommand::ComputePrefixes()
this->FillPrefixesCMakeEnvironment();
}
}
+
this->FillPrefixesUserHints();
+
if (!this->NoDefaultPath) {
if (!this->NoSystemEnvironmentPath) {
this->FillPrefixesSystemEnvironment();
@@ -1209,29 +1265,72 @@ void cmFindPackageCommand::FillPrefixesPackageRoot()
paths.AddPath(path);
}
}
+ if (this->DebugMode) {
+ std::string debugBuffer = "<PackageName>_ROOT CMake variable "
+ "[CMAKE_FIND_USE_PACKAGE_ROOT_PATH].\n";
+ collectPathsForDebug(debugBuffer, paths);
+ this->DebugBuffer = cmStrCat(this->DebugBuffer, debugBuffer, "\n");
+ }
}
void cmFindPackageCommand::FillPrefixesCMakeEnvironment()
{
cmSearchPath& paths = this->LabeledPaths[PathLabel::CMakeEnvironment];
+ std::string debugBuffer;
+ std::size_t debugOffset = 0;
// Check the environment variable with the same name as the cache
// entry.
paths.AddEnvPath(this->Variable);
+ if (this->DebugMode) {
+ debugBuffer = cmStrCat("Env variable ", this->Variable,
+ " [CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH].\n");
+ debugOffset = collectPathsForDebug(debugBuffer, paths);
+ }
// And now the general CMake environment variables
paths.AddEnvPath("CMAKE_PREFIX_PATH");
+ if (this->DebugMode) {
+ debugBuffer = cmStrCat(debugBuffer,
+ "\nCMAKE_PREFIX_PATH env variable "
+ "[CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH].\n");
+ debugOffset = collectPathsForDebug(debugBuffer, paths, debugOffset);
+ }
+
paths.AddEnvPath("CMAKE_FRAMEWORK_PATH");
paths.AddEnvPath("CMAKE_APPBUNDLE_PATH");
+ if (this->DebugMode) {
+ debugBuffer =
+ cmStrCat(debugBuffer,
+ "\nCMAKE_FRAMEWORK_PATH and CMAKE_APPBUNDLE_PATH env "
+ "variables [CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH].\n");
+ collectPathsForDebug(debugBuffer, paths, debugOffset);
+ this->DebugBuffer = cmStrCat(this->DebugBuffer, debugBuffer, "\n");
+ }
}
void cmFindPackageCommand::FillPrefixesCMakeVariable()
{
cmSearchPath& paths = this->LabeledPaths[PathLabel::CMake];
+ std::string debugBuffer;
+ std::size_t debugOffset = 0;
paths.AddCMakePath("CMAKE_PREFIX_PATH");
+ if (this->DebugMode) {
+ debugBuffer = "CMAKE_PREFIX_PATH variable [CMAKE_FIND_USE_CMAKE_PATH].\n";
+ debugOffset = collectPathsForDebug(debugBuffer, paths);
+ }
+
paths.AddCMakePath("CMAKE_FRAMEWORK_PATH");
paths.AddCMakePath("CMAKE_APPBUNDLE_PATH");
+ if (this->DebugMode) {
+ debugBuffer =
+ cmStrCat(debugBuffer,
+ "\nCMAKE_FRAMEWORK_PATH and CMAKE_APPBUNDLE_PATH variables "
+ "[CMAKE_FIND_USE_CMAKE_PATH].\n");
+ collectPathsForDebug(debugBuffer, paths, debugOffset);
+ this->DebugBuffer = cmStrCat(this->DebugBuffer, debugBuffer, "\n");
+ }
}
void cmFindPackageCommand::FillPrefixesSystemEnvironment()
@@ -1251,6 +1350,12 @@ void cmFindPackageCommand::FillPrefixesSystemEnvironment()
paths.AddPath(i);
}
}
+ if (this->DebugMode) {
+ std::string debugBuffer = "Standard system environment variables "
+ "[CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH].\n";
+ collectPathsForDebug(debugBuffer, paths);
+ this->DebugBuffer = cmStrCat(this->DebugBuffer, debugBuffer, "\n");
+ }
}
void cmFindPackageCommand::FillPrefixesUserRegistry()
@@ -1274,6 +1379,13 @@ void cmFindPackageCommand::FillPrefixesUserRegistry()
this->LabeledPaths[PathLabel::UserRegistry]);
}
#endif
+ if (this->DebugMode) {
+ std::string debugBuffer =
+ "CMake User Package Registry [CMAKE_FIND_USE_PACKAGE_REGISTRY].\n";
+ collectPathsForDebug(debugBuffer,
+ this->LabeledPaths[PathLabel::UserRegistry]);
+ this->DebugBuffer = cmStrCat(this->DebugBuffer, debugBuffer, "\n");
+ }
}
void cmFindPackageCommand::FillPrefixesSystemRegistry()
@@ -1285,6 +1397,15 @@ void cmFindPackageCommand::FillPrefixesSystemRegistry()
#if defined(_WIN32) && !defined(__CYGWIN__)
this->LoadPackageRegistryWinSystem();
#endif
+
+ if (this->DebugMode) {
+ std::string debugBuffer =
+ "CMake System Package Registry "
+ "[CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY].\n";
+ collectPathsForDebug(debugBuffer,
+ this->LabeledPaths[PathLabel::SystemRegistry]);
+ this->DebugBuffer = cmStrCat(this->DebugBuffer, debugBuffer, "\n");
+ }
}
#if defined(_WIN32) && !defined(__CYGWIN__)
@@ -1457,6 +1578,13 @@ void cmFindPackageCommand::FillPrefixesCMakeSystemVariable()
paths.AddCMakePath("CMAKE_SYSTEM_PREFIX_PATH");
paths.AddCMakePath("CMAKE_SYSTEM_FRAMEWORK_PATH");
paths.AddCMakePath("CMAKE_SYSTEM_APPBUNDLE_PATH");
+
+ if (this->DebugMode) {
+ std::string debugBuffer = "CMake variables defined in the Platform file "
+ "[CMAKE_FIND_USE_CMAKE_SYSTEM_PATH].\n";
+ collectPathsForDebug(debugBuffer, paths);
+ this->DebugBuffer = cmStrCat(this->DebugBuffer, debugBuffer, "\n");
+ }
}
void cmFindPackageCommand::FillPrefixesUserGuess()
@@ -1466,6 +1594,12 @@ void cmFindPackageCommand::FillPrefixesUserGuess()
for (std::string const& p : this->UserGuessArgs) {
paths.AddUserPath(p);
}
+ if (this->DebugMode) {
+ std::string debugBuffer =
+ "Paths specified by the find_package PATHS option.\n";
+ collectPathsForDebug(debugBuffer, paths);
+ this->DebugBuffer = cmStrCat(this->DebugBuffer, debugBuffer, "\n");
+ }
}
void cmFindPackageCommand::FillPrefixesUserHints()
@@ -1475,6 +1609,12 @@ void cmFindPackageCommand::FillPrefixesUserHints()
for (std::string const& p : this->UserHintsArgs) {
paths.AddUserPath(p);
}
+ if (this->DebugMode) {
+ std::string debugBuffer =
+ "Paths specified by the find_package HINTS option.\n";
+ collectPathsForDebug(debugBuffer, paths);
+ this->DebugBuffer = cmStrCat(this->DebugBuffer, debugBuffer, "\n");
+ }
}
bool cmFindPackageCommand::SearchDirectory(std::string const& dir)
@@ -1519,7 +1659,7 @@ bool cmFindPackageCommand::FindConfigFile(std::string const& dir,
for (std::string const& c : this->Configs) {
file = cmStrCat(dir, '/', c);
if (this->DebugMode) {
- fprintf(stderr, "Checking file [%s]\n", file.c_str());
+ this->DebugBuffer = cmStrCat(this->DebugBuffer, " ", file, "\n");
}
if (cmSystemTools::FileExists(file, true) && this->CheckVersion(file)) {
// Allow resolving symlinks when the config file is found through a link
@@ -2032,9 +2172,6 @@ private:
bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
{
assert(!prefix_in.empty() && prefix_in.back() == '/');
- if (this->DebugMode) {
- fprintf(stderr, "Checking prefix [%s]\n", prefix_in.c_str());
- }
// Skip this if the prefix does not exist.
if (!cmSystemTools::FileIsDirectory(prefix_in)) {
@@ -2188,9 +2325,6 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
bool cmFindPackageCommand::SearchFrameworkPrefix(std::string const& prefix_in)
{
assert(!prefix_in.empty() && prefix_in.back() == '/');
- if (this->DebugMode) {
- fprintf(stderr, "Checking framework prefix [%s]\n", prefix_in.c_str());
- }
// Strip the trailing slash because the path generator is about to
// add one.
@@ -2249,9 +2383,6 @@ bool cmFindPackageCommand::SearchFrameworkPrefix(std::string const& prefix_in)
bool cmFindPackageCommand::SearchAppBundlePrefix(std::string const& prefix_in)
{
assert(!prefix_in.empty() && prefix_in.back() == '/');
- if (this->DebugMode) {
- fprintf(stderr, "Checking bundle prefix [%s]\n", prefix_in.c_str());
- }
// Strip the trailing slash because the path generator is about to
// add one.
diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h
index 85fe7b6..7058a54 100644
--- a/Source/cmFindPackageCommand.h
+++ b/Source/cmFindPackageCommand.h
@@ -12,7 +12,7 @@
#include <string>
#include <vector>
-#include "cm_kwiml.h"
+#include <cm3p/kwiml/int.h>
#include "cmFindCommon.h"
#include "cmPolicies.h"
@@ -174,7 +174,6 @@ private:
bool UseFindModules;
bool NoUserRegistry;
bool NoSystemRegistry;
- bool DebugMode;
bool UseLib32Paths;
bool UseLib64Paths;
bool UseLibx32Paths;
@@ -184,6 +183,7 @@ private:
std::vector<std::string> Names;
std::vector<std::string> Configs;
std::set<std::string> IgnoredPaths;
+ std::string DebugBuffer;
/*! the selected sortOrder (None by default)*/
SortOrderType SortOrder;
diff --git a/Source/cmFindPathCommand.cxx b/Source/cmFindPathCommand.cxx
index f5e2631..4bab469 100644
--- a/Source/cmFindPathCommand.cxx
+++ b/Source/cmFindPathCommand.cxx
@@ -5,6 +5,7 @@
#include "cmsys/Glob.hxx"
#include "cmMakefile.h"
+#include "cmMessageType.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -21,6 +22,7 @@ cmFindPathCommand::cmFindPathCommand(cmExecutionStatus& status)
// cmFindPathCommand
bool cmFindPathCommand::InitialPass(std::vector<std::string> const& argsIn)
{
+ this->DebugMode = ComputeIfDebugModeWanted();
this->VariableDocumentation = "Path to a file.";
this->CMakePathName = "INCLUDE";
if (!this->ParseArguments(argsIn)) {
@@ -42,29 +44,39 @@ bool cmFindPathCommand::InitialPass(std::vector<std::string> const& argsIn)
std::string result = this->FindHeader();
if (!result.empty()) {
this->Makefile->AddCacheDefinition(
- this->VariableName, result.c_str(), this->VariableDocumentation.c_str(),
+ this->VariableName, result, this->VariableDocumentation.c_str(),
(this->IncludeFileInPath) ? cmStateEnums::FILEPATH : cmStateEnums::PATH);
return true;
}
this->Makefile->AddCacheDefinition(
- this->VariableName, (this->VariableName + "-NOTFOUND").c_str(),
+ this->VariableName, this->VariableName + "-NOTFOUND",
this->VariableDocumentation.c_str(),
(this->IncludeFileInPath) ? cmStateEnums::FILEPATH : cmStateEnums::PATH);
+ if (this->Required) {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ "Could not find " + this->VariableName +
+ " using the following files: " + cmJoin(this->Names, ", "));
+ cmSystemTools::SetFatalErrorOccured();
+ }
return true;
}
std::string cmFindPathCommand::FindHeader()
{
+ std::string debug_name = this->IncludeFileInPath ? "find_file" : "find_path";
+ cmFindBaseDebugState debug(debug_name, this);
std::string header;
if (this->SearchFrameworkFirst || this->SearchFrameworkOnly) {
- header = this->FindFrameworkHeader();
+ header = this->FindFrameworkHeader(debug);
}
if (header.empty() && !this->SearchFrameworkOnly) {
- header = this->FindNormalHeader();
+ header = this->FindNormalHeader(debug);
}
if (header.empty() && this->SearchFrameworkLast) {
- header = this->FindFrameworkHeader();
+ header = this->FindFrameworkHeader(debug);
}
+
return header;
}
@@ -116,28 +128,31 @@ std::string cmFindPathCommand::FindHeaderInFramework(std::string const& file,
return "";
}
-std::string cmFindPathCommand::FindNormalHeader()
+std::string cmFindPathCommand::FindNormalHeader(cmFindBaseDebugState& debug)
{
std::string tryPath;
for (std::string const& n : this->Names) {
for (std::string const& sp : this->SearchPaths) {
tryPath = cmStrCat(sp, n);
if (cmSystemTools::FileExists(tryPath)) {
+ debug.FoundAt(tryPath);
if (this->IncludeFileInPath) {
return tryPath;
}
return sp;
}
+ debug.FailedAt(tryPath);
}
}
return "";
}
-std::string cmFindPathCommand::FindFrameworkHeader()
+std::string cmFindPathCommand::FindFrameworkHeader(cmFindBaseDebugState& debug)
{
for (std::string const& n : this->Names) {
for (std::string const& sp : this->SearchPaths) {
std::string fwPath = this->FindHeaderInFramework(n, sp);
+ fwPath.empty() ? debug.FailedAt(fwPath) : debug.FoundAt(fwPath);
if (!fwPath.empty()) {
return fwPath;
}
diff --git a/Source/cmFindPathCommand.h b/Source/cmFindPathCommand.h
index 8d1ea8b..18bfb7d 100644
--- a/Source/cmFindPathCommand.h
+++ b/Source/cmFindPathCommand.h
@@ -32,8 +32,8 @@ private:
std::string FindHeaderInFramework(std::string const& file,
std::string const& dir);
std::string FindHeader();
- std::string FindNormalHeader();
- std::string FindFrameworkHeader();
+ std::string FindNormalHeader(cmFindBaseDebugState& debug);
+ std::string FindFrameworkHeader(cmFindBaseDebugState& debug);
};
bool cmFindPath(std::vector<std::string> const& args,
diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx
index e0a3fbf..599b1d2 100644
--- a/Source/cmFindProgramCommand.cxx
+++ b/Source/cmFindProgramCommand.cxx
@@ -3,6 +3,7 @@
#include "cmFindProgramCommand.h"
#include "cmMakefile.h"
+#include "cmMessageType.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -15,7 +16,9 @@ class cmExecutionStatus;
struct cmFindProgramHelper
{
- cmFindProgramHelper()
+ cmFindProgramHelper(cmMakefile* makefile, cmFindBase const* base)
+ : DebugSearches("find_program", base)
+ , Makefile(makefile)
{
#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
// Consider platform-specific extensions.
@@ -41,6 +44,10 @@ struct cmFindProgramHelper
// Current full path under consideration.
std::string TestPath;
+ // Debug state
+ cmFindBaseDebugState DebugSearches;
+ cmMakefile* Makefile;
+
void AddName(std::string const& name) { this->Names.push_back(name); }
void SetName(std::string const& name)
{
@@ -78,8 +85,10 @@ struct cmFindProgramHelper
this->TestNameExt = cmStrCat(name, ext);
this->TestPath =
cmSystemTools::CollapseFullPath(this->TestNameExt, path);
-
- if (cmSystemTools::FileExists(this->TestPath, true)) {
+ bool exists = cmSystemTools::FileIsExecutable(this->TestPath);
+ exists ? this->DebugSearches.FoundAt(this->TestPath)
+ : this->DebugSearches.FailedAt(this->TestPath);
+ if (exists) {
this->BestPath = this->TestPath;
return true;
}
@@ -97,6 +106,7 @@ cmFindProgramCommand::cmFindProgramCommand(cmExecutionStatus& status)
// cmFindProgramCommand
bool cmFindProgramCommand::InitialPass(std::vector<std::string> const& argsIn)
{
+ this->DebugMode = ComputeIfDebugModeWanted();
this->VariableDocumentation = "Path to a program.";
this->CMakePathName = "PROGRAM";
// call cmFindBase::ParseArguments
@@ -118,15 +128,22 @@ bool cmFindProgramCommand::InitialPass(std::vector<std::string> const& argsIn)
std::string const result = FindProgram();
if (!result.empty()) {
// Save the value in the cache
- this->Makefile->AddCacheDefinition(this->VariableName, result.c_str(),
+ this->Makefile->AddCacheDefinition(this->VariableName, result,
this->VariableDocumentation.c_str(),
cmStateEnums::FILEPATH);
return true;
}
this->Makefile->AddCacheDefinition(
- this->VariableName, (this->VariableName + "-NOTFOUND").c_str(),
+ this->VariableName, this->VariableName + "-NOTFOUND",
this->VariableDocumentation.c_str(), cmStateEnums::FILEPATH);
+ if (this->Required) {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ "Could not find " + this->VariableName +
+ " using the following names: " + cmJoin(this->Names, ", "));
+ cmSystemTools::SetFatalErrorOccured();
+ }
return true;
}
@@ -158,7 +175,7 @@ std::string cmFindProgramCommand::FindNormalProgram()
std::string cmFindProgramCommand::FindNormalProgramNamesPerDir()
{
// Search for all names in each directory.
- cmFindProgramHelper helper;
+ cmFindProgramHelper helper(this->Makefile, this);
for (std::string const& n : this->Names) {
helper.AddName(n);
}
@@ -181,7 +198,7 @@ std::string cmFindProgramCommand::FindNormalProgramNamesPerDir()
std::string cmFindProgramCommand::FindNormalProgramDirsPerName()
{
// Search the entire path for each name.
- cmFindProgramHelper helper;
+ cmFindProgramHelper helper(this->Makefile, this);
for (std::string const& n : this->Names) {
// Switch to searching for this name.
helper.SetName(n);
diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx
index 44392ba..32e7892 100644
--- a/Source/cmForEachCommand.cxx
+++ b/Source/cmForEachCommand.cxx
@@ -2,14 +2,23 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmForEachCommand.h"
-#include <cstdio>
+#include <algorithm>
+#include <cassert>
+#include <cstddef> // IWYU pragma: keep
+// NOTE The declaration of `std::abs` has moved to `cmath` since C++17
+// See https://en.cppreference.com/w/cpp/numeric/math/abs
+// ALERT But IWYU used to lint `#include`s do not "understand"
+// conditional compilation (i.e. `#if __cplusplus >= 201703L`)
#include <cstdlib>
+#include <iterator>
+#include <map>
+#include <sstream>
+#include <stdexcept>
#include <utility>
#include <cm/memory>
#include <cm/string_view>
-
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
#include "cmExecutionStatus.h"
#include "cmFunctionBlocker.h"
@@ -21,12 +30,10 @@
#include "cmSystemTools.h"
namespace {
-bool HandleInMode(std::vector<std::string> const& args, cmMakefile& makefile);
-
class cmForEachFunctionBlocker : public cmFunctionBlocker
{
public:
- cmForEachFunctionBlocker(cmMakefile* mf);
+ explicit cmForEachFunctionBlocker(cmMakefile* mf);
~cmForEachFunctionBlocker() override;
cm::string_view StartCommandName() const override { return "foreach"_s; }
@@ -38,10 +45,33 @@ public:
bool Replay(std::vector<cmListFileFunction> functions,
cmExecutionStatus& inStatus) override;
+ void SetIterationVarsCount(const std::size_t varsCount)
+ {
+ this->IterationVarsCount = varsCount;
+ }
+ void SetZipLists() { this->ZipLists = true; }
+
std::vector<std::string> Args;
private:
+ struct InvokeResult
+ {
+ bool Restore;
+ bool Break;
+ };
+
+ bool ReplayItems(std::vector<cmListFileFunction> const& functions,
+ cmExecutionStatus& inStatus);
+
+ bool ReplayZipLists(std::vector<cmListFileFunction> const& functions,
+ cmExecutionStatus& inStatus);
+
+ InvokeResult invoke(std::vector<cmListFileFunction> const& functions,
+ cmExecutionStatus& inStatus, cmMakefile& mf);
+
cmMakefile* Makefile;
+ std::size_t IterationVarsCount = 0u;
+ bool ZipLists = false;
};
cmForEachFunctionBlocker::cmForEachFunctionBlocker(cmMakefile* mf)
@@ -60,53 +90,288 @@ bool cmForEachFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff,
{
std::vector<std::string> expandedArguments;
mf.ExpandArguments(lff.Arguments, expandedArguments);
- return expandedArguments.empty() || expandedArguments[0] == this->Args[0];
+ return expandedArguments.empty() ||
+ expandedArguments.front() == this->Args.front();
}
bool cmForEachFunctionBlocker::Replay(
std::vector<cmListFileFunction> functions, cmExecutionStatus& inStatus)
{
- cmMakefile& mf = inStatus.GetMakefile();
- // at end of for each execute recorded commands
+ return this->ZipLists ? this->ReplayZipLists(functions, inStatus)
+ : this->ReplayItems(functions, inStatus);
+}
+
+bool cmForEachFunctionBlocker::ReplayItems(
+ std::vector<cmListFileFunction> const& functions,
+ cmExecutionStatus& inStatus)
+{
+ assert("Unexpected number of iteration variables" &&
+ this->IterationVarsCount == 1);
+
+ auto& mf = inStatus.GetMakefile();
+
+ // At end of for each execute recorded commands
// store the old value
std::string oldDef;
- if (mf.GetDefinition(this->Args[0])) {
- oldDef = mf.GetDefinition(this->Args[0]);
+ if (mf.GetDefinition(this->Args.front())) {
+ oldDef = mf.GetDefinition(this->Args.front());
}
+ auto restore = false;
for (std::string const& arg : cmMakeRange(this->Args).advance(1)) {
- // set the variable to the loop value
- mf.AddDefinition(this->Args[0], arg);
+ // Set the variable to the loop value
+ mf.AddDefinition(this->Args.front(), arg);
// Invoke all the functions that were collected in the block.
- for (cmListFileFunction const& func : functions) {
- cmExecutionStatus status(mf);
- mf.ExecuteCommand(func, status);
- if (status.GetReturnInvoked()) {
- inStatus.SetReturnInvoked();
- // restore the variable to its prior value
- mf.AddDefinition(this->Args[0], oldDef);
+ auto r = this->invoke(functions, inStatus, mf);
+ restore = r.Restore;
+ if (r.Break) {
+ break;
+ }
+ }
+
+ if (restore) {
+ // restore the variable to its prior value
+ mf.AddDefinition(this->Args.front(), oldDef);
+ }
+ return true;
+}
+
+bool cmForEachFunctionBlocker::ReplayZipLists(
+ std::vector<cmListFileFunction> const& functions,
+ cmExecutionStatus& inStatus)
+{
+ assert("Unexpected number of iteration variables" &&
+ this->IterationVarsCount >= 1);
+
+ auto& mf = inStatus.GetMakefile();
+
+ // Expand the list of list-variables into a list of lists of strings
+ std::vector<std::vector<std::string>> values;
+ values.reserve(this->Args.size() - this->IterationVarsCount);
+ // Also track the longest list size
+ std::size_t maxItems = 0u;
+ for (auto const& var :
+ cmMakeRange(this->Args).advance(this->IterationVarsCount)) {
+ std::vector<std::string> items;
+ auto const& value = mf.GetSafeDefinition(var);
+ if (!value.empty()) {
+ cmExpandList(value, items, true);
+ }
+ maxItems = std::max(maxItems, items.size());
+ values.emplace_back(std::move(items));
+ }
+
+ // Form the list of iteration variables
+ std::vector<std::string> iterationVars;
+ if (this->IterationVarsCount > 1) {
+ // If multiple iteration variables has given,
+ // just copy them to the `iterationVars` list.
+ iterationVars.reserve(values.size());
+ std::copy(this->Args.begin(),
+ this->Args.begin() + this->IterationVarsCount,
+ std::back_inserter(iterationVars));
+ } else {
+ // In case of the only iteration variable,
+ // generate names as `var_name_N`,
+ // where `N` is the count of lists to zip
+ iterationVars.resize(values.size());
+ const auto iter_var_prefix = this->Args.front() + "_";
+ auto i = 0u;
+ std::generate(
+ iterationVars.begin(), iterationVars.end(),
+ [&]() -> std::string { return iter_var_prefix + std::to_string(i++); });
+ }
+ assert("Sanity check" && iterationVars.size() == values.size());
+
+ // Store old values for iteration variables
+ std::map<std::string, std::string> oldDefs;
+ for (auto i = 0u; i < values.size(); ++i) {
+ if (mf.GetDefinition(iterationVars[i])) {
+ oldDefs.emplace(iterationVars[i], mf.GetDefinition(iterationVars[i]));
+ }
+ }
+
+ // Form a vector of current positions in all lists (Ok, vectors) of values
+ std::vector<decltype(values)::value_type::iterator> positions;
+ positions.reserve(values.size());
+ std::transform(
+ values.begin(), values.end(), std::back_inserter(positions),
+ // Set the initial position to the beginning of every list
+ [](decltype(values)::value_type& list) { return list.begin(); });
+ assert("Sanity check" && positions.size() == values.size());
+
+ auto restore = false;
+ // Iterate over all the lists simulateneously
+ for (auto i = 0u; i < maxItems; ++i) {
+ // Declare iteration variables
+ for (auto j = 0u; j < values.size(); ++j) {
+ // Define (or not) the iteration variable if the current position
+ // still not at the end...
+ if (positions[j] != values[j].end()) {
+ mf.AddDefinition(iterationVars[j], *positions[j]);
+ ++positions[j];
+ } else {
+ mf.RemoveDefinition(iterationVars[j]);
+ }
+ }
+ // Invoke all the functions that were collected in the block.
+ auto r = this->invoke(functions, inStatus, mf);
+ restore = r.Restore;
+ if (r.Break) {
+ break;
+ }
+ }
+
+ // Restore the variables to its prior value
+ if (restore) {
+ for (auto const& p : oldDefs) {
+ mf.AddDefinition(p.first, p.second);
+ }
+ }
+ return true;
+}
+
+auto cmForEachFunctionBlocker::invoke(
+ std::vector<cmListFileFunction> const& functions,
+ cmExecutionStatus& inStatus, cmMakefile& mf) -> InvokeResult
+{
+ InvokeResult result = { true, false };
+ // Invoke all the functions that were collected in the block.
+ for (cmListFileFunction const& func : functions) {
+ cmExecutionStatus status(mf);
+ mf.ExecuteCommand(func, status);
+ if (status.GetReturnInvoked()) {
+ inStatus.SetReturnInvoked();
+ result.Break = true;
+ break;
+ }
+ if (status.GetBreakInvoked()) {
+ result.Break = true;
+ break;
+ }
+ if (status.GetContinueInvoked()) {
+ break;
+ }
+ if (cmSystemTools::GetFatalErrorOccured()) {
+ result.Restore = false;
+ result.Break = true;
+ break;
+ }
+ }
+ return result;
+}
+
+bool HandleInMode(std::vector<std::string> const& args,
+ std::vector<std::string>::const_iterator kwInIter,
+ cmMakefile& makefile)
+{
+ assert("A valid iterator expected" && kwInIter != args.end());
+
+ auto fb = cm::make_unique<cmForEachFunctionBlocker>(&makefile);
+
+ // Copy iteration variable names first
+ std::copy(args.begin(), kwInIter, std::back_inserter(fb->Args));
+ // Remember the count of given iteration variable names
+ const auto varsCount = fb->Args.size();
+ fb->SetIterationVarsCount(varsCount);
+
+ enum Doing
+ {
+ DoingNone,
+ DoingLists,
+ DoingItems,
+ DoingZipLists
+ };
+ Doing doing = DoingNone;
+ // Iterate over arguments past the "IN" keyword
+ for (std::string const& arg : cmMakeRange(++kwInIter, args.end())) {
+ if (arg == "LISTS") {
+ if (doing == DoingZipLists) {
+ makefile.IssueMessage(MessageType::FATAL_ERROR,
+ "ZIP_LISTS can not be used with LISTS or ITEMS");
+ return true;
+ }
+ if (varsCount != 1u) {
+ makefile.IssueMessage(
+ MessageType::FATAL_ERROR,
+ "ITEMS or LISTS require exactly one iteration variable");
return true;
}
- if (status.GetBreakInvoked()) {
- // restore the variable to its prior value
- mf.AddDefinition(this->Args[0], oldDef);
+ doing = DoingLists;
+
+ } else if (arg == "ITEMS") {
+ if (doing == DoingZipLists) {
+ makefile.IssueMessage(MessageType::FATAL_ERROR,
+ "ZIP_LISTS can not be used with LISTS or ITEMS");
return true;
}
- if (status.GetContinueInvoked()) {
- break;
+ if (varsCount != 1u) {
+ makefile.IssueMessage(
+ MessageType::FATAL_ERROR,
+ "ITEMS or LISTS require exactly one iteration variable");
+ return true;
}
- if (cmSystemTools::GetFatalErrorOccured()) {
+ doing = DoingItems;
+
+ } else if (arg == "ZIP_LISTS") {
+ if (doing != DoingNone) {
+ makefile.IssueMessage(MessageType::FATAL_ERROR,
+ "ZIP_LISTS can not be used with LISTS or ITEMS");
return true;
}
+ doing = DoingZipLists;
+ fb->SetZipLists();
+
+ } else if (doing == DoingLists) {
+ auto const& value = makefile.GetSafeDefinition(arg);
+ if (!value.empty()) {
+ cmExpandList(value, fb->Args, true);
+ }
+
+ } else if (doing == DoingItems || doing == DoingZipLists) {
+ fb->Args.push_back(arg);
+
+ } else {
+ makefile.IssueMessage(MessageType::FATAL_ERROR,
+ cmStrCat("Unknown argument:\n", " ", arg, "\n"));
+ return true;
}
}
- // restore the variable to its prior value
- mf.AddDefinition(this->Args[0], oldDef);
+ // If `ZIP_LISTS` given and variables count more than 1,
+ // make sure the given lists count matches variables...
+ if (doing == DoingZipLists && varsCount > 1u &&
+ (2u * varsCount) != fb->Args.size()) {
+ makefile.IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Expected ", std::to_string(varsCount),
+ " list variables, but given ",
+ std::to_string(fb->Args.size() - varsCount)));
+ return true;
+ }
+
+ makefile.AddFunctionBlocker(std::move(fb));
+
return true;
}
+
+bool TryParseInteger(cmExecutionStatus& status, const std::string& str, int& i)
+{
+ try {
+ i = std::stoi(str);
+ } catch (std::invalid_argument&) {
+ std::ostringstream e;
+ e << "Invalid integer: '" << str << "'";
+ status.SetError(e.str());
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ return true;
}
+} // anonymous namespace
+
bool cmForEachCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
@@ -114,8 +379,9 @@ bool cmForEachCommand(std::vector<std::string> const& args,
status.SetError("called with incorrect number of arguments");
return false;
}
- if (args.size() > 1 && args[1] == "IN") {
- return HandleInMode(args, status.GetMakefile());
+ auto kwInIter = std::find(args.begin(), args.end(), "IN");
+ if (kwInIter != args.end()) {
+ return HandleInMode(args, kwInIter, status.GetMakefile());
}
// create a function blocker
@@ -126,16 +392,28 @@ bool cmForEachCommand(std::vector<std::string> const& args,
int stop = 0;
int step = 0;
if (args.size() == 3) {
- stop = atoi(args[2].c_str());
+ if (!TryParseInteger(status, args[2], stop)) {
+ return false;
+ }
}
if (args.size() == 4) {
- start = atoi(args[2].c_str());
- stop = atoi(args[3].c_str());
+ if (!TryParseInteger(status, args[2], start)) {
+ return false;
+ }
+ if (!TryParseInteger(status, args[3], stop)) {
+ return false;
+ }
}
if (args.size() == 5) {
- start = atoi(args[2].c_str());
- stop = atoi(args[3].c_str());
- step = atoi(args[4].c_str());
+ if (!TryParseInteger(status, args[2], start)) {
+ return false;
+ }
+ if (!TryParseInteger(status, args[3], stop)) {
+ return false;
+ }
+ if (!TryParseInteger(status, args[4], step)) {
+ return false;
+ }
}
if (step == 0) {
if (start > stop) {
@@ -149,69 +427,36 @@ bool cmForEachCommand(std::vector<std::string> const& args,
status.SetError(
cmStrCat("called with incorrect range specification: start ", start,
", stop ", stop, ", step ", step));
+ cmSystemTools::SetFatalErrorOccured();
return false;
}
- std::vector<std::string> range;
- char buffer[100];
- range.push_back(args[0]);
- int cc;
- for (cc = start;; cc += step) {
- if ((step > 0 && cc > stop) || (step < 0 && cc < stop)) {
- break;
- }
- sprintf(buffer, "%d", cc);
- range.emplace_back(buffer);
- if (cc == stop) {
- break;
- }
- }
- fb->Args = range;
+
+ // Calculate expected iterations count and reserve enough space
+ // in the `fb->Args` vector. The first item is the iteration variable
+ // name...
+ const std::size_t iter_cnt = 2u +
+ int(start < stop) * (stop - start) / std::abs(step) +
+ int(start > stop) * (start - stop) / std::abs(step);
+ fb->Args.resize(iter_cnt);
+ fb->Args.front() = args.front();
+ auto cc = start;
+ auto generator = [&cc, step]() -> std::string {
+ auto result = std::to_string(cc);
+ cc += step;
+ return result;
+ };
+ // Fill the `range` vector w/ generated string values
+ // (starting from 2nd position)
+ std::generate(++fb->Args.begin(), fb->Args.end(), generator);
} else {
fb->Args = args;
}
} else {
fb->Args = args;
}
- status.GetMakefile().AddFunctionBlocker(std::move(fb));
-
- return true;
-}
-
-namespace {
-bool HandleInMode(std::vector<std::string> const& args, cmMakefile& makefile)
-{
- auto fb = cm::make_unique<cmForEachFunctionBlocker>(&makefile);
- fb->Args.push_back(args[0]);
-
- enum Doing
- {
- DoingNone,
- DoingLists,
- DoingItems
- };
- Doing doing = DoingNone;
- for (unsigned int i = 2; i < args.size(); ++i) {
- if (doing == DoingItems) {
- fb->Args.push_back(args[i]);
- } else if (args[i] == "LISTS") {
- doing = DoingLists;
- } else if (args[i] == "ITEMS") {
- doing = DoingItems;
- } else if (doing == DoingLists) {
- const char* value = makefile.GetDefinition(args[i]);
- if (value && *value) {
- cmExpandList(value, fb->Args, true);
- }
- } else {
- makefile.IssueMessage(
- MessageType::FATAL_ERROR,
- cmStrCat("Unknown argument:\n", " ", args[i], "\n"));
- return true;
- }
- }
- makefile.AddFunctionBlocker(std::move(fb));
+ fb->SetIterationVarsCount(1u);
+ status.GetMakefile().AddFunctionBlocker(std::move(fb));
return true;
}
-}
diff --git a/Source/cmFunctionBlocker.cxx b/Source/cmFunctionBlocker.cxx
index 5778a71..643cd82 100644
--- a/Source/cmFunctionBlocker.cxx
+++ b/Source/cmFunctionBlocker.cxx
@@ -3,7 +3,9 @@
#include "cmFunctionBlocker.h"
#include <cassert>
+#include <memory> // IWYU pragma: keep
#include <sstream>
+#include <string> // IWYU pragma: keep
#include <utility>
#include "cmExecutionStatus.h"
diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx
index b3ddfe0..b6f58bd 100644
--- a/Source/cmFunctionCommand.cxx
+++ b/Source/cmFunctionCommand.cxx
@@ -2,15 +2,13 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmFunctionCommand.h"
-#include <sstream>
#include <utility>
#include <cm/memory>
#include <cm/string_view>
+#include <cmext/algorithm>
+#include <cmext/string_view>
-#include "cm_static_string_view.hxx"
-
-#include "cmAlgorithms.h"
#include "cmExecutionStatus.h"
#include "cmFunctionBlocker.h"
#include "cmListFileCache.h"
@@ -19,8 +17,20 @@
#include "cmRange.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
namespace {
+std::string const ARGC = "ARGC";
+std::string const ARGN = "ARGN";
+std::string const ARGV = "ARGV";
+std::string const CMAKE_CURRENT_FUNCTION = "CMAKE_CURRENT_FUNCTION";
+std::string const CMAKE_CURRENT_FUNCTION_LIST_FILE =
+ "CMAKE_CURRENT_FUNCTION_LIST_FILE";
+std::string const CMAKE_CURRENT_FUNCTION_LIST_DIR =
+ "CMAKE_CURRENT_FUNCTION_LIST_DIR";
+std::string const CMAKE_CURRENT_FUNCTION_LIST_LINE =
+ "CMAKE_CURRENT_FUNCTION_LIST_LINE";
+
// define the class for function commands
class cmFunctionHelperCommand
{
@@ -36,8 +46,8 @@ public:
std::vector<cmListFileFunction> Functions;
cmPolicies::PolicyMap Policies;
std::string FilePath;
+ long Line;
};
-}
bool cmFunctionHelperCommand::operator()(
std::vector<cmListFileArgument> const& args,
@@ -52,9 +62,9 @@ bool cmFunctionHelperCommand::operator()(
// make sure the number of arguments passed is at least the number
// required by the signature
if (expandedArgs.size() < this->Args.size() - 1) {
- std::string errorMsg = cmStrCat(
+ auto const errorMsg = cmStrCat(
"Function invoked with incorrect arguments for function named: ",
- this->Args[0]);
+ this->Args.front());
inStatus.SetError(errorMsg);
return false;
}
@@ -63,30 +73,40 @@ bool cmFunctionHelperCommand::operator()(
this->Policies);
// set the value of argc
- makefile.AddDefinition("ARGC", std::to_string(expandedArgs.size()));
- makefile.MarkVariableAsUsed("ARGC");
+ makefile.AddDefinition(ARGC, std::to_string(expandedArgs.size()));
+ makefile.MarkVariableAsUsed(ARGC);
// set the values for ARGV0 ARGV1 ...
- for (unsigned int t = 0; t < expandedArgs.size(); ++t) {
- std::ostringstream tmpStream;
- tmpStream << "ARGV" << t;
- makefile.AddDefinition(tmpStream.str(), expandedArgs[t]);
- makefile.MarkVariableAsUsed(tmpStream.str());
+ for (auto t = 0u; t < expandedArgs.size(); ++t) {
+ auto const value = cmStrCat(ARGV, std::to_string(t));
+ makefile.AddDefinition(value, expandedArgs[t]);
+ makefile.MarkVariableAsUsed(value);
}
// define the formal arguments
- for (unsigned int j = 1; j < this->Args.size(); ++j) {
+ for (auto j = 1u; j < this->Args.size(); ++j) {
makefile.AddDefinition(this->Args[j], expandedArgs[j - 1]);
}
// define ARGV and ARGN
- std::string argvDef = cmJoin(expandedArgs, ";");
- auto eit = expandedArgs.begin() + (this->Args.size() - 1);
- std::string argnDef = cmJoin(cmMakeRange(eit, expandedArgs.end()), ";");
- makefile.AddDefinition("ARGV", argvDef);
- makefile.MarkVariableAsUsed("ARGV");
- makefile.AddDefinition("ARGN", argnDef);
- makefile.MarkVariableAsUsed("ARGN");
+ auto const argvDef = cmJoin(expandedArgs, ";");
+ auto const eit = expandedArgs.begin() + (this->Args.size() - 1);
+ auto const argnDef = cmJoin(cmMakeRange(eit, expandedArgs.end()), ";");
+ makefile.AddDefinition(ARGV, argvDef);
+ makefile.MarkVariableAsUsed(ARGV);
+ makefile.AddDefinition(ARGN, argnDef);
+ makefile.MarkVariableAsUsed(ARGN);
+
+ makefile.AddDefinition(CMAKE_CURRENT_FUNCTION, this->Args.front());
+ makefile.MarkVariableAsUsed(CMAKE_CURRENT_FUNCTION);
+ makefile.AddDefinition(CMAKE_CURRENT_FUNCTION_LIST_FILE, this->FilePath);
+ makefile.MarkVariableAsUsed(CMAKE_CURRENT_FUNCTION_LIST_FILE);
+ makefile.AddDefinition(CMAKE_CURRENT_FUNCTION_LIST_DIR,
+ cmSystemTools::GetFilenamePath(this->FilePath));
+ makefile.MarkVariableAsUsed(CMAKE_CURRENT_FUNCTION_LIST_DIR);
+ makefile.AddDefinition(CMAKE_CURRENT_FUNCTION_LIST_LINE,
+ std::to_string(this->Line));
+ makefile.MarkVariableAsUsed(CMAKE_CURRENT_FUNCTION_LIST_LINE);
// Invoke all the functions that were collected in the block.
// for each function
@@ -100,7 +120,7 @@ bool cmFunctionHelperCommand::operator()(
return false;
}
if (status.GetReturnInvoked()) {
- return true;
+ break;
}
}
@@ -129,7 +149,8 @@ bool cmFunctionFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff,
std::vector<std::string> expandedArguments;
mf.ExpandArguments(lff.Arguments, expandedArguments,
this->GetStartingContext().FilePath.c_str());
- return expandedArguments.empty() || expandedArguments[0] == this->Args[0];
+ return expandedArguments.empty() ||
+ expandedArguments.front() == this->Args.front();
}
bool cmFunctionFunctionBlocker::Replay(
@@ -141,11 +162,14 @@ bool cmFunctionFunctionBlocker::Replay(
f.Args = this->Args;
f.Functions = std::move(functions);
f.FilePath = this->GetStartingContext().FilePath;
+ f.Line = this->GetStartingContext().Line;
mf.RecordPolicies(f.Policies);
- mf.GetState()->AddScriptedCommand(this->Args[0], std::move(f));
+ mf.GetState()->AddScriptedCommand(this->Args.front(), std::move(f));
return true;
}
+} // anonymous namespace
+
bool cmFunctionCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
@@ -155,10 +179,9 @@ bool cmFunctionCommand(std::vector<std::string> const& args,
}
// create a function blocker
- {
- auto fb = cm::make_unique<cmFunctionFunctionBlocker>();
- cmAppend(fb->Args, args);
- status.GetMakefile().AddFunctionBlocker(std::move(fb));
- }
+ auto fb = cm::make_unique<cmFunctionFunctionBlocker>();
+ cm::append(fb->Args, args);
+ status.GetMakefile().AddFunctionBlocker(std::move(fb));
+
return true;
}
diff --git a/Source/cmGccDepfileLexerHelper.cxx b/Source/cmGccDepfileLexerHelper.cxx
new file mode 100644
index 0000000..957896f
--- /dev/null
+++ b/Source/cmGccDepfileLexerHelper.cxx
@@ -0,0 +1,126 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmGccDepfileLexerHelper.h"
+
+#include <cstdio>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "cmGccDepfileReaderTypes.h"
+
+#include "LexerParser/cmGccDepfileLexer.h"
+
+#ifdef _WIN32
+# include "cmsys/Encoding.h"
+#endif
+
+bool cmGccDepfileLexerHelper::readFile(const char* filePath)
+{
+#ifdef _WIN32
+ wchar_t* wpath = cmsysEncoding_DupToWide(filePath);
+ FILE* file = _wfopen(wpath, L"rb");
+ free(wpath);
+#else
+ FILE* file = fopen(filePath, "r");
+#endif
+ if (!file) {
+ return false;
+ }
+ newEntry();
+ yyscan_t scanner;
+ cmGccDepfile_yylex_init(&scanner);
+ cmGccDepfile_yyset_extra(this, scanner);
+ cmGccDepfile_yyrestart(file, scanner);
+ cmGccDepfile_yylex(scanner);
+ cmGccDepfile_yylex_destroy(scanner);
+ sanitizeContent();
+ fclose(file);
+ return true;
+}
+
+void cmGccDepfileLexerHelper::newEntry()
+{
+ this->HelperState = State::Rule;
+ this->Content.emplace_back();
+ newRule();
+}
+
+void cmGccDepfileLexerHelper::newRule()
+{
+ auto& entry = this->Content.back();
+ if (entry.rules.empty() || !entry.rules.back().empty()) {
+ entry.rules.emplace_back();
+ }
+}
+
+void cmGccDepfileLexerHelper::newDependency()
+{
+ // printf("NEW DEP\n");
+ this->HelperState = State::Dependency;
+ if (this->Content.back().paths.empty() ||
+ !this->Content.back().paths.back().empty()) {
+ this->Content.back().paths.emplace_back();
+ }
+}
+
+void cmGccDepfileLexerHelper::newRuleOrDependency()
+{
+ if (this->HelperState == State::Rule) {
+ newRule();
+ } else {
+ newDependency();
+ }
+}
+
+void cmGccDepfileLexerHelper::addToCurrentPath(const char* s)
+{
+ if (this->Content.empty()) {
+ return;
+ }
+ cmGccStyleDependency* dep = &this->Content.back();
+ std::string* dst = nullptr;
+ switch (this->HelperState) {
+ case State::Rule: {
+ if (dep->rules.empty()) {
+ return;
+ }
+ dst = &dep->rules.back();
+ } break;
+ case State::Dependency: {
+ if (dep->paths.empty()) {
+ return;
+ }
+ dst = &dep->paths.back();
+ } break;
+ }
+ dst->append(s);
+}
+
+void cmGccDepfileLexerHelper::sanitizeContent()
+{
+ for (auto it = this->Content.begin(); it != this->Content.end();) {
+ // Remove empty rules
+ for (auto rit = it->rules.begin(); rit != it->rules.end();) {
+ if (rit->empty()) {
+ rit = it->rules.erase(rit);
+ } else {
+ ++rit;
+ }
+ }
+ // Remove the entry if rules are empty
+ if (it->rules.empty()) {
+ it = this->Content.erase(it);
+ } else {
+ // Remove empty paths
+ for (auto pit = it->paths.begin(); pit != it->paths.end();) {
+ if (pit->empty()) {
+ pit = it->paths.erase(pit);
+ } else {
+ ++pit;
+ }
+ }
+ ++it;
+ }
+ }
+}
diff --git a/Source/cmGccDepfileLexerHelper.h b/Source/cmGccDepfileLexerHelper.h
new file mode 100644
index 0000000..e6b2fcf
--- /dev/null
+++ b/Source/cmGccDepfileLexerHelper.h
@@ -0,0 +1,40 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmGccDepfileLexerHelper_h
+#define cmGccDepfileLexerHelper_h
+
+#include <utility>
+
+#include <cmGccDepfileReaderTypes.h>
+
+class cmGccDepfileLexerHelper
+{
+public:
+ cmGccDepfileLexerHelper() = default;
+
+ bool readFile(const char* filePath);
+ cmGccDepfileContent extractContent() && { return std::move(this->Content); }
+
+ // Functions called by the lexer
+ void newEntry();
+ void newRule();
+ void newDependency();
+ void newRuleOrDependency();
+ void addToCurrentPath(const char* s);
+
+private:
+ void sanitizeContent();
+
+ cmGccDepfileContent Content;
+
+ enum class State
+ {
+ Rule,
+ Dependency
+ };
+ State HelperState = State::Rule;
+};
+
+#define YY_EXTRA_TYPE cmGccDepfileLexerHelper*
+
+#endif
diff --git a/Source/cmGccDepfileReader.cxx b/Source/cmGccDepfileReader.cxx
new file mode 100644
index 0000000..9d70ede
--- /dev/null
+++ b/Source/cmGccDepfileReader.cxx
@@ -0,0 +1,18 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmGccDepfileReader.h"
+
+#include <type_traits>
+#include <utility>
+
+#include "cmGccDepfileLexerHelper.h"
+
+cmGccDepfileContent cmReadGccDepfile(const char* filePath)
+{
+ cmGccDepfileContent result;
+ cmGccDepfileLexerHelper helper;
+ if (helper.readFile(filePath)) {
+ result = std::move(helper).extractContent();
+ }
+ return result;
+}
diff --git a/Source/cmGccDepfileReader.h b/Source/cmGccDepfileReader.h
new file mode 100644
index 0000000..9313010
--- /dev/null
+++ b/Source/cmGccDepfileReader.h
@@ -0,0 +1,10 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmGccDepfileReader_h
+#define cmGccDepfileReader_h
+
+#include "cmGccDepfileReaderTypes.h"
+
+cmGccDepfileContent cmReadGccDepfile(const char* filePath);
+
+#endif
diff --git a/Source/cmGccDepfileReaderTypes.h b/Source/cmGccDepfileReaderTypes.h
new file mode 100644
index 0000000..8b15c73
--- /dev/null
+++ b/Source/cmGccDepfileReaderTypes.h
@@ -0,0 +1,17 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmGccDepfileReaderTypes_h
+#define cmGccDepfileReaderTypes_h
+
+#include <string>
+#include <vector>
+
+struct cmGccStyleDependency
+{
+ std::vector<std::string> rules;
+ std::vector<std::string> paths;
+};
+
+using cmGccDepfileContent = std::vector<cmGccStyleDependency>;
+
+#endif
diff --git a/Source/cmGeneratedFileStream.cxx b/Source/cmGeneratedFileStream.cxx
index 2af04b6..9cee0e6 100644
--- a/Source/cmGeneratedFileStream.cxx
+++ b/Source/cmGeneratedFileStream.cxx
@@ -8,8 +8,9 @@
#include "cmSystemTools.h"
#if !defined(CMAKE_BOOTSTRAP)
+# include <cm3p/zlib.h>
+
# include "cm_codecvt.hxx"
-# include "cm_zlib.h"
#endif
cmGeneratedFileStream::cmGeneratedFileStream(Encoding encoding)
@@ -180,6 +181,7 @@ int cmGeneratedFileStreamBase::CompressFile(std::string const& oldname,
}
FILE* ifs = cmsys::SystemTools::Fopen(oldname, "r");
if (!ifs) {
+ gzclose(gf);
return 0;
}
size_t res;
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index b7f7d1d..6e293d5 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -8,7 +8,6 @@
#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
#include "cmGeneratorExpressionContext.h"
#include "cmGeneratorExpressionDAGChecker.h"
#include "cmGeneratorExpressionEvaluator.h"
@@ -22,6 +21,8 @@ cmGeneratorExpression::cmGeneratorExpression(cmListFileBacktrace backtrace)
{
}
+cmCompiledGeneratorExpression::~cmCompiledGeneratorExpression() = default;
+
cmGeneratorExpression::~cmGeneratorExpression() = default;
std::unique_ptr<cmCompiledGeneratorExpression> cmGeneratorExpression::Parse(
@@ -31,12 +32,6 @@ std::unique_ptr<cmCompiledGeneratorExpression> cmGeneratorExpression::Parse(
new cmCompiledGeneratorExpression(this->Backtrace, std::move(input)));
}
-std::unique_ptr<cmCompiledGeneratorExpression> cmGeneratorExpression::Parse(
- const char* input) const
-{
- return this->Parse(std::string(input ? input : ""));
-}
-
std::string cmGeneratorExpression::Evaluate(
std::string input, cmLocalGenerator* lg, const std::string& config,
cmGeneratorTarget const* headTarget,
@@ -51,17 +46,6 @@ std::string cmGeneratorExpression::Evaluate(
return input;
}
-std::string cmGeneratorExpression::Evaluate(
- const char* input, cmLocalGenerator* lg, const std::string& config,
- cmGeneratorTarget const* headTarget,
- cmGeneratorExpressionDAGChecker* dagChecker,
- cmGeneratorTarget const* currentTarget, std::string const& language)
-{
- return input ? Evaluate(std::string(input), lg, config, headTarget,
- dagChecker, currentTarget, language)
- : "";
-}
-
const std::string& cmCompiledGeneratorExpression::Evaluate(
cmLocalGenerator* lg, const std::string& config,
const cmGeneratorTarget* headTarget,
@@ -86,7 +70,7 @@ const std::string& cmCompiledGeneratorExpression::EvaluateWithContext(
this->Output.clear();
- for (const cmGeneratorExpressionEvaluator* it : this->Evaluators) {
+ for (const auto& it : this->Evaluators) {
this->Output += it->Evaluate(&context, dagChecker);
this->SeenTargetProperties.insert(context.SeenTargetProperties.cbegin(),
@@ -102,6 +86,8 @@ const std::string& cmCompiledGeneratorExpression::EvaluateWithContext(
if (!context.HadError) {
this->HadContextSensitiveCondition = context.HadContextSensitiveCondition;
this->HadHeadSensitiveCondition = context.HadHeadSensitiveCondition;
+ this->HadLinkLanguageSensitiveCondition =
+ context.HadLinkLanguageSensitiveCondition;
this->SourceSensitiveTargets = context.SourceSensitiveTargets;
}
@@ -118,6 +104,7 @@ cmCompiledGeneratorExpression::cmCompiledGeneratorExpression(
, Quiet(false)
, HadContextSensitiveCondition(false)
, HadHeadSensitiveCondition(false)
+ , HadLinkLanguageSensitiveCondition(false)
{
cmGeneratorExpressionLexer l;
std::vector<cmGeneratorExpressionToken> tokens = l.Tokenize(this->Input);
@@ -129,11 +116,6 @@ cmCompiledGeneratorExpression::cmCompiledGeneratorExpression(
}
}
-cmCompiledGeneratorExpression::~cmCompiledGeneratorExpression()
-{
- cmDeleteAll(this->Evaluators);
-}
-
std::string cmGeneratorExpression::StripEmptyListElements(
const std::string& input)
{
@@ -385,6 +367,20 @@ bool cmGeneratorExpression::IsValidTargetName(const std::string& input)
return targetNameValidator.find(input);
}
+void cmGeneratorExpression::ReplaceInstallPrefix(
+ std::string& input, const std::string& replacement)
+{
+ std::string::size_type pos = 0;
+ std::string::size_type lastPos = pos;
+
+ while ((pos = input.find("$<INSTALL_PREFIX>", lastPos)) !=
+ std::string::npos) {
+ std::string::size_type endPos = pos + sizeof("$<INSTALL_PREFIX>") - 1;
+ input.replace(pos, endPos - pos, replacement);
+ lastPos = endPos;
+ }
+}
+
void cmCompiledGeneratorExpression::GetMaxLanguageStandard(
const cmGeneratorTarget* tgt, std::map<std::string, std::string>& mapping)
{
diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h
index 4bd1c9f..75bba02 100644
--- a/Source/cmGeneratorExpression.h
+++ b/Source/cmGeneratorExpression.h
@@ -42,8 +42,6 @@ public:
std::unique_ptr<cmCompiledGeneratorExpression> Parse(
std::string input) const;
- std::unique_ptr<cmCompiledGeneratorExpression> Parse(
- const char* input) const;
static std::string Evaluate(
std::string input, cmLocalGenerator* lg, const std::string& config,
@@ -51,12 +49,6 @@ public:
cmGeneratorExpressionDAGChecker* dagChecker = nullptr,
cmGeneratorTarget const* currentTarget = nullptr,
std::string const& language = std::string());
- static std::string Evaluate(
- const char* input, cmLocalGenerator* lg, const std::string& config,
- cmGeneratorTarget const* headTarget = nullptr,
- cmGeneratorExpressionDAGChecker* dagChecker = nullptr,
- cmGeneratorTarget const* currentTarget = nullptr,
- std::string const& language = std::string());
enum PreprocessContext
{
@@ -87,6 +79,9 @@ public:
return input != nullptr && input[0] == '$' && input[1] == '<';
}
+ static void ReplaceInstallPrefix(std::string& input,
+ const std::string& replacement);
+
private:
cmListFileBacktrace Backtrace;
};
@@ -134,6 +129,10 @@ public:
{
return this->HadHeadSensitiveCondition;
}
+ bool GetHadLinkLanguageSensitiveCondition() const
+ {
+ return this->HadLinkLanguageSensitiveCondition;
+ }
std::set<cmGeneratorTarget const*> GetSourceSensitiveTargets() const
{
return this->SourceSensitiveTargets;
@@ -160,7 +159,7 @@ private:
friend class cmGeneratorExpression;
cmListFileBacktrace Backtrace;
- std::vector<cmGeneratorExpressionEvaluator*> Evaluators;
+ std::vector<std::unique_ptr<cmGeneratorExpressionEvaluator>> Evaluators;
const std::string Input;
bool NeedsEvaluation;
bool EvaluateForBuildsystem;
@@ -175,6 +174,7 @@ private:
mutable std::string Output;
mutable bool HadContextSensitiveCondition;
mutable bool HadHeadSensitiveCondition;
+ mutable bool HadLinkLanguageSensitiveCondition;
mutable std::set<cmGeneratorTarget const*> SourceSensitiveTargets;
};
diff --git a/Source/cmGeneratorExpressionContext.cxx b/Source/cmGeneratorExpressionContext.cxx
index 6d97331..42cbe2a 100644
--- a/Source/cmGeneratorExpressionContext.cxx
+++ b/Source/cmGeneratorExpressionContext.cxx
@@ -19,6 +19,7 @@ cmGeneratorExpressionContext::cmGeneratorExpressionContext(
, HadError(false)
, HadContextSensitiveCondition(false)
, HadHeadSensitiveCondition(false)
+ , HadLinkLanguageSensitiveCondition(false)
, EvaluateForBuildsystem(evaluateForBuildsystem)
{
}
diff --git a/Source/cmGeneratorExpressionContext.h b/Source/cmGeneratorExpressionContext.h
index 4709fa0..bceff12 100644
--- a/Source/cmGeneratorExpressionContext.h
+++ b/Source/cmGeneratorExpressionContext.h
@@ -40,6 +40,7 @@ struct cmGeneratorExpressionContext
bool HadError;
bool HadContextSensitiveCondition;
bool HadHeadSensitiveCondition;
+ bool HadLinkLanguageSensitiveCondition;
bool EvaluateForBuildsystem;
};
diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx
index 643ba34..4f379cd 100644
--- a/Source/cmGeneratorExpressionDAGChecker.cxx
+++ b/Source/cmGeneratorExpressionDAGChecker.cxx
@@ -6,6 +6,9 @@
#include <sstream>
#include <utility>
+#include <cm/string_view>
+#include <cmext/string_view>
+
#include "cmGeneratorExpressionContext.h"
#include "cmGeneratorExpressionEvaluator.h"
#include "cmGeneratorTarget.h"
@@ -44,12 +47,7 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
void cmGeneratorExpressionDAGChecker::Initialize()
{
- const cmGeneratorExpressionDAGChecker* top = this;
- const cmGeneratorExpressionDAGChecker* p = this->Parent;
- while (p) {
- top = p;
- p = p->Parent;
- }
+ const auto* top = this->Top();
this->CheckResult = this->CheckGraph();
#define TEST_TRANSITIVE_PROPERTY_METHOD(METHOD) top->METHOD() ||
@@ -140,61 +138,57 @@ cmGeneratorExpressionDAGChecker::CheckGraph() const
return DAG;
}
-bool cmGeneratorExpressionDAGChecker::GetTransitivePropertiesOnly()
+bool cmGeneratorExpressionDAGChecker::GetTransitivePropertiesOnly() const
{
- const cmGeneratorExpressionDAGChecker* top = this;
- const cmGeneratorExpressionDAGChecker* parent = this->Parent;
- while (parent) {
- top = parent;
- parent = parent->Parent;
- }
+ return this->Top()->TransitivePropertiesOnly;
+}
- return top->TransitivePropertiesOnly;
+bool cmGeneratorExpressionDAGChecker::EvaluatingGenexExpression() const
+{
+ return cmHasLiteralPrefix(this->Property, "TARGET_GENEX_EVAL:") ||
+ cmHasLiteralPrefix(this->Property, "GENEX_EVAL:");
}
-bool cmGeneratorExpressionDAGChecker::EvaluatingGenexExpression()
+bool cmGeneratorExpressionDAGChecker::EvaluatingPICExpression() const
{
- return this->Property.find("TARGET_GENEX_EVAL:") == 0 ||
- this->Property.find("GENEX_EVAL:", 0) == 0;
+ return this->Top()->Property == "INTERFACE_POSITION_INDEPENDENT_CODE";
}
-bool cmGeneratorExpressionDAGChecker::EvaluatingPICExpression()
+bool cmGeneratorExpressionDAGChecker::EvaluatingLinkExpression() const
{
- const cmGeneratorExpressionDAGChecker* top = this;
- const cmGeneratorExpressionDAGChecker* parent = this->Parent;
- while (parent) {
- top = parent;
- parent = parent->Parent;
- }
+ cm::string_view property(this->Top()->Property);
+
+ return property == "LINK_DIRECTORIES"_s || property == "LINK_OPTIONS"_s ||
+ property == "LINK_DEPENDS"_s;
+}
+
+bool cmGeneratorExpressionDAGChecker::EvaluatingLinkOptionsExpression() const
+{
+ cm::string_view property(this->Top()->Property);
- return top->Property == "INTERFACE_POSITION_INDEPENDENT_CODE";
+ return property == "LINK_OPTIONS"_s;
}
bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(
- cmGeneratorTarget const* tgt)
+ cmGeneratorTarget const* tgt) const
{
- const cmGeneratorExpressionDAGChecker* top = this;
- const cmGeneratorExpressionDAGChecker* parent = this->Parent;
- while (parent) {
- top = parent;
- parent = parent->Parent;
- }
+ const auto* top = this->Top();
- const char* prop = top->Property.c_str();
+ cm::string_view prop(top->Property);
if (tgt) {
- return top->Target == tgt && strcmp(prop, "LINK_LIBRARIES") == 0;
+ return top->Target == tgt && prop == "LINK_LIBRARIES"_s;
}
- return (strcmp(prop, "LINK_LIBRARIES") == 0 ||
- strcmp(prop, "LINK_INTERFACE_LIBRARIES") == 0 ||
- strcmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES") == 0 ||
- cmHasLiteralPrefix(prop, "LINK_INTERFACE_LIBRARIES_") ||
- cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES_")) ||
- strcmp(prop, "INTERFACE_LINK_LIBRARIES") == 0;
+ return prop == "LINK_LIBRARIES"_s || prop == "LINK_INTERFACE_LIBRARIES"_s ||
+ prop == "IMPORTED_LINK_INTERFACE_LIBRARIES"_s ||
+ cmHasLiteralPrefix(prop, "LINK_INTERFACE_LIBRARIES_") ||
+ cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES_") ||
+ prop == "INTERFACE_LINK_LIBRARIES"_s;
}
-cmGeneratorTarget const* cmGeneratorExpressionDAGChecker::TopTarget() const
+cmGeneratorExpressionDAGChecker const* cmGeneratorExpressionDAGChecker::Top()
+ const
{
const cmGeneratorExpressionDAGChecker* top = this;
const cmGeneratorExpressionDAGChecker* parent = this->Parent;
@@ -202,7 +196,12 @@ cmGeneratorTarget const* cmGeneratorExpressionDAGChecker::TopTarget() const
top = parent;
parent = parent->Parent;
}
- return top->Target;
+ return top;
+}
+
+cmGeneratorTarget const* cmGeneratorExpressionDAGChecker::TopTarget() const
+{
+ return this->Top()->Target;
}
enum TransitiveProperty
diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h
index f2c49bb..c2c5b6b 100644
--- a/Source/cmGeneratorExpressionDAGChecker.h
+++ b/Source/cmGeneratorExpressionDAGChecker.h
@@ -66,9 +66,12 @@ struct cmGeneratorExpressionDAGChecker
void ReportError(cmGeneratorExpressionContext* context,
const std::string& expr);
- bool EvaluatingGenexExpression();
- bool EvaluatingPICExpression();
- bool EvaluatingLinkLibraries(cmGeneratorTarget const* tgt = nullptr);
+ bool EvaluatingGenexExpression() const;
+ bool EvaluatingPICExpression() const;
+ bool EvaluatingLinkExpression() const;
+ bool EvaluatingLinkOptionsExpression() const;
+
+ bool EvaluatingLinkLibraries(cmGeneratorTarget const* tgt = nullptr) const;
#define DECLARE_TRANSITIVE_PROPERTY_METHOD(METHOD) bool METHOD() const;
@@ -76,9 +79,10 @@ struct cmGeneratorExpressionDAGChecker
#undef DECLARE_TRANSITIVE_PROPERTY_METHOD
- bool GetTransitivePropertiesOnly();
+ bool GetTransitivePropertiesOnly() const;
void SetTransitivePropertiesOnly() { this->TransitivePropertiesOnly = true; }
+ cmGeneratorExpressionDAGChecker const* Top() const;
cmGeneratorTarget const* TopTarget() const;
private:
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index e0ae170..4129a0c 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -2,10 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGeneratorExpressionEvaluator.h"
-#include <algorithm>
#include <sstream>
-#include "cmAlgorithms.h"
#include "cmGeneratorExpressionContext.h"
#include "cmGeneratorExpressionNode.h"
@@ -16,6 +14,8 @@ GeneratorExpressionContent::GeneratorExpressionContent(
{
}
+GeneratorExpressionContent::~GeneratorExpressionContent() = default;
+
std::string GeneratorExpressionContent::GetOriginalExpression() const
{
return std::string(this->StartContent, this->ContentLength);
@@ -25,14 +25,13 @@ std::string GeneratorExpressionContent::ProcessArbitraryContent(
const cmGeneratorExpressionNode* node, const std::string& identifier,
cmGeneratorExpressionContext* context,
cmGeneratorExpressionDAGChecker* dagChecker,
- std::vector<std::vector<cmGeneratorExpressionEvaluator*>>::const_iterator
- pit) const
+ std::vector<cmGeneratorExpressionEvaluatorVector>::const_iterator pit) const
{
std::string result;
const auto pend = this->ParamChildren.end();
for (; pit != pend; ++pit) {
- for (cmGeneratorExpressionEvaluator* pExprEval : *pit) {
+ for (auto& pExprEval : *pit) {
if (node->RequiresLiteralInput()) {
if (pExprEval->GetType() != cmGeneratorExpressionEvaluator::Text) {
reportError(context, this->GetOriginalExpression(),
@@ -64,8 +63,7 @@ std::string GeneratorExpressionContent::Evaluate(
{
std::string identifier;
{
- for (cmGeneratorExpressionEvaluator* pExprEval :
- this->IdentifierChildren) {
+ for (auto& pExprEval : this->IdentifierChildren) {
identifier += pExprEval->Evaluate(context, dagChecker);
if (context->HadError) {
return std::string();
@@ -126,7 +124,7 @@ std::string GeneratorExpressionContent::EvaluateParameters(
return std::string();
}
std::string parameter;
- for (cmGeneratorExpressionEvaluator* pExprEval : *pit) {
+ for (auto& pExprEval : *pit) {
parameter += pExprEval->Evaluate(context, dagChecker);
if (context->HadError) {
return std::string();
@@ -174,10 +172,3 @@ std::string GeneratorExpressionContent::EvaluateParameters(
}
return std::string();
}
-
-GeneratorExpressionContent::~GeneratorExpressionContent()
-{
- cmDeleteAll(this->IdentifierChildren);
- std::for_each(this->ParamChildren.begin(), this->ParamChildren.end(),
- cmDeleteAll<std::vector<cmGeneratorExpressionEvaluator*>>);
-}
diff --git a/Source/cmGeneratorExpressionEvaluator.h b/Source/cmGeneratorExpressionEvaluator.h
index b10bb5b..10496fd 100644
--- a/Source/cmGeneratorExpressionEvaluator.h
+++ b/Source/cmGeneratorExpressionEvaluator.h
@@ -6,6 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <cstddef>
+#include <memory>
#include <string>
#include <utility>
#include <vector>
@@ -36,6 +37,9 @@ struct cmGeneratorExpressionEvaluator
cmGeneratorExpressionDAGChecker*) const = 0;
};
+using cmGeneratorExpressionEvaluatorVector =
+ std::vector<std::unique_ptr<cmGeneratorExpressionEvaluator>>;
+
struct TextContent : public cmGeneratorExpressionEvaluator
{
TextContent(const char* start, size_t length)
@@ -68,13 +72,13 @@ struct GeneratorExpressionContent : public cmGeneratorExpressionEvaluator
{
GeneratorExpressionContent(const char* startContent, size_t length);
- void SetIdentifier(std::vector<cmGeneratorExpressionEvaluator*> identifier)
+ void SetIdentifier(cmGeneratorExpressionEvaluatorVector&& identifier)
{
this->IdentifierChildren = std::move(identifier);
}
void SetParameters(
- std::vector<std::vector<cmGeneratorExpressionEvaluator*>> parameters)
+ std::vector<cmGeneratorExpressionEvaluatorVector>&& parameters)
{
this->ParamChildren = std::move(parameters);
}
@@ -102,12 +106,12 @@ private:
const cmGeneratorExpressionNode* node, const std::string& identifier,
cmGeneratorExpressionContext* context,
cmGeneratorExpressionDAGChecker* dagChecker,
- std::vector<std::vector<cmGeneratorExpressionEvaluator*>>::const_iterator
- pit) const;
+ std::vector<cmGeneratorExpressionEvaluatorVector>::const_iterator pit)
+ const;
private:
- std::vector<cmGeneratorExpressionEvaluator*> IdentifierChildren;
- std::vector<std::vector<cmGeneratorExpressionEvaluator*>> ParamChildren;
+ cmGeneratorExpressionEvaluatorVector IdentifierChildren;
+ std::vector<cmGeneratorExpressionEvaluatorVector> ParamChildren;
const char* StartContent;
size_t ContentLength;
};
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 66f1c71..e3de2d8 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -14,12 +14,14 @@
#include <utility>
#include <cm/iterator>
+#include <cm/string_view>
+#include <cm/vector>
+#include <cmext/algorithm>
+#include <cmext/string_view>
#include "cmsys/RegularExpression.hxx"
#include "cmsys/String.h"
-#include "cm_static_string_view.hxx"
-
#include "cmAlgorithms.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorExpressionContext.h"
@@ -37,7 +39,6 @@
#include "cmState.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
-#include "cmString.hxx"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
@@ -62,6 +63,9 @@ std::string cmGeneratorExpressionNode::EvaluateDependentExpression(
if (cge->GetHadHeadSensitiveCondition()) {
context->HadHeadSensitiveCondition = true;
}
+ if (cge->GetHadLinkLanguageSensitiveCondition()) {
+ context->HadLinkLanguageSensitiveCondition = true;
+ }
return result;
}
@@ -310,7 +314,7 @@ static const struct InListNode : public cmGeneratorExpressionNode
break;
}
- return cmContains(values, parameters.front()) ? "1" : "0";
+ return cm::contains(values, parameters.front()) ? "1" : "0";
}
} inListNode;
@@ -904,22 +908,21 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
}
if (context->CurrentTarget && context->CurrentTarget->IsImported()) {
- const char* loc = nullptr;
- const char* imp = nullptr;
+ cmProp loc = nullptr;
+ cmProp imp = nullptr;
std::string suffix;
- if (context->CurrentTarget->Target->GetMappedConfig(
- context->Config, &loc, &imp, suffix)) {
+ if (context->CurrentTarget->Target->GetMappedConfig(context->Config, loc,
+ imp, suffix)) {
// This imported target has an appropriate location
// for this (possibly mapped) config.
// Check if there is a proper config mapping for the tested config.
std::vector<std::string> mappedConfigs;
std::string mapProp = cmStrCat(
"MAP_IMPORTED_CONFIG_", cmSystemTools::UpperCase(context->Config));
- if (const char* mapValue =
- context->CurrentTarget->GetProperty(mapProp)) {
- cmExpandList(cmSystemTools::UpperCase(mapValue), mappedConfigs);
- return cmContains(mappedConfigs,
- cmSystemTools::UpperCase(parameters.front()))
+ if (cmProp mapValue = context->CurrentTarget->GetProperty(mapProp)) {
+ cmExpandList(cmSystemTools::UpperCase(*mapValue), mappedConfigs);
+ return cm::contains(mappedConfigs,
+ cmSystemTools::UpperCase(parameters.front()))
? "1"
: "0";
}
@@ -1039,6 +1042,214 @@ static const struct CompileLanguageAndIdNode : public cmGeneratorExpressionNode
}
} languageAndIdNode;
+static const struct LinkLanguageNode : public cmGeneratorExpressionNode
+{
+ LinkLanguageNode() {} // NOLINT(modernize-use-equals-default)
+
+ int NumExpectedParameters() const override { return ZeroOrMoreParameters; }
+
+ std::string Evaluate(
+ const std::vector<std::string>& parameters,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content,
+ cmGeneratorExpressionDAGChecker* dagChecker) const override
+ {
+ if (!context->HeadTarget || !dagChecker ||
+ !(dagChecker->EvaluatingLinkExpression() ||
+ dagChecker->EvaluatingLinkLibraries())) {
+ reportError(context, content->GetOriginalExpression(),
+ "$<LINK_LANGUAGE:...> may only be used with binary targets "
+ "to specify link libraries, link directories, link options "
+ "and link depends.");
+ return std::string();
+ }
+ if (dagChecker->EvaluatingLinkLibraries() && parameters.empty()) {
+ reportError(
+ context, content->GetOriginalExpression(),
+ "$<LINK_LANGUAGE> is not supported in link libraries expression.");
+ return std::string();
+ }
+
+ cmGlobalGenerator* gg = context->LG->GetGlobalGenerator();
+ std::string genName = gg->GetName();
+ if (genName.find("Makefiles") == std::string::npos &&
+ genName.find("Ninja") == std::string::npos &&
+ genName.find("Visual Studio") == std::string::npos &&
+ genName.find("Xcode") == std::string::npos &&
+ genName.find("Watcom WMake") == std::string::npos) {
+ reportError(context, content->GetOriginalExpression(),
+ "$<LINK_LANGUAGE:...> not supported for this generator.");
+ return std::string();
+ }
+
+ if (dagChecker->EvaluatingLinkLibraries()) {
+ context->HadHeadSensitiveCondition = true;
+ context->HadLinkLanguageSensitiveCondition = true;
+ }
+
+ if (parameters.empty()) {
+ return context->Language;
+ }
+
+ for (auto& param : parameters) {
+ if (context->Language == param) {
+ return "1";
+ }
+ }
+ return "0";
+ }
+} linkLanguageNode;
+
+namespace {
+struct LinkerId
+{
+ static std::string Evaluate(const std::vector<std::string>& parameters,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content,
+ const std::string& lang)
+ {
+ std::string const& linkerId =
+ context->LG->GetMakefile()->GetSafeDefinition("CMAKE_" + lang +
+ "_COMPILER_ID");
+ if (parameters.empty()) {
+ return linkerId;
+ }
+ if (linkerId.empty()) {
+ return parameters.front().empty() ? "1" : "0";
+ }
+ static cmsys::RegularExpression linkerIdValidator("^[A-Za-z0-9_]*$");
+
+ for (auto& param : parameters) {
+ if (!linkerIdValidator.find(param)) {
+ reportError(context, content->GetOriginalExpression(),
+ "Expression syntax not recognized.");
+ return std::string();
+ }
+
+ if (param == linkerId) {
+ return "1";
+ }
+ }
+ return "0";
+ }
+};
+}
+
+static const struct LinkLanguageAndIdNode : public cmGeneratorExpressionNode
+{
+ LinkLanguageAndIdNode() {} // NOLINT(modernize-use-equals-default)
+
+ int NumExpectedParameters() const override { return TwoOrMoreParameters; }
+
+ std::string Evaluate(
+ const std::vector<std::string>& parameters,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content,
+ cmGeneratorExpressionDAGChecker* dagChecker) const override
+ {
+ if (!context->HeadTarget || !dagChecker ||
+ !(dagChecker->EvaluatingLinkExpression() ||
+ dagChecker->EvaluatingLinkLibraries())) {
+ reportError(
+ context, content->GetOriginalExpression(),
+ "$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets "
+ "to specify link libraries, link directories, link options, and link "
+ "depends.");
+ return std::string();
+ }
+
+ cmGlobalGenerator* gg = context->LG->GetGlobalGenerator();
+ std::string genName = gg->GetName();
+ if (genName.find("Makefiles") == std::string::npos &&
+ genName.find("Ninja") == std::string::npos &&
+ genName.find("Visual Studio") == std::string::npos &&
+ genName.find("Xcode") == std::string::npos &&
+ genName.find("Watcom WMake") == std::string::npos) {
+ reportError(
+ context, content->GetOriginalExpression(),
+ "$<LINK_LANG_AND_ID:lang,id> not supported for this generator.");
+ return std::string();
+ }
+
+ if (dagChecker->EvaluatingLinkLibraries()) {
+ context->HadHeadSensitiveCondition = true;
+ context->HadLinkLanguageSensitiveCondition = true;
+ }
+
+ const std::string& lang = context->Language;
+ if (lang == parameters.front()) {
+ std::vector<std::string> idParameter((parameters.cbegin() + 1),
+ parameters.cend());
+ return LinkerId::Evaluate(idParameter, context, content, lang);
+ }
+ return "0";
+ }
+} linkLanguageAndIdNode;
+
+static const struct HostLinkNode : public cmGeneratorExpressionNode
+{
+ HostLinkNode() {} // NOLINT(modernize-use-equals-default)
+
+ int NumExpectedParameters() const override { return ZeroOrMoreParameters; }
+
+ std::string Evaluate(
+ const std::vector<std::string>& parameters,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content,
+ cmGeneratorExpressionDAGChecker* dagChecker) const override
+ {
+ if (!context->HeadTarget || !dagChecker ||
+ !dagChecker->EvaluatingLinkOptionsExpression()) {
+ reportError(context, content->GetOriginalExpression(),
+ "$<HOST_LINK:...> may only be used with binary targets "
+ "to specify link options.");
+ return std::string();
+ }
+
+ return context->HeadTarget->IsDeviceLink() ? std::string()
+ : cmJoin(parameters, ";");
+ }
+} hostLinkNode;
+
+static const struct DeviceLinkNode : public cmGeneratorExpressionNode
+{
+ DeviceLinkNode() {} // NOLINT(modernize-use-equals-default)
+
+ int NumExpectedParameters() const override { return ZeroOrMoreParameters; }
+
+ std::string Evaluate(
+ const std::vector<std::string>& parameters,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content,
+ cmGeneratorExpressionDAGChecker* dagChecker) const override
+ {
+ if (!context->HeadTarget || !dagChecker ||
+ !dagChecker->EvaluatingLinkOptionsExpression()) {
+ reportError(context, content->GetOriginalExpression(),
+ "$<DEVICE_LINK:...> may only be used with binary targets "
+ "to specify link options.");
+ return std::string();
+ }
+
+ if (context->HeadTarget->IsDeviceLink()) {
+ std::vector<std::string> list;
+ cmExpandLists(parameters.begin(), parameters.end(), list);
+ const auto DL_BEGIN = "<DEVICE_LINK>"_s;
+ const auto DL_END = "</DEVICE_LINK>"_s;
+ cm::erase_if(list, [&](const std::string& item) {
+ return item == DL_BEGIN || item == DL_END;
+ });
+
+ list.insert(list.begin(), static_cast<std::string>(DL_BEGIN));
+ list.push_back(static_cast<std::string>(DL_END));
+
+ return cmJoin(list, ";");
+ }
+
+ return std::string();
+ }
+} deviceLinkNode;
+
std::string getLinkedTargetsContent(
cmGeneratorTarget const* target, std::string const& prop,
cmGeneratorExpressionContext* context,
@@ -1156,6 +1367,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
context, content->GetOriginalExpression(),
"$<TARGET_PROPERTY:prop> may only be used with binary targets. "
"It may not be used with add_custom_command or add_custom_target. "
+ " "
"Specify the target to read a property from using the "
"$<TARGET_PROPERTY:tgt,prop> signature instead.");
return std::string();
@@ -1270,8 +1482,8 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
std::string result;
bool haveProp = false;
- if (const char* p = target->GetProperty(propertyName)) {
- result = p;
+ if (cmProp p = target->GetProperty(propertyName)) {
+ result = *p;
haveProp = true;
} else if (evaluatingLinkLibraries) {
return std::string();
@@ -1418,11 +1630,11 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
std::vector<std::string> objects;
if (gt->IsImported()) {
- const char* loc = nullptr;
- const char* imp = nullptr;
+ cmProp loc = nullptr;
+ cmProp imp = nullptr;
std::string suffix;
- if (gt->Target->GetMappedConfig(context->Config, &loc, &imp, suffix)) {
- cmExpandList(loc, objects);
+ if (gt->Target->GetMappedConfig(context->Config, loc, imp, suffix)) {
+ cmExpandList(*loc, objects);
}
context->HadContextSensitiveCondition = true;
} else {
@@ -1509,13 +1721,13 @@ static const struct CompileFeaturesNode : public cmGeneratorExpressionNode
for (auto const& lit : testedFeatures) {
std::vector<std::string> const& langAvailable =
availableFeatures[lit.first];
- const char* standardDefault = context->LG->GetMakefile()->GetDefinition(
+ cmProp standardDefault = context->LG->GetMakefile()->GetDef(
"CMAKE_" + lit.first + "_STANDARD_DEFAULT");
for (std::string const& it : lit.second) {
- if (!cmContains(langAvailable, it)) {
+ if (!cm::contains(langAvailable, it)) {
return "0";
}
- if (standardDefault && !*standardDefault) {
+ if (standardDefault && standardDefault->empty()) {
// This compiler has no notion of language standard levels.
// All features known for the language are always available.
continue;
@@ -1523,12 +1735,12 @@ static const struct CompileFeaturesNode : public cmGeneratorExpressionNode
if (!context->LG->GetMakefile()->HaveStandardAvailable(
target->Target, lit.first, it)) {
if (evalLL) {
- const char* l = target->GetProperty(lit.first + "_STANDARD");
+ cmProp l = target->GetProperty(lit.first + "_STANDARD");
if (!l) {
l = standardDefault;
}
assert(l);
- context->MaxLanguageStandard[target][lit.first] = l;
+ context->MaxLanguageStandard[target][lit.first] = *l;
} else {
return "0";
}
@@ -2314,6 +2526,10 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
{ "LINK_ONLY", &linkOnlyNode },
{ "COMPILE_LANG_AND_ID", &languageAndIdNode },
{ "COMPILE_LANGUAGE", &languageNode },
+ { "LINK_LANG_AND_ID", &linkLanguageAndIdNode },
+ { "LINK_LANGUAGE", &linkLanguageNode },
+ { "HOST_LINK", &hostLinkNode },
+ { "DEVICE_LINK", &deviceLinkNode },
{ "SHELL_PATH", &shellPathNode }
};
diff --git a/Source/cmGeneratorExpressionParser.cxx b/Source/cmGeneratorExpressionParser.cxx
index d6cc6ab..c2c9ef7 100644
--- a/Source/cmGeneratorExpressionParser.cxx
+++ b/Source/cmGeneratorExpressionParser.cxx
@@ -6,7 +6,10 @@
#include <cstddef>
#include <utility>
-#include "cmAlgorithms.h"
+#include <cm/memory>
+#include <cmext/algorithm>
+#include <cmext/memory>
+
#include "cmGeneratorExpressionEvaluator.h"
cmGeneratorExpressionParser::cmGeneratorExpressionParser(
@@ -17,7 +20,7 @@ cmGeneratorExpressionParser::cmGeneratorExpressionParser(
}
void cmGeneratorExpressionParser::Parse(
- std::vector<cmGeneratorExpressionEvaluator*>& result)
+ cmGeneratorExpressionEvaluatorVector& result)
{
it = this->Tokens.begin();
@@ -27,40 +30,38 @@ void cmGeneratorExpressionParser::Parse(
}
static void extendText(
- std::vector<cmGeneratorExpressionEvaluator*>& result,
+ cmGeneratorExpressionEvaluatorVector& result,
std::vector<cmGeneratorExpressionToken>::const_iterator it)
{
if (!result.empty() &&
(*(result.end() - 1))->GetType() ==
cmGeneratorExpressionEvaluator::Text) {
- TextContent* textContent = static_cast<TextContent*>(*(result.end() - 1));
- textContent->Extend(it->Length);
+ cm::static_reference_cast<TextContent>(*(result.end() - 1))
+ .Extend(it->Length);
} else {
- TextContent* textContent = new TextContent(it->Content, it->Length);
- result.push_back(textContent);
+ auto textContent = cm::make_unique<TextContent>(it->Content, it->Length);
+ result.push_back(std::move(textContent));
}
}
static void extendResult(
- std::vector<cmGeneratorExpressionEvaluator*>& result,
- const std::vector<cmGeneratorExpressionEvaluator*>& contents)
+ cmGeneratorExpressionParser::cmGeneratorExpressionEvaluatorVector& result,
+ cmGeneratorExpressionParser::cmGeneratorExpressionEvaluatorVector&& contents)
{
if (!result.empty() &&
(*(result.end() - 1))->GetType() ==
cmGeneratorExpressionEvaluator::Text &&
contents.front()->GetType() == cmGeneratorExpressionEvaluator::Text) {
- TextContent* textContent = static_cast<TextContent*>(*(result.end() - 1));
- textContent->Extend(
- static_cast<TextContent*>(contents.front())->GetLength());
- delete contents.front();
- cmAppend(result, contents.begin() + 1, contents.end());
- } else {
- cmAppend(result, contents);
+ cm::static_reference_cast<TextContent>(*(result.end() - 1))
+ .Extend(
+ cm::static_reference_cast<TextContent>(contents.front()).GetLength());
+ contents.erase(contents.begin());
}
+ cm::append(result, std::move(contents));
}
void cmGeneratorExpressionParser::ParseGeneratorExpression(
- std::vector<cmGeneratorExpressionEvaluator*>& result)
+ cmGeneratorExpressionEvaluatorVector& result)
{
assert(this->it != this->Tokens.end());
unsigned int nestedLevel = this->NestingLevel;
@@ -68,7 +69,7 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression(
auto startToken = this->it - 1;
- std::vector<cmGeneratorExpressionEvaluator*> identifier;
+ cmGeneratorExpressionEvaluatorVector identifier;
while (this->it->TokenType != cmGeneratorExpressionToken::EndExpression &&
this->it->TokenType != cmGeneratorExpressionToken::ColonSeparator) {
if (this->it->TokenType == cmGeneratorExpressionToken::CommaSeparator) {
@@ -87,18 +88,18 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression(
if (this->it != this->Tokens.end() &&
this->it->TokenType == cmGeneratorExpressionToken::EndExpression) {
- GeneratorExpressionContent* content = new GeneratorExpressionContent(
+ auto content = cm::make_unique<GeneratorExpressionContent>(
startToken->Content,
this->it->Content - startToken->Content + this->it->Length);
assert(this->it != this->Tokens.end());
++this->it;
--this->NestingLevel;
content->SetIdentifier(std::move(identifier));
- result.push_back(content);
+ result.push_back(std::move(content));
return;
}
- std::vector<std::vector<cmGeneratorExpressionEvaluator*>> parameters;
+ std::vector<cmGeneratorExpressionEvaluatorVector> parameters;
std::vector<std::vector<cmGeneratorExpressionToken>::const_iterator>
commaTokens;
std::vector<cmGeneratorExpressionToken>::const_iterator colonToken;
@@ -169,7 +170,7 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression(
// treat the '$<' as having been plain text, along with the
// corresponding : and , tokens that might have been found.
extendText(result, startToken);
- extendResult(result, identifier);
+ extendResult(result, std::move(identifier));
if (!parameters.empty()) {
extendText(result, colonToken);
@@ -179,7 +180,7 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression(
assert(parameters.size() > commaTokens.size());
for (; pit != pend; ++pit, ++commaIt) {
if (!pit->empty() && !emptyParamTermination) {
- extendResult(result, *pit);
+ extendResult(result, std::move(*pit));
}
if (commaIt != commaTokens.end()) {
extendText(result, *commaIt);
@@ -193,15 +194,15 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression(
size_t contentLength =
((this->it - 1)->Content - startToken->Content) + (this->it - 1)->Length;
- GeneratorExpressionContent* content =
- new GeneratorExpressionContent(startToken->Content, contentLength);
+ auto content = cm::make_unique<GeneratorExpressionContent>(
+ startToken->Content, contentLength);
content->SetIdentifier(std::move(identifier));
content->SetParameters(std::move(parameters));
- result.push_back(content);
+ result.push_back(std::move(content));
}
void cmGeneratorExpressionParser::ParseContent(
- std::vector<cmGeneratorExpressionEvaluator*>& result)
+ cmGeneratorExpressionEvaluatorVector& result)
{
assert(this->it != this->Tokens.end());
switch (this->it->TokenType) {
@@ -213,17 +214,16 @@ void cmGeneratorExpressionParser::ParseContent(
// A comma in 'plain text' could have split text that should
// otherwise be continuous. Extend the last text content instead of
// creating a new one.
- TextContent* textContent =
- static_cast<TextContent*>(*(result.end() - 1));
- textContent->Extend(this->it->Length);
+ cm::static_reference_cast<TextContent>(*(result.end() - 1))
+ .Extend(this->it->Length);
assert(this->it != this->Tokens.end());
++this->it;
return;
}
}
- cmGeneratorExpressionEvaluator* n =
- new TextContent(this->it->Content, this->it->Length);
- result.push_back(n);
+ auto n =
+ cm::make_unique<TextContent>(this->it->Content, this->it->Length);
+ result.push_back(std::move(n));
assert(this->it != this->Tokens.end());
++this->it;
return;
diff --git a/Source/cmGeneratorExpressionParser.h b/Source/cmGeneratorExpressionParser.h
index e663496..1ba1654 100644
--- a/Source/cmGeneratorExpressionParser.h
+++ b/Source/cmGeneratorExpressionParser.h
@@ -5,6 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <memory>
#include <vector>
#include "cmGeneratorExpressionLexer.h"
@@ -15,11 +16,14 @@ struct cmGeneratorExpressionParser
{
cmGeneratorExpressionParser(std::vector<cmGeneratorExpressionToken> tokens);
- void Parse(std::vector<cmGeneratorExpressionEvaluator*>& result);
+ using cmGeneratorExpressionEvaluatorVector =
+ std::vector<std::unique_ptr<cmGeneratorExpressionEvaluator>>;
+
+ void Parse(cmGeneratorExpressionEvaluatorVector& result);
private:
- void ParseContent(std::vector<cmGeneratorExpressionEvaluator*>&);
- void ParseGeneratorExpression(std::vector<cmGeneratorExpressionEvaluator*>&);
+ void ParseContent(cmGeneratorExpressionEvaluatorVector&);
+ void ParseGeneratorExpression(cmGeneratorExpressionEvaluatorVector&);
private:
std::vector<cmGeneratorExpressionToken>::const_iterator it;
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 171c3ed..a44126c 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -10,14 +10,15 @@
#include <cstdlib>
#include <cstring>
#include <iterator>
-#include <memory>
+#include <queue>
#include <sstream>
#include <unordered_set>
#include <utility>
+#include <cm/memory>
#include <cm/string_view>
-
-#include <queue>
+#include <cmext/algorithm>
+#include <cmext/string_view>
#include "cmsys/RegularExpression.hxx"
@@ -26,6 +27,7 @@
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
#include "cmCustomCommandLines.h"
+#include "cmFileTimes.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorExpressionContext.h"
@@ -51,15 +53,15 @@
class cmMessenger;
template <>
-const char* cmTargetPropertyComputer::GetSources<cmGeneratorTarget>(
+cmProp cmTargetPropertyComputer::GetSources<cmGeneratorTarget>(
cmGeneratorTarget const* tgt, cmMessenger* /* messenger */,
cmListFileBacktrace const& /* context */)
{
- return tgt->GetSourcesProperty();
+ return &tgt->GetSourcesProperty();
}
template <>
-const char*
+const std::string&
cmTargetPropertyComputer::ComputeLocationForBuild<cmGeneratorTarget>(
cmGeneratorTarget const* tgt)
{
@@ -67,7 +69,8 @@ cmTargetPropertyComputer::ComputeLocationForBuild<cmGeneratorTarget>(
}
template <>
-const char* cmTargetPropertyComputer::ComputeLocation<cmGeneratorTarget>(
+const std::string&
+cmTargetPropertyComputer::ComputeLocation<cmGeneratorTarget>(
cmGeneratorTarget const* tgt, const std::string& config)
{
return tgt->GetLocation(config);
@@ -162,7 +165,8 @@ private:
cmListFileBacktrace Backtrace;
};
-cmGeneratorTarget::TargetPropertyEntry* CreateTargetPropertyEntry(
+std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry>
+CreateTargetPropertyEntry(
const std::string& propertyValue,
cmListFileBacktrace backtrace = cmListFileBacktrace(),
bool evaluateForBuildsystem = false)
@@ -172,15 +176,18 @@ cmGeneratorTarget::TargetPropertyEntry* CreateTargetPropertyEntry(
std::unique_ptr<cmCompiledGeneratorExpression> cge =
ge.Parse(propertyValue);
cge->SetEvaluateForBuildsystem(evaluateForBuildsystem);
- return new TargetPropertyEntryGenex(std::move(cge));
+ return std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry>(
+ cm::make_unique<TargetPropertyEntryGenex>(std::move(cge)));
}
- return new TargetPropertyEntryString(propertyValue, std::move(backtrace));
+ return std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry>(
+ cm::make_unique<TargetPropertyEntryString>(propertyValue,
+ std::move(backtrace)));
}
void CreatePropertyGeneratorExpressions(
cmStringRange entries, cmBacktraceRange backtraces,
- std::vector<cmGeneratorTarget::TargetPropertyEntry*>& items,
+ std::vector<std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry>>& items,
bool evaluateForBuildsystem = false)
{
auto btIt = backtraces.begin();
@@ -219,28 +226,35 @@ struct EvaluatedTargetPropertyEntry
EvaluatedTargetPropertyEntry EvaluateTargetPropertyEntry(
cmGeneratorTarget const* thisTarget, std::string const& config,
std::string const& lang, cmGeneratorExpressionDAGChecker* dagChecker,
- cmGeneratorTarget::TargetPropertyEntry* entry)
+ cmGeneratorTarget::TargetPropertyEntry& entry)
{
- EvaluatedTargetPropertyEntry ee(entry->LinkImplItem, entry->GetBacktrace());
- cmExpandList(entry->Evaluate(thisTarget->GetLocalGenerator(), config,
- thisTarget, dagChecker, lang),
+ EvaluatedTargetPropertyEntry ee(entry.LinkImplItem, entry.GetBacktrace());
+ cmExpandList(entry.Evaluate(thisTarget->GetLocalGenerator(), config,
+ thisTarget, dagChecker, lang),
ee.Values);
- if (entry->GetHadContextSensitiveCondition()) {
+ if (entry.GetHadContextSensitiveCondition()) {
ee.ContextDependent = true;
}
return ee;
}
-std::vector<EvaluatedTargetPropertyEntry> EvaluateTargetPropertyEntries(
+struct EvaluatedTargetPropertyEntries
+{
+ std::vector<EvaluatedTargetPropertyEntry> Entries;
+ bool HadContextSensitiveCondition = false;
+};
+
+EvaluatedTargetPropertyEntries EvaluateTargetPropertyEntries(
cmGeneratorTarget const* thisTarget, std::string const& config,
std::string const& lang, cmGeneratorExpressionDAGChecker* dagChecker,
- std::vector<cmGeneratorTarget::TargetPropertyEntry*> const& in)
+ std::vector<std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry>> const&
+ in)
{
- std::vector<EvaluatedTargetPropertyEntry> out;
- out.reserve(in.size());
- for (cmGeneratorTarget::TargetPropertyEntry* entry : in) {
- out.emplace_back(EvaluateTargetPropertyEntry(thisTarget, config, lang,
- dagChecker, entry));
+ EvaluatedTargetPropertyEntries out;
+ out.Entries.reserve(in.size());
+ for (auto& entry : in) {
+ out.Entries.emplace_back(EvaluateTargetPropertyEntry(
+ thisTarget, config, lang, dagChecker, *entry));
}
return out;
}
@@ -302,31 +316,27 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
this->SourceEntries, true);
this->PolicyMap = t->GetPolicyMap();
-}
-cmGeneratorTarget::~cmGeneratorTarget()
-{
- cmDeleteAll(this->IncludeDirectoriesEntries);
- cmDeleteAll(this->CompileOptionsEntries);
- cmDeleteAll(this->CompileFeaturesEntries);
- cmDeleteAll(this->CompileDefinitionsEntries);
- cmDeleteAll(this->LinkOptionsEntries);
- cmDeleteAll(this->LinkDirectoriesEntries);
- cmDeleteAll(this->PrecompileHeadersEntries);
- cmDeleteAll(this->SourceEntries);
- cmDeleteAll(this->LinkInformation);
+ // Get hard-coded linker language
+ if (this->Target->GetProperty("HAS_CXX")) {
+ this->LinkerLanguage = "CXX";
+ } else {
+ this->LinkerLanguage = this->Target->GetSafeProperty("LINKER_LANGUAGE");
+ }
}
-const char* cmGeneratorTarget::GetSourcesProperty() const
+cmGeneratorTarget::~cmGeneratorTarget() = default;
+
+const std::string& cmGeneratorTarget::GetSourcesProperty() const
{
std::vector<std::string> values;
- for (TargetPropertyEntry* se : this->SourceEntries) {
+ for (auto& se : this->SourceEntries) {
values.push_back(se->GetInput());
}
static std::string value;
value.clear();
value = cmJoin(values, ";");
- return value.c_str();
+ return value;
}
cmGlobalGenerator* cmGeneratorTarget::GetGlobalGenerator() const
@@ -351,29 +361,29 @@ const std::string& cmGeneratorTarget::GetName() const
std::string cmGeneratorTarget::GetExportName() const
{
- const char* exportName = this->GetProperty("EXPORT_NAME");
+ cmProp exportName = this->GetProperty("EXPORT_NAME");
- if (exportName && *exportName) {
- if (!cmGeneratorExpression::IsValidTargetName(exportName)) {
+ if (exportName && !exportName->empty()) {
+ if (!cmGeneratorExpression::IsValidTargetName(*exportName)) {
std::ostringstream e;
- e << "EXPORT_NAME property \"" << exportName << "\" for \""
+ e << "EXPORT_NAME property \"" << *exportName << "\" for \""
<< this->GetName() << "\": is not valid.";
cmSystemTools::Error(e.str());
return "";
}
- return exportName;
+ return *exportName;
}
return this->GetName();
}
-const char* cmGeneratorTarget::GetProperty(const std::string& prop) const
+cmProp cmGeneratorTarget::GetProperty(const std::string& prop) const
{
if (!cmTargetPropertyComputer::PassesWhitelist(
this->GetType(), prop, this->Makefile->GetMessenger(),
this->GetBacktrace())) {
return nullptr;
}
- if (const char* result = cmTargetPropertyComputer::GetProperty(
+ if (cmProp result = cmTargetPropertyComputer::GetProperty(
this, prop, this->Makefile->GetMessenger(), this->GetBacktrace())) {
return result;
}
@@ -383,13 +393,16 @@ const char* cmGeneratorTarget::GetProperty(const std::string& prop) const
return this->Target->GetProperty(prop);
}
-const char* cmGeneratorTarget::GetSafeProperty(const std::string& prop) const
+std::string const& cmGeneratorTarget::GetSafeProperty(
+ std::string const& prop) const
{
- const char* ret = this->GetProperty(prop);
- if (!ret) {
- return "";
+ cmProp ret = this->GetProperty(prop);
+ if (ret) {
+ return *ret;
}
- return ret;
+
+ static std::string const s_empty;
+ return s_empty;
}
const char* cmGeneratorTarget::GetOutputTargetType(
@@ -478,8 +491,8 @@ std::string cmGeneratorTarget::GetOutputName(
std::string outName;
for (std::string const& p : props) {
- if (const char* outNameProp = this->GetProperty(p)) {
- outName = outNameProp;
+ if (cmProp outNameProp = this->GetProperty(p)) {
+ outName = *outNameProp;
break;
}
}
@@ -535,18 +548,46 @@ std::string cmGeneratorTarget::GetFileSuffix(
std::string cmGeneratorTarget::GetFilePostfix(const std::string& config) const
{
- const char* postfix = nullptr;
+ cmProp postfix = nullptr;
+ std::string frameworkPostfix;
if (!config.empty()) {
std::string configProp =
cmStrCat(cmSystemTools::UpperCase(config), "_POSTFIX");
postfix = this->GetProperty(configProp);
- // Mac application bundles and frameworks have no postfix.
+
+ // Mac application bundles and frameworks have no regular postfix like
+ // libraries do.
if (!this->IsImported() && postfix &&
(this->IsAppBundleOnApple() || this->IsFrameworkOnApple())) {
postfix = nullptr;
}
+
+ // Frameworks created by multi config generators can have a special
+ // framework postfix.
+ frameworkPostfix = GetFrameworkMultiConfigPostfix(config);
+ if (!frameworkPostfix.empty()) {
+ postfix = &frameworkPostfix;
+ }
+ }
+ return postfix ? *postfix : std::string();
+}
+
+std::string cmGeneratorTarget::GetFrameworkMultiConfigPostfix(
+ const std::string& config) const
+{
+ cmProp postfix = nullptr;
+ if (!config.empty()) {
+ std::string configProp = cmStrCat("FRAMEWORK_MULTI_CONFIG_POSTFIX_",
+ cmSystemTools::UpperCase(config));
+ postfix = this->GetProperty(configProp);
+
+ if (!this->IsImported() && postfix &&
+ (this->IsFrameworkOnApple() &&
+ !GetGlobalGenerator()->IsMultiConfig())) {
+ postfix = nullptr;
+ }
}
- return postfix ? postfix : std::string();
+ return postfix ? *postfix : std::string();
}
const char* cmGeneratorTarget::GetFilePrefixInternal(
@@ -579,7 +620,7 @@ const char* cmGeneratorTarget::GetFilePrefixInternal(
}
// Compute prefix value.
- const char* targetPrefix =
+ cmProp targetPrefix =
(isImportedLibraryArtifact ? this->GetProperty("IMPORT_PREFIX")
: this->GetProperty("PREFIX"));
@@ -587,17 +628,17 @@ const char* cmGeneratorTarget::GetFilePrefixInternal(
const char* prefixVar = this->Target->GetPrefixVariableInternal(artifact);
if (!language.empty() && prefixVar && *prefixVar) {
std::string langPrefix = prefixVar + std::string("_") + language;
- targetPrefix = this->Makefile->GetDefinition(langPrefix);
+ targetPrefix = this->Makefile->GetDef(langPrefix);
}
// if there is no prefix on the target nor specific language
// use the cmake definition.
if (!targetPrefix && prefixVar) {
- targetPrefix = this->Makefile->GetDefinition(prefixVar);
+ targetPrefix = this->Makefile->GetDef(prefixVar);
}
}
- return targetPrefix;
+ return targetPrefix ? targetPrefix->c_str() : nullptr;
}
const char* cmGeneratorTarget::GetFileSuffixInternal(
std::string const& config, cmStateEnums::ArtifactType artifact,
@@ -629,7 +670,7 @@ const char* cmGeneratorTarget::GetFileSuffixInternal(
}
// Compute suffix value.
- const char* targetSuffix =
+ cmProp targetSuffix =
(isImportedLibraryArtifact ? this->GetProperty("IMPORT_SUFFIX")
: this->GetProperty("SUFFIX"));
@@ -637,17 +678,17 @@ const char* cmGeneratorTarget::GetFileSuffixInternal(
const char* suffixVar = this->Target->GetSuffixVariableInternal(artifact);
if (!language.empty() && suffixVar && *suffixVar) {
std::string langSuffix = suffixVar + std::string("_") + language;
- targetSuffix = this->Makefile->GetDefinition(langSuffix);
+ targetSuffix = this->Makefile->GetDef(langSuffix);
}
// if there is no suffix on the target nor specific language
// use the cmake definition.
if (!targetSuffix && suffixVar) {
- targetSuffix = this->Makefile->GetDefinition(suffixVar);
+ targetSuffix = this->Makefile->GetDef(suffixVar);
}
}
- return targetSuffix;
+ return targetSuffix ? targetSuffix->c_str() : nullptr;
}
void cmGeneratorTarget::ClearSourcesCache()
@@ -655,6 +696,7 @@ void cmGeneratorTarget::ClearSourcesCache()
this->KindedSourcesMap.clear();
this->LinkImplementationLanguageIsContextDependent = true;
this->Objects.clear();
+ this->VisitedConfigsForObjects.clear();
}
void cmGeneratorTarget::AddSourceCommon(const std::string& src, bool before)
@@ -708,9 +750,9 @@ void handleSystemIncludesDep(cmLocalGenerator* lg,
std::vector<std::string>& result,
bool excludeImported, std::string const& language)
{
- if (const char* dirs =
+ if (cmProp dirs =
depTgt->GetProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES")) {
- cmExpandList(cmGeneratorExpression::Evaluate(dirs, lg, config, headTarget,
+ cmExpandList(cmGeneratorExpression::Evaluate(*dirs, lg, config, headTarget,
dagChecker, depTgt, language),
result);
}
@@ -718,9 +760,8 @@ void handleSystemIncludesDep(cmLocalGenerator* lg,
return;
}
- if (const char* dirs =
- depTgt->GetProperty("INTERFACE_INCLUDE_DIRECTORIES")) {
- cmExpandList(cmGeneratorExpression::Evaluate(dirs, lg, config, headTarget,
+ if (cmProp dirs = depTgt->GetProperty("INTERFACE_INCLUDE_DIRECTORIES")) {
+ cmExpandList(cmGeneratorExpression::Evaluate(*dirs, lg, config, headTarget,
dagChecker, depTgt, language),
result);
}
@@ -744,7 +785,7 @@ void cmGeneratorTarget::GetObjectSources(
{
IMPLEMENT_VISIT(SourceKindObjectSource);
- if (!this->Objects.empty()) {
+ if (this->VisitedConfigsForObjects.count(config)) {
return;
}
@@ -753,16 +794,17 @@ void cmGeneratorTarget::GetObjectSources(
}
this->LocalGenerator->ComputeObjectFilenames(this->Objects, this);
+ this->VisitedConfigsForObjects.insert(config);
}
void cmGeneratorTarget::ComputeObjectMapping()
{
- if (!this->Objects.empty()) {
+ auto const& configs = this->Makefile->GetGeneratorConfigs();
+ std::set<std::string> configSet(configs.begin(), configs.end());
+ if (configSet == this->VisitedConfigsForObjects) {
return;
}
- std::vector<std::string> const& configs =
- this->Makefile->GetGeneratorConfigs();
for (std::string const& c : configs) {
std::vector<cmSourceFile const*> sourceFiles;
this->GetObjectSources(sourceFiles, c);
@@ -775,12 +817,12 @@ const char* cmGeneratorTarget::GetFeature(const std::string& feature,
if (!config.empty()) {
std::string featureConfig =
cmStrCat(feature, '_', cmSystemTools::UpperCase(config));
- if (const char* value = this->GetProperty(featureConfig)) {
- return value;
+ if (cmProp value = this->GetProperty(featureConfig)) {
+ return value->c_str();
}
}
- if (const char* value = this->GetProperty(feature)) {
- return value;
+ if (cmProp value = this->GetProperty(feature)) {
+ return value->c_str();
}
return this->LocalGenerator->GetFeature(feature, config);
}
@@ -982,13 +1024,15 @@ std::set<cmLinkItem> const& cmGeneratorTarget::GetUtilityItems() const
{
if (!this->UtilityItemsDone) {
this->UtilityItemsDone = true;
- std::set<BT<std::string>> const& utilities = this->GetUtilities();
- for (BT<std::string> const& i : utilities) {
+ std::set<BT<std::pair<std::string, bool>>> const& utilities =
+ this->GetUtilities();
+ for (BT<std::pair<std::string, bool>> const& i : utilities) {
if (cmGeneratorTarget* gt =
- this->LocalGenerator->FindGeneratorTargetToUse(i.Value)) {
- this->UtilityItems.insert(cmLinkItem(gt, i.Backtrace));
+ this->LocalGenerator->FindGeneratorTargetToUse(i.Value.first)) {
+ this->UtilityItems.insert(cmLinkItem(gt, i.Value.second, i.Backtrace));
} else {
- this->UtilityItems.insert(cmLinkItem(i.Value, i.Backtrace));
+ this->UtilityItems.insert(
+ cmLinkItem(i.Value.first, i.Value.second, i.Backtrace));
}
}
}
@@ -1001,7 +1045,8 @@ void cmGeneratorTarget::GetXamlSources(std::vector<cmSourceFile const*>& data,
IMPLEMENT_VISIT(SourceKindXaml);
}
-const char* cmGeneratorTarget::GetLocation(const std::string& config) const
+const std::string& cmGeneratorTarget::GetLocation(
+ const std::string& config) const
{
static std::string location;
if (this->IsImported()) {
@@ -1010,7 +1055,7 @@ const char* cmGeneratorTarget::GetLocation(const std::string& config) const
} else {
location = this->GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact);
}
- return location.c_str();
+ return location;
}
std::vector<cmCustomCommand> const& cmGeneratorTarget::GetPreBuildCommands()
@@ -1041,13 +1086,13 @@ bool cmGeneratorTarget::IsImportedGloballyVisible() const
return this->Target->IsImportedGloballyVisible();
}
-const char* cmGeneratorTarget::GetLocationForBuild() const
+const std::string& cmGeneratorTarget::GetLocationForBuild() const
{
static std::string location;
if (this->IsImported()) {
location = this->Target->ImportedGetFullPath(
"", cmStateEnums::RuntimeBinaryArtifact);
- return location.c_str();
+ return location;
}
// Now handle the deprecated build-time configuration location.
@@ -1067,7 +1112,7 @@ const char* cmGeneratorTarget::GetLocationForBuild() const
}
location += "/";
location += this->GetFullName("", cmStateEnums::RuntimeBinaryArtifact);
- return location.c_str();
+ return location;
}
bool cmGeneratorTarget::IsSystemIncludeDirectory(
@@ -1122,7 +1167,8 @@ bool cmGeneratorTarget::GetPropertyAsBool(const std::string& prop) const
}
bool cmGeneratorTarget::MaybeHaveInterfaceProperty(
- std::string const& prop, cmGeneratorExpressionContext* context) const
+ std::string const& prop, cmGeneratorExpressionContext* context,
+ bool usage_requirements_only) const
{
std::string const key = prop + '@' + context->Config;
auto i = this->MaybeInterfacePropertyExists.find(key);
@@ -1132,8 +1178,8 @@ bool cmGeneratorTarget::MaybeHaveInterfaceProperty(
bool& maybeInterfaceProp = i->second;
// If this target itself has a non-empty property value, we are done.
- const char* p = this->GetProperty(prop);
- maybeInterfaceProp = p && *p;
+ cmProp p = this->GetProperty(prop);
+ maybeInterfaceProp = p && !p->empty();
// Otherwise, recurse to interface dependencies.
if (!maybeInterfaceProp) {
@@ -1141,7 +1187,7 @@ bool cmGeneratorTarget::MaybeHaveInterfaceProperty(
context->HeadTarget ? context->HeadTarget : this;
if (cmLinkInterfaceLibraries const* iface =
this->GetLinkInterfaceLibraries(context->Config, headTarget,
- true)) {
+ usage_requirements_only)) {
if (iface->HadHeadSensitiveCondition) {
// With a different head target we may get to a library with
// this interface property.
@@ -1151,7 +1197,8 @@ bool cmGeneratorTarget::MaybeHaveInterfaceProperty(
// head target, so we can follow them.
for (cmLinkItem const& lib : iface->Libraries) {
if (lib.Target &&
- lib.Target->MaybeHaveInterfaceProperty(prop, context)) {
+ lib.Target->MaybeHaveInterfaceProperty(
+ prop, context, usage_requirements_only)) {
maybeInterfaceProp = true;
break;
}
@@ -1165,12 +1212,14 @@ bool cmGeneratorTarget::MaybeHaveInterfaceProperty(
std::string cmGeneratorTarget::EvaluateInterfaceProperty(
std::string const& prop, cmGeneratorExpressionContext* context,
- cmGeneratorExpressionDAGChecker* dagCheckerParent) const
+ cmGeneratorExpressionDAGChecker* dagCheckerParent,
+ bool usage_requirements_only) const
{
std::string result;
// If the property does not appear transitively at all, we are done.
- if (!this->MaybeHaveInterfaceProperty(prop, context)) {
+ if (!this->MaybeHaveInterfaceProperty(prop, context,
+ usage_requirements_only)) {
return result;
}
@@ -1186,7 +1235,6 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty(
return result;
case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
// No error. We just skip cyclic references.
- return result;
case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
// No error. We have already seen this transitive property.
return result;
@@ -1197,13 +1245,16 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty(
cmGeneratorTarget const* headTarget =
context->HeadTarget ? context->HeadTarget : this;
- if (const char* p = this->GetProperty(prop)) {
+ if (cmProp p = this->GetProperty(prop)) {
result = cmGeneratorExpressionNode::EvaluateDependentExpression(
- p, context->LG, context, headTarget, &dagChecker, this);
+ *p, context->LG, context, headTarget, &dagChecker, this);
}
- if (cmLinkInterfaceLibraries const* iface =
- this->GetLinkInterfaceLibraries(context->Config, headTarget, true)) {
+ if (cmLinkInterfaceLibraries const* iface = this->GetLinkInterfaceLibraries(
+ context->Config, headTarget, usage_requirements_only)) {
+ context->HadContextSensitiveCondition =
+ context->HadContextSensitiveCondition ||
+ iface->HadContextSensitiveCondition;
for (cmLinkItem const& lib : iface->Libraries) {
// Broken code can have a target in its own link interface.
// Don't follow such link interface entries so as not to create a
@@ -1217,8 +1268,8 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty(
context->EvaluateForBuildsystem, context->Backtrace,
context->Language);
std::string libResult = cmGeneratorExpression::StripEmptyListElements(
- lib.Target->EvaluateInterfaceProperty(prop, &libContext,
- &dagChecker));
+ lib.Target->EvaluateInterfaceProperty(prop, &libContext, &dagChecker,
+ usage_requirements_only));
if (!libResult.empty()) {
if (result.empty()) {
result = std::move(libResult);
@@ -1242,14 +1293,96 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty(
}
namespace {
+std::string AddSwiftInterfaceIncludeDirectories(
+ const cmGeneratorTarget* root, const cmGeneratorTarget* target,
+ const std::string& config, cmGeneratorExpressionDAGChecker* context)
+{
+ cmGeneratorExpressionDAGChecker dag{ target->GetBacktrace(), target,
+ "Swift_MODULE_DIRECTORY", nullptr,
+ context };
+ switch (dag.Check()) {
+ case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
+ dag.ReportError(nullptr,
+ "$<TARGET_PROPERTY:" + target->GetName() +
+ ",Swift_MODULE_DIRECTORY>");
+ CM_FALLTHROUGH;
+ case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
+ // No error. We just skip cyclic references.
+ case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
+ // No error. We have already seen this transitive property.
+ return "";
+ case cmGeneratorExpressionDAGChecker::DAG:
+ break;
+ }
+
+ std::string directories;
+ if (const auto* interface =
+ target->GetLinkInterfaceLibraries(config, root, true)) {
+ for (const cmLinkItem& library : interface->Libraries) {
+ if (const cmGeneratorTarget* dependency = library.Target) {
+ if (cm::contains(dependency->GetAllConfigCompileLanguages(),
+ "Swift")) {
+ std::string value =
+ dependency->GetSafeProperty("Swift_MODULE_DIRECTORY");
+ if (value.empty()) {
+ value =
+ dependency->GetLocalGenerator()->GetCurrentBinaryDirectory();
+ }
+
+ if (!directories.empty()) {
+ directories += ";";
+ }
+ directories += value;
+ }
+ }
+ }
+ }
+ return directories;
+}
+
+void AddSwiftImplicitIncludeDirectories(
+ const cmGeneratorTarget* target, const std::string& config,
+ EvaluatedTargetPropertyEntries& entries)
+{
+ if (const auto* libraries = target->GetLinkImplementationLibraries(config)) {
+ cmGeneratorExpressionDAGChecker dag{ target->GetBacktrace(), target,
+ "Swift_MODULE_DIRECTORY", nullptr,
+ nullptr };
+
+ for (const cmLinkImplItem& library : libraries->Libraries) {
+ if (const cmGeneratorTarget* dependency = library.Target) {
+ if (cm::contains(dependency->GetAllConfigCompileLanguages(),
+ "Swift")) {
+ EvaluatedTargetPropertyEntry entry{ library, library.Backtrace };
+
+ if (cmProp val = dependency->GetProperty("Swift_MODULE_DIRECTORY")) {
+ entry.Values.emplace_back(*val);
+ } else {
+ entry.Values.emplace_back(
+ dependency->GetLocalGenerator()->GetCurrentBinaryDirectory());
+ }
+
+ cmExpandList(AddSwiftInterfaceIncludeDirectories(target, dependency,
+ config, &dag),
+ entry.Values);
+
+ entries.Entries.emplace_back(std::move(entry));
+ }
+ }
+ }
+ }
+}
+
void AddInterfaceEntries(cmGeneratorTarget const* headTarget,
std::string const& config, std::string const& prop,
std::string const& lang,
cmGeneratorExpressionDAGChecker* dagChecker,
- std::vector<EvaluatedTargetPropertyEntry>& entries)
+ EvaluatedTargetPropertyEntries& entries,
+ bool usage_requirements_only = true)
{
if (cmLinkImplementationLibraries const* impl =
headTarget->GetLinkImplementationLibraries(config)) {
+ entries.HadContextSensitiveCondition = impl->HadContextSensitiveCondition;
for (cmLinkImplItem const& lib : impl->Libraries) {
if (lib.Target) {
EvaluatedTargetPropertyEntry ee(lib, lib.Backtrace);
@@ -1259,11 +1392,11 @@ void AddInterfaceEntries(cmGeneratorTarget const* headTarget,
cmGeneratorExpressionContext context(
headTarget->GetLocalGenerator(), config, false, headTarget,
headTarget, true, lib.Backtrace, lang);
- cmExpandList(
- lib.Target->EvaluateInterfaceProperty(prop, &context, dagChecker),
- ee.Values);
+ cmExpandList(lib.Target->EvaluateInterfaceProperty(
+ prop, &context, dagChecker, usage_requirements_only),
+ ee.Values);
ee.ContextDependent = context.HadContextSensitiveCondition;
- entries.emplace_back(std::move(ee));
+ entries.Entries.emplace_back(std::move(ee));
}
}
}
@@ -1272,10 +1405,11 @@ void AddInterfaceEntries(cmGeneratorTarget const* headTarget,
void AddObjectEntries(cmGeneratorTarget const* headTarget,
std::string const& config,
cmGeneratorExpressionDAGChecker* dagChecker,
- std::vector<EvaluatedTargetPropertyEntry>& entries)
+ EvaluatedTargetPropertyEntries& entries)
{
if (cmLinkImplementationLibraries const* impl =
headTarget->GetLinkImplementationLibraries(config)) {
+ entries.HadContextSensitiveCondition = impl->HadContextSensitiveCondition;
for (cmLinkImplItem const& lib : impl->Libraries) {
if (lib.Target &&
lib.Target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
@@ -1294,23 +1428,23 @@ void AddObjectEntries(cmGeneratorTarget const* headTarget,
if (cge->GetHadContextSensitiveCondition()) {
ee.ContextDependent = true;
}
- entries.emplace_back(std::move(ee));
+ entries.Entries.emplace_back(std::move(ee));
}
}
}
}
bool processSources(cmGeneratorTarget const* tgt,
- std::vector<EvaluatedTargetPropertyEntry>& entries,
+ EvaluatedTargetPropertyEntries& entries,
std::vector<BT<std::string>>& srcs,
std::unordered_set<std::string>& uniqueSrcs,
bool debugSources)
{
cmMakefile* mf = tgt->Target->GetMakefile();
- bool contextDependent = false;
+ bool contextDependent = entries.HadContextSensitiveCondition;
- for (EvaluatedTargetPropertyEntry& entry : entries) {
+ for (EvaluatedTargetPropertyEntry& entry : entries.Entries) {
if (entry.ContextDependent) {
contextDependent = true;
}
@@ -1402,7 +1536,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
}
bool debugSources =
- !this->DebugSourcesDone && cmContains(debugProperties, "SOURCES");
+ !this->DebugSourcesDone && cm::contains(debugProperties, "SOURCES");
if (this->LocalGenerator->GetGlobalGenerator()->GetConfigureDoneCMP0026()) {
this->DebugSourcesDone = true;
@@ -1411,16 +1545,15 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
cmGeneratorExpressionDAGChecker dagChecker(this, "SOURCES", nullptr,
nullptr);
- std::vector<EvaluatedTargetPropertyEntry> entries =
- EvaluateTargetPropertyEntries(this, config, std::string(), &dagChecker,
- this->SourceEntries);
+ EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
+ this, config, std::string(), &dagChecker, this->SourceEntries);
std::unordered_set<std::string> uniqueSrcs;
bool contextDependentDirectSources =
processSources(this, entries, files, uniqueSrcs, debugSources);
// Collect INTERFACE_SOURCES of all direct link-dependencies.
- std::vector<EvaluatedTargetPropertyEntry> linkInterfaceSourcesEntries;
+ EvaluatedTargetPropertyEntries linkInterfaceSourcesEntries;
AddInterfaceEntries(this, config, "INTERFACE_SOURCES", std::string(),
&dagChecker, linkInterfaceSourcesEntries);
std::vector<std::string>::size_type numFilesBefore = files.size();
@@ -1431,7 +1564,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
bool contextDependentObjects = false;
std::vector<std::string>::size_type numFilesBefore2 = files.size();
if (this->GetType() != cmStateEnums::OBJECT_LIBRARY) {
- std::vector<EvaluatedTargetPropertyEntry> linkObjectsEntries;
+ EvaluatedTargetPropertyEntries linkObjectsEntries;
AddObjectEntries(this, config, &dagChecker, linkObjectsEntries);
contextDependentObjects = processSources(this, linkObjectsEntries, files,
uniqueSrcs, debugSources);
@@ -1567,10 +1700,14 @@ void cmGeneratorTarget::ComputeKindedSources(KindedSources& files,
std::string ext = cmSystemTools::LowerCase(sf->GetExtension());
if (sf->GetCustomCommand()) {
kind = SourceKindCustomCommand;
+ // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
+ // NOLINTNEXTLINE(bugprone-branch-clone)
} else if (this->Target->GetType() == cmStateEnums::UTILITY) {
kind = SourceKindExtra;
} else if (this->IsSourceFilePartOfUnityBatch(sf->ResolveFullPath())) {
kind = SourceKindUnityBatched;
+ // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
+ // NOLINTNEXTLINE(bugprone-branch-clone)
} else if (sf->GetPropertyAsBool("HEADER_FILE_ONLY")) {
kind = SourceKindHeader;
} else if (sf->GetPropertyAsBool("EXTERNAL_OBJECT")) {
@@ -1672,6 +1809,19 @@ void cmGeneratorTarget::ComputeAllConfigSources() const
}
}
+std::set<std::string> cmGeneratorTarget::GetAllConfigCompileLanguages() const
+{
+ std::set<std::string> languages;
+ std::vector<AllConfigSource> const& sources = this->GetAllConfigSources();
+ for (AllConfigSource const& si : sources) {
+ std::string const& lang = si.Source->GetOrDetermineLanguage();
+ if (!lang.empty()) {
+ languages.emplace(lang);
+ }
+ }
+ return languages;
+}
+
std::string cmGeneratorTarget::GetCompilePDBName(
const std::string& config) const
{
@@ -1684,14 +1834,14 @@ std::string cmGeneratorTarget::GetCompilePDBName(
// Check for a per-configuration output directory target property.
std::string configUpper = cmSystemTools::UpperCase(config);
std::string configProp = cmStrCat("COMPILE_PDB_NAME_", configUpper);
- const char* config_name = this->GetProperty(configProp);
- if (config_name && *config_name) {
- return prefix + config_name + ".pdb";
+ cmProp config_name = this->GetProperty(configProp);
+ if (config_name && !config_name->empty()) {
+ return prefix + *config_name + ".pdb";
}
- const char* name = this->GetProperty("COMPILE_PDB_NAME");
- if (name && *name) {
- return prefix + name + ".pdb";
+ cmProp name = this->GetProperty("COMPILE_PDB_NAME");
+ if (name && !name->empty()) {
+ return prefix + *name + ".pdb";
}
return "";
@@ -1873,10 +2023,9 @@ bool cmGeneratorTarget::HasMacOSXRpathInstallNameDir(
if (this->GetType() != cmStateEnums::SHARED_LIBRARY) {
return false;
}
- const char* install_name = this->GetProperty("INSTALL_NAME_DIR");
+ cmProp install_name = this->GetProperty("INSTALL_NAME_DIR");
bool use_install_name = this->MacOSXUseInstallNameDir();
- if (install_name && use_install_name &&
- std::string(install_name) == "@rpath") {
+ if (install_name && use_install_name && *install_name == "@rpath") {
install_name_is_rpath = true;
} else if (install_name && use_install_name) {
return false;
@@ -1889,7 +2038,7 @@ bool cmGeneratorTarget::HasMacOSXRpathInstallNameDir(
if (cmGeneratorTarget::ImportInfo const* info =
this->GetImportInfo(config)) {
if (!info->NoSOName && !info->SOName.empty()) {
- if (info->SOName.find("@rpath/") == 0) {
+ if (cmHasLiteralPrefix(info->SOName, "@rpath/")) {
install_name_is_rpath = true;
}
} else {
@@ -1932,7 +2081,7 @@ bool cmGeneratorTarget::MacOSXRpathInstallNameDirDefault() const
return false;
}
- const char* macosx_rpath_str = this->GetProperty("MACOSX_RPATH");
+ cmProp macosx_rpath_str = this->GetProperty("MACOSX_RPATH");
if (macosx_rpath_str) {
return this->GetPropertyAsBool("MACOSX_RPATH");
}
@@ -1949,10 +2098,10 @@ bool cmGeneratorTarget::MacOSXRpathInstallNameDirDefault() const
bool cmGeneratorTarget::MacOSXUseInstallNameDir() const
{
- const char* build_with_install_name =
+ cmProp build_with_install_name =
this->GetProperty("BUILD_WITH_INSTALL_NAME_DIR");
if (build_with_install_name) {
- return cmIsOn(build_with_install_name);
+ return cmIsOn(*build_with_install_name);
}
cmPolicies::PolicyStatus cmp0068 = this->GetPolicyStatusCMP0068();
@@ -2006,7 +2155,7 @@ std::string cmGeneratorTarget::GetSOName(const std::string& config) const
return cmSystemTools::GetFilenameName(info->Location);
}
// Use the soname given if any.
- if (info->SOName.find("@rpath/") == 0) {
+ if (cmHasLiteralPrefix(info->SOName, "@rpath/")) {
return info->SOName.substr(6);
}
return info->SOName;
@@ -2034,11 +2183,8 @@ std::string cmGeneratorTarget::GetAppBundleDirectory(
{
std::string fpath = cmStrCat(
this->GetFullName(config, cmStateEnums::RuntimeBinaryArtifact), '.');
- const char* ext = this->GetProperty("BUNDLE_EXTENSION");
- if (!ext) {
- ext = "app";
- }
- fpath += ext;
+ cmProp ext = this->GetProperty("BUNDLE_EXTENSION");
+ fpath += (ext ? *ext : "app");
if (shouldAddContentLevel(level) &&
!this->Makefile->PlatformIsAppleEmbedded()) {
fpath += "/Contents";
@@ -2060,8 +2206,10 @@ std::string cmGeneratorTarget::GetCFBundleDirectory(
{
std::string fpath = cmStrCat(
this->GetOutputName(config, cmStateEnums::RuntimeBinaryArtifact), '.');
- const char* ext = this->GetProperty("BUNDLE_EXTENSION");
- if (!ext) {
+ std::string ext;
+ if (cmProp p = this->GetProperty("BUNDLE_EXTENSION")) {
+ ext = *p;
+ } else {
if (this->IsXCTestOnApple()) {
ext = "xctest";
} else {
@@ -2084,11 +2232,8 @@ std::string cmGeneratorTarget::GetFrameworkDirectory(
{
std::string fpath = cmStrCat(
this->GetOutputName(config, cmStateEnums::RuntimeBinaryArtifact), '.');
- const char* ext = this->GetProperty("BUNDLE_EXTENSION");
- if (!ext) {
- ext = "framework";
- }
- fpath += ext;
+ cmProp ext = this->GetProperty("BUNDLE_EXTENSION");
+ fpath += (ext ? *ext : "framework");
if (shouldAddFullLevel(level) &&
!this->Makefile->PlatformIsAppleEmbedded()) {
fpath += "/Versions/";
@@ -2114,7 +2259,9 @@ std::string cmGeneratorTarget::GetInstallNameDirForBuildTree(
// If building directly for installation then the build tree install_name
// is the same as the install tree.
if (this->MacOSXUseInstallNameDir()) {
- return this->GetInstallNameDirForInstallTree();
+ std::string installPrefix =
+ this->Makefile->GetSafeDefinition("CMAKE_INSTALL_PREFIX");
+ return this->GetInstallNameDirForInstallTree(config, installPrefix);
}
// Use the build tree directory for the target.
@@ -2132,15 +2279,22 @@ std::string cmGeneratorTarget::GetInstallNameDirForBuildTree(
return "";
}
-std::string cmGeneratorTarget::GetInstallNameDirForInstallTree() const
+std::string cmGeneratorTarget::GetInstallNameDirForInstallTree(
+ const std::string& config, const std::string& installPrefix) const
{
if (this->Makefile->IsOn("CMAKE_PLATFORM_HAS_INSTALLNAME")) {
std::string dir;
- const char* install_name_dir = this->GetProperty("INSTALL_NAME_DIR");
+ cmProp install_name_dir = this->GetProperty("INSTALL_NAME_DIR");
if (this->CanGenerateInstallNameDir(INSTALL_NAME_FOR_INSTALL)) {
- if (install_name_dir && *install_name_dir) {
- dir = cmStrCat(install_name_dir, '/');
+ if (install_name_dir && !install_name_dir->empty()) {
+ dir = *install_name_dir;
+ cmGeneratorExpression::ReplaceInstallPrefix(dir, installPrefix);
+ dir =
+ cmGeneratorExpression::Evaluate(dir, this->LocalGenerator, config);
+ if (!dir.empty()) {
+ dir = cmStrCat(dir, '/');
+ }
}
}
if (!install_name_dir) {
@@ -2158,7 +2312,8 @@ cmListFileBacktrace cmGeneratorTarget::GetBacktrace() const
return this->Target->GetBacktrace();
}
-const std::set<BT<std::string>>& cmGeneratorTarget::GetUtilities() const
+const std::set<BT<std::pair<std::string, bool>>>&
+cmGeneratorTarget::GetUtilities() const
{
return this->Target->GetUtilities();
}
@@ -2178,8 +2333,8 @@ const std::string* cmGeneratorTarget::GetExportMacro() const
if (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->GetType() == cmStateEnums::MODULE_LIBRARY ||
this->IsExecutableWithExports()) {
- if (const char* custom_export_name = this->GetProperty("DEFINE_SYMBOL")) {
- this->ExportMacro = custom_export_name;
+ if (cmProp custom_export_name = this->GetProperty("DEFINE_SYMBOL")) {
+ this->ExportMacro = *custom_export_name;
} else {
std::string in = cmStrCat(this->GetName(), "_EXPORTS");
this->ExportMacro = cmSystemTools::MakeCidentifier(in);
@@ -2195,11 +2350,12 @@ public:
cmTargetCollectLinkLanguages(cmGeneratorTarget const* target,
std::string config,
std::unordered_set<std::string>& languages,
- cmGeneratorTarget const* head)
+ cmGeneratorTarget const* head, bool secondPass)
: Config(std::move(config))
, Languages(languages)
, HeadTarget(head)
, Target(target)
+ , SecondPass(secondPass)
{
this->Visited.insert(target);
}
@@ -2241,11 +2397,14 @@ public:
if (!this->Visited.insert(item.Target).second) {
return;
}
- cmLinkInterface const* iface =
- item.Target->GetLinkInterface(this->Config, this->HeadTarget);
+ cmLinkInterface const* iface = item.Target->GetLinkInterface(
+ this->Config, this->HeadTarget, this->SecondPass);
if (!iface) {
return;
}
+ if (iface->HadLinkLanguageSensitiveCondition) {
+ this->HadLinkLanguageSensitiveCondition = true;
+ }
for (std::string const& language : iface->Languages) {
this->Languages.insert(language);
@@ -2256,12 +2415,19 @@ public:
}
}
+ bool GetHadLinkLanguageSensitiveCondition()
+ {
+ return HadLinkLanguageSensitiveCondition;
+ }
+
private:
std::string Config;
std::unordered_set<std::string>& Languages;
cmGeneratorTarget const* HeadTarget;
const cmGeneratorTarget* Target;
std::set<cmGeneratorTarget const*> Visited;
+ bool SecondPass;
+ bool HadLinkLanguageSensitiveCondition = false;
};
cmGeneratorTarget::LinkClosure const* cmGeneratorTarget::GetLinkClosure(
@@ -2292,7 +2458,7 @@ public:
{
this->GG = this->Target->GetLocalGenerator()->GetGlobalGenerator();
}
- void Consider(const char* lang)
+ void Consider(const std::string& lang)
{
int preference = this->GG->GetLinkerPreference(lang);
if (preference > this->Preference) {
@@ -2325,40 +2491,36 @@ public:
}
};
-void cmGeneratorTarget::ComputeLinkClosure(const std::string& config,
- LinkClosure& lc) const
+bool cmGeneratorTarget::ComputeLinkClosure(const std::string& config,
+ LinkClosure& lc,
+ bool secondPass) const
{
// Get languages built in this target.
std::unordered_set<std::string> languages;
- cmLinkImplementation const* impl = this->GetLinkImplementation(config);
+ cmLinkImplementation const* impl =
+ this->GetLinkImplementation(config, secondPass);
assert(impl);
- for (std::string const& li : impl->Languages) {
- languages.insert(li);
- }
+ languages.insert(impl->Languages.cbegin(), impl->Languages.cend());
// Add interface languages from linked targets.
- cmTargetCollectLinkLanguages cll(this, config, languages, this);
+ // cmTargetCollectLinkLanguages cll(this, config, languages, this,
+ // secondPass);
+ cmTargetCollectLinkLanguages cll(this, config, languages, this, secondPass);
for (cmLinkImplItem const& lib : impl->Libraries) {
cll.Visit(lib);
}
// Store the transitive closure of languages.
- for (std::string const& lang : languages) {
- lc.Languages.push_back(lang);
- }
+ cm::append(lc.Languages, languages);
// Choose the language whose linker should be used.
- if (this->GetProperty("HAS_CXX")) {
- lc.LinkerLanguage = "CXX";
- } else if (const char* linkerLang = this->GetProperty("LINKER_LANGUAGE")) {
- lc.LinkerLanguage = linkerLang;
- } else {
+ if (secondPass || lc.LinkerLanguage.empty()) {
// Find the language with the highest preference value.
cmTargetSelectLinker tsl(this);
// First select from the languages compiled directly in this target.
for (std::string const& l : impl->Languages) {
- tsl.Consider(l.c_str());
+ tsl.Consider(l);
}
// Now consider languages that propagate from linked targets.
@@ -2366,12 +2528,50 @@ void cmGeneratorTarget::ComputeLinkClosure(const std::string& config,
std::string propagates =
"CMAKE_" + lang + "_LINKER_PREFERENCE_PROPAGATES";
if (this->Makefile->IsOn(propagates)) {
- tsl.Consider(lang.c_str());
+ tsl.Consider(lang);
}
}
lc.LinkerLanguage = tsl.Choose();
}
+
+ return impl->HadLinkLanguageSensitiveCondition ||
+ cll.GetHadLinkLanguageSensitiveCondition();
+}
+
+void cmGeneratorTarget::ComputeLinkClosure(const std::string& config,
+ LinkClosure& lc) const
+{
+ bool secondPass = false;
+
+ {
+ LinkClosure linkClosure;
+ linkClosure.LinkerLanguage = this->LinkerLanguage;
+
+ // Get languages built in this target.
+ secondPass = this->ComputeLinkClosure(config, linkClosure, false);
+ this->LinkerLanguage = linkClosure.LinkerLanguage;
+ if (!secondPass) {
+ lc = std::move(linkClosure);
+ }
+ }
+
+ if (secondPass) {
+ LinkClosure linkClosure;
+
+ this->ComputeLinkClosure(config, linkClosure, secondPass);
+ lc = std::move(linkClosure);
+
+ // linker language must not be changed between the two passes
+ if (this->LinkerLanguage != lc.LinkerLanguage) {
+ std::ostringstream e;
+ e << "Evaluation of $<LINK_LANGUAGE:...> or $<LINK_LAND_AND_ID:...> "
+ "changes\nthe linker language for target \""
+ << this->GetName() << "\" (from '" << this->LinkerLanguage << "' to '"
+ << lc.LinkerLanguage << "') which is invalid.";
+ cmSystemTools::Error(e.str());
+ }
+ }
}
void cmGeneratorTarget::GetFullNameComponents(
@@ -2421,9 +2621,9 @@ std::string cmGeneratorTarget::GetEffectiveFolderName() const
return effectiveFolder;
}
- const char* targetFolder = this->GetProperty("FOLDER");
+ cmProp targetFolder = this->GetProperty("FOLDER");
if (targetFolder) {
- effectiveFolder += targetFolder;
+ effectiveFolder += *targetFolder;
}
return effectiveFolder;
@@ -2492,11 +2692,11 @@ void cmGeneratorTarget::ComputeModuleDefinitionInfo(
info.WindowsExportAllSymbols =
this->Makefile->IsOn("CMAKE_SUPPORT_WINDOWS_EXPORT_ALL_SYMBOLS") &&
this->GetPropertyAsBool("WINDOWS_EXPORT_ALL_SYMBOLS");
-#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
+#if !defined(CMAKE_BOOTSTRAP)
info.DefFileGenerated =
info.WindowsExportAllSymbols || info.Sources.size() > 1;
#else
- // Our __create_def helper is only available on Windows.
+ // Our __create_def helper is not available during CMake bootstrap.
info.DefFileGenerated = false;
#endif
if (info.DefFileGenerated) {
@@ -2614,7 +2814,7 @@ cmTargetTraceDependencies::cmTargetTraceDependencies(cmGeneratorTarget* target)
for (cmSourceFile* sf : sources) {
const std::set<cmGeneratorTarget const*> tgts =
this->GlobalGenerator->GetFilenameTargetDepends(sf);
- if (cmContains(tgts, this->GeneratorTarget)) {
+ if (cm::contains(tgts, this->GeneratorTarget)) {
std::ostringstream e;
e << "Evaluation output file\n \"" << sf->ResolveFullPath()
<< "\"\ndepends on the sources of a target it is used in. This "
@@ -2647,8 +2847,8 @@ void cmTargetTraceDependencies::Trace()
this->CurrentEntry = &this->GeneratorTarget->SourceDepends[sf];
// Queue dependencies added explicitly by the user.
- if (const char* additionalDeps = sf->GetProperty("OBJECT_DEPENDS")) {
- std::vector<std::string> objDeps = cmExpandedList(additionalDeps);
+ if (cmProp additionalDeps = sf->GetProperty("OBJECT_DEPENDS")) {
+ std::vector<std::string> objDeps = cmExpandedList(*additionalDeps);
for (std::string& objDep : objDeps) {
if (cmSystemTools::FileIsFullPath(objDep)) {
objDep = cmSystemTools::CollapseFullPath(objDep);
@@ -2691,12 +2891,23 @@ void cmTargetTraceDependencies::FollowName(std::string const& name)
if (i == this->NameMap.end() || i->first != name) {
// Check if we know how to generate this file.
cmSourcesWithOutput sources = this->Makefile->GetSourcesWithOutput(name);
+ // If we failed to find a target or source and we have a relative path, it
+ // might be a valid source if made relative to the current binary
+ // directory.
+ if (!sources.Target && !sources.Source &&
+ !cmSystemTools::FileIsFullPath(name)) {
+ auto fullname =
+ cmStrCat(this->Makefile->GetCurrentBinaryDirectory(), '/', name);
+ fullname = cmSystemTools::CollapseFullPath(
+ fullname, this->Makefile->GetHomeOutputDirectory());
+ sources = this->Makefile->GetSourcesWithOutput(fullname);
+ }
i = this->NameMap.emplace_hint(i, name, sources);
}
if (cmTarget* t = i->second.Target) {
// The name is a byproduct of a utility target or a PRE_BUILD, PRE_LINK, or
// POST_BUILD command.
- this->GeneratorTarget->Target->AddUtility(t->GetName());
+ this->GeneratorTarget->Target->AddUtility(t->GetName(), false);
}
if (cmSourceFile* sf = i->second.Source) {
// For now only follow the dependency if the source file is not a
@@ -2751,14 +2962,14 @@ bool cmTargetTraceDependencies::IsUtility(std::string const& dep)
depLocation = cmSystemTools::CollapseFullPath(depLocation);
tLocation = cmSystemTools::CollapseFullPath(tLocation);
if (depLocation == tLocation) {
- this->GeneratorTarget->Target->AddUtility(util);
+ this->GeneratorTarget->Target->AddUtility(util, false);
return true;
}
}
} else {
// The original name of the dependency was not a full path. It
// must name a target, so add the target-level dependency.
- this->GeneratorTarget->Target->AddUtility(util);
+ this->GeneratorTarget->Target->AddUtility(util, false);
return true;
}
}
@@ -2786,7 +2997,7 @@ void cmTargetTraceDependencies::CheckCustomCommand(cmCustomCommand const& cc)
// this project. Add the target-level dependency to make
// sure the executable is up to date before this custom
// command possibly runs.
- this->GeneratorTarget->Target->AddUtility(command);
+ this->GeneratorTarget->Target->AddUtility(command, true);
}
}
@@ -2801,7 +3012,7 @@ void cmTargetTraceDependencies::CheckCustomCommand(cmCustomCommand const& cc)
}
for (cmGeneratorTarget* target : targets) {
- this->GeneratorTarget->Target->AddUtility(target->GetName());
+ this->GeneratorTarget->Target->AddUtility(target->GetName(), true);
}
// Queue the custom command dependencies.
@@ -2868,7 +3079,7 @@ std::string cmGeneratorTarget::GetCompilePDBDirectory(
void cmGeneratorTarget::GetAppleArchs(const std::string& config,
std::vector<std::string>& archVec) const
{
- const char* archs = nullptr;
+ cmProp archs = nullptr;
if (!config.empty()) {
std::string defVarName =
cmStrCat("OSX_ARCHITECTURES_", cmSystemTools::UpperCase(config));
@@ -2878,7 +3089,96 @@ void cmGeneratorTarget::GetAppleArchs(const std::string& config,
archs = this->GetProperty("OSX_ARCHITECTURES");
}
if (archs) {
- cmExpandList(std::string(archs), archVec);
+ cmExpandList(*archs, archVec);
+ }
+}
+
+void cmGeneratorTarget::AddCUDAArchitectureFlags(std::string& flags) const
+{
+ struct CudaArchitecture
+ {
+ std::string name;
+ bool real{ true };
+ bool virtual_{ true };
+ };
+ std::vector<CudaArchitecture> architectures;
+
+ {
+ std::vector<std::string> options;
+ cmExpandList(this->GetSafeProperty("CUDA_ARCHITECTURES"), options);
+
+ if (options.empty()) {
+ switch (this->GetPolicyStatusCMP0104()) {
+ case cmPolicies::WARN:
+ if (!this->LocalGenerator->GetCMakeInstance()->GetIsInTryCompile()) {
+ this->Makefile->IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmPolicies::GetPolicyWarning(cmPolicies::CMP0104) +
+ "\nCUDA_ARCHITECTURES is empty for target \"" +
+ this->GetName() + "\".");
+ }
+ CM_FALLTHROUGH;
+ case cmPolicies::OLD:
+ break;
+ default:
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ "CUDA_ARCHITECTURES is empty for target \"" + this->GetName() +
+ "\".");
+ }
+ }
+
+ for (std::string& option : options) {
+ CudaArchitecture architecture;
+
+ // Architecture name is up to the first specifier.
+ std::size_t pos = option.find_first_of('-');
+ architecture.name = option.substr(0, pos);
+
+ if (pos != std::string::npos) {
+ cm::string_view specifier{ option.c_str() + pos + 1,
+ option.length() - pos - 1 };
+
+ if (specifier == "real") {
+ architecture.real = true;
+ architecture.virtual_ = false;
+ } else if (specifier == "virtual") {
+ architecture.real = false;
+ architecture.virtual_ = true;
+ } else {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ "Uknown CUDA architecture specifier \"" + std::string(specifier) +
+ "\".");
+ }
+ }
+
+ architectures.emplace_back(architecture);
+ }
+ }
+
+ std::string const& compiler =
+ this->Makefile->GetSafeDefinition("CMAKE_CUDA_COMPILER_ID");
+
+ if (compiler == "NVIDIA") {
+ for (CudaArchitecture& architecture : architectures) {
+ flags +=
+ " --generate-code=arch=compute_" + architecture.name + ",code=[";
+
+ if (architecture.virtual_) {
+ flags += "compute_" + architecture.name;
+
+ if (architecture.real) {
+ flags += ",";
+ }
+ }
+
+ if (architecture.real) {
+ flags += "sm_" + architecture.name;
+ }
+
+ flags += "]";
+ }
}
}
@@ -2926,13 +3226,13 @@ std::string cmGeneratorTarget::GetCreateRuleVariable(
}
namespace {
-void processIncludeDirectories(
- cmGeneratorTarget const* tgt,
- std::vector<EvaluatedTargetPropertyEntry>& entries,
- std::vector<BT<std::string>>& includes,
- std::unordered_set<std::string>& uniqueIncludes, bool debugIncludes)
+void processIncludeDirectories(cmGeneratorTarget const* tgt,
+ EvaluatedTargetPropertyEntries& entries,
+ std::vector<BT<std::string>>& includes,
+ std::unordered_set<std::string>& uniqueIncludes,
+ bool debugIncludes)
{
- for (EvaluatedTargetPropertyEntry& entry : entries) {
+ for (EvaluatedTargetPropertyEntry& entry : entries.Entries) {
cmLinkImplItem const& item = entry.LinkImplItem;
std::string const& targetName = item.AsStr();
bool const fromImported = item.Target && item.Target->IsImported();
@@ -3047,15 +3347,18 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
}
bool debugIncludes = !this->DebugIncludesDone &&
- cmContains(debugProperties, "INCLUDE_DIRECTORIES");
+ cm::contains(debugProperties, "INCLUDE_DIRECTORIES");
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugIncludesDone = true;
}
- std::vector<EvaluatedTargetPropertyEntry> entries =
- EvaluateTargetPropertyEntries(this, config, lang, &dagChecker,
- this->IncludeDirectoriesEntries);
+ EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
+ this, config, lang, &dagChecker, this->IncludeDirectoriesEntries);
+
+ if (lang == "Swift") {
+ AddSwiftImplicitIncludeDirectories(this, config, entries);
+ }
AddInterfaceEntries(this, config, "INTERFACE_INCLUDE_DIRECTORIES", lang,
&dagChecker, entries);
@@ -3064,7 +3367,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
cmLinkImplementationLibraries const* impl =
this->GetLinkImplementationLibraries(config);
for (cmLinkImplItem const& lib : impl->Libraries) {
- std::string libDir = cmSystemTools::CollapseFullPath(lib.AsStr());
+ std::string libDir = cmSystemTools::CollapseFullPath(
+ lib.AsStr(), this->Makefile->GetHomeOutputDirectory());
static cmsys::RegularExpression frameworkCheck(
"(.*\\.framework)(/Versions/[^/]+)?/[^/]+$");
@@ -3076,7 +3380,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
EvaluatedTargetPropertyEntry ee(lib, cmListFileBacktrace());
ee.Values.emplace_back(std::move(libDir));
- entries.emplace_back(std::move(ee));
+ entries.Entries.emplace_back(std::move(ee));
}
}
@@ -3093,22 +3397,38 @@ enum class OptionsParse
};
namespace {
+const auto DL_BEGIN = "<DEVICE_LINK>"_s;
+const auto DL_END = "</DEVICE_LINK>"_s;
+
void processOptions(cmGeneratorTarget const* tgt,
- std::vector<EvaluatedTargetPropertyEntry> const& entries,
+ EvaluatedTargetPropertyEntries const& entries,
std::vector<BT<std::string>>& options,
std::unordered_set<std::string>& uniqueOptions,
- bool debugOptions, const char* logName, OptionsParse parse)
+ bool debugOptions, const char* logName, OptionsParse parse,
+ bool processDeviceOptions = false)
{
- for (EvaluatedTargetPropertyEntry const& entry : entries) {
+ bool splitOption = !processDeviceOptions;
+ for (EvaluatedTargetPropertyEntry const& entry : entries.Entries) {
std::string usedOptions;
for (std::string const& opt : entry.Values) {
+ if (processDeviceOptions && (opt == DL_BEGIN || opt == DL_END)) {
+ options.emplace_back(opt, entry.Backtrace);
+ splitOption = opt == DL_BEGIN;
+ continue;
+ }
+
if (uniqueOptions.insert(opt).second) {
if (parse == OptionsParse::Shell &&
cmHasLiteralPrefix(opt, "SHELL:")) {
- std::vector<std::string> tmp;
- cmSystemTools::ParseUnixCommandLine(opt.c_str() + 6, tmp);
- for (std::string& o : tmp) {
- options.emplace_back(std::move(o), entry.Backtrace);
+ if (splitOption) {
+ std::vector<std::string> tmp;
+ cmSystemTools::ParseUnixCommandLine(opt.c_str() + 6, tmp);
+ for (std::string& o : tmp) {
+ options.emplace_back(std::move(o), entry.Backtrace);
+ }
+ } else {
+ options.emplace_back(std::string(opt.c_str() + 6),
+ entry.Backtrace);
}
} else {
options.emplace_back(opt, entry.Backtrace);
@@ -3127,6 +3447,63 @@ void processOptions(cmGeneratorTarget const* tgt,
}
}
}
+
+std::vector<BT<std::string>> wrapOptions(
+ std::vector<std::string>& options, const cmListFileBacktrace& bt,
+ const std::vector<std::string>& wrapperFlag, const std::string& wrapperSep,
+ bool concatFlagAndArgs)
+{
+ std::vector<BT<std::string>> result;
+
+ if (options.empty()) {
+ return result;
+ }
+
+ if (wrapperFlag.empty() || cmHasLiteralPrefix(options.front(), "LINKER:")) {
+ // nothing specified or LINKER wrapper, insert elements as is
+ result.reserve(options.size());
+ for (std::string& o : options) {
+ result.emplace_back(std::move(o), bt);
+ }
+ } else {
+ if (!wrapperSep.empty()) {
+ if (concatFlagAndArgs) {
+ // insert flag elements except last one
+ for (auto i = wrapperFlag.begin(); i != wrapperFlag.end() - 1; ++i) {
+ result.emplace_back(*i, bt);
+ }
+ // concatenate last flag element and all list values
+ // in one option
+ result.emplace_back(wrapperFlag.back() + cmJoin(options, wrapperSep),
+ bt);
+ } else {
+ for (std::string const& i : wrapperFlag) {
+ result.emplace_back(i, bt);
+ }
+ // concatenate all list values in one option
+ result.emplace_back(cmJoin(options, wrapperSep), bt);
+ }
+ } else {
+ // prefix each element of list with wrapper
+ if (concatFlagAndArgs) {
+ std::transform(options.begin(), options.end(), options.begin(),
+ [&wrapperFlag](std::string const& o) -> std::string {
+ return wrapperFlag.back() + o;
+ });
+ }
+ for (std::string& o : options) {
+ for (auto i = wrapperFlag.begin(),
+ e = concatFlagAndArgs ? wrapperFlag.end() - 1
+ : wrapperFlag.end();
+ i != e; ++i) {
+ result.emplace_back(*i, bt);
+ }
+ result.emplace_back(std::move(o), bt);
+ }
+ }
+ }
+ return result;
+}
}
void cmGeneratorTarget::GetCompileOptions(std::vector<std::string>& result,
@@ -3157,15 +3534,14 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileOptions(
}
bool debugOptions = !this->DebugCompileOptionsDone &&
- cmContains(debugProperties, "COMPILE_OPTIONS");
+ cm::contains(debugProperties, "COMPILE_OPTIONS");
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugCompileOptionsDone = true;
}
- std::vector<EvaluatedTargetPropertyEntry> entries =
- EvaluateTargetPropertyEntries(this, config, language, &dagChecker,
- this->CompileOptionsEntries);
+ EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
+ this, config, language, &dagChecker, this->CompileOptionsEntries);
AddInterfaceEntries(this, config, "INTERFACE_COMPILE_OPTIONS", language,
&dagChecker, entries);
@@ -3203,15 +3579,14 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileFeatures(
}
bool debugFeatures = !this->DebugCompileFeaturesDone &&
- cmContains(debugProperties, "COMPILE_FEATURES");
+ cm::contains(debugProperties, "COMPILE_FEATURES");
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugCompileFeaturesDone = true;
}
- std::vector<EvaluatedTargetPropertyEntry> entries =
- EvaluateTargetPropertyEntries(this, config, std::string(), &dagChecker,
- this->CompileFeaturesEntries);
+ EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
+ this, config, std::string(), &dagChecker, this->CompileFeaturesEntries);
AddInterfaceEntries(this, config, "INTERFACE_COMPILE_FEATURES",
std::string(), &dagChecker, entries);
@@ -3251,15 +3626,14 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions(
}
bool debugDefines = !this->DebugCompileDefinitionsDone &&
- cmContains(debugProperties, "COMPILE_DEFINITIONS");
+ cm::contains(debugProperties, "COMPILE_DEFINITIONS");
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugCompileDefinitionsDone = true;
}
- std::vector<EvaluatedTargetPropertyEntry> entries =
- EvaluateTargetPropertyEntries(this, config, language, &dagChecker,
- this->CompileDefinitionsEntries);
+ EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
+ this, config, language, &dagChecker, this->CompileDefinitionsEntries);
AddInterfaceEntries(this, config, "INTERFACE_COMPILE_DEFINITIONS", language,
&dagChecker, entries);
@@ -3267,7 +3641,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions(
if (!config.empty()) {
std::string configPropName =
"COMPILE_DEFINITIONS_" + cmSystemTools::UpperCase(config);
- const char* configProp = this->GetProperty(configPropName);
+ cmProp configProp = this->GetProperty(configPropName);
if (configProp) {
switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0043)) {
case cmPolicies::WARN: {
@@ -3277,10 +3651,10 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions(
CM_FALLTHROUGH;
}
case cmPolicies::OLD: {
- std::unique_ptr<TargetPropertyEntry> entry(
- CreateTargetPropertyEntry(configProp));
- entries.emplace_back(EvaluateTargetPropertyEntry(
- this, config, language, &dagChecker, entry.get()));
+ std::unique_ptr<TargetPropertyEntry> entry =
+ CreateTargetPropertyEntry(*configProp);
+ entries.Entries.emplace_back(EvaluateTargetPropertyEntry(
+ this, config, language, &dagChecker, *entry));
} break;
case cmPolicies::NEW:
case cmPolicies::REQUIRED_ALWAYS:
@@ -3319,9 +3693,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetPrecompileHeaders(
this->DebugPrecompileHeadersDone = true;
}
- std::vector<EvaluatedTargetPropertyEntry> entries =
- EvaluateTargetPropertyEntries(this, config, language, &dagChecker,
- this->PrecompileHeadersEntries);
+ EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
+ this, config, language, &dagChecker, this->PrecompileHeadersEntries);
AddInterfaceEntries(this, config, "INTERFACE_PRECOMPILE_HEADERS", language,
&dagChecker, entries);
@@ -3334,7 +3707,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetPrecompileHeaders(
}
std::string cmGeneratorTarget::GetPchHeader(const std::string& config,
- const std::string& language) const
+ const std::string& language,
+ const std::string& arch) const
{
if (language != "C" && language != "CXX" && language != "OBJC" &&
language != "OBJCXX") {
@@ -3345,11 +3719,11 @@ std::string cmGeneratorTarget::GetPchHeader(const std::string& config,
return std::string();
}
const cmGeneratorTarget* generatorTarget = this;
- const char* pchReuseFrom =
+ cmProp pchReuseFrom =
generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
const auto inserted =
- this->PchHeaders.insert(std::make_pair(language + config, ""));
+ this->PchHeaders.insert(std::make_pair(language + config + arch, ""));
if (inserted.second) {
const std::vector<BT<std::string>> headers =
this->GetPrecompileHeaders(config, language);
@@ -3360,7 +3734,7 @@ std::string cmGeneratorTarget::GetPchHeader(const std::string& config,
if (pchReuseFrom) {
generatorTarget =
- this->GetGlobalGenerator()->FindGeneratorTarget(pchReuseFrom);
+ this->GetGlobalGenerator()->FindGeneratorTarget(*pchReuseFrom);
}
filename = cmStrCat(
@@ -3373,14 +3747,23 @@ std::string cmGeneratorTarget::GetPchHeader(const std::string& config,
{ "OBJCXX", ".objcxx.hxx" }
};
- filename = cmStrCat(filename, "CMakeFiles/", generatorTarget->GetName(),
- ".dir/cmake_pch", languageToExtension.at(language));
+ filename =
+ cmStrCat(filename, "CMakeFiles/", generatorTarget->GetName(), ".dir");
+
+ if (this->GetGlobalGenerator()->IsMultiConfig()) {
+ filename = cmStrCat(filename, "/", config);
+ }
+
+ filename =
+ cmStrCat(filename, "/cmake_pch", arch.empty() ? "" : cmStrCat("_", arch),
+ languageToExtension.at(language));
const std::string filename_tmp = cmStrCat(filename, ".tmp");
if (!pchReuseFrom) {
auto pchPrologue = this->Makefile->GetDefinition("CMAKE_PCH_PROLOGUE");
auto pchEpilogue = this->Makefile->GetDefinition("CMAKE_PCH_EPILOGUE");
+ std::string firstHeaderOnDisk;
{
cmGeneratedFileStream file(
filename_tmp, false,
@@ -3404,6 +3787,11 @@ std::string cmGeneratorTarget::GetPchHeader(const std::string& config,
} else {
file << "#include \"" << header_bt.Value << "\"\n";
}
+
+ if (cmSystemTools::FileExists(header_bt.Value) &&
+ firstHeaderOnDisk.empty()) {
+ firstHeaderOnDisk = header_bt.Value;
+ }
}
if (language == "CXX") {
file << "#endif // __cplusplus\n";
@@ -3415,6 +3803,11 @@ std::string cmGeneratorTarget::GetPchHeader(const std::string& config,
file << pchEpilogue << "\n";
}
}
+
+ if (!firstHeaderOnDisk.empty()) {
+ cmFileTimes::Copy(firstHeaderOnDisk, filename_tmp);
+ }
+
cmSystemTools::MoveFileIfDifferent(filename_tmp, filename);
}
}
@@ -3422,27 +3815,28 @@ std::string cmGeneratorTarget::GetPchHeader(const std::string& config,
}
std::string cmGeneratorTarget::GetPchSource(const std::string& config,
- const std::string& language) const
+ const std::string& language,
+ const std::string& arch) const
{
if (language != "C" && language != "CXX" && language != "OBJC" &&
language != "OBJCXX") {
return std::string();
}
const auto inserted =
- this->PchSources.insert(std::make_pair(language + config, ""));
+ this->PchSources.insert(std::make_pair(language + config + arch, ""));
if (inserted.second) {
- const std::string pchHeader = this->GetPchHeader(config, language);
+ const std::string pchHeader = this->GetPchHeader(config, language, arch);
if (pchHeader.empty()) {
return std::string();
}
std::string& filename = inserted.first->second;
const cmGeneratorTarget* generatorTarget = this;
- const char* pchReuseFrom =
+ cmProp pchReuseFrom =
generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
if (pchReuseFrom) {
generatorTarget =
- this->GetGlobalGenerator()->FindGeneratorTarget(pchReuseFrom);
+ this->GetGlobalGenerator()->FindGeneratorTarget(*pchReuseFrom);
}
filename =
@@ -3458,13 +3852,15 @@ std::string cmGeneratorTarget::GetPchSource(const std::string& config,
{ "OBJCXX", ".objcxx.hxx.mm" }
};
- filename += languageToExtension.at(language);
+ filename = cmStrCat(filename, arch.empty() ? "" : cmStrCat("_", arch),
+ languageToExtension.at(language));
} else {
const std::map<std::string, std::string> languageToExtension = {
{ "C", ".c" }, { "CXX", ".cxx" }, { "OBJC", ".m" }, { "OBJCXX", ".mm" }
};
- filename += languageToExtension.at(language);
+ filename = cmStrCat(filename, arch.empty() ? "" : cmStrCat("_", arch),
+ languageToExtension.at(language));
}
const std::string filename_tmp = cmStrCat(filename, ".tmp");
@@ -3473,6 +3869,7 @@ std::string cmGeneratorTarget::GetPchSource(const std::string& config,
cmGeneratedFileStream file(filename_tmp);
file << "/* generated by CMake */\n";
}
+ cmFileTimes::Copy(pchHeader, filename_tmp);
cmSystemTools::MoveFileIfDifferent(filename_tmp, filename);
}
}
@@ -3480,16 +3877,17 @@ std::string cmGeneratorTarget::GetPchSource(const std::string& config,
}
std::string cmGeneratorTarget::GetPchFileObject(const std::string& config,
- const std::string& language)
+ const std::string& language,
+ const std::string& arch)
{
if (language != "C" && language != "CXX" && language != "OBJC" &&
language != "OBJCXX") {
return std::string();
}
const auto inserted =
- this->PchObjectFiles.insert(std::make_pair(language + config, ""));
+ this->PchObjectFiles.insert(std::make_pair(language + config + arch, ""));
if (inserted.second) {
- const std::string pchSource = this->GetPchSource(config, language);
+ const std::string pchSource = this->GetPchSource(config, language, arch);
if (pchSource.empty()) {
return std::string();
}
@@ -3506,10 +3904,11 @@ std::string cmGeneratorTarget::GetPchFileObject(const std::string& config,
}
std::string cmGeneratorTarget::GetPchFile(const std::string& config,
- const std::string& language)
+ const std::string& language,
+ const std::string& arch)
{
const auto inserted =
- this->PchFiles.insert(std::make_pair(language + config, ""));
+ this->PchFiles.insert(std::make_pair(language + config + arch, ""));
if (inserted.second) {
std::string& pchFile = inserted.first->second;
@@ -3529,20 +3928,20 @@ std::string cmGeneratorTarget::GetPchFile(const std::string& config,
};
cmGeneratorTarget* generatorTarget = this;
- const char* pchReuseFrom =
+ cmProp pchReuseFrom =
generatorTarget->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
if (pchReuseFrom) {
generatorTarget =
- this->GetGlobalGenerator()->FindGeneratorTarget(pchReuseFrom);
+ this->GetGlobalGenerator()->FindGeneratorTarget(*pchReuseFrom);
}
const std::string pchFileObject =
- generatorTarget->GetPchFileObject(config, language);
+ generatorTarget->GetPchFileObject(config, language, arch);
if (!pchExtension.empty()) {
pchFile = replaceExtension(pchFileObject, pchExtension);
}
} else {
- pchFile = this->GetPchHeader(config, language);
+ pchFile = this->GetPchHeader(config, language, arch);
pchFile += pchExtension;
}
}
@@ -3550,19 +3949,27 @@ std::string cmGeneratorTarget::GetPchFile(const std::string& config,
}
std::string cmGeneratorTarget::GetPchCreateCompileOptions(
- const std::string& config, const std::string& language)
+ const std::string& config, const std::string& language,
+ const std::string& arch)
{
const auto inserted = this->PchCreateCompileOptions.insert(
- std::make_pair(language + config, ""));
+ std::make_pair(language + config + arch, ""));
if (inserted.second) {
std::string& createOptionList = inserted.first->second;
+ if (this->GetPropertyAsBool("PCH_WARN_INVALID")) {
+ createOptionList = this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", language, "_COMPILE_OPTIONS_INVALID_PCH"));
+ }
+
const std::string createOptVar =
cmStrCat("CMAKE_", language, "_COMPILE_OPTIONS_CREATE_PCH");
- createOptionList = this->Makefile->GetSafeDefinition(createOptVar);
- const std::string pchHeader = this->GetPchHeader(config, language);
- const std::string pchFile = this->GetPchFile(config, language);
+ createOptionList = cmStrCat(
+ createOptionList, ";", this->Makefile->GetSafeDefinition(createOptVar));
+
+ const std::string pchHeader = this->GetPchHeader(config, language, arch);
+ const std::string pchFile = this->GetPchFile(config, language, arch);
cmSystemTools::ReplaceString(createOptionList, "<PCH_HEADER>", pchHeader);
cmSystemTools::ReplaceString(createOptionList, "<PCH_FILE>", pchFile);
@@ -3571,19 +3978,33 @@ std::string cmGeneratorTarget::GetPchCreateCompileOptions(
}
std::string cmGeneratorTarget::GetPchUseCompileOptions(
- const std::string& config, const std::string& language)
+ const std::string& config, const std::string& language,
+ const std::string& arch)
{
- const auto inserted =
- this->PchUseCompileOptions.insert(std::make_pair(language + config, ""));
+ const auto inserted = this->PchUseCompileOptions.insert(
+ std::make_pair(language + config + arch, ""));
if (inserted.second) {
std::string& useOptionList = inserted.first->second;
+ if (this->GetPropertyAsBool("PCH_WARN_INVALID")) {
+ useOptionList = this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", language, "_COMPILE_OPTIONS_INVALID_PCH"));
+ }
+
const std::string useOptVar =
- cmStrCat("CMAKE_", language, "_COMPILE_OPTIONS_USE_PCH");
- useOptionList = this->Makefile->GetSafeDefinition(useOptVar);
+ cmStrCat(language, "_COMPILE_OPTIONS_USE_PCH");
+
+ std::string const& useOptionListProperty =
+ this->GetSafeProperty(useOptVar);
- const std::string pchHeader = this->GetPchHeader(config, language);
- const std::string pchFile = this->GetPchFile(config, language);
+ useOptionList = cmStrCat(
+ useOptionList, ";",
+ useOptionListProperty.empty()
+ ? this->Makefile->GetSafeDefinition(cmStrCat("CMAKE_", useOptVar))
+ : useOptionListProperty);
+
+ const std::string pchHeader = this->GetPchHeader(config, language, arch);
+ const std::string pchFile = this->GetPchFile(config, language, arch);
cmSystemTools::ReplaceString(useOptionList, "<PCH_HEADER>", pchHeader);
cmSystemTools::ReplaceString(useOptionList, "<PCH_FILE>", pchFile);
@@ -3612,6 +4033,12 @@ void cmGeneratorTarget::GetLinkOptions(std::vector<std::string>& result,
const std::string& config,
const std::string& language) const
{
+ if (this->IsDeviceLink() &&
+ this->GetPolicyStatusCMP0105() != cmPolicies::NEW) {
+ // link options are not propagated to the device link step
+ return;
+ }
+
std::vector<BT<std::string>> tmp = this->GetLinkOptions(config, language);
result.reserve(tmp.size());
for (BT<std::string>& v : tmp) {
@@ -3635,30 +4062,80 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions(
cmExpandList(debugProp, debugProperties);
}
- bool debugOptions =
- !this->DebugLinkOptionsDone && cmContains(debugProperties, "LINK_OPTIONS");
+ bool debugOptions = !this->DebugLinkOptionsDone &&
+ cm::contains(debugProperties, "LINK_OPTIONS");
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugLinkOptionsDone = true;
}
- std::vector<EvaluatedTargetPropertyEntry> entries =
- EvaluateTargetPropertyEntries(this, config, language, &dagChecker,
- this->LinkOptionsEntries);
+ EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
+ this, config, language, &dagChecker, this->LinkOptionsEntries);
AddInterfaceEntries(this, config, "INTERFACE_LINK_OPTIONS", language,
- &dagChecker, entries);
+ &dagChecker, entries,
+ this->GetPolicyStatusCMP0099() != cmPolicies::NEW);
processOptions(this, entries, result, uniqueOptions, debugOptions,
- "link options", OptionsParse::Shell);
+ "link options", OptionsParse::Shell, this->IsDeviceLink());
+
+ if (this->IsDeviceLink()) {
+ // wrap host link options
+ const std::string wrapper(this->Makefile->GetSafeDefinition(
+ "CMAKE_" + language + "_DEVICE_COMPILER_WRAPPER_FLAG"));
+ std::vector<std::string> wrapperFlag = cmExpandedList(wrapper);
+ const std::string wrapperSep(this->Makefile->GetSafeDefinition(
+ "CMAKE_" + language + "_DEVICE_COMPILER_WRAPPER_FLAG_SEP"));
+ bool concatFlagAndArgs = true;
+ if (!wrapperFlag.empty() && wrapperFlag.back() == " ") {
+ concatFlagAndArgs = false;
+ wrapperFlag.pop_back();
+ }
+
+ auto it = result.begin();
+ while (it != result.end()) {
+ if (it->Value == DL_BEGIN) {
+ // device link options, no treatment
+ it = result.erase(it);
+ it = std::find_if(it, result.end(), [](const BT<std::string>& item) {
+ return item.Value == DL_END;
+ });
+ if (it != result.end()) {
+ it = result.erase(it);
+ }
+ } else {
+ // host link options must be wrapped
+ std::vector<std::string> options;
+ cmSystemTools::ParseUnixCommandLine(it->Value.c_str(), options);
+ auto hostOptions = wrapOptions(options, it->Backtrace, wrapperFlag,
+ wrapperSep, concatFlagAndArgs);
+ it = result.erase(it);
+ // some compilers (like gcc 4.8 or Intel 19.0 or XLC 16) do not respect
+ // C++11 standard: 'std::vector::insert()' do not returns an iterator,
+ // so need to recompute the iterator after insertion.
+ if (it == result.end()) {
+ cm::append(result, hostOptions);
+ it = result.end();
+ } else {
+ auto index = it - result.begin();
+ result.insert(it, hostOptions.begin(), hostOptions.end());
+ it = result.begin() + index + hostOptions.size();
+ }
+ }
+ }
+ }
// Last step: replace "LINKER:" prefixed elements by
// actual linker wrapper
const std::string wrapper(this->Makefile->GetSafeDefinition(
- "CMAKE_" + language + "_LINKER_WRAPPER_FLAG"));
+ "CMAKE_" + language +
+ (this->IsDeviceLink() ? "_DEVICE_LINKER_WRAPPER_FLAG"
+ : "_LINKER_WRAPPER_FLAG")));
std::vector<std::string> wrapperFlag = cmExpandedList(wrapper);
const std::string wrapperSep(this->Makefile->GetSafeDefinition(
- "CMAKE_" + language + "_LINKER_WRAPPER_FLAG_SEP"));
+ "CMAKE_" + language +
+ (this->IsDeviceLink() ? "_DEVICE_LINKER_WRAPPER_FLAG_SEP"
+ : "_LINKER_WRAPPER_FLAG_SEP")));
bool concatFlagAndArgs = true;
if (!wrapperFlag.empty() && wrapperFlag.back() == " ") {
concatFlagAndArgs = false;
@@ -3704,51 +4181,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions(
return result;
}
- std::vector<BT<std::string>> options;
- if (wrapperFlag.empty()) {
- // nothing specified, insert elements as is
- options.reserve(linkerOptions.size());
- for (std::string& o : linkerOptions) {
- options.emplace_back(std::move(o), bt);
- }
- } else {
- if (!wrapperSep.empty()) {
- if (concatFlagAndArgs) {
- // insert flag elements except last one
- for (auto i = wrapperFlag.begin(); i != wrapperFlag.end() - 1; ++i) {
- options.emplace_back(*i, bt);
- }
- // concatenate last flag element and all LINKER list values
- // in one option
- options.emplace_back(
- wrapperFlag.back() + cmJoin(linkerOptions, wrapperSep), bt);
- } else {
- for (std::string const& i : wrapperFlag) {
- options.emplace_back(i, bt);
- }
- // concatenate all LINKER list values in one option
- options.emplace_back(cmJoin(linkerOptions, wrapperSep), bt);
- }
- } else {
- // prefix each element of LINKER list with wrapper
- if (concatFlagAndArgs) {
- std::transform(linkerOptions.begin(), linkerOptions.end(),
- linkerOptions.begin(),
- [&wrapperFlag](std::string const& o) -> std::string {
- return wrapperFlag.back() + o;
- });
- }
- for (std::string& o : linkerOptions) {
- for (auto i = wrapperFlag.begin(),
- e = concatFlagAndArgs ? wrapperFlag.end() - 1
- : wrapperFlag.end();
- i != e; ++i) {
- options.emplace_back(*i, bt);
- }
- options.emplace_back(std::move(o), bt);
- }
- }
- }
+ std::vector<BT<std::string>> options = wrapOptions(
+ linkerOptions, bt, wrapperFlag, wrapperSep, concatFlagAndArgs);
result.insert(entry, options.begin(), options.end());
}
return result;
@@ -3775,14 +4209,14 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetStaticLibraryLinkOptions(
cmGeneratorExpressionDAGChecker dagChecker(this, "STATIC_LIBRARY_OPTIONS",
nullptr, nullptr);
- std::vector<EvaluatedTargetPropertyEntry> entries;
- if (const char* linkOptions = this->GetProperty("STATIC_LIBRARY_OPTIONS")) {
- std::vector<std::string> options = cmExpandedList(linkOptions);
+ EvaluatedTargetPropertyEntries entries;
+ if (cmProp linkOptions = this->GetProperty("STATIC_LIBRARY_OPTIONS")) {
+ std::vector<std::string> options = cmExpandedList(*linkOptions);
for (const auto& option : options) {
- std::unique_ptr<TargetPropertyEntry> entry(
- CreateTargetPropertyEntry(option));
- entries.emplace_back(EvaluateTargetPropertyEntry(
- this, config, language, &dagChecker, entry.get()));
+ std::unique_ptr<TargetPropertyEntry> entry =
+ CreateTargetPropertyEntry(option);
+ entries.Entries.emplace_back(EvaluateTargetPropertyEntry(
+ this, config, language, &dagChecker, *entry));
}
}
processOptions(this, entries, result, uniqueOptions, false,
@@ -3793,12 +4227,12 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetStaticLibraryLinkOptions(
namespace {
void processLinkDirectories(cmGeneratorTarget const* tgt,
- std::vector<EvaluatedTargetPropertyEntry>& entries,
+ EvaluatedTargetPropertyEntries& entries,
std::vector<BT<std::string>>& directories,
std::unordered_set<std::string>& uniqueDirectories,
bool debugDirectories)
{
- for (EvaluatedTargetPropertyEntry& entry : entries) {
+ for (EvaluatedTargetPropertyEntry& entry : entries.Entries) {
cmLinkImplItem const& item = entry.LinkImplItem;
std::string const& targetName = item.AsStr();
@@ -3891,18 +4325,18 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDirectories(
}
bool debugDirectories = !this->DebugLinkDirectoriesDone &&
- cmContains(debugProperties, "LINK_DIRECTORIES");
+ cm::contains(debugProperties, "LINK_DIRECTORIES");
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugLinkDirectoriesDone = true;
}
- std::vector<EvaluatedTargetPropertyEntry> entries =
- EvaluateTargetPropertyEntries(this, config, language, &dagChecker,
- this->LinkDirectoriesEntries);
+ EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
+ this, config, language, &dagChecker, this->LinkDirectoriesEntries);
AddInterfaceEntries(this, config, "INTERFACE_LINK_DIRECTORIES", language,
- &dagChecker, entries);
+ &dagChecker, entries,
+ this->GetPolicyStatusCMP0099() != cmPolicies::NEW);
processLinkDirectories(this, entries, result, uniqueDirectories,
debugDirectories);
@@ -3929,18 +4363,19 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDepends(
cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_DEPENDS", nullptr,
nullptr);
- std::vector<EvaluatedTargetPropertyEntry> entries;
- if (const char* linkDepends = this->GetProperty("LINK_DEPENDS")) {
- std::vector<std::string> depends = cmExpandedList(linkDepends);
+ EvaluatedTargetPropertyEntries entries;
+ if (cmProp linkDepends = this->GetProperty("LINK_DEPENDS")) {
+ std::vector<std::string> depends = cmExpandedList(*linkDepends);
for (const auto& depend : depends) {
- std::unique_ptr<TargetPropertyEntry> entry(
- CreateTargetPropertyEntry(depend));
- entries.emplace_back(EvaluateTargetPropertyEntry(
- this, config, language, &dagChecker, entry.get()));
+ std::unique_ptr<TargetPropertyEntry> entry =
+ CreateTargetPropertyEntry(depend);
+ entries.Entries.emplace_back(EvaluateTargetPropertyEntry(
+ this, config, language, &dagChecker, *entry));
}
}
AddInterfaceEntries(this, config, "INTERFACE_LINK_DEPENDS", language,
- &dagChecker, entries);
+ &dagChecker, entries,
+ this->GetPolicyStatusCMP0099() != cmPolicies::NEW);
processOptions(this, entries, result, uniqueOptions, false, "link depends",
OptionsParse::None);
@@ -4090,8 +4525,8 @@ cmGeneratorTarget::Names cmGeneratorTarget::GetLibraryNames(
}
// Check for library version properties.
- const char* version = this->GetProperty("VERSION");
- const char* soversion = this->GetProperty("SOVERSION");
+ cmProp version = this->GetProperty("VERSION");
+ cmProp soversion = this->GetProperty("SOVERSION");
if (!this->HasSOName(config) ||
this->Makefile->IsOn("CMAKE_PLATFORM_NO_VERSIONED_SONAME") ||
this->IsFrameworkOnApple()) {
@@ -4126,17 +4561,18 @@ cmGeneratorTarget::Names cmGeneratorTarget::GetLibraryNames(
targetNames.Real += this->GetFrameworkVersion();
targetNames.Real += "/";
}
- targetNames.Real += targetNames.Base;
- targetNames.SharedObject = targetNames.Real;
+ targetNames.Real += targetNames.Base + suffix;
+ targetNames.SharedObject = targetNames.Real + suffix;
} else {
// The library's soname.
this->ComputeVersionedName(targetNames.SharedObject, prefix,
targetNames.Base, suffix, targetNames.Output,
- soversion);
+ (soversion ? soversion->c_str() : nullptr));
// The library's real name on disk.
this->ComputeVersionedName(targetNames.Real, prefix, targetNames.Base,
- suffix, targetNames.Output, version);
+ suffix, targetNames.Output,
+ (version ? version->c_str() : nullptr));
}
// The import library name.
@@ -4169,10 +4605,13 @@ cmGeneratorTarget::Names cmGeneratorTarget::GetExecutableNames(
// This versioning is supported only for executables and then only
// when the platform supports symbolic links.
#if defined(_WIN32) && !defined(__CYGWIN__)
- const char* version = 0;
+ const char* version = nullptr;
#else
// Check for executable version properties.
- const char* version = this->GetProperty("VERSION");
+ const char* version = nullptr;
+ if (cmProp p = this->GetProperty("VERSION")) {
+ version = p->c_str();
+ }
if (this->GetType() != cmStateEnums::EXECUTABLE ||
this->Makefile->IsOn("XCODE")) {
version = nullptr;
@@ -4302,15 +4741,23 @@ void cmGeneratorTarget::GetFullNameInternal(
outBase += this->GetOutputName(config, artifact);
// Append the per-configuration postfix.
- outBase += configPostfix;
+ // When using Xcode, the postfix should be part of the suffix rather than
+ // the base, because the suffix ends up being used in Xcode's
+ // EXECUTABLE_SUFFIX attribute.
+ if (this->IsFrameworkOnApple() &&
+ GetGlobalGenerator()->GetName() == "Xcode") {
+ targetSuffix = configPostfix.c_str();
+ } else {
+ outBase += configPostfix;
+ }
// Name shared libraries with their version number on some platforms.
- if (const char* soversion = this->GetProperty("SOVERSION")) {
+ if (cmProp soversion = this->GetProperty("SOVERSION")) {
if (this->GetType() == cmStateEnums::SHARED_LIBRARY &&
!isImportedLibraryArtifact &&
this->Makefile->IsOn("CMAKE_SHARED_LIBRARY_NAME_WITH_VERSION")) {
outBase += "-";
- outBase += soversion;
+ outBase += *soversion;
}
}
@@ -4341,8 +4788,8 @@ std::string cmGeneratorTarget::GetPDBOutputName(
props.emplace_back("PDB_NAME");
for (std::string const& p : props) {
- if (const char* outName = this->GetProperty(p)) {
- base = outName;
+ if (cmProp outName = this->GetProperty(p)) {
+ base = *outName;
break;
}
}
@@ -4368,8 +4815,8 @@ std::string cmGeneratorTarget::GetPDBName(const std::string& config) const
props.emplace_back("PDB_NAME");
for (std::string const& p : props) {
- if (const char* outName = this->GetProperty(p)) {
- base = outName;
+ if (cmProp outName = this->GetProperty(p)) {
+ base = *outName;
break;
}
}
@@ -4441,16 +4888,16 @@ cmGeneratorTarget::GetTargetSourceFileFlags(const cmSourceFile* sf) const
} else {
// Handle the MACOSX_PACKAGE_LOCATION property on source files that
// were not listed in one of the other lists.
- if (const char* location = sf->GetProperty("MACOSX_PACKAGE_LOCATION")) {
- flags.MacFolder = location;
+ if (cmProp location = sf->GetProperty("MACOSX_PACKAGE_LOCATION")) {
+ flags.MacFolder = location->c_str();
const bool stripResources =
this->GlobalGenerator->ShouldStripResourcePath(this->Makefile);
- if (strcmp(location, "Resources") == 0) {
+ if (*location == "Resources") {
flags.Type = cmGeneratorTarget::SourceFileTypeResource;
if (stripResources) {
flags.MacFolder = "";
}
- } else if (cmHasLiteralPrefix(location, "Resources/")) {
+ } else if (cmHasLiteralPrefix(*location, "Resources/")) {
flags.Type = cmGeneratorTarget::SourceFileTypeDeepResource;
if (stripResources) {
flags.MacFolder += strlen("Resources/");
@@ -4471,8 +4918,8 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const
this->SourceFileFlagsConstructed = true;
// Process public headers to mark the source files.
- if (const char* files = this->GetProperty("PUBLIC_HEADER")) {
- std::vector<std::string> relFiles = cmExpandedList(files);
+ if (cmProp files = this->GetProperty("PUBLIC_HEADER")) {
+ std::vector<std::string> relFiles = cmExpandedList(*files);
for (std::string const& relFile : relFiles) {
if (cmSourceFile* sf = this->Makefile->GetSource(relFile)) {
SourceFileFlags& flags = this->SourceFlagsMap[sf];
@@ -4484,8 +4931,8 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const
// Process private headers after public headers so that they take
// precedence if a file is listed in both.
- if (const char* files = this->GetProperty("PRIVATE_HEADER")) {
- std::vector<std::string> relFiles = cmExpandedList(files);
+ if (cmProp files = this->GetProperty("PRIVATE_HEADER")) {
+ std::vector<std::string> relFiles = cmExpandedList(*files);
for (std::string const& relFile : relFiles) {
if (cmSourceFile* sf = this->Makefile->GetSource(relFile)) {
SourceFileFlags& flags = this->SourceFlagsMap[sf];
@@ -4496,8 +4943,8 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const
}
// Mark sources listed as resources.
- if (const char* files = this->GetProperty("RESOURCE")) {
- std::vector<std::string> relFiles = cmExpandedList(files);
+ if (cmProp files = this->GetProperty("RESOURCE")) {
+ std::vector<std::string> relFiles = cmExpandedList(*files);
for (std::string const& relFile : relFiles) {
if (cmSourceFile* sf = this->Makefile->GetSource(relFile)) {
SourceFileFlags& flags = this->SourceFlagsMap[sf];
@@ -4524,9 +4971,9 @@ cmGeneratorTarget::GetCompatibleInterfaces(std::string const& config) const
this->GetLinkImplementationClosure(config);
for (cmGeneratorTarget const* li : deps) {
#define CM_READ_COMPATIBLE_INTERFACE(X, x) \
- if (const char* prop = li->GetProperty("COMPATIBLE_INTERFACE_" #X)) { \
+ if (cmProp prop = li->GetProperty("COMPATIBLE_INTERFACE_" #X)) { \
std::vector<std::string> props; \
- cmExpandList(prop, props); \
+ cmExpandList(*prop, props); \
compat.Props##x.insert(props.begin(), props.end()); \
}
CM_READ_COMPATIBLE_INTERFACE(BOOL, Bool)
@@ -4634,12 +5081,12 @@ void checkPropertyConsistency(cmGeneratorTarget const* depender,
const std::string& config, CompatibleType t,
PropertyType* /*unused*/)
{
- const char* prop = dependee->GetProperty(propName);
+ cmProp prop = dependee->GetProperty(propName);
if (!prop) {
return;
}
- std::vector<std::string> props = cmExpandedList(prop);
+ std::vector<std::string> props = cmExpandedList(*prop);
std::string pdir =
cmStrCat(cmSystemTools::GetCMakeRoot(), "/Help/prop_tgt/");
@@ -4720,9 +5167,9 @@ std::string intersect(const std::set<std::string>& s1,
}
void cmGeneratorTarget::CheckPropertyCompatibility(
- cmComputeLinkInformation* info, const std::string& config) const
+ cmComputeLinkInformation& info, const std::string& config) const
{
- const cmComputeLinkInformation::ItemVector& deps = info->GetItems();
+ const cmComputeLinkInformation::ItemVector& deps = info.GetItems();
std::set<std::string> emittedBools;
static const std::string strBool = "COMPATIBLE_INTERFACE_BOOL";
@@ -4793,7 +5240,8 @@ void cmGeneratorTarget::CheckPropertyCompatibility(
std::ostringstream e;
e << "Property \"" << prop << "\" appears in both the " << propsString
<< " property in the dependencies of target \"" << this->GetName()
- << "\". This is not allowed. A property may only require compatibility "
+ << "\". This is not allowed. A property may only require "
+ "compatibility "
"in a boolean interpretation, a numeric minimum, a numeric maximum "
"or a "
"string interpretation, but not a mixture.";
@@ -4868,8 +5316,9 @@ bool getTypedProperty<bool>(cmGeneratorTarget const* tgt,
return tgt->GetPropertyAsBool(prop);
}
- const char* value = tgt->GetProperty(prop);
- return cmIsOn(genexInterpreter->Evaluate(value, prop));
+ cmProp value = tgt->GetProperty(prop);
+ return cmIsOn(
+ genexInterpreter->Evaluate(value ? value->c_str() : nullptr, prop));
}
template <>
@@ -4877,13 +5326,14 @@ const char* getTypedProperty<const char*>(
cmGeneratorTarget const* tgt, const std::string& prop,
cmGeneratorExpressionInterpreter* genexInterpreter)
{
- const char* value = tgt->GetProperty(prop);
+ cmProp value = tgt->GetProperty(prop);
if (genexInterpreter == nullptr) {
- return value;
+ return value ? value->c_str() : nullptr;
}
- return genexInterpreter->Evaluate(value, prop).c_str();
+ return genexInterpreter->Evaluate(value ? value->c_str() : nullptr, prop)
+ .c_str();
}
template <>
@@ -4891,13 +5341,13 @@ std::string getTypedProperty<std::string>(
cmGeneratorTarget const* tgt, const std::string& prop,
cmGeneratorExpressionInterpreter* genexInterpreter)
{
- const char* value = tgt->GetProperty(prop);
+ cmProp value = tgt->GetProperty(prop);
if (genexInterpreter == nullptr) {
- return valueAsString(value);
+ return valueAsString(value ? value->c_str() : nullptr);
}
- return genexInterpreter->Evaluate(value, prop);
+ return genexInterpreter->Evaluate(value ? value->c_str() : nullptr, prop);
}
template <typename PropertyType>
@@ -5042,7 +5492,7 @@ PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt,
PropertyType propContent = getTypedProperty<PropertyType>(tgt, p);
std::vector<std::string> headPropKeys = tgt->GetPropertyKeys();
- const bool explicitlySet = cmContains(headPropKeys, p);
+ const bool explicitlySet = cm::contains(headPropKeys, p);
const bool impliedByUse = tgt->IsNullImpliedByLinkLibraries(p);
assert((impliedByUse ^ explicitlySet) || (!impliedByUse && !explicitlySet));
@@ -5067,10 +5517,11 @@ PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt,
}
std::string interfaceProperty = "INTERFACE_" + p;
- std::unique_ptr<cmGeneratorExpressionInterpreter> genexInterpreter(
- p == "POSITION_INDEPENDENT_CODE" ? new cmGeneratorExpressionInterpreter(
- tgt->GetLocalGenerator(), config, tgt)
- : nullptr);
+ std::unique_ptr<cmGeneratorExpressionInterpreter> genexInterpreter;
+ if (p == "POSITION_INDEPENDENT_CODE") {
+ genexInterpreter = cm::make_unique<cmGeneratorExpressionInterpreter>(
+ tgt->GetLocalGenerator(), config, tgt);
+ }
for (cmGeneratorTarget const* theTarget : deps) {
// An error should be reported if one dependency
@@ -5081,7 +5532,7 @@ PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt,
std::vector<std::string> propKeys = theTarget->GetPropertyKeys();
- const bool ifaceIsSet = cmContains(propKeys, interfaceProperty);
+ const bool ifaceIsSet = cm::contains(propKeys, interfaceProperty);
PropertyType ifacePropContent = getTypedProperty<PropertyType>(
theTarget, interfaceProperty, genexInterpreter.get());
@@ -5174,6 +5625,13 @@ PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt,
return propContent;
}
+bool cmGeneratorTarget::SetDeviceLink(bool deviceLink)
+{
+ bool previous = this->DeviceLink;
+ this->DeviceLink = deviceLink;
+ return previous;
+}
+
bool cmGeneratorTarget::GetLinkInterfaceDependentBoolProperty(
const std::string& p, const std::string& config) const
{
@@ -5217,32 +5675,41 @@ cmComputeLinkInformation* cmGeneratorTarget::GetLinkInformation(
auto i = this->LinkInformation.find(key);
if (i == this->LinkInformation.end()) {
// Compute information for this configuration.
- cmComputeLinkInformation* info =
- new cmComputeLinkInformation(this, config);
- if (!info || !info->Compute()) {
- delete info;
- info = nullptr;
+ auto info = cm::make_unique<cmComputeLinkInformation>(this, config);
+ if (info && !info->Compute()) {
+ info.reset();
}
// Store the information for this configuration.
- cmTargetLinkInformationMap::value_type entry(key, info);
- i = this->LinkInformation.insert(entry).first;
+ i = this->LinkInformation.emplace(key, std::move(info)).first;
- if (info) {
- this->CheckPropertyCompatibility(info, config);
+ if (i->second) {
+ this->CheckPropertyCompatibility(*i->second, config);
}
}
- return i->second;
+ return i->second.get();
}
void cmGeneratorTarget::GetTargetVersion(int& major, int& minor) const
{
int patch;
- this->GetTargetVersion(false, major, minor, patch);
+ this->GetTargetVersion("VERSION", major, minor, patch);
}
-void cmGeneratorTarget::GetTargetVersion(bool soversion, int& major,
- int& minor, int& patch) const
+void cmGeneratorTarget::GetTargetVersionFallback(
+ const std::string& property, const std::string& fallback_property,
+ int& major, int& minor, int& patch) const
+{
+ if (this->GetProperty(property)) {
+ this->GetTargetVersion(property, major, minor, patch);
+ } else {
+ this->GetTargetVersion(fallback_property, major, minor, patch);
+ }
+}
+
+void cmGeneratorTarget::GetTargetVersion(const std::string& property,
+ int& major, int& minor,
+ int& patch) const
{
// Set the default values.
major = 0;
@@ -5251,15 +5718,13 @@ void cmGeneratorTarget::GetTargetVersion(bool soversion, int& major,
assert(this->GetType() != cmStateEnums::INTERFACE_LIBRARY);
- // Look for a VERSION or SOVERSION property.
- const char* prop = soversion ? "SOVERSION" : "VERSION";
- if (const char* version = this->GetProperty(prop)) {
+ if (cmProp version = this->GetProperty(property)) {
// Try to parse the version number and store the results that were
// successfully parsed.
int parsed_major;
int parsed_minor;
int parsed_patch;
- switch (sscanf(version, "%d.%d.%d", &parsed_major, &parsed_minor,
+ switch (sscanf(version->c_str(), "%d.%d.%d", &parsed_major, &parsed_minor,
&parsed_patch)) {
case 3:
patch = parsed_patch;
@@ -5293,8 +5758,8 @@ std::string cmGeneratorTarget::CreateFortranModuleDirectory(
{
std::string mod_dir;
std::string target_mod_dir;
- if (const char* prop = this->GetProperty("Fortran_MODULE_DIRECTORY")) {
- target_mod_dir = prop;
+ if (cmProp prop = this->GetProperty("Fortran_MODULE_DIRECTORY")) {
+ target_mod_dir = *prop;
} else {
std::string const& default_mod_dir =
this->LocalGenerator->GetCurrentBinaryDirectory();
@@ -5325,11 +5790,11 @@ std::string cmGeneratorTarget::GetFrameworkVersion() const
{
assert(this->GetType() != cmStateEnums::INTERFACE_LIBRARY);
- if (const char* fversion = this->GetProperty("FRAMEWORK_VERSION")) {
- return fversion;
+ if (cmProp fversion = this->GetProperty("FRAMEWORK_VERSION")) {
+ return *fversion;
}
- if (const char* tversion = this->GetProperty("VERSION")) {
- return tversion;
+ if (cmProp tversion = this->GetProperty("VERSION")) {
+ return *tversion;
}
return "A";
}
@@ -5365,8 +5830,8 @@ void cmGeneratorTarget::ReportPropertyOrigin(
cmExpandList(debugProp, debugProperties);
}
- bool debugOrigin =
- !this->DebugCompatiblePropertiesDone[p] && cmContains(debugProperties, p);
+ bool debugOrigin = !this->DebugCompatiblePropertiesDone[p] &&
+ cm::contains(debugProperties, p);
if (this->GlobalGenerator->GetConfigureDoneCMP0026()) {
this->DebugCompatiblePropertiesDone[p] = true;
@@ -5383,46 +5848,83 @@ void cmGeneratorTarget::ReportPropertyOrigin(
areport);
}
+bool cmGeneratorTarget::IsLinkLookupScope(std::string const& n,
+ cmLocalGenerator const*& lg) const
+{
+ if (cmHasLiteralPrefix(n, CMAKE_DIRECTORY_ID_SEP)) {
+ cmDirectoryId const dirId = n.substr(sizeof(CMAKE_DIRECTORY_ID_SEP) - 1);
+ if (dirId.String.empty()) {
+ lg = this->LocalGenerator;
+ return true;
+ }
+ if (cmLocalGenerator const* otherLG =
+ this->GlobalGenerator->FindLocalGenerator(dirId)) {
+ lg = otherLG;
+ return true;
+ }
+ }
+ return false;
+}
+
void cmGeneratorTarget::LookupLinkItems(std::vector<std::string> const& names,
cmListFileBacktrace const& bt,
std::vector<cmLinkItem>& items) const
{
+ cmLocalGenerator const* lg = this->LocalGenerator;
for (std::string const& n : names) {
+ if (this->IsLinkLookupScope(n, lg)) {
+ continue;
+ }
+
std::string name = this->CheckCMP0004(n);
if (name == this->GetName() || name.empty()) {
continue;
}
- items.push_back(this->ResolveLinkItem(name, bt));
+ items.push_back(this->ResolveLinkItem(name, bt, lg));
}
}
void cmGeneratorTarget::ExpandLinkItems(
std::string const& prop, std::string const& value, std::string const& config,
cmGeneratorTarget const* headTarget, bool usage_requirements_only,
- std::vector<cmLinkItem>& items, bool& hadHeadSensitiveCondition) const
+ std::vector<cmLinkItem>& items, bool& hadHeadSensitiveCondition,
+ bool& hadContextSensitiveCondition,
+ bool& hadLinkLanguageSensitiveCondition) const
{
+ // Keep this logic in sync with ComputeLinkImplementationLibraries.
cmGeneratorExpression ge;
cmGeneratorExpressionDAGChecker dagChecker(this, prop, nullptr, nullptr);
- // The $<LINK_ONLY> expression may be in a link interface to specify private
- // link dependencies that are otherwise excluded from usage requirements.
+ // The $<LINK_ONLY> expression may be in a link interface to specify
+ // private link dependencies that are otherwise excluded from usage
+ // requirements.
if (usage_requirements_only) {
dagChecker.SetTransitivePropertiesOnly();
}
std::vector<std::string> libs;
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
- cmExpandList(
- cge->Evaluate(this->LocalGenerator, config, headTarget, &dagChecker, this),
- libs);
+ cmExpandList(cge->Evaluate(this->LocalGenerator, config, headTarget,
+ &dagChecker, this, headTarget->LinkerLanguage),
+ libs);
this->LookupLinkItems(libs, cge->GetBacktrace(), items);
hadHeadSensitiveCondition = cge->GetHadHeadSensitiveCondition();
+ hadContextSensitiveCondition = cge->GetHadContextSensitiveCondition();
+ hadLinkLanguageSensitiveCondition =
+ cge->GetHadLinkLanguageSensitiveCondition();
}
cmLinkInterface const* cmGeneratorTarget::GetLinkInterface(
const std::string& config, cmGeneratorTarget const* head) const
{
+ return this->GetLinkInterface(config, head, false);
+}
+
+cmLinkInterface const* cmGeneratorTarget::GetLinkInterface(
+ const std::string& config, cmGeneratorTarget const* head,
+ bool secondPass) const
+{
// Imported targets have their own link interface.
if (this->IsImported()) {
- return this->GetImportLinkInterface(config, head, false);
+ return this->GetImportLinkInterface(config, head, false, secondPass);
}
// Link interfaces are not supported for executables that do not
@@ -5435,6 +5937,10 @@ cmLinkInterface const* cmGeneratorTarget::GetLinkInterface(
// Lookup any existing link interface for this configuration.
cmHeadToLinkInterfaceMap& hm = this->GetHeadToLinkInterfaceMap(config);
+ if (secondPass) {
+ hm.erase(head);
+ }
+
// If the link interface does not depend on the head target
// then return the one we computed first.
if (!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition) {
@@ -5449,7 +5955,7 @@ cmLinkInterface const* cmGeneratorTarget::GetLinkInterface(
if (!iface.AllDone) {
iface.AllDone = true;
if (iface.Exists) {
- this->ComputeLinkInterface(config, iface, head);
+ this->ComputeLinkInterface(config, iface, head, secondPass);
}
}
@@ -5460,6 +5966,13 @@ void cmGeneratorTarget::ComputeLinkInterface(
const std::string& config, cmOptionalLinkInterface& iface,
cmGeneratorTarget const* headTarget) const
{
+ this->ComputeLinkInterface(config, iface, headTarget, false);
+}
+
+void cmGeneratorTarget::ComputeLinkInterface(
+ const std::string& config, cmOptionalLinkInterface& iface,
+ cmGeneratorTarget const* headTarget, bool secondPass) const
+{
if (iface.Explicit) {
if (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->GetType() == cmStateEnums::STATIC_LIBRARY ||
@@ -5471,7 +5984,8 @@ void cmGeneratorTarget::ComputeLinkInterface(
emitted.insert(lib);
}
if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
- cmLinkImplementation const* impl = this->GetLinkImplementation(config);
+ cmLinkImplementation const* impl =
+ this->GetLinkImplementation(config, secondPass);
for (cmLinkImplItem const& lib : impl->Libraries) {
if (emitted.insert(lib).second) {
if (lib.Target) {
@@ -5481,9 +5995,9 @@ void cmGeneratorTarget::ComputeLinkInterface(
}
} else {
// TODO: Recognize shared library file names. Perhaps this
- // should be moved to cmComputeLinkInformation, but that creates
- // a chicken-and-egg problem since this list is needed for its
- // construction.
+ // should be moved to cmComputeLinkInformation, but that
+ // creates a chicken-and-egg problem since this list is needed
+ // for its construction.
}
}
}
@@ -5501,7 +6015,7 @@ void cmGeneratorTarget::ComputeLinkInterface(
if (this->LinkLanguagePropagatesToDependents()) {
// Targets using this archive need its language runtime libraries.
if (cmLinkImplementation const* impl =
- this->GetLinkImplementation(config)) {
+ this->GetLinkImplementation(config, secondPass)) {
iface.Languages = impl->Languages;
}
}
@@ -5518,11 +6032,11 @@ void cmGeneratorTarget::ComputeLinkInterface(
// How many repetitions are needed if this library has cyclic
// dependencies?
std::string propName = cmStrCat("LINK_INTERFACE_MULTIPLICITY", suffix);
- if (const char* config_reps = this->GetProperty(propName)) {
- sscanf(config_reps, "%u", &iface.Multiplicity);
- } else if (const char* reps =
+ if (cmProp config_reps = this->GetProperty(propName)) {
+ sscanf(config_reps->c_str(), "%u", &iface.Multiplicity);
+ } else if (cmProp reps =
this->GetProperty("LINK_INTERFACE_MULTIPLICITY")) {
- sscanf(reps, "%u", &iface.Multiplicity);
+ sscanf(reps->c_str(), "%u", &iface.Multiplicity);
}
}
}
@@ -5544,7 +6058,6 @@ const cmLinkInterfaceLibraries* cmGeneratorTarget::GetLinkInterfaceLibraries(
}
// Lookup any existing link interface for this configuration.
- std::string CONFIG = cmSystemTools::UpperCase(config);
cmHeadToLinkInterfaceMap& hm =
(usage_requirements_only
? this->GetHeadToLinkInterfaceUsageRequirementsMap(config)
@@ -5673,21 +6186,21 @@ bool cmGeneratorTarget::ComputeOutputDir(const std::string& config,
}
// Select an output directory.
- if (const char* config_outdir = this->GetProperty(configProp)) {
+ if (cmProp config_outdir = this->GetProperty(configProp)) {
// Use the user-specified per-configuration output directory.
- out = cmGeneratorExpression::Evaluate(config_outdir, this->LocalGenerator,
+ out = cmGeneratorExpression::Evaluate(*config_outdir, this->LocalGenerator,
config);
// Skip per-configuration subdirectory.
conf.clear();
- } else if (const char* outdir = this->GetProperty(propertyName)) {
+ } else if (cmProp outdir = this->GetProperty(propertyName)) {
// Use the user-specified output directory.
out =
- cmGeneratorExpression::Evaluate(outdir, this->LocalGenerator, config);
+ cmGeneratorExpression::Evaluate(*outdir, this->LocalGenerator, config);
// Skip per-configuration subdirectory if the value contained a
// generator expression.
- if (out != outdir) {
+ if (out != *outdir) {
conf.clear();
}
} else if (this->GetType() == cmStateEnums::EXECUTABLE) {
@@ -5749,21 +6262,21 @@ bool cmGeneratorTarget::ComputePDBOutputDir(const std::string& kind,
}
// Select an output directory.
- if (const char* config_outdir = this->GetProperty(configProp)) {
+ if (cmProp config_outdir = this->GetProperty(configProp)) {
// Use the user-specified per-configuration output directory.
- out = cmGeneratorExpression::Evaluate(config_outdir, this->LocalGenerator,
+ out = cmGeneratorExpression::Evaluate(*config_outdir, this->LocalGenerator,
config);
// Skip per-configuration subdirectory.
conf.clear();
- } else if (const char* outdir = this->GetProperty(propertyName)) {
+ } else if (cmProp outdir = this->GetProperty(propertyName)) {
// Use the user-specified output directory.
out =
- cmGeneratorExpression::Evaluate(outdir, this->LocalGenerator, config);
+ cmGeneratorExpression::Evaluate(*outdir, this->LocalGenerator, config);
// Skip per-configuration subdirectory if the value contained a
// generator expression.
- if (out != outdir) {
+ if (out != *outdir) {
conf.clear();
}
}
@@ -5809,12 +6322,13 @@ bool cmGeneratorTarget::GetRPATH(const std::string& config,
const std::string& prop,
std::string& rpath) const
{
- const char* value = this->GetProperty(prop);
+ cmProp value = this->GetProperty(prop);
if (!value) {
return false;
}
- rpath = cmGeneratorExpression::Evaluate(value, this->LocalGenerator, config);
+ rpath =
+ cmGeneratorExpression::Evaluate(*value, this->LocalGenerator, config);
return true;
}
@@ -5833,7 +6347,7 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
// An explicit list of interface libraries may be set for shared
// libraries and executables that export symbols.
- const char* explicitLibraries = nullptr;
+ cmProp explicitLibraries = nullptr;
std::string linkIfaceProp;
bool const cmp0022NEW = (this->GetPolicyStatusCMP0022() != cmPolicies::OLD &&
this->GetPolicyStatusCMP0022() != cmPolicies::WARN);
@@ -5862,10 +6376,10 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
!this->PolicyWarnedCMP0022) {
// Compare the explicitly set old link interface properties to the
// preferred new link interface property one and warn if different.
- const char* newExplicitLibraries =
+ cmProp newExplicitLibraries =
this->GetProperty("INTERFACE_LINK_LIBRARIES");
if (newExplicitLibraries &&
- strcmp(newExplicitLibraries, explicitLibraries) != 0) {
+ (*newExplicitLibraries != *explicitLibraries)) {
std::ostringstream w;
/* clang-format off */
w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0022) << "\n"
@@ -5874,9 +6388,9 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
linkIfaceProp << " properties."
"\n"
"INTERFACE_LINK_LIBRARIES:\n"
- " " << newExplicitLibraries << "\n" <<
+ " " << *newExplicitLibraries << "\n" <<
linkIfaceProp << ":\n"
- " " << explicitLibraries << "\n";
+ " " << *explicitLibraries << "\n";
/* clang-format on */
this->LocalGenerator->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
this->PolicyWarnedCMP0022 = true;
@@ -5895,9 +6409,11 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
if (explicitLibraries) {
// The interface libraries have been explicitly set.
- this->ExpandLinkItems(linkIfaceProp, explicitLibraries, config, headTarget,
- usage_requirements_only, iface.Libraries,
- iface.HadHeadSensitiveCondition);
+ this->ExpandLinkItems(linkIfaceProp, *explicitLibraries, config,
+ headTarget, usage_requirements_only, iface.Libraries,
+ iface.HadHeadSensitiveCondition,
+ iface.HadContextSensitiveCondition,
+ iface.HadLinkLanguageSensitiveCondition);
} else if (!cmp0022NEW)
// If CMP0022 is NEW then the plain tll signature sets the
// INTERFACE_LINK_LIBRARIES, so if we get here then the project
@@ -5915,11 +6431,15 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
// preferred new link interface property and warn if different.
std::vector<cmLinkItem> ifaceLibs;
static const std::string newProp = "INTERFACE_LINK_LIBRARIES";
- if (const char* newExplicitLibraries = this->GetProperty(newProp)) {
+ if (cmProp newExplicitLibraries = this->GetProperty(newProp)) {
bool hadHeadSensitiveConditionDummy = false;
- this->ExpandLinkItems(newProp, newExplicitLibraries, config,
+ bool hadContextSensitiveConditionDummy = false;
+ bool hadLinkLanguageSensitiveConditionDummy = false;
+ this->ExpandLinkItems(newProp, *newExplicitLibraries, config,
headTarget, usage_requirements_only, ifaceLibs,
- hadHeadSensitiveConditionDummy);
+ hadHeadSensitiveConditionDummy,
+ hadContextSensitiveConditionDummy,
+ hadLinkLanguageSensitiveConditionDummy);
}
if (ifaceLibs != iface.Libraries) {
std::string oldLibraries = cmJoin(impl->Libraries, ";");
@@ -5956,19 +6476,22 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
const cmLinkInterface* cmGeneratorTarget::GetImportLinkInterface(
const std::string& config, cmGeneratorTarget const* headTarget,
- bool usage_requirements_only) const
+ bool usage_requirements_only, bool secondPass) const
{
cmGeneratorTarget::ImportInfo const* info = this->GetImportInfo(config);
if (!info) {
return nullptr;
}
- std::string CONFIG = cmSystemTools::UpperCase(config);
cmHeadToLinkInterfaceMap& hm =
(usage_requirements_only
? this->GetHeadToLinkInterfaceUsageRequirementsMap(config)
: this->GetHeadToLinkInterfaceMap(config));
+ if (secondPass) {
+ hm.erase(headTarget);
+ }
+
// If the link interface does not depend on the head target
// then return the one we computed first.
if (!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition) {
@@ -5982,7 +6505,9 @@ const cmLinkInterface* cmGeneratorTarget::GetImportLinkInterface(
cmExpandList(info->Languages, iface.Languages);
this->ExpandLinkItems(info->LibrariesProp, info->Libraries, config,
headTarget, usage_requirements_only, iface.Libraries,
- iface.HadHeadSensitiveCondition);
+ iface.HadHeadSensitiveCondition,
+ iface.HadContextSensitiveCondition,
+ iface.HadLinkLanguageSensitiveCondition);
std::vector<std::string> deps = cmExpandedList(info->SharedDeps);
this->LookupLinkItems(deps, cmListFileBacktrace(), iface.SharedDeps);
}
@@ -6038,17 +6563,17 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
// Initialize members.
info.NoSOName = false;
- const char* loc = nullptr;
- const char* imp = nullptr;
+ cmProp loc = nullptr;
+ cmProp imp = nullptr;
std::string suffix;
- if (!this->Target->GetMappedConfig(desired_config, &loc, &imp, suffix)) {
+ if (!this->Target->GetMappedConfig(desired_config, loc, imp, suffix)) {
return;
}
// Get the link interface.
{
std::string linkProp = "INTERFACE_LINK_LIBRARIES";
- const char* propertyLibs = this->GetProperty(linkProp);
+ cmProp propertyLibs = this->GetProperty(linkProp);
if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
if (!propertyLibs) {
@@ -6063,12 +6588,12 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
}
if (propertyLibs) {
info.LibrariesProp = linkProp;
- info.Libraries = propertyLibs;
+ info.Libraries = *propertyLibs;
}
}
if (this->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
if (loc) {
- info.LibName = loc;
+ info.LibName = *loc;
}
return;
}
@@ -6078,47 +6603,46 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
// Get the location.
if (loc) {
- info.Location = loc;
+ info.Location = *loc;
} else {
std::string impProp = cmStrCat("IMPORTED_LOCATION", suffix);
- if (const char* config_location = this->GetProperty(impProp)) {
- info.Location = config_location;
- } else if (const char* location = this->GetProperty("IMPORTED_LOCATION")) {
- info.Location = location;
+ if (cmProp config_location = this->GetProperty(impProp)) {
+ info.Location = *config_location;
+ } else if (cmProp location = this->GetProperty("IMPORTED_LOCATION")) {
+ info.Location = *location;
}
}
// Get the soname.
if (this->GetType() == cmStateEnums::SHARED_LIBRARY) {
std::string soProp = cmStrCat("IMPORTED_SONAME", suffix);
- if (const char* config_soname = this->GetProperty(soProp)) {
- info.SOName = config_soname;
- } else if (const char* soname = this->GetProperty("IMPORTED_SONAME")) {
- info.SOName = soname;
+ if (cmProp config_soname = this->GetProperty(soProp)) {
+ info.SOName = *config_soname;
+ } else if (cmProp soname = this->GetProperty("IMPORTED_SONAME")) {
+ info.SOName = *soname;
}
}
// Get the "no-soname" mark.
if (this->GetType() == cmStateEnums::SHARED_LIBRARY) {
std::string soProp = cmStrCat("IMPORTED_NO_SONAME", suffix);
- if (const char* config_no_soname = this->GetProperty(soProp)) {
- info.NoSOName = cmIsOn(config_no_soname);
- } else if (const char* no_soname =
- this->GetProperty("IMPORTED_NO_SONAME")) {
- info.NoSOName = cmIsOn(no_soname);
+ if (cmProp config_no_soname = this->GetProperty(soProp)) {
+ info.NoSOName = cmIsOn(*config_no_soname);
+ } else if (cmProp no_soname = this->GetProperty("IMPORTED_NO_SONAME")) {
+ info.NoSOName = cmIsOn(*no_soname);
}
}
// Get the import library.
if (imp) {
- info.ImportLibrary = imp;
+ info.ImportLibrary = *imp;
} else if (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->IsExecutableWithExports()) {
std::string impProp = cmStrCat("IMPORTED_IMPLIB", suffix);
- if (const char* config_implib = this->GetProperty(impProp)) {
- info.ImportLibrary = config_implib;
- } else if (const char* implib = this->GetProperty("IMPORTED_IMPLIB")) {
- info.ImportLibrary = implib;
+ if (cmProp config_implib = this->GetProperty(impProp)) {
+ info.ImportLibrary = *config_implib;
+ } else if (cmProp implib = this->GetProperty("IMPORTED_IMPLIB")) {
+ info.ImportLibrary = *implib;
}
}
@@ -6126,11 +6650,11 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
{
std::string linkProp =
cmStrCat("IMPORTED_LINK_DEPENDENT_LIBRARIES", suffix);
- if (const char* config_libs = this->GetProperty(linkProp)) {
- info.SharedDeps = config_libs;
- } else if (const char* libs =
+ if (cmProp config_libs = this->GetProperty(linkProp)) {
+ info.SharedDeps = *config_libs;
+ } else if (cmProp libs =
this->GetProperty("IMPORTED_LINK_DEPENDENT_LIBRARIES")) {
- info.SharedDeps = libs;
+ info.SharedDeps = *libs;
}
}
@@ -6138,21 +6662,21 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
if (this->LinkLanguagePropagatesToDependents()) {
std::string linkProp =
cmStrCat("IMPORTED_LINK_INTERFACE_LANGUAGES", suffix);
- if (const char* config_libs = this->GetProperty(linkProp)) {
- info.Languages = config_libs;
- } else if (const char* libs =
+ if (cmProp config_libs = this->GetProperty(linkProp)) {
+ info.Languages = *config_libs;
+ } else if (cmProp libs =
this->GetProperty("IMPORTED_LINK_INTERFACE_LANGUAGES")) {
- info.Languages = libs;
+ info.Languages = *libs;
}
}
// Get information if target is managed assembly.
{
std::string linkProp = "IMPORTED_COMMON_LANGUAGE_RUNTIME";
- if (auto pc = this->GetProperty(linkProp + suffix)) {
- info.Managed = this->CheckManagedType(pc);
- } else if (auto p = this->GetProperty(linkProp)) {
- info.Managed = this->CheckManagedType(p);
+ if (cmProp pc = this->GetProperty(linkProp + suffix)) {
+ info.Managed = this->CheckManagedType(*pc);
+ } else if (cmProp p = this->GetProperty(linkProp)) {
+ info.Managed = this->CheckManagedType(*p);
}
}
@@ -6160,11 +6684,11 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
if (this->GetType() == cmStateEnums::STATIC_LIBRARY) {
std::string linkProp =
cmStrCat("IMPORTED_LINK_INTERFACE_MULTIPLICITY", suffix);
- if (const char* config_reps = this->GetProperty(linkProp)) {
- sscanf(config_reps, "%u", &info.Multiplicity);
- } else if (const char* reps =
+ if (cmProp config_reps = this->GetProperty(linkProp)) {
+ sscanf(config_reps->c_str(), "%u", &info.Multiplicity);
+ } else if (cmProp reps =
this->GetProperty("IMPORTED_LINK_INTERFACE_MULTIPLICITY")) {
- sscanf(reps, "%u", &info.Multiplicity);
+ sscanf(reps->c_str(), "%u", &info.Multiplicity);
}
}
}
@@ -6172,28 +6696,36 @@ void cmGeneratorTarget::ComputeImportInfo(std::string const& desired_config,
cmHeadToLinkInterfaceMap& cmGeneratorTarget::GetHeadToLinkInterfaceMap(
const std::string& config) const
{
- std::string CONFIG = cmSystemTools::UpperCase(config);
- return this->LinkInterfaceMap[CONFIG];
+ return this->LinkInterfaceMap[cmSystemTools::UpperCase(config)];
}
cmHeadToLinkInterfaceMap&
cmGeneratorTarget::GetHeadToLinkInterfaceUsageRequirementsMap(
const std::string& config) const
{
- std::string CONFIG = cmSystemTools::UpperCase(config);
- return this->LinkInterfaceUsageRequirementsOnlyMap[CONFIG];
+ return this
+ ->LinkInterfaceUsageRequirementsOnlyMap[cmSystemTools::UpperCase(config)];
}
const cmLinkImplementation* cmGeneratorTarget::GetLinkImplementation(
const std::string& config) const
{
+ return this->GetLinkImplementation(config, false);
+}
+
+const cmLinkImplementation* cmGeneratorTarget::GetLinkImplementation(
+ const std::string& config, bool secondPass) const
+{
// There is no link implementation for imported targets.
if (this->IsImported()) {
return nullptr;
}
- std::string CONFIG = cmSystemTools::UpperCase(config);
- cmOptionalLinkImplementation& impl = this->LinkImplMap[CONFIG][this];
+ cmOptionalLinkImplementation& impl =
+ this->LinkImplMap[cmSystemTools::UpperCase(config)][this];
+ if (secondPass) {
+ impl = cmOptionalLinkImplementation();
+ }
if (!impl.LibrariesDone) {
impl.LibrariesDone = true;
this->ComputeLinkImplementationLibraries(config, impl, this);
@@ -6330,6 +6862,21 @@ std::string cmGeneratorTarget::CheckCMP0004(std::string const& item) const
return lib;
}
+bool cmGeneratorTarget::IsDeprecated() const
+{
+ cmProp deprecation = this->GetProperty("DEPRECATION");
+ return deprecation && !deprecation->empty();
+}
+
+std::string cmGeneratorTarget::GetDeprecation() const
+{
+ // find DEPRECATION property
+ if (cmProp deprecation = this->GetProperty("DEPRECATION")) {
+ return *deprecation;
+ }
+ return std::string();
+}
+
void cmGeneratorTarget::GetLanguages(std::set<std::string>& languages,
const std::string& config) const
{
@@ -6379,13 +6926,12 @@ bool cmGeneratorTarget::IsCSharpOnly() const
this->GetType() != cmStateEnums::EXECUTABLE) {
return false;
}
- std::set<std::string> languages;
- this->GetLanguages(languages, "");
+ std::set<std::string> languages = this->GetAllConfigCompileLanguages();
// Consider an explicit linker language property, but *not* the
// computed linker language that may depend on linked targets.
- const char* linkLang = this->GetProperty("LINKER_LANGUAGE");
- if (linkLang && *linkLang) {
- languages.insert(linkLang);
+ cmProp linkLang = this->GetProperty("LINKER_LANGUAGE");
+ if (linkLang && !linkLang->empty()) {
+ languages.insert(*linkLang);
}
return languages.size() == 1 && languages.count("CSharp") > 0;
}
@@ -6435,8 +6981,8 @@ cmGeneratorTarget::GetLinkImplementationLibrariesInternal(
}
// Populate the link implementation libraries for this configuration.
- std::string CONFIG = cmSystemTools::UpperCase(config);
- HeadToLinkImplementationMap& hm = this->LinkImplMap[CONFIG];
+ HeadToLinkImplementationMap& hm =
+ this->LinkImplMap[cmSystemTools::UpperCase(config)];
// If the link implementation does not depend on the head target
// then return the one we computed first.
@@ -6455,13 +7001,14 @@ cmGeneratorTarget::GetLinkImplementationLibrariesInternal(
bool cmGeneratorTarget::IsNullImpliedByLinkLibraries(
const std::string& p) const
{
- return cmContains(this->LinkImplicitNullProperties, p);
+ return cm::contains(this->LinkImplicitNullProperties, p);
}
void cmGeneratorTarget::ComputeLinkImplementationLibraries(
const std::string& config, cmOptionalLinkImplementation& impl,
cmGeneratorTarget const* head) const
{
+ cmLocalGenerator const* lg = this->LocalGenerator;
cmStringRange entryRange = this->Target->GetLinkImplementationEntries();
cmBacktraceRange btRange = this->Target->GetLinkImplementationBacktraces();
cmBacktraceRange::const_iterator btIt = btRange.begin();
@@ -6470,18 +7017,30 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
end = entryRange.end();
le != end; ++le, ++btIt) {
std::vector<std::string> llibs;
+ // Keep this logic in sync with ExpandLinkItems.
cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_LIBRARIES", nullptr,
nullptr);
cmGeneratorExpression ge(*btIt);
std::unique_ptr<cmCompiledGeneratorExpression> const cge = ge.Parse(*le);
std::string const& evaluated =
- cge->Evaluate(this->LocalGenerator, config, head, &dagChecker);
+ cge->Evaluate(this->LocalGenerator, config, head, &dagChecker, nullptr,
+ this->LinkerLanguage);
cmExpandList(evaluated, llibs);
if (cge->GetHadHeadSensitiveCondition()) {
impl.HadHeadSensitiveCondition = true;
}
+ if (cge->GetHadContextSensitiveCondition()) {
+ impl.HadContextSensitiveCondition = true;
+ }
+ if (cge->GetHadLinkLanguageSensitiveCondition()) {
+ impl.HadLinkLanguageSensitiveCondition = true;
+ }
for (std::string const& lib : llibs) {
+ if (this->IsLinkLookupScope(lib, lg)) {
+ continue;
+ }
+
// Skip entries that resolve to the target itself or are empty.
std::string name = this->CheckCMP0004(lib);
if (name == this->GetName() || name.empty()) {
@@ -6516,7 +7075,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
}
// The entry is meant for this configuration.
- impl.Libraries.emplace_back(this->ResolveLinkItem(name, *btIt),
+ impl.Libraries.emplace_back(this->ResolveLinkItem(name, *btIt, lg),
evaluated != *le);
}
@@ -6553,38 +7112,16 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
cmGeneratorTarget::TargetOrString cmGeneratorTarget::ResolveTargetReference(
std::string const& name) const
{
- cmLocalGenerator const* lg = this->LocalGenerator;
- std::string const* lookupName = &name;
-
- // When target_link_libraries() is called with a LHS target that is
- // not created in the calling directory it adds a directory id suffix
- // that we can use to look up the calling directory. It is that scope
- // in which the item name is meaningful. This case is relatively rare
- // so we allocate a separate string only when the directory id is present.
- std::string::size_type pos = name.find(CMAKE_DIRECTORY_ID_SEP);
- std::string plainName;
- if (pos != std::string::npos) {
- // We will look up the plain name without the directory id suffix.
- plainName = name.substr(0, pos);
-
- // We will look up in the scope of the directory id.
- // If we do not recognize the id then leave the original
- // syntax in place to produce an indicative error later.
- cmDirectoryId const dirId =
- name.substr(pos + sizeof(CMAKE_DIRECTORY_ID_SEP) - 1);
- if (cmLocalGenerator const* otherLG =
- this->GlobalGenerator->FindLocalGenerator(dirId)) {
- lg = otherLG;
- lookupName = &plainName;
- }
- }
+ return this->ResolveTargetReference(name, this->LocalGenerator);
+}
+cmGeneratorTarget::TargetOrString cmGeneratorTarget::ResolveTargetReference(
+ std::string const& name, cmLocalGenerator const* lg) const
+{
TargetOrString resolved;
- if (cmGeneratorTarget* tgt = lg->FindGeneratorTargetToUse(*lookupName)) {
+ if (cmGeneratorTarget* tgt = lg->FindGeneratorTargetToUse(name)) {
resolved.Target = tgt;
- } else if (lookupName == &plainName) {
- resolved.String = std::move(plainName);
} else {
resolved.String = name;
}
@@ -6595,10 +7132,30 @@ cmGeneratorTarget::TargetOrString cmGeneratorTarget::ResolveTargetReference(
cmLinkItem cmGeneratorTarget::ResolveLinkItem(
std::string const& name, cmListFileBacktrace const& bt) const
{
- TargetOrString resolved = this->ResolveTargetReference(name);
+ return this->ResolveLinkItem(name, bt, this->LocalGenerator);
+}
+
+cmLinkItem cmGeneratorTarget::ResolveLinkItem(std::string const& name,
+ cmListFileBacktrace const& bt,
+ cmLocalGenerator const* lg) const
+{
+ TargetOrString resolved = this->ResolveTargetReference(name, lg);
if (!resolved.Target) {
- return cmLinkItem(resolved.String, bt);
+ return cmLinkItem(resolved.String, false, bt);
+ }
+
+ // Check deprecation, issue message with `bt` backtrace.
+ if (resolved.Target->IsDeprecated()) {
+ std::ostringstream w;
+ /* clang-format off */
+ w <<
+ "The library that is being linked to, " << resolved.Target->GetName() <<
+ ", is marked as being deprecated by the owner. The message provided by "
+ "the developer is: \n" << resolved.Target->GetDeprecation() << "\n";
+ /* clang-format on */
+ this->LocalGenerator->GetCMakeInstance()->IssueMessage(
+ MessageType::AUTHOR_WARNING, w.str(), bt);
}
// Skip targets that will not really be linked. This is probably a
@@ -6606,10 +7163,10 @@ cmLinkItem cmGeneratorTarget::ResolveLinkItem(
// within the project.
if (resolved.Target->GetType() == cmStateEnums::EXECUTABLE &&
!resolved.Target->IsExecutableWithExports()) {
- return cmLinkItem(resolved.Target->GetName(), bt);
+ return cmLinkItem(resolved.Target->GetName(), false, bt);
}
- return cmLinkItem(resolved.Target, bt);
+ return cmLinkItem(resolved.Target, false, bt);
}
std::string cmGeneratorTarget::GetPDBDirectory(const std::string& config) const
@@ -6755,8 +7312,8 @@ cmGeneratorTarget::ManagedType cmGeneratorTarget::GetManagedType(
}
// Check for explicitly set clr target property.
- if (auto* clr = this->GetProperty("COMMON_LANGUAGE_RUNTIME")) {
- return this->CheckManagedType(clr);
+ if (cmProp clr = this->GetProperty("COMMON_LANGUAGE_RUNTIME")) {
+ return this->CheckManagedType(*clr);
}
// C# targets are always managed. This language specific check
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 493eafc..ff03914 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -7,6 +7,7 @@
#include <cstddef>
#include <map>
+#include <memory>
#include <set>
#include <string>
#include <unordered_map>
@@ -30,6 +31,8 @@ class cmTarget;
struct cmGeneratorExpressionContext;
struct cmGeneratorExpressionDAGChecker;
+using cmProp = const std::string*;
+
class cmGeneratorTarget
{
public:
@@ -45,7 +48,7 @@ public:
bool IsImported() const;
bool IsImportedGloballyVisible() const;
- const char* GetLocation(const std::string& config) const;
+ const std::string& GetLocation(const std::string& config) const;
std::vector<cmCustomCommand> const& GetPreBuildCommands() const;
std::vector<cmCustomCommand> const& GetPreLinkCommands() const;
@@ -64,7 +67,7 @@ public:
/** Get the location of the target in the build tree with a placeholder
referencing the configuration in the native build system. This
location is suitable for use as the LOCATION target property. */
- const char* GetLocationForBuild() const;
+ const std::string& GetLocationForBuild() const;
cmComputeLinkInformation* GetLinkInformation(
const std::string& config) const;
@@ -75,9 +78,9 @@ public:
std::vector<std::string> GetPropertyKeys() const;
//! Might return a nullptr if the property is not set or invalid
- const char* GetProperty(const std::string& prop) const;
+ cmProp GetProperty(const std::string& prop) const;
//! Always returns a valid pointer
- const char* GetSafeProperty(const std::string& prop) const;
+ std::string const& GetSafeProperty(std::string const& prop) const;
bool GetPropertyAsBool(const std::string& prop) const;
void GetSourceFiles(std::vector<cmSourceFile*>& files,
const std::string& config) const;
@@ -125,7 +128,7 @@ public:
struct AllConfigSource
{
- cmSourceFile const* Source;
+ cmSourceFile* Source;
cmGeneratorTarget::SourceKind Kind;
std::vector<size_t> Configs;
};
@@ -134,6 +137,10 @@ public:
per-source configurations assigned. */
std::vector<AllConfigSource> const& GetAllConfigSources() const;
+ /** Get all languages used to compile sources in any configuration.
+ This excludes the languages of objects from object libraries. */
+ std::set<std::string> GetAllConfigCompileLanguages() const;
+
void GetObjectSources(std::vector<cmSourceFile const*>&,
const std::string& config) const;
const std::string& GetObjectName(cmSourceFile const* file);
@@ -199,6 +206,24 @@ public:
const char* GetLinkInterfaceDependentNumberMaxProperty(
const std::string& p, const std::string& config) const;
+ class DeviceLinkSetter
+ {
+ public:
+ DeviceLinkSetter(cmGeneratorTarget& target)
+ : Target(target)
+ {
+ this->PreviousState = target.SetDeviceLink(true);
+ }
+ ~DeviceLinkSetter() { this->Target.SetDeviceLink(this->PreviousState); };
+
+ private:
+ cmGeneratorTarget& Target;
+ bool PreviousState;
+ };
+
+ bool SetDeviceLink(bool deviceLink);
+ bool IsDeviceLink() const { return this->DeviceLink; }
+
cmLinkInterface const* GetLinkInterface(
const std::string& config, const cmGeneratorTarget* headTarget) const;
void ComputeLinkInterface(const std::string& config,
@@ -245,6 +270,13 @@ public:
std::string GetAppBundleDirectory(const std::string& config,
BundleDirectoryLevel level) const;
+ /** Return whether this target is marked as deprecated by the
+ maintainer */
+ bool IsDeprecated() const;
+
+ /** Returns the deprecation message provided by the maintainer */
+ std::string GetDeprecation() const;
+
/** Return whether this target is an executable Bundle, a framework
or CFBundle on Apple. */
bool IsBundleOnApple() const;
@@ -274,11 +306,12 @@ public:
/** Return the install name directory for the target in the
* install tree. For example: "\@rpath/" or "\@loader_path/". */
- std::string GetInstallNameDirForInstallTree() const;
+ std::string GetInstallNameDirForInstallTree(
+ const std::string& config, const std::string& installPrefix) const;
cmListFileBacktrace GetBacktrace() const;
- std::set<BT<std::string>> const& GetUtilities() const;
+ std::set<BT<std::pair<std::string, bool>>> const& GetUtilities() const;
bool LinkLanguagePropagatesToDependents() const
{
@@ -344,7 +377,6 @@ public:
};
LinkClosure const* GetLinkClosure(const std::string& config) const;
- void ComputeLinkClosure(const std::string& config, LinkClosure& lc) const;
cmLinkImplementation const* GetLinkImplementation(
const std::string& config) const;
@@ -365,9 +397,14 @@ public:
cmGeneratorTarget* Target = nullptr;
};
TargetOrString ResolveTargetReference(std::string const& name) const;
+ TargetOrString ResolveTargetReference(std::string const& name,
+ cmLocalGenerator const* lg) const;
cmLinkItem ResolveLinkItem(std::string const& name,
cmListFileBacktrace const& bt) const;
+ cmLinkItem ResolveLinkItem(std::string const& name,
+ cmListFileBacktrace const& bt,
+ cmLocalGenerator const* lg) const;
// Compute the set of languages compiled by the target. This is
// computed every time it is called because the languages can change
@@ -404,6 +441,8 @@ public:
void GetAppleArchs(const std::string& config,
std::vector<std::string>& archVec) const;
+ void AddCUDAArchitectureFlags(std::string& flags) const;
+
std::string GetFeatureSpecificLinkRuleVariable(
std::string const& var, std::string const& lang,
std::string const& config) const;
@@ -461,17 +500,23 @@ public:
const std::string& config, const std::string& language) const;
std::string GetPchHeader(const std::string& config,
- const std::string& language) const;
+ const std::string& language,
+ const std::string& arch = std::string()) const;
std::string GetPchSource(const std::string& config,
- const std::string& language) const;
+ const std::string& language,
+ const std::string& arch = std::string()) const;
std::string GetPchFileObject(const std::string& config,
- const std::string& language);
+ const std::string& language,
+ const std::string& arch = std::string());
std::string GetPchFile(const std::string& config,
- const std::string& language);
- std::string GetPchCreateCompileOptions(const std::string& config,
- const std::string& language);
+ const std::string& language,
+ const std::string& arch = std::string());
+ std::string GetPchCreateCompileOptions(
+ const std::string& config, const std::string& language,
+ const std::string& arch = std::string());
std::string GetPchUseCompileOptions(const std::string& config,
- const std::string& language);
+ const std::string& language,
+ const std::string& arch = std::string());
void AddSourceFileToUnityBatch(const std::string& sourceFilename);
bool IsSourceFilePartOfUnityBatch(const std::string& sourceFilename) const;
@@ -571,6 +616,9 @@ public:
/** Get target file postfix */
std::string GetFilePostfix(const std::string& config) const;
+ /** Get framework multi-config-specific postfix */
+ std::string GetFrameworkMultiConfigPostfix(const std::string& config) const;
+
/** Clears cached meta data for local and external source files.
* The meta data will be recomputed on demand.
*/
@@ -701,7 +749,8 @@ public:
std::string EvaluateInterfaceProperty(
std::string const& prop, cmGeneratorExpressionContext* context,
- cmGeneratorExpressionDAGChecker* dagCheckerParent) const;
+ cmGeneratorExpressionDAGChecker* dagCheckerParent,
+ bool usage_requirements_only = true) const;
bool HaveInstallTreeRPATH(const std::string& config) const;
@@ -736,14 +785,22 @@ public:
void GetTargetVersion(int& major, int& minor) const;
/** Get the target major, minor, and patch version numbers
- interpreted from the VERSION or SOVERSION property. Version 0
+ interpreted from the given property. Version 0
is returned if the property is not set or cannot be parsed. */
- void GetTargetVersion(bool soversion, int& major, int& minor,
+ void GetTargetVersion(std::string const& property, int& major, int& minor,
int& patch) const;
+ /** Get the target major, minor, and patch version numbers
+ interpreted from the given property and if empty use the
+ fallback property. Version 0 is returned if the property is
+ not set or cannot be parsed. */
+ void GetTargetVersionFallback(const std::string& property,
+ const std::string& fallback_property,
+ int& major, int& minor, int& patch) const;
+
std::string GetFortranModuleDirectory(std::string const& working_dir) const;
- const char* GetSourcesProperty() const;
+ const std::string& GetSourcesProperty() const;
private:
void AddSourceCommon(const std::string& src, bool before = false);
@@ -760,6 +817,7 @@ private:
};
using SourceEntriesType = std::map<cmSourceFile const*, SourceEntry>;
SourceEntriesType SourceDepends;
+ mutable std::set<std::string> VisitedConfigsForObjects;
mutable std::map<cmSourceFile const*, std::string> Objects;
std::set<cmSourceFile const*> ExplicitObjectName;
mutable std::map<std::string, std::vector<std::string>> SystemIncludesCache;
@@ -788,8 +846,10 @@ private:
std::string& outPrefix, std::string& outBase,
std::string& outSuffix) const;
+ mutable std::string LinkerLanguage;
using LinkClosureMapType = std::map<std::string, LinkClosure>;
mutable LinkClosureMapType LinkClosureMap;
+ bool DeviceLink = false;
// Returns ARCHIVE, LIBRARY, or RUNTIME based on platform and type.
const char* GetOutputTargetType(cmStateEnums::ArtifactType artifact) const;
@@ -816,12 +876,16 @@ private:
mutable std::map<std::string, CompatibleInterfaces> CompatibleInterfacesMap;
using cmTargetLinkInformationMap =
- std::map<std::string, cmComputeLinkInformation*>;
+ std::map<std::string, std::unique_ptr<cmComputeLinkInformation>>;
mutable cmTargetLinkInformationMap LinkInformation;
- void CheckPropertyCompatibility(cmComputeLinkInformation* info,
+ void CheckPropertyCompatibility(cmComputeLinkInformation& info,
const std::string& config) const;
+ void ComputeLinkClosure(const std::string& config, LinkClosure& lc) const;
+ bool ComputeLinkClosure(const std::string& config, LinkClosure& lc,
+ bool secondPass) const;
+
struct LinkImplClosure : public std::vector<cmGeneratorTarget const*>
{
bool Done = false;
@@ -840,6 +904,17 @@ private:
std::string GetLinkInterfaceDependentStringAsBoolProperty(
const std::string& p, const std::string& config) const;
+ friend class cmTargetCollectLinkLanguages;
+ cmLinkInterface const* GetLinkInterface(const std::string& config,
+ const cmGeneratorTarget* headTarget,
+ bool secondPass) const;
+ void ComputeLinkInterface(const std::string& config,
+ cmOptionalLinkInterface& iface,
+ const cmGeneratorTarget* head,
+ bool secondPass) const;
+ cmLinkImplementation const* GetLinkImplementation(const std::string& config,
+ bool secondPass) const;
+
// Cache import information from properties for each configuration.
struct ImportInfo
{
@@ -866,9 +941,10 @@ private:
the link dependencies of this target. */
std::string CheckCMP0004(std::string const& item) const;
- cmLinkInterface const* GetImportLinkInterface(
- const std::string& config, const cmGeneratorTarget* head,
- bool usage_requirements_only) const;
+ cmLinkInterface const* GetImportLinkInterface(const std::string& config,
+ const cmGeneratorTarget* head,
+ bool usage_requirements_only,
+ bool secondPass = false) const;
using KindedSourcesMapType = std::map<std::string, KindedSources>;
mutable KindedSourcesMapType KindedSourcesMap;
@@ -880,16 +956,20 @@ private:
mutable std::unordered_map<std::string, bool> MaybeInterfacePropertyExists;
bool MaybeHaveInterfaceProperty(std::string const& prop,
- cmGeneratorExpressionContext* context) const;
-
- std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries;
- std::vector<TargetPropertyEntry*> CompileOptionsEntries;
- std::vector<TargetPropertyEntry*> CompileFeaturesEntries;
- std::vector<TargetPropertyEntry*> CompileDefinitionsEntries;
- std::vector<TargetPropertyEntry*> LinkOptionsEntries;
- std::vector<TargetPropertyEntry*> LinkDirectoriesEntries;
- std::vector<TargetPropertyEntry*> PrecompileHeadersEntries;
- std::vector<TargetPropertyEntry*> SourceEntries;
+ cmGeneratorExpressionContext* context,
+ bool usage_requirements_only) const;
+
+ using TargetPropertyEntryVector =
+ std::vector<std::unique_ptr<TargetPropertyEntry>>;
+
+ TargetPropertyEntryVector IncludeDirectoriesEntries;
+ TargetPropertyEntryVector CompileOptionsEntries;
+ TargetPropertyEntryVector CompileFeaturesEntries;
+ TargetPropertyEntryVector CompileDefinitionsEntries;
+ TargetPropertyEntryVector LinkOptionsEntries;
+ TargetPropertyEntryVector LinkDirectoriesEntries;
+ TargetPropertyEntryVector PrecompileHeadersEntries;
+ TargetPropertyEntryVector SourceEntries;
mutable std::set<std::string> LinkImplicitNullProperties;
mutable std::map<std::string, std::string> PchHeaders;
mutable std::map<std::string, std::string> PchSources;
@@ -900,12 +980,17 @@ private:
std::unordered_set<std::string> UnityBatchedSourceFiles;
+ bool IsLinkLookupScope(std::string const& n,
+ cmLocalGenerator const*& lg) const;
+
void ExpandLinkItems(std::string const& prop, std::string const& value,
std::string const& config,
const cmGeneratorTarget* headTarget,
bool usage_requirements_only,
std::vector<cmLinkItem>& items,
- bool& hadHeadSensitiveCondition) const;
+ bool& hadHeadSensitiveCondition,
+ bool& hadContextSensitiveCondition,
+ bool& hadLinkLanguageSensitiveCondition) const;
void LookupLinkItems(std::vector<std::string> const& names,
cmListFileBacktrace const& bt,
std::vector<cmLinkItem>& items) const;
diff --git a/Source/cmGetCMakePropertyCommand.cxx b/Source/cmGetCMakePropertyCommand.cxx
index ff4e312..0480876 100644
--- a/Source/cmGetCMakePropertyCommand.cxx
+++ b/Source/cmGetCMakePropertyCommand.cxx
@@ -23,25 +23,25 @@ bool cmGetCMakePropertyCommand(std::vector<std::string> const& args,
std::string output = "NOTFOUND";
if (args[1] == "VARIABLES") {
- if (const char* varsProp = status.GetMakefile().GetProperty("VARIABLES")) {
- output = varsProp;
+ if (cmProp varsProp = status.GetMakefile().GetProperty("VARIABLES")) {
+ output = *varsProp;
}
} else if (args[1] == "MACROS") {
output.clear();
- if (const char* macrosProp = status.GetMakefile().GetProperty("MACROS")) {
- output = macrosProp;
+ if (cmProp macrosProp = status.GetMakefile().GetProperty("MACROS")) {
+ output = *macrosProp;
}
} else if (args[1] == "COMPONENTS") {
const std::set<std::string>* components =
status.GetMakefile().GetGlobalGenerator()->GetInstallComponents();
output = cmJoin(*components, ";");
} else {
- const char* prop = nullptr;
+ cmProp prop = nullptr;
if (!args[1].empty()) {
prop = status.GetMakefile().GetState()->GetGlobalProperty(args[1]);
}
if (prop) {
- output = prop;
+ output = *prop;
}
}
diff --git a/Source/cmGetDirectoryPropertyCommand.cxx b/Source/cmGetDirectoryPropertyCommand.cxx
index 64438d5..2833977 100644
--- a/Source/cmGetDirectoryPropertyCommand.cxx
+++ b/Source/cmGetDirectoryPropertyCommand.cxx
@@ -7,7 +7,6 @@
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
-#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
namespace {
@@ -37,14 +36,8 @@ bool cmGetDirectoryPropertyCommand(std::vector<std::string> const& args,
"DIRECTORY argument provided without subsequent arguments");
return false;
}
- std::string sd = *i;
- // make sure the start dir is a full path
- if (!cmSystemTools::FileIsFullPath(sd)) {
- sd = cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', *i);
- }
-
- // The local generators are associated with collapsed paths.
- sd = cmSystemTools::CollapseFullPath(sd);
+ std::string sd = cmSystemTools::CollapseFullPath(
+ *i, status.GetMakefile().GetCurrentSourceDirectory());
// lookup the makefile from the directory name
dir = status.GetMakefile().GetGlobalGenerator()->FindMakefile(sd);
@@ -92,7 +85,9 @@ bool cmGetDirectoryPropertyCommand(std::vector<std::string> const& args,
break;
}
}
- prop = dir->GetProperty(*i);
+ if (cmProp p = dir->GetProperty(*i)) {
+ prop = p->c_str();
+ }
}
StoreResult(status.GetMakefile(), variable, prop);
return true;
diff --git a/Source/cmGetFilenameComponentCommand.cxx b/Source/cmGetFilenameComponentCommand.cxx
index 7d91a75..811421a 100644
--- a/Source/cmGetFilenameComponentCommand.cxx
+++ b/Source/cmGetFilenameComponentCommand.cxx
@@ -120,11 +120,11 @@ bool cmGetFilenameComponentCommand(std::vector<std::string> const& args,
if (args.size() >= 4 && args.back() == "CACHE") {
if (!programArgs.empty() && !storeArgs.empty()) {
status.GetMakefile().AddCacheDefinition(
- storeArgs, programArgs.c_str(), "",
+ storeArgs, programArgs, "",
args[2] == "PATH" ? cmStateEnums::FILEPATH : cmStateEnums::STRING);
}
status.GetMakefile().AddCacheDefinition(
- args.front(), result.c_str(), "",
+ args.front(), result, "",
args[2] == "PATH" ? cmStateEnums::FILEPATH : cmStateEnums::STRING);
} else {
if (!programArgs.empty() && !storeArgs.empty()) {
diff --git a/Source/cmGetPipes.cxx b/Source/cmGetPipes.cxx
index 4eda1c5..a5b6469 100644
--- a/Source/cmGetPipes.cxx
+++ b/Source/cmGetPipes.cxx
@@ -2,10 +2,9 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGetPipes.h"
+#include <cm3p/uv.h>
#include <fcntl.h>
-#include "cm_uv.h"
-
#if defined(_WIN32) && !defined(__CYGWIN__)
# include <io.h>
diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx
index 947d893..851f426 100644
--- a/Source/cmGetPropertyCommand.cxx
+++ b/Source/cmGetPropertyCommand.cxx
@@ -11,6 +11,7 @@
#include "cmPolicies.h"
#include "cmProperty.h"
#include "cmPropertyDefinition.h"
+#include "cmSetPropertyCommand.h"
#include "cmSourceFile.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
@@ -48,7 +49,9 @@ bool HandleTargetMode(cmExecutionStatus& status, const std::string& name,
const std::string& propertyName);
bool HandleSourceMode(cmExecutionStatus& status, const std::string& name,
OutType infoType, const std::string& variable,
- const std::string& propertyName);
+ const std::string& propertyName,
+ cmMakefile& directory_makefile,
+ bool source_file_paths_should_be_absolute);
bool HandleTestMode(cmExecutionStatus& status, const std::string& name,
OutType infoType, const std::string& variable,
const std::string& propertyName);
@@ -78,6 +81,11 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args,
std::string name;
std::string propertyName;
+ std::vector<std::string> source_file_directories;
+ std::vector<std::string> source_file_target_directories;
+ bool source_file_directory_option_enabled = false;
+ bool source_file_target_option_enabled = false;
+
// Get the scope from which to get the property.
cmProperty::ScopeType scope;
if (args[1] == "GLOBAL") {
@@ -111,7 +119,9 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args,
DoingNone,
DoingName,
DoingProperty,
- DoingType
+ DoingType,
+ DoingSourceDirectory,
+ DoingSourceTargetDirectory
};
Doing doing = DoingName;
for (unsigned int i = 2; i < args.size(); ++i) {
@@ -132,6 +142,20 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args,
} else if (doing == DoingName) {
doing = DoingNone;
name = args[i];
+ } else if (doing == DoingNone && scope == cmProperty::SOURCE_FILE &&
+ args[i] == "DIRECTORY") {
+ doing = DoingSourceDirectory;
+ source_file_directory_option_enabled = true;
+ } else if (doing == DoingNone && scope == cmProperty::SOURCE_FILE &&
+ args[i] == "TARGET_DIRECTORY") {
+ doing = DoingSourceTargetDirectory;
+ source_file_target_option_enabled = true;
+ } else if (doing == DoingSourceDirectory) {
+ source_file_directories.push_back(args[i]);
+ doing = DoingNone;
+ } else if (doing == DoingSourceTargetDirectory) {
+ source_file_target_directories.push_back(args[i]);
+ doing = DoingNone;
} else if (doing == DoingProperty) {
doing = DoingNone;
propertyName = args[i];
@@ -147,6 +171,16 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args,
return false;
}
+ std::vector<cmMakefile*> source_file_directory_makefiles;
+ bool file_scopes_handled =
+ SetPropertyCommand::HandleAndValidateSourceFileDirectortoryScopes(
+ status, source_file_directory_option_enabled,
+ source_file_target_option_enabled, source_file_directories,
+ source_file_target_directories, source_file_directory_makefiles);
+ if (!file_scopes_handled) {
+ return false;
+ }
+
// Compute requested output.
if (infoType == OutBriefDoc) {
// Lookup brief documentation.
@@ -180,6 +214,11 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args,
}
} else {
// Dispatch property getting.
+ cmMakefile& directory_scope_mf = *(source_file_directory_makefiles[0]);
+ bool source_file_paths_should_be_absolute =
+ source_file_directory_option_enabled ||
+ source_file_target_option_enabled;
+
switch (scope) {
case cmProperty::GLOBAL:
return HandleGlobalMode(status, name, infoType, variable,
@@ -191,8 +230,9 @@ bool cmGetPropertyCommand(std::vector<std::string> const& args,
return HandleTargetMode(status, name, infoType, variable,
propertyName);
case cmProperty::SOURCE_FILE:
- return HandleSourceMode(status, name, infoType, variable,
- propertyName);
+ return HandleSourceMode(status, name, infoType, variable, propertyName,
+ directory_scope_mf,
+ source_file_paths_should_be_absolute);
case cmProperty::TEST:
return HandleTestMode(status, name, infoType, variable, propertyName);
case cmProperty::VARIABLE:
@@ -241,8 +281,9 @@ bool HandleGlobalMode(cmExecutionStatus& status, const std::string& name,
// Get the property.
cmake* cm = status.GetMakefile().GetCMakeInstance();
+ cmProp p = cm->GetState()->GetGlobalProperty(propertyName);
return StoreResult(infoType, status.GetMakefile(), variable,
- cm->GetState()->GetGlobalProperty(propertyName));
+ p ? p->c_str() : nullptr);
}
bool HandleDirectoryMode(cmExecutionStatus& status, const std::string& name,
@@ -256,14 +297,8 @@ bool HandleDirectoryMode(cmExecutionStatus& status, const std::string& name,
if (!name.empty()) {
// Construct the directory name. Interpret relative paths with
// respect to the current directory.
- std::string dir = name;
- if (!cmSystemTools::FileIsFullPath(dir)) {
- dir =
- cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/', name);
- }
-
- // The local generators are associated with collapsed paths.
- dir = cmSystemTools::CollapseFullPath(dir);
+ std::string dir = cmSystemTools::CollapseFullPath(
+ name, status.GetMakefile().GetCurrentSourceDirectory());
// Lookup the generator.
mf = status.GetMakefile().GetGlobalGenerator()->FindMakefile(dir);
@@ -294,8 +329,9 @@ bool HandleDirectoryMode(cmExecutionStatus& status, const std::string& name,
}
// Get the property.
+ cmProp p = mf->GetProperty(propertyName);
return StoreResult(infoType, status.GetMakefile(), variable,
- mf->GetProperty(propertyName));
+ p ? p->c_str() : nullptr);
}
bool HandleTargetMode(cmExecutionStatus& status, const std::string& name,
@@ -315,7 +351,7 @@ bool HandleTargetMode(cmExecutionStatus& status, const std::string& name,
}
return StoreResult(infoType, status.GetMakefile(), variable, nullptr);
}
- const char* prop_cstr = nullptr;
+ cmProp prop_cstr = nullptr;
cmListFileBacktrace bt = status.GetMakefile().GetBacktrace();
cmMessenger* messenger = status.GetMakefile().GetMessenger();
if (cmTargetPropertyComputer::PassesWhitelist(
@@ -325,7 +361,8 @@ bool HandleTargetMode(cmExecutionStatus& status, const std::string& name,
prop_cstr = target->GetProperty(propertyName);
}
}
- return StoreResult(infoType, status.GetMakefile(), variable, prop_cstr);
+ return StoreResult(infoType, status.GetMakefile(), variable,
+ prop_cstr ? prop_cstr->c_str() : nullptr);
}
status.SetError(cmStrCat("could not find TARGET ", name,
". Perhaps it has not yet been created."));
@@ -334,7 +371,9 @@ bool HandleTargetMode(cmExecutionStatus& status, const std::string& name,
bool HandleSourceMode(cmExecutionStatus& status, const std::string& name,
OutType infoType, const std::string& variable,
- const std::string& propertyName)
+ const std::string& propertyName,
+ cmMakefile& directory_makefile,
+ const bool source_file_paths_should_be_absolute)
{
if (name.empty()) {
status.SetError("not given name for SOURCE scope.");
@@ -342,12 +381,17 @@ bool HandleSourceMode(cmExecutionStatus& status, const std::string& name,
}
// Get the source file.
- if (cmSourceFile* sf = status.GetMakefile().GetOrCreateSource(name)) {
+ const std::string source_file_absolute_path =
+ SetPropertyCommand::MakeSourceFilePathAbsoluteIfNeeded(
+ status, name, source_file_paths_should_be_absolute);
+ if (cmSourceFile* sf =
+ directory_makefile.GetOrCreateSource(source_file_absolute_path)) {
return StoreResult(infoType, status.GetMakefile(), variable,
sf->GetPropertyForUser(propertyName));
}
status.SetError(
- cmStrCat("given SOURCE name that could not be found or created: ", name));
+ cmStrCat("given SOURCE name that could not be found or created: ",
+ source_file_absolute_path));
return false;
}
@@ -393,12 +437,13 @@ bool HandleCacheMode(cmExecutionStatus& status, const std::string& name,
return false;
}
- const char* value = nullptr;
+ cmProp value = nullptr;
if (status.GetMakefile().GetState()->GetCacheEntryValue(name)) {
value = status.GetMakefile().GetState()->GetCacheEntryProperty(
name, propertyName);
}
- StoreResult(infoType, status.GetMakefile(), variable, value);
+ StoreResult(infoType, status.GetMakefile(), variable,
+ value ? value->c_str() : nullptr);
return true;
}
diff --git a/Source/cmGetSourceFilePropertyCommand.cxx b/Source/cmGetSourceFilePropertyCommand.cxx
index eefdc6c..5395bc8 100644
--- a/Source/cmGetSourceFilePropertyCommand.cxx
+++ b/Source/cmGetSourceFilePropertyCommand.cxx
@@ -4,35 +4,71 @@
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
+#include "cmSetPropertyCommand.h"
#include "cmSourceFile.h"
bool cmGetSourceFilePropertyCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
- if (args.size() != 3) {
+ std::vector<std::string>::size_type args_size = args.size();
+ if (args_size != 3 && args_size != 5) {
status.SetError("called with incorrect number of arguments");
return false;
}
+
+ std::vector<std::string> source_file_directories;
+ std::vector<std::string> source_file_target_directories;
+ bool source_file_directory_option_enabled = false;
+ bool source_file_target_option_enabled = false;
+
+ int property_arg_index = 2;
+ if (args[2] == "DIRECTORY" && args_size == 5) {
+ property_arg_index = 4;
+ source_file_directory_option_enabled = true;
+ source_file_directories.push_back(args[3]);
+ } else if (args[2] == "TARGET_DIRECTORY" && args_size == 5) {
+ property_arg_index = 4;
+ source_file_target_option_enabled = true;
+ source_file_target_directories.push_back(args[3]);
+ }
+
+ std::vector<cmMakefile*> source_file_directory_makefiles;
+ bool file_scopes_handled =
+ SetPropertyCommand::HandleAndValidateSourceFileDirectortoryScopes(
+ status, source_file_directory_option_enabled,
+ source_file_target_option_enabled, source_file_directories,
+ source_file_target_directories, source_file_directory_makefiles);
+ if (!file_scopes_handled) {
+ return false;
+ }
+
std::string const& var = args[0];
- std::string const& file = args[1];
- cmMakefile& mf = status.GetMakefile();
+ bool source_file_paths_should_be_absolute =
+ source_file_directory_option_enabled || source_file_target_option_enabled;
+ std::string const file =
+ SetPropertyCommand::MakeSourceFilePathAbsoluteIfNeeded(
+ status, args[1], source_file_paths_should_be_absolute);
+ cmMakefile& mf = *source_file_directory_makefiles[0];
cmSourceFile* sf = mf.GetSource(file);
// for the location we must create a source file first
- if (!sf && args[2] == "LOCATION") {
+ if (!sf && args[property_arg_index] == "LOCATION") {
sf = mf.CreateSource(file);
}
+
if (sf) {
const char* prop = nullptr;
- if (!args[2].empty()) {
- prop = sf->GetPropertyForUser(args[2]);
+ if (!args[property_arg_index].empty()) {
+ prop = sf->GetPropertyForUser(args[property_arg_index]);
}
if (prop) {
- mf.AddDefinition(var, prop);
+ // Set the value on the original Makefile scope, not the scope of the
+ // requested directory.
+ status.GetMakefile().AddDefinition(var, prop);
return true;
}
}
- mf.AddDefinition(var, "NOTFOUND");
+ status.GetMakefile().AddDefinition(var, "NOTFOUND");
return true;
}
diff --git a/Source/cmGetTargetPropertyCommand.cxx b/Source/cmGetTargetPropertyCommand.cxx
index 7f5df9c..6b850d1 100644
--- a/Source/cmGetTargetPropertyCommand.cxx
+++ b/Source/cmGetTargetPropertyCommand.cxx
@@ -34,7 +34,7 @@ bool cmGetTargetPropertyCommand(std::vector<std::string> const& args,
prop_exists = true;
}
} else if (!args[2].empty()) {
- const char* prop_cstr = nullptr;
+ cmProp prop_cstr = nullptr;
cmListFileBacktrace bt = mf.GetBacktrace();
cmMessenger* messenger = mf.GetMessenger();
if (cmTargetPropertyComputer::PassesWhitelist(tgt->GetType(), args[2],
@@ -45,7 +45,7 @@ bool cmGetTargetPropertyCommand(std::vector<std::string> const& args,
}
}
if (prop_cstr) {
- prop = prop_cstr;
+ prop = *prop_cstr;
prop_exists = true;
}
}
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
index 8e4352e..a5e496b 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -14,7 +14,7 @@
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGhsMultiGenerator.h"
-#include "cmLinkLineComputer.h"
+#include "cmLinkLineComputer.h" // IWYU pragma: keep
#include "cmLocalGenerator.h"
#include "cmLocalGhsMultiGenerator.h"
#include "cmMakefile.h"
@@ -113,7 +113,7 @@ void cmGhsMultiTargetGenerator::Generate()
// Tell the global generator the name of the project file
this->GeneratorTarget->Target->SetProperty("GENERATOR_FILE_NAME",
- this->Name.c_str());
+ this->Name);
this->GeneratorTarget->Target->SetProperty(
"GENERATOR_FILE_NAME_EXT", GhsMultiGpj::GetGpjTag(this->TagType));
@@ -165,13 +165,15 @@ void cmGhsMultiTargetGenerator::WriteTargetSpecifics(std::ostream& fout,
outpath = this->GeneratorTarget->GetDirectory(config);
outpath =
this->LocalGenerator->MaybeConvertToRelativePath(rootpath, outpath);
- fout << " :binDirRelative=\"" << outpath << "\"" << std::endl;
- fout << " -o \"" << this->TargetNameReal << "\"" << std::endl;
+ /* clang-format off */
+ fout << " :binDirRelative=\"" << outpath << "\"\n"
+ " -o \"" << this->TargetNameReal << "\"\n";
+ /* clang-format on */
}
// set target object file destination
outpath = this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
- fout << " :outputDirRelative=\"" << outpath << "\"" << std::endl;
+ fout << " :outputDirRelative=\"" << outpath << "\"\n";
}
void cmGhsMultiTargetGenerator::SetCompilerFlags(std::string const& config,
@@ -180,15 +182,12 @@ void cmGhsMultiTargetGenerator::SetCompilerFlags(std::string const& config,
auto i = this->FlagsByLanguage.find(language);
if (i == this->FlagsByLanguage.end()) {
std::string flags;
- const char* lang = language.c_str();
-
- this->LocalGenerator->AddLanguageFlags(flags, this->GeneratorTarget, lang,
- config);
-
- this->LocalGenerator->AddCMP0018Flags(flags, this->GeneratorTarget, lang,
- config);
+ this->LocalGenerator->AddLanguageFlags(flags, this->GeneratorTarget,
+ language, config);
+ this->LocalGenerator->AddCMP0018Flags(flags, this->GeneratorTarget,
+ language, config);
this->LocalGenerator->AddVisibilityPresetFlags(
- flags, this->GeneratorTarget, lang);
+ flags, this->GeneratorTarget, language);
// Append old-style preprocessor definition flags.
if (this->Makefile->GetDefineFlags() != " ") {
@@ -197,8 +196,8 @@ void cmGhsMultiTargetGenerator::SetCompilerFlags(std::string const& config,
}
// Add target-specific flags.
- this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget, lang,
- config);
+ this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget,
+ language, config);
std::map<std::string, std::string>::value_type entry(language, flags);
i = this->FlagsByLanguage.insert(entry).first;
@@ -211,13 +210,12 @@ std::string cmGhsMultiTargetGenerator::GetDefines(const std::string& language,
auto i = this->DefinesByLanguage.find(language);
if (i == this->DefinesByLanguage.end()) {
std::set<std::string> defines;
- const char* lang = language.c_str();
// Add preprocessor definitions for this target and configuration.
this->LocalGenerator->GetTargetDefines(this->GeneratorTarget, config,
language, defines);
std::string definesString;
- this->LocalGenerator->JoinDefines(defines, definesString, lang);
+ this->LocalGenerator->JoinDefines(defines, definesString, language);
std::map<std::string, std::string>::value_type entry(language,
definesString);
@@ -235,8 +233,8 @@ void cmGhsMultiTargetGenerator::WriteCompilerFlags(std::ostream& fout,
if (!flagsByLangI->second.empty()) {
std::vector<std::string> ghsCompFlags =
cmSystemTools::ParseArguments(flagsByLangI->second);
- for (auto& f : ghsCompFlags) {
- fout << " " << f << std::endl;
+ for (const std::string& f : ghsCompFlags) {
+ fout << " " << f << '\n';
}
}
}
@@ -249,7 +247,7 @@ void cmGhsMultiTargetGenerator::WriteCompilerDefinitions(
this->GeneratorTarget->GetCompileDefinitions(compileDefinitions, config,
language);
for (std::string const& compileDefinition : compileDefinitions) {
- fout << " -D" << compileDefinition << std::endl;
+ fout << " -D" << compileDefinition << '\n';
}
}
@@ -262,7 +260,7 @@ void cmGhsMultiTargetGenerator::WriteIncludes(std::ostream& fout,
language, config);
for (std::string const& include : includes) {
- fout << " -I\"" << include << "\"" << std::endl;
+ fout << " -I\"" << include << "\"\n";
}
}
@@ -279,10 +277,10 @@ void cmGhsMultiTargetGenerator::WriteTargetLinkLine(std::ostream& fout,
std::string frameworkPath;
std::string linkPath;
- std::unique_ptr<cmLinkLineComputer> linkLineComputer(
+ std::unique_ptr<cmLinkLineComputer> linkLineComputer =
this->GetGlobalGenerator()->CreateLinkLineComputer(
this->LocalGenerator,
- this->LocalGenerator->GetStateSnapshot().GetDirectory()));
+ this->LocalGenerator->GetStateSnapshot().GetDirectory());
this->LocalGenerator->GetTargetFlags(
linkLineComputer.get(), config, linkLibraries, flags, linkFlags,
@@ -290,15 +288,15 @@ void cmGhsMultiTargetGenerator::WriteTargetLinkLine(std::ostream& fout,
// write out link options
std::vector<std::string> lopts = cmSystemTools::ParseArguments(linkFlags);
- for (auto& l : lopts) {
- fout << " " << l << std::endl;
+ for (const std::string& l : lopts) {
+ fout << " " << l << '\n';
}
// write out link search paths
// must be quoted for paths that contain spaces
std::vector<std::string> lpath = cmSystemTools::ParseArguments(linkPath);
- for (auto& l : lpath) {
- fout << " -L\"" << l << "\"" << std::endl;
+ for (const std::string& l : lpath) {
+ fout << " -L\"" << l << "\"\n";
}
// write out link libs
@@ -307,12 +305,12 @@ void cmGhsMultiTargetGenerator::WriteTargetLinkLine(std::ostream& fout,
std::vector<std::string> llibs =
cmSystemTools::ParseArguments(linkLibraries);
- for (auto& l : llibs) {
+ for (const std::string& l : llibs) {
if (l.compare(0, 2, "-l") == 0) {
- fout << " \"" << l << "\"" << std::endl;
+ fout << " \"" << l << "\"\n";
} else {
std::string rl = cmSystemTools::CollapseFullPath(l, cbd);
- fout << " -l\"" << rl << "\"" << std::endl;
+ fout << " -l\"" << rl << "\"\n";
}
}
}
@@ -353,13 +351,12 @@ void cmGhsMultiTargetGenerator::WriteBuildEventsHelper(
this->WriteCustomCommandsHelper(f, ccg);
f.Close();
if (this->TagType != GhsMultiGpj::CUSTOM_TARGET) {
- fout << " :" << cmd << "=\"" << fname << "\"" << std::endl;
+ fout << " :" << cmd << "=\"" << fname << "\"\n";
} else {
- fout << fname << std::endl;
- fout << " :outputName=\"" << fname << ".rule\"" << std::endl;
+ fout << fname << "\n :outputName=\"" << fname << ".rule\"\n";
}
for (auto& byp : ccg.GetByproducts()) {
- fout << " :extraOutputFile=\"" << byp << "\"" << std::endl;
+ fout << " :extraOutputFile=\"" << byp << "\"\n";
}
}
}
@@ -451,8 +448,7 @@ void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper(
// push back the custom commands
for (auto const& c : cmdLines) {
- fout << c << std::endl;
- fout << check_error << std::endl;
+ fout << c << '\n' << check_error << '\n';
}
}
@@ -460,11 +456,11 @@ void cmGhsMultiTargetGenerator::WriteSourceProperty(
std::ostream& fout, const cmSourceFile* sf, std::string const& propName,
std::string const& propFlag)
{
- const char* prop = sf->GetProperty(propName);
+ cmProp prop = sf->GetProperty(propName);
if (prop) {
- std::vector<std::string> list = cmExpandedList(prop);
- for (auto& p : list) {
- fout << " " << propFlag << p << std::endl;
+ std::vector<std::string> list = cmExpandedList(*prop);
+ for (const std::string& p : list) {
+ fout << " " << propFlag << p << '\n';
}
}
}
@@ -483,7 +479,7 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
/* for each source file assign it to its group */
std::map<std::string, std::vector<cmSourceFile*>> groupFiles;
std::set<std::string> groupNames;
- for (auto& sf : sources) {
+ for (cmSourceFile* sf : sources) {
cmSourceGroup* sourceGroup =
this->Makefile->FindSourceGroup(sf->ResolveFullPath(), sourceGroups);
std::string gn = sourceGroup->GetFullName();
@@ -553,8 +549,8 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
*/
for (auto& sg : groupFilesList) {
std::ostream* fout;
- bool useProjectFile =
- cmIsOn(this->GeneratorTarget->GetProperty("GHS_NO_SOURCE_GROUP_FILE")) ||
+ bool useProjectFile = cmIsOn(*this->GeneratorTarget->GetProperty(
+ "GHS_NO_SOURCE_GROUP_FILE")) ||
cmIsOn(this->Makefile->GetDefinition("CMAKE_GHS_NO_SOURCE_GROUP_FILE"));
if (useProjectFile || sg.empty()) {
fout = &fout_proj;
@@ -579,12 +575,12 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
if (useProjectFile) {
if (sg.empty()) {
- *fout << "{comment} Others" << std::endl;
+ *fout << "{comment} Others" << '\n';
} else {
- *fout << "{comment} " << sg << std::endl;
+ *fout << "{comment} " << sg << '\n';
}
} else if (sg.empty()) {
- *fout << "{comment} Others" << std::endl;
+ *fout << "{comment} Others\n";
}
if (sg != "CMake Rules") {
@@ -612,7 +608,7 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
compile = false;
}
- *fout << comment << fname << std::endl;
+ *fout << comment << fname << '\n';
if (compile) {
if ("ld" != si->GetExtension() && "int" != si->GetExtension() &&
"bsp" != si->GetExtension()) {
@@ -628,7 +624,7 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
std::string objectName = this->GeneratorTarget->GetObjectName(si);
if (!objectName.empty() &&
this->GeneratorTarget->HasExplicitObjectName(si)) {
- *fout << " -o " << objectName << std::endl;
+ *fout << " -o " << objectName << '\n';
}
}
}
@@ -695,14 +691,14 @@ void cmGhsMultiTargetGenerator::WriteCustomCommandLine(
*/
bool specifyExtra = true;
for (auto& out : ccg.GetOutputs()) {
- fout << fname << std::endl;
- fout << " :outputName=\"" << out << "\"" << std::endl;
+ fout << fname << '\n';
+ fout << " :outputName=\"" << out << "\"\n";
if (specifyExtra) {
for (auto& byp : ccg.GetByproducts()) {
- fout << " :extraOutputFile=\"" << byp << "\"" << std::endl;
+ fout << " :extraOutputFile=\"" << byp << "\"\n";
}
for (auto& dep : ccg.GetDepends()) {
- fout << " :depends=\"" << dep << "\"" << std::endl;
+ fout << " :depends=\"" << dep << "\"\n";
}
specifyExtra = false;
}
@@ -712,25 +708,25 @@ void cmGhsMultiTargetGenerator::WriteCustomCommandLine(
void cmGhsMultiTargetGenerator::WriteObjectLangOverride(
std::ostream& fout, const cmSourceFile* sourceFile)
{
- const char* rawLangProp = sourceFile->GetProperty("LANGUAGE");
+ cmProp rawLangProp = sourceFile->GetProperty("LANGUAGE");
if (nullptr != rawLangProp) {
- std::string sourceLangProp(rawLangProp);
+ std::string sourceLangProp(*rawLangProp);
std::string const& extension = sourceFile->GetExtension();
if ("CXX" == sourceLangProp && ("c" == extension || "C" == extension)) {
- fout << " -dotciscxx" << std::endl;
+ fout << " -dotciscxx\n";
}
}
}
bool cmGhsMultiTargetGenerator::DetermineIfIntegrityApp()
{
- const char* p = this->GeneratorTarget->GetProperty("ghs_integrity_app");
+ cmProp p = this->GeneratorTarget->GetProperty("ghs_integrity_app");
if (p) {
- return cmIsOn(this->GeneratorTarget->GetProperty("ghs_integrity_app"));
+ return cmIsOn(*p);
}
std::vector<cmSourceFile*> sources;
this->GeneratorTarget->GetSourceFiles(sources, this->ConfigName);
- for (auto& sf : sources) {
+ for (const cmSourceFile* sf : sources) {
if ("int" == sf->GetExtension()) {
return true;
}
diff --git a/Source/cmGlobVerificationManager.cxx b/Source/cmGlobVerificationManager.cxx
index 4817773..9ac5cd5 100644
--- a/Source/cmGlobVerificationManager.cxx
+++ b/Source/cmGlobVerificationManager.cxx
@@ -38,6 +38,8 @@ bool cmGlobVerificationManager::SaveVerificationScript(const std::string& path)
<< cmVersion::GetMajorVersion() << "."
<< cmVersion::GetMinorVersion() << "\n";
+ verifyScriptFile << "cmake_policy(SET CMP0009 NEW)\n";
+
for (auto const& i : this->Cache) {
CacheEntryKey k = std::get<0>(i);
CacheEntryValue v = std::get<1>(i);
diff --git a/Source/cmGlobalBorlandMakefileGenerator.cxx b/Source/cmGlobalBorlandMakefileGenerator.cxx
index 51d681d..06943e7 100644
--- a/Source/cmGlobalBorlandMakefileGenerator.cxx
+++ b/Source/cmGlobalBorlandMakefileGenerator.cxx
@@ -2,6 +2,10 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalBorlandMakefileGenerator.h"
+#include <utility>
+
+#include <cm/memory>
+
#include "cmDocumentationEntry.h"
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
@@ -35,15 +39,14 @@ void cmGlobalBorlandMakefileGenerator::EnableLanguage(
}
//! Create a local generator appropriate to this Global Generator
-cmLocalGenerator* cmGlobalBorlandMakefileGenerator::CreateLocalGenerator(
- cmMakefile* mf)
+std::unique_ptr<cmLocalGenerator>
+cmGlobalBorlandMakefileGenerator::CreateLocalGenerator(cmMakefile* mf)
{
- cmLocalUnixMakefileGenerator3* lg =
- new cmLocalUnixMakefileGenerator3(this, mf);
+ auto lg = cm::make_unique<cmLocalUnixMakefileGenerator3>(this, mf);
lg->SetMakefileVariableSize(32);
lg->SetMakeCommandEscapeTargetTwice(true);
lg->SetBorlandMakeCurlyHack(true);
- return lg;
+ return std::unique_ptr<cmLocalGenerator>(std::move(lg));
}
void cmGlobalBorlandMakefileGenerator::GetDocumentation(
diff --git a/Source/cmGlobalBorlandMakefileGenerator.h b/Source/cmGlobalBorlandMakefileGenerator.h
index da04743..3c97955 100644
--- a/Source/cmGlobalBorlandMakefileGenerator.h
+++ b/Source/cmGlobalBorlandMakefileGenerator.h
@@ -4,6 +4,7 @@
#define cmGlobalBorlandMakefileGenerator_h
#include <iosfwd>
+#include <memory>
#include "cmGlobalNMakeMakefileGenerator.h"
@@ -16,10 +17,10 @@ class cmGlobalBorlandMakefileGenerator : public cmGlobalUnixMakefileGenerator3
{
public:
cmGlobalBorlandMakefileGenerator(cmake* cm);
- static cmGlobalGeneratorFactory* NewFactory()
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory()
{
- return new cmGlobalGeneratorSimpleFactory<
- cmGlobalBorlandMakefileGenerator>();
+ return std::unique_ptr<cmGlobalGeneratorFactory>(
+ new cmGlobalGeneratorSimpleFactory<cmGlobalBorlandMakefileGenerator>());
}
//! Get the name for the generator.
@@ -33,7 +34,8 @@ public:
static void GetDocumentation(cmDocumentationEntry& entry);
//! Create a local generator appropriate to this Global Generator
- cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) override;
+ std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
+ cmMakefile* mf) override;
/**
* Try to determine system information such as shared library
@@ -44,6 +46,7 @@ public:
bool AllowNotParallel() const override { return false; }
bool AllowDeleteOnError() const override { return false; }
+ bool CanEscapeOctothorpe() const override { return true; }
protected:
std::vector<GeneratedMakeCommand> GenerateBuildCommand(
diff --git a/Source/cmGlobalCommonGenerator.cxx b/Source/cmGlobalCommonGenerator.cxx
index 9fa4467..f57ef04 100644
--- a/Source/cmGlobalCommonGenerator.cxx
+++ b/Source/cmGlobalCommonGenerator.cxx
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalCommonGenerator.h"
+#include <memory>
#include <utility>
#include "cmGeneratorTarget.h"
@@ -24,15 +25,15 @@ std::map<std::string, cmGlobalCommonGenerator::DirectoryTarget>
cmGlobalCommonGenerator::ComputeDirectoryTargets() const
{
std::map<std::string, DirectoryTarget> dirTargets;
- for (cmLocalGenerator* lg : this->LocalGenerators) {
+ for (const auto& lg : this->LocalGenerators) {
std::string const& currentBinaryDir(
lg->GetStateSnapshot().GetDirectory().GetCurrentBinary());
DirectoryTarget& dirTarget = dirTargets[currentBinaryDir];
- dirTarget.LG = lg;
+ dirTarget.LG = lg.get();
// The directory-level rule should depend on the target-level rules
// for all targets in the directory.
- for (auto gt : lg->GetGeneratorTargets()) {
+ for (const auto& gt : lg->GetGeneratorTargets()) {
cmStateEnums::TargetType const type = gt->GetType();
if (type != cmStateEnums::EXECUTABLE &&
type != cmStateEnums::STATIC_LIBRARY &&
@@ -43,9 +44,9 @@ cmGlobalCommonGenerator::ComputeDirectoryTargets() const
continue;
}
DirectoryTarget::Target t;
- t.GT = gt;
- if (const char* exclude = gt->GetProperty("EXCLUDE_FROM_ALL")) {
- if (cmIsOn(exclude)) {
+ t.GT = gt.get();
+ if (cmProp exclude = gt->GetProperty("EXCLUDE_FROM_ALL")) {
+ if (cmIsOn(*exclude)) {
// This target has been explicitly excluded.
t.ExcludeFromAll = true;
} else {
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 09fb87d..6370ed2 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -7,9 +7,14 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
+#include <functional>
#include <initializer_list>
#include <iterator>
#include <sstream>
+#include <utility>
+
+#include <cm/memory>
+#include <cmext/algorithm>
#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
@@ -31,6 +36,7 @@
#include "cmGeneratorTarget.h"
#include "cmInstallGenerator.h"
#include "cmLinkLineComputer.h"
+#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMSVC60LinkLineComputer.h"
#include "cmMakefile.h"
@@ -46,8 +52,8 @@
#include "cmake.h"
#if !defined(CMAKE_BOOTSTRAP)
-# include "cm_jsoncpp_value.h"
-# include "cm_jsoncpp_writer.h"
+# include <cm3p/json/value.h>
+# include <cm3p/json/writer.h>
# include "cmCryptoHash.h"
# include "cmQtAutoGenGlobalInitializer.h"
@@ -121,6 +127,7 @@ Json::Value cmGlobalGenerator::GetJson() const
{
Json::Value generator = Json::objectValue;
generator["name"] = this->GetName();
+ generator["multiConfig"] = this->IsMultiConfig();
return generator;
}
#endif
@@ -165,7 +172,7 @@ bool cmGlobalGenerator::SetGeneratorPlatform(std::string const& p,
return false;
}
-bool cmGlobalGenerator::SetGeneratorToolset(std::string const& ts,
+bool cmGlobalGenerator::SetGeneratorToolset(std::string const& ts, bool,
cmMakefile* mf)
{
if (ts.empty()) {
@@ -225,7 +232,7 @@ void cmGlobalGenerator::ResolveLanguageCompiler(const std::string& lang,
if (!optional && (path.empty() || !cmSystemTools::FileExists(path))) {
return;
}
- const std::string* cname =
+ cmProp cname =
this->GetCMakeInstance()->GetState()->GetInitializedCacheValue(langComp);
std::string changeVars;
if (cname && !optional) {
@@ -240,11 +247,10 @@ void cmGlobalGenerator::ResolveLanguageCompiler(const std::string& lang,
cmSystemTools::ConvertToUnixSlashes(cnameString);
cmSystemTools::ConvertToUnixSlashes(pathString);
if (cnameString != pathString) {
- const char* cvars =
- this->GetCMakeInstance()->GetState()->GetGlobalProperty(
- "__CMAKE_DELETE_CACHE_CHANGE_VARS_");
+ cmProp cvars = this->GetCMakeInstance()->GetState()->GetGlobalProperty(
+ "__CMAKE_DELETE_CACHE_CHANGE_VARS_");
if (cvars) {
- changeVars += cvars;
+ changeVars += *cvars;
changeVars += ";";
}
changeVars += langComp;
@@ -264,8 +270,8 @@ void cmGlobalGenerator::AddBuildExportSet(cmExportBuildFileGenerator* gen)
void cmGlobalGenerator::AddBuildExportExportSet(
cmExportBuildFileGenerator* gen)
{
- this->BuildExportSets[gen->GetMainExportFileName()] = gen;
this->BuildExportExportSets[gen->GetMainExportFileName()] = gen;
+ this->AddBuildExportSet(gen);
}
bool cmGlobalGenerator::GenerateImportFile(const std::string& file)
@@ -275,13 +281,11 @@ bool cmGlobalGenerator::GenerateImportFile(const std::string& file)
bool result = it->second->GenerateImportFile();
if (!this->ConfigureDoneCMP0026AndCMP0024) {
- for (cmMakefile* m : this->Makefiles) {
+ for (const auto& m : this->Makefiles) {
m->RemoveExportBuildFileGeneratorCMP0024(it->second);
}
}
- delete it->second;
- it->second = nullptr;
this->BuildExportSets.erase(it);
return result;
}
@@ -295,14 +299,18 @@ void cmGlobalGenerator::ForceLinkerLanguages()
bool cmGlobalGenerator::CheckTargetsForMissingSources() const
{
bool failed = false;
- for (cmLocalGenerator* localGen : this->LocalGenerators) {
- for (cmGeneratorTarget* target : localGen->GetGeneratorTargets()) {
+ for (const auto& localGen : this->LocalGenerators) {
+ for (const auto& target : localGen->GetGeneratorTargets()) {
if (target->GetType() == cmStateEnums::TargetType::GLOBAL_TARGET ||
target->GetType() == cmStateEnums::TargetType::INTERFACE_LIBRARY ||
- target->GetType() == cmStateEnums::TargetType::UTILITY ||
- cmIsOn(target->GetProperty("ghs_integrity_app"))) {
+ target->GetType() == cmStateEnums::TargetType::UTILITY) {
continue;
}
+ if (cmProp p = target->GetProperty("ghs_integrity_app")) {
+ if (cmIsOn(*p)) {
+ continue;
+ }
+ }
std::vector<std::string> configs;
target->Makefile->GetConfigurations(configs);
@@ -335,8 +343,8 @@ bool cmGlobalGenerator::CheckTargetsForType() const
return false;
}
bool failed = false;
- for (cmLocalGenerator* generator : this->LocalGenerators) {
- for (cmGeneratorTarget* target : generator->GetGeneratorTargets()) {
+ for (const auto& generator : this->LocalGenerators) {
+ for (const auto& target : generator->GetGeneratorTargets()) {
if (target->GetType() == cmStateEnums::EXECUTABLE &&
target->GetPropertyAsBool("WIN32_EXECUTABLE")) {
std::vector<std::string> const& configs =
@@ -363,18 +371,22 @@ bool cmGlobalGenerator::CheckTargetsForPchCompilePdb() const
return false;
}
bool failed = false;
- for (cmLocalGenerator* generator : this->LocalGenerators) {
- for (cmGeneratorTarget* target : generator->GetGeneratorTargets()) {
+ for (const auto& generator : this->LocalGenerators) {
+ for (const auto& target : generator->GetGeneratorTargets()) {
if (target->GetType() == cmStateEnums::TargetType::GLOBAL_TARGET ||
target->GetType() == cmStateEnums::TargetType::INTERFACE_LIBRARY ||
- target->GetType() == cmStateEnums::TargetType::UTILITY ||
- cmIsOn(target->GetProperty("ghs_integrity_app"))) {
+ target->GetType() == cmStateEnums::TargetType::UTILITY) {
continue;
}
+ if (cmProp p = target->GetProperty("ghs_integrity_app")) {
+ if (cmIsOn(*p)) {
+ continue;
+ }
+ }
- const std::string reuseFrom =
+ std::string const& reuseFrom =
target->GetSafeProperty("PRECOMPILE_HEADERS_REUSE_FROM");
- const std::string compilePdb =
+ std::string const& compilePdb =
target->GetSafeProperty("COMPILE_PDB_NAME");
if (!reuseFrom.empty() && reuseFrom != compilePdb) {
@@ -400,7 +412,7 @@ bool cmGlobalGenerator::IsExportedTargetsFile(
if (it == this->BuildExportSets.end()) {
return false;
}
- return !cmContains(this->BuildExportExportSets, filename);
+ return !cm::contains(this->BuildExportExportSets, filename);
}
// Find the make program for the generator, required for try compiles
@@ -441,8 +453,8 @@ bool cmGlobalGenerator::FindMakeProgram(cmMakefile* mf)
cmSystemTools::GetShortPath(makeProgram, makeProgram);
cmSystemTools::SplitProgramPath(makeProgram, dir, file);
makeProgram = cmStrCat(dir, '/', saveFile);
- mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM", makeProgram.c_str(),
- "make program", cmStateEnums::FILEPATH);
+ mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM", makeProgram, "make program",
+ cmStateEnums::FILEPATH);
}
return true;
}
@@ -526,7 +538,7 @@ void cmGlobalGenerator::EnableLanguage(
if (lang == "NONE") {
this->SetLanguageEnabled("NONE", mf);
} else {
- if (!cmContains(this->LanguagesReady, lang)) {
+ if (!cm::contains(this->LanguagesReady, lang)) {
std::ostringstream e;
e << "The test project needs language " << lang
<< " which is not enabled.";
@@ -650,7 +662,7 @@ void cmGlobalGenerator::EnableLanguage(
// Tell the generator about the toolset, if any.
std::string toolset = mf->GetSafeDefinition("CMAKE_GENERATOR_TOOLSET");
- if (!this->SetGeneratorToolset(toolset, mf)) {
+ if (!this->SetGeneratorToolset(toolset, false, mf)) {
cmSystemTools::SetFatalErrorOccured();
return;
}
@@ -1091,7 +1103,7 @@ void cmGlobalGenerator::SetLanguageEnabledMaps(const std::string& l,
{
// use LanguageToLinkerPreference to detect whether this functions has
// run before
- if (cmContains(this->LanguageToLinkerPreference, l)) {
+ if (cm::contains(this->LanguageToLinkerPreference, l)) {
return;
}
@@ -1199,13 +1211,12 @@ void cmGlobalGenerator::ClearEnabledLanguages()
void cmGlobalGenerator::CreateLocalGenerators()
{
this->LocalGeneratorSearchIndex.clear();
- cmDeleteAll(this->LocalGenerators);
this->LocalGenerators.clear();
this->LocalGenerators.reserve(this->Makefiles.size());
- for (cmMakefile* m : this->Makefiles) {
- cmLocalGenerator* lg = this->CreateLocalGenerator(m);
- this->LocalGenerators.push_back(lg);
- this->IndexLocalGenerator(lg);
+ for (const auto& m : this->Makefiles) {
+ auto lg = this->CreateLocalGenerator(m.get());
+ this->IndexLocalGenerator(lg.get());
+ this->LocalGenerators.push_back(std::move(lg));
}
}
@@ -1221,9 +1232,10 @@ void cmGlobalGenerator::Configure()
snapshot.GetDirectory().SetCurrentBinary(
this->CMakeInstance->GetHomeOutputDirectory());
- cmMakefile* dirMf = new cmMakefile(this, snapshot);
+ auto dirMfu = cm::make_unique<cmMakefile>(this, snapshot);
+ auto dirMf = dirMfu.get();
+ this->Makefiles.push_back(std::move(dirMfu));
dirMf->SetRecursionDepth(this->RecursionDepth);
- this->Makefiles.push_back(dirMf);
this->IndexMakefile(dirMf);
this->BinaryDirectories.insert(
@@ -1241,11 +1253,11 @@ void cmGlobalGenerator::Configure()
std::vector<GlobalTargetInfo> globalTargets;
this->CreateDefaultGlobalTargets(globalTargets);
- for (cmMakefile* mf : this->Makefiles) {
+ for (const auto& mf : this->Makefiles) {
auto& targets = mf->GetTargets();
for (GlobalTargetInfo const& globalTarget : globalTargets) {
targets.emplace(globalTarget.Name,
- this->CreateGlobalTarget(globalTarget, mf));
+ this->CreateGlobalTarget(globalTarget, mf.get()));
}
}
}
@@ -1258,10 +1270,6 @@ void cmGlobalGenerator::Configure()
"number of local generators",
cmStateEnums::INTERNAL);
- // check for link libraries and include directories containing "NOTFOUND"
- // and for infinite loops
- this->CheckTargetProperties();
-
if (this->CMakeInstance->GetWorkingMode() == cmake::NORMAL_MODE) {
std::ostringstream msg;
if (cmSystemTools::GetErrorOccuredFlag()) {
@@ -1284,6 +1292,10 @@ void cmGlobalGenerator::Configure()
void cmGlobalGenerator::CreateGenerationObjects(TargetTypes targetTypes)
{
this->CreateLocalGenerators();
+ // Commit side effects only if we are actually generating
+ if (this->GetConfigureDoneCMP0026()) {
+ this->CheckTargetProperties();
+ }
this->CreateGeneratorTargets(targetTypes);
this->ComputeBuildFileGenerators();
}
@@ -1294,8 +1306,11 @@ void cmGlobalGenerator::CreateImportedGenerationObjects(
{
this->CreateGenerationObjects(ImportedOnly);
auto const mfit =
- std::find(this->Makefiles.begin(), this->Makefiles.end(), mf);
- cmLocalGenerator* lg =
+ std::find_if(this->Makefiles.begin(), this->Makefiles.end(),
+ [mf](const std::unique_ptr<cmMakefile>& item) {
+ return item.get() == mf;
+ });
+ auto& lg =
this->LocalGenerators[std::distance(this->Makefiles.begin(), mfit)];
for (std::string const& t : targets) {
cmGeneratorTarget* gt = lg->FindGeneratorTargetToUse(t);
@@ -1345,16 +1360,51 @@ bool cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const
void cmGlobalGenerator::ComputeBuildFileGenerators()
{
for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i) {
- std::vector<cmExportBuildFileGenerator*> gens =
+ std::vector<std::unique_ptr<cmExportBuildFileGenerator>> const& gens =
this->Makefiles[i]->GetExportBuildFileGenerators();
- for (cmExportBuildFileGenerator* g : gens) {
- g->Compute(this->LocalGenerators[i]);
+ for (std::unique_ptr<cmExportBuildFileGenerator> const& g : gens) {
+ g->Compute(this->LocalGenerators[i].get());
}
}
}
+bool cmGlobalGenerator::UnsupportedVariableIsDefined(const std::string& name,
+ bool supported) const
+{
+ if (!supported && this->Makefiles.front()->GetDefinition(name)) {
+ std::ostringstream e;
+ /* clang-format off */
+ e <<
+ "Generator\n"
+ " " << this->GetName() << "\n"
+ "does not support variable\n"
+ " " << name << "\n"
+ "but it has been specified."
+ ;
+ /* clang-format on */
+ this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ return true;
+ }
+
+ return false;
+}
+
bool cmGlobalGenerator::Compute()
{
+ // Make sure unsupported variables are not used.
+ if (this->UnsupportedVariableIsDefined("CMAKE_DEFAULT_BUILD_TYPE",
+ this->SupportsDefaultBuildType())) {
+ return false;
+ }
+ if (this->UnsupportedVariableIsDefined("CMAKE_CROSS_CONFIGS",
+ this->SupportsCrossConfigs())) {
+ return false;
+ }
+ if (this->UnsupportedVariableIsDefined("CMAKE_DEFAULT_CONFIGS",
+ this->SupportsDefaultConfigs())) {
+ return false;
+ }
+
// Some generators track files replaced during the Generate.
// Start with an empty vector:
this->FilesReplacedDuringGenerate.clear();
@@ -1387,7 +1437,7 @@ bool cmGlobalGenerator::Compute()
}
// Add generator specific helper commands
- for (cmLocalGenerator* localGen : this->LocalGenerators) {
+ for (const auto& localGen : this->LocalGenerators) {
localGen->AddHelperCommands();
}
@@ -1397,16 +1447,16 @@ bool cmGlobalGenerator::Compute()
// on the original cmTarget instance. It accumulates features
// across all configurations. Some refactoring is needed to
// compute a per-config resulta purely during generation.
- for (cmLocalGenerator* localGen : this->LocalGenerators) {
+ for (const auto& localGen : this->LocalGenerators) {
if (!localGen->ComputeTargetCompileFeatures()) {
return false;
}
}
- for (cmLocalGenerator* localGen : this->LocalGenerators) {
+ for (const auto& localGen : this->LocalGenerators) {
cmMakefile* mf = localGen->GetMakefile();
- for (cmInstallGenerator* g : mf->GetInstallGenerators()) {
- if (!g->Compute(localGen)) {
+ for (const auto& g : mf->GetInstallGenerators()) {
+ if (!g->Compute(localGen.get())) {
return false;
}
}
@@ -1416,7 +1466,7 @@ bool cmGlobalGenerator::Compute()
// Trace the dependencies, after that no custom commands should be added
// because their dependencies might not be handled correctly
- for (cmLocalGenerator* localGen : this->LocalGenerators) {
+ for (const auto& localGen : this->LocalGenerators) {
localGen->TraceDependencies();
}
@@ -1428,7 +1478,7 @@ bool cmGlobalGenerator::Compute()
this->ForceLinkerLanguages();
// Compute the manifest of main targets generated.
- for (cmLocalGenerator* localGen : this->LocalGenerators) {
+ for (const auto& localGen : this->LocalGenerators) {
localGen->ComputeTargetManifest();
}
@@ -1445,7 +1495,7 @@ bool cmGlobalGenerator::Compute()
return false;
}
- for (cmLocalGenerator* localGen : this->LocalGenerators) {
+ for (const auto& localGen : this->LocalGenerators) {
localGen->ComputeHomeRelativeOutputPath();
}
@@ -1460,6 +1510,8 @@ void cmGlobalGenerator::Generate()
this->ProcessEvaluationFiles();
+ this->CMakeInstance->UpdateProgress("Generating", 0.1f);
+
// Generate project files
for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i) {
this->SetCurrentMakefile(this->LocalGenerators[i]->GetMakefile());
@@ -1471,8 +1523,9 @@ void cmGlobalGenerator::Generate()
this->LocalGenerators[i]->GenerateTestFiles();
this->CMakeInstance->UpdateProgress(
"Generating",
- (static_cast<float>(i) + 1.0f) /
- static_cast<float>(this->LocalGenerators.size()));
+ 0.1f +
+ 0.9f * (static_cast<float>(i) + 1.0f) /
+ static_cast<float>(this->LocalGenerators.size()));
}
this->SetCurrentMakefile(nullptr);
@@ -1555,40 +1608,42 @@ bool cmGlobalGenerator::QtAutoGen()
bool cmGlobalGenerator::AddAutomaticSources()
{
- for (cmLocalGenerator* lg : this->LocalGenerators) {
+ for (const auto& lg : this->LocalGenerators) {
lg->CreateEvaluationFileOutputs();
- for (cmGeneratorTarget* gt : lg->GetGeneratorTargets()) {
+ for (const auto& gt : lg->GetGeneratorTargets()) {
if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
gt->GetType() == cmStateEnums::UTILITY ||
gt->GetType() == cmStateEnums::GLOBAL_TARGET) {
continue;
}
- lg->AddUnityBuild(gt);
- lg->AddPchDependencies(gt);
+ lg->AddUnityBuild(gt.get());
+ lg->AddPchDependencies(gt.get());
}
}
// The above transformations may have changed the classification of sources.
// Clear the source list and classification cache (KindedSources) of all
// targets so that it will be recomputed correctly by the generators later
// now that the above transformations are done for all targets.
- for (cmLocalGenerator* lg : this->LocalGenerators) {
- for (cmGeneratorTarget* gt : lg->GetGeneratorTargets()) {
+ for (const auto& lg : this->LocalGenerators) {
+ for (const auto& gt : lg->GetGeneratorTargets()) {
gt->ClearSourcesCache();
}
}
return true;
}
-cmLinkLineComputer* cmGlobalGenerator::CreateLinkLineComputer(
+std::unique_ptr<cmLinkLineComputer> cmGlobalGenerator::CreateLinkLineComputer(
cmOutputConverter* outputConverter, cmStateDirectory const& stateDir) const
{
- return new cmLinkLineComputer(outputConverter, stateDir);
+ return cm::make_unique<cmLinkLineComputer>(outputConverter, stateDir);
}
-cmLinkLineComputer* cmGlobalGenerator::CreateMSVC60LinkLineComputer(
+std::unique_ptr<cmLinkLineComputer>
+cmGlobalGenerator::CreateMSVC60LinkLineComputer(
cmOutputConverter* outputConverter, cmStateDirectory const& stateDir) const
{
- return new cmMSVC60LinkLineComputer(outputConverter, stateDir);
+ return std::unique_ptr<cmLinkLineComputer>(
+ cm::make_unique<cmMSVC60LinkLineComputer>(outputConverter, stateDir));
}
void cmGlobalGenerator::FinalizeTargetCompileInfo()
@@ -1597,7 +1652,7 @@ void cmGlobalGenerator::FinalizeTargetCompileInfo()
this->CMakeInstance->GetState()->GetEnabledLanguages();
// Construct per-target generator information.
- for (cmMakefile* mf : this->Makefiles) {
+ for (const auto& mf : this->Makefiles) {
const cmStringRange noconfig_compile_definitions =
mf->GetCompileDefinitionsEntries();
const cmBacktraceRange noconfig_compile_definitions_bts =
@@ -1632,7 +1687,9 @@ void cmGlobalGenerator::FinalizeTargetCompileInfo()
for (std::string const& c : configs) {
std::string defPropName =
cmStrCat("COMPILE_DEFINITIONS_", cmSystemTools::UpperCase(c));
- t->AppendProperty(defPropName, mf->GetProperty(defPropName));
+ if (cmProp val = mf->GetProperty(defPropName)) {
+ t->AppendProperty(defPropName, *val);
+ }
}
}
}
@@ -1661,8 +1718,7 @@ void cmGlobalGenerator::CreateGeneratorTargets(
if (targetTypes == AllTargets) {
for (auto& target : mf->GetTargets()) {
cmTarget* t = &target.second;
- cmGeneratorTarget* gt = new cmGeneratorTarget(t, lg);
- lg->AddGeneratorTarget(gt);
+ lg->AddGeneratorTarget(cm::make_unique<cmGeneratorTarget>(t, lg));
}
}
@@ -1675,31 +1731,28 @@ void cmGlobalGenerator::CreateGeneratorTargets(TargetTypes targetTypes)
{
std::map<cmTarget*, cmGeneratorTarget*> importedMap;
for (unsigned int i = 0; i < this->Makefiles.size(); ++i) {
- cmMakefile* mf = this->Makefiles[i];
- for (cmTarget* ownedImpTgt : mf->GetOwnedImportedTargets()) {
- cmLocalGenerator* lg = this->LocalGenerators[i];
- cmGeneratorTarget* gt = new cmGeneratorTarget(ownedImpTgt, lg);
- lg->AddOwnedImportedGeneratorTarget(gt);
- importedMap[ownedImpTgt] = gt;
+ auto& mf = this->Makefiles[i];
+ for (const auto& ownedImpTgt : mf->GetOwnedImportedTargets()) {
+ cmLocalGenerator* lg = this->LocalGenerators[i].get();
+ auto gt = cm::make_unique<cmGeneratorTarget>(ownedImpTgt.get(), lg);
+ importedMap[ownedImpTgt.get()] = gt.get();
+ lg->AddOwnedImportedGeneratorTarget(std::move(gt));
}
}
// Construct per-target generator information.
for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i) {
- this->CreateGeneratorTargets(targetTypes, this->Makefiles[i],
- this->LocalGenerators[i], importedMap);
+ this->CreateGeneratorTargets(targetTypes, this->Makefiles[i].get(),
+ this->LocalGenerators[i].get(), importedMap);
}
}
void cmGlobalGenerator::ClearGeneratorMembers()
{
- cmDeleteAll(this->BuildExportSets);
this->BuildExportSets.clear();
- cmDeleteAll(this->Makefiles);
this->Makefiles.clear();
- cmDeleteAll(this->LocalGenerators);
this->LocalGenerators.clear();
this->AliasTargets.clear();
@@ -1722,12 +1775,12 @@ void cmGlobalGenerator::ComputeTargetObjectDirectory(
void cmGlobalGenerator::CheckTargetProperties()
{
+ // check for link libraries and include directories containing "NOTFOUND"
+ // and for infinite loops
std::map<std::string, std::string> notFoundMap;
- // std::set<std::string> notFoundMap;
- // after it is all done do a ConfigureFinalPass
cmState* state = this->GetCMakeInstance()->GetState();
for (unsigned int i = 0; i < this->Makefiles.size(); ++i) {
- this->Makefiles[i]->ConfigureFinalPass();
+ this->Makefiles[i]->Generate(*this->LocalGenerators[i]);
for (auto const& target : this->Makefiles[i]->GetTargets()) {
if (target.second.GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
@@ -1746,14 +1799,13 @@ void cmGlobalGenerator::CheckTargetProperties()
}
}
std::vector<std::string> incs;
- const char* incDirProp =
- target.second.GetProperty("INCLUDE_DIRECTORIES");
+ cmProp incDirProp = target.second.GetProperty("INCLUDE_DIRECTORIES");
if (!incDirProp) {
continue;
}
std::string incDirs = cmGeneratorExpression::Preprocess(
- incDirProp, cmGeneratorExpression::StripAllGeneratorExpressions);
+ *incDirProp, cmGeneratorExpression::StripAllGeneratorExpressions);
cmExpandList(incDirs, incs);
@@ -1771,11 +1823,6 @@ void cmGlobalGenerator::CheckTargetProperties()
}
}
}
- this->CMakeInstance->UpdateProgress(
- "Configuring",
- 0.9f +
- 0.1f * (static_cast<float>(i) + 1.0f) /
- static_cast<float>(this->Makefiles.size()));
}
if (!notFoundMap.empty()) {
@@ -1872,6 +1919,10 @@ int cmGlobalGenerator::Build(
output += "\n";
return 1;
}
+ std::string realConfig = config;
+ if (realConfig.empty()) {
+ realConfig = this->GetDefaultBuildConfig();
+ }
int retVal = 0;
cmSystemTools::SetRunCommandHideConsole(true);
@@ -1880,7 +1931,7 @@ int cmGlobalGenerator::Build(
std::vector<GeneratedMakeCommand> makeCommand =
this->GenerateBuildCommand(makeCommandCSTR, projectName, bindir, targets,
- config, fast, jobs, verbose, nativeOptions);
+ realConfig, fast, jobs, verbose, nativeOptions);
// Workaround to convince some commands to produce output.
if (outputflag == cmSystemTools::OUTPUT_PASSTHROUGH &&
@@ -1892,7 +1943,7 @@ int cmGlobalGenerator::Build(
if (clean) {
std::vector<GeneratedMakeCommand> cleanCommand =
this->GenerateBuildCommand(makeCommandCSTR, projectName, bindir,
- { "clean" }, config, fast, jobs, verbose);
+ { "clean" }, realConfig, fast, jobs, verbose);
output += "\nRun Clean Command:";
output += cleanCommand.front().Printable();
output += "\n";
@@ -1999,16 +2050,15 @@ std::string cmGlobalGenerator::GenerateCMakeBuildCommand(
return makeCommand;
}
-void cmGlobalGenerator::AddMakefile(cmMakefile* mf)
+void cmGlobalGenerator::AddMakefile(std::unique_ptr<cmMakefile> mf)
{
- this->Makefiles.push_back(mf);
- this->IndexMakefile(mf);
+ this->IndexMakefile(mf.get());
+ this->Makefiles.push_back(std::move(mf));
// update progress
// estimate how many lg there will be
- const std::string* numGenC =
- this->CMakeInstance->GetState()->GetInitializedCacheValue(
- "CMAKE_NUMBER_OF_MAKEFILES");
+ cmProp numGenC = this->CMakeInstance->GetState()->GetInitializedCacheValue(
+ "CMAKE_NUMBER_OF_MAKEFILES");
if (!numGenC) {
// If CMAKE_NUMBER_OF_MAKEFILES is not set
@@ -2025,10 +2075,10 @@ void cmGlobalGenerator::AddMakefile(cmMakefile* mf)
}
int numGen = atoi(numGenC->c_str());
- float prog = 0.9f * static_cast<float>(this->Makefiles.size()) /
- static_cast<float>(numGen);
- if (prog > 0.9f) {
- prog = 0.9f;
+ float prog =
+ static_cast<float>(this->Makefiles.size()) / static_cast<float>(numGen);
+ if (prog > 1.0f) {
+ prog = 1.0f;
}
this->CMakeInstance->UpdateProgress("Configuring", prog);
}
@@ -2045,9 +2095,10 @@ void cmGlobalGenerator::EnableInstallTarget()
this->InstallTargetEnabled = true;
}
-cmLocalGenerator* cmGlobalGenerator::CreateLocalGenerator(cmMakefile* mf)
+std::unique_ptr<cmLocalGenerator> cmGlobalGenerator::CreateLocalGenerator(
+ cmMakefile* mf)
{
- return new cmLocalGenerator(this, mf);
+ return cm::make_unique<cmLocalGenerator>(this, mf);
}
void cmGlobalGenerator::EnableLanguagesFromGenerator(cmGlobalGenerator* gen,
@@ -2116,8 +2167,8 @@ bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root,
if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
return true;
}
- if (const char* exclude = target->GetProperty("EXCLUDE_FROM_ALL")) {
- return cmIsOn(exclude);
+ if (cmProp exclude = target->GetProperty("EXCLUDE_FROM_ALL")) {
+ return cmIsOn(*exclude);
}
// This target is included in its directory. Check whether the
// directory is excluded.
@@ -2142,7 +2193,7 @@ int cmGlobalGenerator::GetLinkerPreference(const std::string& lang) const
void cmGlobalGenerator::FillProjectMap()
{
this->ProjectMap.clear(); // make sure we start with a clean map
- for (cmLocalGenerator* localGen : this->LocalGenerators) {
+ for (const auto& localGen : this->LocalGenerators) {
// for each local generator add all projects
cmStateSnapshot snp = localGen->GetStateSnapshot();
std::string name;
@@ -2150,7 +2201,7 @@ void cmGlobalGenerator::FillProjectMap()
std::string snpProjName = snp.GetProjectName();
if (name != snpProjName) {
name = snpProjName;
- this->ProjectMap[name].push_back(localGen);
+ this->ProjectMap[name].push_back(localGen.get());
}
snp = snp.GetBuildsystemDirectoryParent();
} while (snp.IsValid());
@@ -2184,7 +2235,7 @@ void cmGlobalGenerator::AddAlias(const std::string& name,
bool cmGlobalGenerator::IsAlias(const std::string& name) const
{
- return cmContains(this->AliasTargets, name);
+ return cm::contains(this->AliasTargets, name);
}
void cmGlobalGenerator::IndexTarget(cmTarget* t)
@@ -2210,10 +2261,12 @@ std::string cmGlobalGenerator::IndexGeneratorTargetUniquely(
// Use a ":" prefix to avoid conflict with project-defined targets.
// We must satisfy cmGeneratorExpression::IsValidTargetName so use no
// other special characters.
- char buf[1 + sizeof(gt) * 2];
+ constexpr size_t sizeof_ptr =
+ sizeof(gt); // NOLINT(bugprone-sizeof-expression)
+ char buf[1 + sizeof_ptr * 2];
char* b = buf;
*b++ = ':';
- for (size_t i = 0; i < sizeof(gt); ++i) {
+ for (size_t i = 0; i < sizeof_ptr; ++i) {
unsigned char const c = reinterpret_cast<unsigned char const*>(&gt)[i];
*b++ = hexDigits[(c & 0xf0) >> 4];
*b++ = hexDigits[(c & 0x0f)];
@@ -2353,7 +2406,7 @@ void cmGlobalGenerator::CreateDefaultGlobalTargets(
void cmGlobalGenerator::AddGlobalTarget_Package(
std::vector<GlobalTargetInfo>& targets)
{
- cmMakefile* mf = this->Makefiles[0];
+ auto& mf = this->Makefiles[0];
std::string configFile =
cmStrCat(mf->GetCurrentBinaryDirectory(), "/CPackConfig.cmake");
if (!cmSystemTools::FileExists(configFile)) {
@@ -2402,7 +2455,7 @@ void cmGlobalGenerator::AddGlobalTarget_PackageSource(
return;
}
- cmMakefile* mf = this->Makefiles[0];
+ auto& mf = this->Makefiles[0];
std::string configFile =
cmStrCat(mf->GetCurrentBinaryDirectory(), "/CPackSourceConfig.cmake");
if (!cmSystemTools::FileExists(configFile)) {
@@ -2434,7 +2487,7 @@ void cmGlobalGenerator::AddGlobalTarget_PackageSource(
void cmGlobalGenerator::AddGlobalTarget_Test(
std::vector<GlobalTargetInfo>& targets)
{
- cmMakefile* mf = this->Makefiles[0];
+ auto& mf = this->Makefiles[0];
if (!mf->IsOn("CMAKE_TESTING_ENABLED")) {
return;
}
@@ -2454,6 +2507,13 @@ void cmGlobalGenerator::AddGlobalTarget_Test(
cmCustomCommandLine singleLine;
singleLine.push_back(cmSystemTools::GetCTestCommand());
singleLine.push_back("--force-new-ctest-process");
+ if (auto testArgs = mf->GetDefinition("CMAKE_CTEST_ARGUMENTS")) {
+ std::vector<std::string> args;
+ cmExpandList(testArgs, args);
+ for (auto const& arg : args) {
+ singleLine.push_back(arg);
+ }
+ }
if (cmakeCfgIntDir && *cmakeCfgIntDir && cmakeCfgIntDir[0] != '.') {
singleLine.push_back("-C");
singleLine.push_back(cmakeCfgIntDir);
@@ -2475,6 +2535,7 @@ void cmGlobalGenerator::AddGlobalTarget_EditCache(
}
GlobalTargetInfo gti;
gti.Name = editCacheTargetName;
+ gti.PerConfig = false;
cmCustomCommandLine singleLine;
// Use generator preference for the edit_cache rule if it is defined.
@@ -2492,6 +2553,7 @@ void cmGlobalGenerator::AddGlobalTarget_EditCache(
singleLine.push_back("No interactive CMake dialog available.");
gti.Message = "No interactive CMake dialog available...";
gti.UsesTerminal = false;
+ gti.StdPipesUTF8 = true;
}
gti.CommandLines.push_back(std::move(singleLine));
@@ -2509,18 +2571,21 @@ void cmGlobalGenerator::AddGlobalTarget_RebuildCache(
gti.Name = rebuildCacheTargetName;
gti.Message = "Running CMake to regenerate build system...";
gti.UsesTerminal = true;
+ gti.PerConfig = false;
cmCustomCommandLine singleLine;
singleLine.push_back(cmSystemTools::GetCMakeCommand());
+ singleLine.push_back("--regenerate-during-build");
singleLine.push_back("-S$(CMAKE_SOURCE_DIR)");
singleLine.push_back("-B$(CMAKE_BINARY_DIR)");
gti.CommandLines.push_back(std::move(singleLine));
+ gti.StdPipesUTF8 = true;
targets.push_back(std::move(gti));
}
void cmGlobalGenerator::AddGlobalTarget_Install(
std::vector<GlobalTargetInfo>& targets)
{
- cmMakefile* mf = this->Makefiles[0];
+ auto& mf = this->Makefiles[0];
const char* cmakeCfgIntDir = this->GetCMakeCFGIntDir();
bool skipInstallRules = mf->IsOn("CMAKE_SKIP_INSTALL_RULES");
if (this->InstallTargetEnabled && skipInstallRules) {
@@ -2550,6 +2615,7 @@ void cmGlobalGenerator::AddGlobalTarget_Install(
gti.Name = this->GetInstallTargetName();
gti.Message = "Install the project...";
gti.UsesTerminal = true;
+ gti.StdPipesUTF8 = true;
cmCustomCommandLine singleLine;
if (this->GetPreinstallTargetName()) {
gti.Depends.emplace_back(this->GetPreinstallTargetName());
@@ -2570,7 +2636,7 @@ void cmGlobalGenerator::AddGlobalTarget_Install(
singleLine.push_back(cmd);
if (cmakeCfgIntDir && *cmakeCfgIntDir && cmakeCfgIntDir[0] != '.') {
std::string cfgArg = "-DBUILD_TYPE=";
- bool useEPN = this->UseEffectivePlatformName(mf);
+ bool useEPN = this->UseEffectivePlatformName(mf.get());
if (useEPN) {
cfgArg += "$(CONFIGURATION)";
singleLine.push_back(cfgArg);
@@ -2619,13 +2685,13 @@ void cmGlobalGenerator::AddGlobalTarget_Install(
}
}
-const char* cmGlobalGenerator::GetPredefinedTargetsFolder()
+std::string cmGlobalGenerator::GetPredefinedTargetsFolder()
{
- const char* prop = this->GetCMakeInstance()->GetState()->GetGlobalProperty(
+ cmProp prop = this->GetCMakeInstance()->GetState()->GetGlobalProperty(
"PREDEFINED_TARGETS_FOLDER");
if (prop) {
- return prop;
+ return *prop;
}
return "CMakePredefinedTargets";
@@ -2633,13 +2699,13 @@ const char* cmGlobalGenerator::GetPredefinedTargetsFolder()
bool cmGlobalGenerator::UseFolderProperty() const
{
- const char* prop =
+ cmProp prop =
this->GetCMakeInstance()->GetState()->GetGlobalProperty("USE_FOLDERS");
// If this property is defined, let the setter turn this on or off...
//
if (prop) {
- return cmIsOn(prop);
+ return cmIsOn(*prop);
}
// By default, this feature is OFF, since it is not supported in the
@@ -2653,22 +2719,23 @@ cmTarget cmGlobalGenerator::CreateGlobalTarget(GlobalTargetInfo const& gti,
{
// Package
cmTarget target(gti.Name, cmStateEnums::GLOBAL_TARGET,
- cmTarget::VisibilityNormal, mf);
+ cmTarget::VisibilityNormal, mf, gti.PerConfig);
target.SetProperty("EXCLUDE_FROM_ALL", "TRUE");
std::vector<std::string> no_outputs;
std::vector<std::string> no_byproducts;
std::vector<std::string> no_depends;
// Store the custom command in the target.
- cmCustomCommand cc(nullptr, no_outputs, no_byproducts, no_depends,
- gti.CommandLines, nullptr, gti.WorkingDir.c_str());
+ cmCustomCommand cc(no_outputs, no_byproducts, no_depends, gti.CommandLines,
+ cmListFileBacktrace(), nullptr, gti.WorkingDir.c_str(),
+ gti.StdPipesUTF8);
cc.SetUsesTerminal(gti.UsesTerminal);
target.AddPostBuildCommand(std::move(cc));
if (!gti.Message.empty()) {
- target.SetProperty("EchoString", gti.Message.c_str());
+ target.SetProperty("EchoString", gti.Message);
}
for (std::string const& d : gti.Depends) {
- target.AddUtility(d);
+ target.AddUtility(d, false);
}
// Organize in the "predefined targets" folder:
@@ -2733,13 +2800,13 @@ bool cmGlobalGenerator::IsReservedTarget(std::string const& name)
"clean", "edit_cache", "rebuild_cache",
"ZERO_CHECK" };
- return cmContains(reservedTargets, name);
+ return cm::contains(reservedTargets, name);
}
void cmGlobalGenerator::SetExternalMakefileProjectGenerator(
- cmExternalMakefileProjectGenerator* extraGenerator)
+ std::unique_ptr<cmExternalMakefileProjectGenerator> extraGenerator)
{
- this->ExtraGenerator.reset(extraGenerator);
+ this->ExtraGenerator = std::move(extraGenerator);
if (this->ExtraGenerator) {
this->ExtraGenerator->SetGlobalGenerator(this);
}
@@ -2765,27 +2832,26 @@ void cmGlobalGenerator::GetFilesReplacedDuringGenerate(
std::back_inserter(filenames));
}
-void cmGlobalGenerator::GetTargetSets(TargetDependSet& projectTargets,
- TargetDependSet& originalTargets,
- cmLocalGenerator* root,
- GeneratorVector const& generators)
+void cmGlobalGenerator::GetTargetSets(
+ TargetDependSet& projectTargets, TargetDependSet& originalTargets,
+ cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators)
{
// loop over all local generators
- for (cmLocalGenerator* generator : generators) {
+ for (auto generator : generators) {
// check to make sure generator is not excluded
if (this->IsExcluded(root, generator)) {
continue;
}
// loop over all the generator targets in the makefile
- for (cmGeneratorTarget* target : generator->GetGeneratorTargets()) {
- if (this->IsRootOnlyTarget(target) &&
+ for (const auto& target : generator->GetGeneratorTargets()) {
+ if (this->IsRootOnlyTarget(target.get()) &&
target->GetLocalGenerator() != root) {
continue;
}
// put the target in the set of original targets
- originalTargets.insert(target);
+ originalTargets.insert(target.get());
// Get the set of targets that depend on target
- this->AddTargetDepends(target, projectTargets);
+ this->AddTargetDepends(target.get(), projectTargets);
}
}
}
@@ -2961,12 +3027,12 @@ void cmGlobalGenerator::WriteSummary()
"/CMakeFiles/TargetDirectories.txt");
cmGeneratedFileStream fout(fname);
- for (cmLocalGenerator* lg : this->LocalGenerators) {
- for (cmGeneratorTarget* tgt : lg->GetGeneratorTargets()) {
+ for (const auto& lg : this->LocalGenerators) {
+ for (const auto& tgt : lg->GetGeneratorTargets()) {
if (tgt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
- this->WriteSummary(tgt);
+ this->WriteSummary(tgt.get());
fout << tgt->GetSupportDirectory() << "\n";
}
}
@@ -2981,8 +3047,8 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target)
#ifndef CMAKE_BOOTSTRAP
// Check whether labels are enabled for this target.
- const char* targetLabels = target->GetProperty("LABELS");
- const char* directoryLabels =
+ cmProp targetLabels = target->GetProperty("LABELS");
+ cmProp directoryLabels =
target->Target->GetMakefile()->GetProperty("LABELS");
const char* cmakeDirectoryLabels =
target->Target->GetMakefile()->GetDefinition("CMAKE_DIRECTORY_LABELS");
@@ -3001,7 +3067,7 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target)
// List the target-wide labels. All sources in the target get
// these labels.
if (targetLabels) {
- cmExpandList(targetLabels, labels);
+ cmExpandList(*targetLabels, labels);
if (!labels.empty()) {
fout << "# Target labels\n";
for (std::string const& l : labels) {
@@ -3016,7 +3082,7 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target)
std::vector<std::string> cmakeDirectoryLabelsList;
if (directoryLabels) {
- cmExpandList(directoryLabels, directoryLabelsList);
+ cmExpandList(*directoryLabels, directoryLabelsList);
}
if (cmakeDirectoryLabels) {
@@ -3051,10 +3117,10 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target)
std::string const& sfp = sf->ResolveFullPath();
fout << sfp << "\n";
lj_source["file"] = sfp;
- if (const char* svalue = sf->GetProperty("LABELS")) {
+ if (cmProp svalue = sf->GetProperty("LABELS")) {
labels.clear();
Json::Value& lj_source_labels = lj_source["labels"] = Json::arrayValue;
- cmExpandList(svalue, labels);
+ cmExpandList(*svalue, labels);
for (std::string const& label : labels) {
fout << " " << label << "\n";
lj_source_labels.append(label);
@@ -3108,10 +3174,20 @@ cmGlobalGenerator::GetFilenameTargetDepends(cmSourceFile* sf) const
return this->FilenameTargetDepends[sf];
}
+const std::string& cmGlobalGenerator::GetRealPath(const std::string& dir)
+{
+ auto i = this->RealPaths.lower_bound(dir);
+ if (i == this->RealPaths.end() ||
+ this->RealPaths.key_comp()(dir, i->first)) {
+ i = this->RealPaths.emplace_hint(i, dir, cmSystemTools::GetRealPath(dir));
+ }
+ return i->second;
+}
+
void cmGlobalGenerator::ProcessEvaluationFiles()
{
std::vector<std::string> generatedFiles;
- for (cmLocalGenerator* localGen : this->LocalGenerators) {
+ for (auto& localGen : this->LocalGenerators) {
localGen->ProcessEvaluationFiles(generatedFiles);
}
}
@@ -3127,7 +3203,7 @@ bool cmGlobalGenerator::GenerateCPackPropertiesFile()
cmake::InstalledFilesMap const& installedFiles =
this->CMakeInstance->GetInstalledFiles();
- cmLocalGenerator* lg = this->LocalGenerators[0];
+ const auto& lg = this->LocalGenerators[0];
cmMakefile* mf = lg->GetMakefile();
std::vector<std::string> configs;
@@ -3146,8 +3222,8 @@ bool cmGlobalGenerator::GenerateCPackPropertiesFile()
for (auto const& i : installedFiles) {
cmInstalledFile const& installedFile = i.second;
- cmCPackPropertiesGenerator cpackPropertiesGenerator(lg, installedFile,
- configs);
+ cmCPackPropertiesGenerator cpackPropertiesGenerator(
+ lg.get(), installedFile, configs);
cpackPropertiesGenerator.Generate(file, config, configs);
}
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index f25ff7b..dcd5a66 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -14,9 +14,10 @@
#include <utility>
#include <vector>
+#include <cmext/algorithm>
+
#include "cm_codecvt.hxx"
-#include "cmAlgorithms.h"
#include "cmCustomCommandLines.h"
#include "cmDuration.h"
#include "cmExportSet.h"
@@ -27,7 +28,7 @@
#include "cmTargetDepend.h"
#if !defined(CMAKE_BOOTSTRAP)
-# include "cm_jsoncpp_value.h"
+# include <cm3p/json/value.h>
# include "cmFileLockPool.h"
#endif
@@ -43,6 +44,7 @@ class cmLocalGenerator;
class cmMakefile;
class cmOutputConverter;
class cmSourceFile;
+class cmState;
class cmStateDirectory;
class cmake;
@@ -71,7 +73,7 @@ struct GeneratedMakeCommand
void Add(std::vector<std::string>::const_iterator start,
std::vector<std::string>::const_iterator end)
{
- cmAppend(PrimaryCommand, start, end);
+ cm::append(PrimaryCommand, start, end);
}
std::string Printable() const { return cmJoin(PrimaryCommand, " "); }
@@ -90,11 +92,14 @@ struct GeneratedMakeCommand
class cmGlobalGenerator
{
public:
+ using LocalGeneratorVector = std::vector<std::unique_ptr<cmLocalGenerator>>;
+
//! Free any memory allocated with the GlobalGenerator
cmGlobalGenerator(cmake* cm);
virtual ~cmGlobalGenerator();
- virtual cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf);
+ virtual std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
+ cmMakefile* mf);
//! Get the name for this generator
virtual std::string GetName() const { return "Generic"; }
@@ -128,7 +133,14 @@ public:
/** Set the generator-specific toolset name. Returns true if toolset
is supported and false otherwise. */
- virtual bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf);
+ virtual bool SetGeneratorToolset(std::string const& ts, bool build,
+ cmMakefile* mf);
+
+ /** Read any other cache entries needed for cmake --build. */
+ virtual bool ReadCacheEntriesForBuild(const cmState& /*state*/)
+ {
+ return true;
+ }
/**
* Create LocalGenerators and process the CMakeLists files. This does not
@@ -157,11 +169,11 @@ public:
*/
virtual void Generate();
- virtual cmLinkLineComputer* CreateLinkLineComputer(
+ virtual std::unique_ptr<cmLinkLineComputer> CreateLinkLineComputer(
cmOutputConverter* outputConverter,
cmStateDirectory const& stateDir) const;
- cmLinkLineComputer* CreateMSVC60LinkLineComputer(
+ std::unique_ptr<cmLinkLineComputer> CreateMSVC60LinkLineComputer(
cmOutputConverter* outputConverter,
cmStateDirectory const& stateDir) const;
@@ -244,11 +256,11 @@ public:
cmake* GetCMakeInstance() const { return this->CMakeInstance; }
void SetConfiguredFilesPath(cmGlobalGenerator* gen);
- const std::vector<cmMakefile*>& GetMakefiles() const
+ const std::vector<std::unique_ptr<cmMakefile>>& GetMakefiles() const
{
return this->Makefiles;
}
- const std::vector<cmLocalGenerator*>& GetLocalGenerators() const
+ const LocalGeneratorVector& GetLocalGenerators() const
{
return this->LocalGenerators;
}
@@ -263,11 +275,11 @@ public:
this->CurrentConfigureMakefile = mf;
}
- void AddMakefile(cmMakefile* mf);
+ void AddMakefile(std::unique_ptr<cmMakefile> mf);
//! Set an generator for an "external makefile based project"
void SetExternalMakefileProjectGenerator(
- cmExternalMakefileProjectGenerator* extraGenerator);
+ std::unique_ptr<cmExternalMakefileProjectGenerator> extraGenerator);
std::string GetExtraGeneratorName() const;
@@ -377,6 +389,9 @@ public:
// Lookup edit_cache target command preferred by this generator.
virtual std::string GetEditCacheCommand() const { return ""; }
+ // Default config to use for cmake --build
+ virtual std::string GetDefaultBuildConfig() const { return "Debug"; }
+
// Class to track a set of dependencies.
using TargetDependSet = cmTargetDependSet;
@@ -410,6 +425,8 @@ public:
virtual bool IsXcode() const { return false; }
+ virtual bool IsVisualStudio() const { return false; }
+
/** Return true if we know the exact location of object files.
If false, store the reason in the given string.
This is meaningful only after EnableLanguage has been called. */
@@ -431,11 +448,17 @@ public:
MacFolder. */
virtual bool ShouldStripResourcePath(cmMakefile*) const;
+ virtual bool SupportsCustomCommandDepfile() const { return false; }
+
std::string GetSharedLibFlagsForLanguage(std::string const& lang) const;
/** Generate an <output>.rule file path for a given command output. */
virtual std::string GenerateRuleFile(std::string const& output) const;
+ virtual bool SupportsDefaultBuildType() const { return false; }
+ virtual bool SupportsCrossConfigs() const { return false; }
+ virtual bool SupportsDefaultConfigs() const { return false; }
+
static std::string EscapeJSON(const std::string& s);
void ProcessEvaluationFiles();
@@ -444,8 +467,8 @@ public:
{
return this->BuildExportSets;
}
- void AddBuildExportSet(cmExportBuildFileGenerator*);
- void AddBuildExportExportSet(cmExportBuildFileGenerator*);
+ void AddBuildExportSet(cmExportBuildFileGenerator* gen);
+ void AddBuildExportExportSet(cmExportBuildFileGenerator* gen);
bool IsExportedTargetsFile(const std::string& filename) const;
bool GenerateImportFile(const std::string& file);
cmExportBuildFileGenerator* GetExportedTargetsFile(
@@ -475,13 +498,19 @@ public:
int RecursionDepth;
+ virtual void GetQtAutoGenConfigs(std::vector<std::string>& configs) const
+ {
+ configs.emplace_back("$<CONFIG>");
+ }
+
+ std::string const& GetRealPath(std::string const& dir);
+
protected:
- using GeneratorVector = std::vector<cmLocalGenerator*>;
// for a project collect all its targets by following depend
// information, and also collect all the targets
void GetTargetSets(TargetDependSet& projectTargets,
TargetDependSet& originalTargets, cmLocalGenerator* root,
- GeneratorVector const&);
+ std::vector<cmLocalGenerator*>& generators);
bool IsRootOnlyTarget(cmGeneratorTarget* target) const;
void AddTargetDepends(const cmGeneratorTarget* target,
TargetDependSet& projectTargets);
@@ -524,6 +553,8 @@ protected:
std::vector<std::string> Depends;
std::string WorkingDir;
bool UsesTerminal = false;
+ bool PerConfig = true;
+ bool StdPipesUTF8 = false;
};
void CreateDefaultGlobalTargets(std::vector<GlobalTargetInfo>& targets);
@@ -539,8 +570,8 @@ protected:
std::string FindMakeProgramFile;
std::string ConfiguredFilesPath;
cmake* CMakeInstance;
- std::vector<cmMakefile*> Makefiles;
- std::vector<cmLocalGenerator*> LocalGenerators;
+ std::vector<std::unique_ptr<cmMakefile>> Makefiles;
+ LocalGeneratorVector LocalGenerators;
cmMakefile* CurrentConfigureMakefile;
// map from project name to vector of local generators in that project
std::map<std::string, std::vector<cmLocalGenerator*>> ProjectMap;
@@ -558,7 +589,7 @@ protected:
cmGeneratorTarget* FindGeneratorTargetImpl(std::string const& name) const;
- const char* GetPredefinedTargetsFolder();
+ std::string GetPredefinedTargetsFolder();
private:
using TargetMap = std::unordered_map<std::string, cmTarget*>;
@@ -646,6 +677,9 @@ private:
virtual const char* GetBuildIgnoreErrorsFlag() const { return nullptr; }
+ bool UnsupportedVariableIsDefined(const std::string& name,
+ bool supported) const;
+
// Cache directory content and target files to be built.
struct DirectoryContent
{
@@ -666,6 +700,8 @@ private:
mutable std::map<cmSourceFile*, std::set<cmGeneratorTarget const*>>
FilenameTargetDepends;
+ std::map<std::string, std::string> RealPaths;
+
#if !defined(CMAKE_BOOTSTRAP)
// Pool of file locks
cmFileLockPool FileLockPool;
diff --git a/Source/cmGlobalGeneratorFactory.h b/Source/cmGlobalGeneratorFactory.h
index bb5f74c..3709365 100644
--- a/Source/cmGlobalGeneratorFactory.h
+++ b/Source/cmGlobalGeneratorFactory.h
@@ -8,6 +8,8 @@
#include <string>
#include <vector>
+#include <cm/memory>
+
class cmGlobalGenerator;
class cmake;
struct cmDocumentationEntry;
@@ -23,8 +25,8 @@ public:
virtual ~cmGlobalGeneratorFactory() = default;
/** Create a GlobalGenerator */
- virtual cmGlobalGenerator* CreateGlobalGenerator(const std::string& n,
- cmake* cm) const = 0;
+ virtual std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
+ const std::string& n, cmake* cm) const = 0;
/** Get the documentation entry for this factory */
virtual void GetDocumentation(cmDocumentationEntry& entry) const = 0;
@@ -51,13 +53,13 @@ class cmGlobalGeneratorSimpleFactory : public cmGlobalGeneratorFactory
{
public:
/** Create a GlobalGenerator */
- cmGlobalGenerator* CreateGlobalGenerator(const std::string& name,
- cmake* cm) const override
+ std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
+ const std::string& name, cmake* cm) const override
{
if (name != T::GetActualName()) {
- return nullptr;
+ return std::unique_ptr<cmGlobalGenerator>();
}
- return new T(cm);
+ return std::unique_ptr<cmGlobalGenerator>(cm::make_unique<T>(cm));
}
/** Get the documentation entry for this factory */
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
index 5a708ab..651bfbd 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -8,7 +8,10 @@
#include <ostream>
#include <utility>
-#include "cmAlgorithms.h"
+#include <cm/memory>
+#include <cm/string>
+#include <cmext/algorithm>
+
#include "cmDocumentationEntry.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
@@ -40,10 +43,11 @@ cmGlobalGhsMultiGenerator::cmGlobalGhsMultiGenerator(cmake* cm)
cmGlobalGhsMultiGenerator::~cmGlobalGhsMultiGenerator() = default;
-cmLocalGenerator* cmGlobalGhsMultiGenerator::CreateLocalGenerator(
- cmMakefile* mf)
+std::unique_ptr<cmLocalGenerator>
+cmGlobalGhsMultiGenerator::CreateLocalGenerator(cmMakefile* mf)
{
- return new cmLocalGhsMultiGenerator(this, mf);
+ return std::unique_ptr<cmLocalGenerator>(
+ cm::make_unique<cmLocalGhsMultiGenerator>(this, mf));
}
void cmGlobalGhsMultiGenerator::GetDocumentation(cmDocumentationEntry& entry)
@@ -64,8 +68,11 @@ void cmGlobalGhsMultiGenerator::ComputeTargetObjectDirectory(
}
bool cmGlobalGhsMultiGenerator::SetGeneratorToolset(std::string const& ts,
- cmMakefile* mf)
+ bool build, cmMakefile* mf)
{
+ if (build) {
+ return true;
+ }
std::string tsp; /* toolset path */
this->GetToolset(mf, tsp, ts);
@@ -84,7 +91,7 @@ bool cmGlobalGhsMultiGenerator::SetGeneratorToolset(std::string const& ts,
/* store the full toolset for later use
* -- already done if -T<toolset> was specified
*/
- mf->AddCacheDefinition("CMAKE_GENERATOR_TOOLSET", tsp.c_str(),
+ mf->AddCacheDefinition("CMAKE_GENERATOR_TOOLSET", tsp,
"Location of generator toolset.",
cmStateEnums::INTERNAL);
}
@@ -106,8 +113,8 @@ bool cmGlobalGhsMultiGenerator::SetGeneratorToolset(std::string const& ts,
}
/* store the toolset that is being used for this build */
- mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM", gbuild.c_str(),
- "build program to use", cmStateEnums::INTERNAL, true);
+ mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM", gbuild, "build program to use",
+ cmStateEnums::INTERNAL, true);
mf->AddDefinition("CMAKE_SYSTEM_VERSION", tsp);
@@ -126,7 +133,7 @@ bool cmGlobalGhsMultiGenerator::SetGeneratorPlatform(std::string const& p,
/* store the platform name for later use
* -- already done if -A<arch> was specified
*/
- mf->AddCacheDefinition("CMAKE_GENERATOR_PLATFORM", arch.c_str(),
+ mf->AddCacheDefinition("CMAKE_GENERATOR_PLATFORM", arch,
"Name of generator platform.",
cmStateEnums::INTERNAL);
} else {
@@ -160,7 +167,7 @@ bool cmGlobalGhsMultiGenerator::SetGeneratorPlatform(std::string const& p,
if (cmIsOff(bspName) && platform.find("integrity") != std::string::npos) {
bspName = "sim" + arch;
/* write back the calculate name for next time */
- mf->AddCacheDefinition("GHS_BSP_NAME", bspName.c_str(),
+ mf->AddCacheDefinition("GHS_BSP_NAME", bspName,
"Name of GHS target platform.",
cmStateEnums::STRING, true);
std::string m = cmStrCat(
@@ -247,14 +254,15 @@ void cmGlobalGhsMultiGenerator::GetToolset(cmMakefile* mf, std::string& tsd,
void cmGlobalGhsMultiGenerator::WriteFileHeader(std::ostream& fout)
{
- fout << "#!gbuild" << std::endl;
- fout << "#" << std::endl
- << "# CMAKE generated file: DO NOT EDIT!" << std::endl
- << "# Generated by \"" << GetActualName() << "\""
- << " Generator, CMake Version " << cmVersion::GetMajorVersion() << "."
- << cmVersion::GetMinorVersion() << std::endl
- << "#" << std::endl
- << std::endl;
+ /* clang-format off */
+ fout << "#!gbuild\n"
+ "#\n"
+ "# CMAKE generated file: DO NOT EDIT!\n"
+ "# Generated by \"" << GetActualName() << "\""
+ " Generator, CMake Version " << cmVersion::GetMajorVersion() << '.'
+ << cmVersion::GetMinorVersion() << "\n"
+ "#\n\n";
+ /* clang-format on */
}
void cmGlobalGhsMultiGenerator::WriteCustomRuleBOD(std::ostream& fout)
@@ -262,36 +270,36 @@ void cmGlobalGhsMultiGenerator::WriteCustomRuleBOD(std::ostream& fout)
fout << "Commands {\n"
" Custom_Rule_Command {\n"
" name = \"Custom Rule Command\"\n"
- " exec = \"";
+ " exec = \""
#ifdef _WIN32
- fout << "cmd.exe";
+ "cmd.exe"
#else
- fout << "/bin/sh";
+ "/bin/sh"
#endif
- fout << "\"\n"
+ "\"\n"
" options = {\"SpecialOptions\"}\n"
" }\n"
- "}\n";
+ "}\n"
- fout << "\n\n";
- fout << "FileTypes {\n"
+ "\n\n"
+ "FileTypes {\n"
" CmakeRule {\n"
" name = \"Custom Rule\"\n"
" action = \"&Run\"\n"
- " extensions = {\"";
+ " extensions = {\""
#ifdef _WIN32
- fout << "bat";
+ "bat"
#else
- fout << "sh";
+ "sh"
#endif
- fout << "\"}\n"
+ "\"}\n"
" grepable = false\n"
" command = \"Custom Rule Command\"\n"
- " commandLine = \"$COMMAND ";
+ " commandLine = \"$COMMAND "
#ifdef _WIN32
- fout << "/c";
+ "/c"
#endif
- fout << " $INPUTFILE\"\n"
+ " $INPUTFILE\"\n"
" progress = \"Processing Custom Rule\"\n"
" promoteToFirstPass = true\n"
" outputType = \"None\"\n"
@@ -321,13 +329,13 @@ void cmGlobalGhsMultiGenerator::WriteTopLevelProject(std::ostream& fout,
this->WriteHighLevelDirectives(root, fout);
GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, fout);
- fout << "# Top Level Project File" << std::endl;
+ fout << "# Top Level Project File\n";
// Specify BSP option if supplied by user
const char* bspName =
this->GetCMakeInstance()->GetCacheDefinition("GHS_BSP_NAME");
if (!cmIsOff(bspName)) {
- fout << " -bsp " << bspName << std::endl;
+ fout << " -bsp " << bspName << '\n';
}
// Specify OS DIR if supplied by user
@@ -342,14 +350,14 @@ void cmGlobalGhsMultiGenerator::WriteTopLevelProject(std::ostream& fout,
} else {
fout << osDirOption;
}
- fout << "\"" << this->OsDir << "\"" << std::endl;
+ fout << "\"" << this->OsDir << "\"\n";
}
}
void cmGlobalGhsMultiGenerator::WriteSubProjects(std::ostream& fout,
std::string& all_target)
{
- fout << "CMakeFiles/" << all_target << " [Project]" << std::endl;
+ fout << "CMakeFiles/" << all_target << " [Project]\n";
// All known targets
for (cmGeneratorTarget const* target : this->ProjectTargets) {
if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
@@ -360,7 +368,7 @@ void cmGlobalGhsMultiGenerator::WriteSubProjects(std::ostream& fout,
continue;
}
fout << "CMakeFiles/" << target->GetName() + ".tgt" + FILE_EXTENSION
- << " [Project]" << std::endl;
+ << " [Project]\n";
}
}
@@ -368,8 +376,8 @@ void cmGlobalGhsMultiGenerator::WriteProjectLine(
std::ostream& fout, cmGeneratorTarget const* target, cmLocalGenerator* root,
std::string& rootBinaryDir)
{
- const char* projName = target->GetProperty("GENERATOR_FILE_NAME");
- const char* projType = target->GetProperty("GENERATOR_FILE_NAME_EXT");
+ cmProp projName = target->GetProperty("GENERATOR_FILE_NAME");
+ cmProp projType = target->GetProperty("GENERATOR_FILE_NAME_EXT");
if (projName && projType) {
cmLocalGenerator* lg = target->GetLocalGenerator();
std::string dir = lg->GetCurrentBinaryDirectory();
@@ -382,9 +390,9 @@ void cmGlobalGhsMultiGenerator::WriteProjectLine(
}
}
- std::string projFile = dir + projName + FILE_EXTENSION;
+ std::string projFile = dir + *projName + FILE_EXTENSION;
fout << projFile;
- fout << " " << projType << std::endl;
+ fout << ' ' << *projType << '\n';
} else {
/* Should never happen */
std::string message =
@@ -461,7 +469,8 @@ void cmGlobalGhsMultiGenerator::WriteAllTarget(
if (t->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
- if (!cmIsOn(t->GetProperty("EXCLUDE_FROM_ALL"))) {
+ cmProp p = t->GetProperty("EXCLUDE_FROM_ALL");
+ if (!(p && cmIsOn(*p))) {
defaultTargets.push_back(t);
}
}
@@ -577,14 +586,14 @@ cmGlobalGhsMultiGenerator::GenerateBuildCommand(
/* if multiple top-projects are found in build directory
* then prefer projectName top-project.
*/
- if (!cmContains(files, proj)) {
+ if (!cm::contains(files, proj)) {
proj = files.at(0);
}
}
makeCommand.Add("-top", proj);
if (!targetNames.empty()) {
- if (cmContains(targetNames, "clean")) {
+ if (cm::contains(targetNames, "clean")) {
makeCommand.Add("-clean");
} else {
for (const auto& tname : targetNames) {
@@ -606,14 +615,14 @@ cmGlobalGhsMultiGenerator::GenerateBuildCommand(
void cmGlobalGhsMultiGenerator::WriteMacros(std::ostream& fout,
cmLocalGenerator* root)
{
- fout << "macro PROJ_NAME=" << root->GetProjectName() << std::endl;
+ fout << "macro PROJ_NAME=" << root->GetProjectName() << '\n';
char const* ghsGpjMacros =
this->GetCMakeInstance()->GetCacheDefinition("GHS_GPJ_MACROS");
if (nullptr != ghsGpjMacros) {
std::vector<std::string> expandedList =
cmExpandedList(std::string(ghsGpjMacros));
for (std::string const& arg : expandedList) {
- fout << "macro " << arg << std::endl;
+ fout << "macro " << arg << '\n';
}
}
}
@@ -636,30 +645,27 @@ void cmGlobalGhsMultiGenerator::WriteHighLevelDirectives(
tgt = cmStrCat((a ? a : ""), '_', (p ? p : ""), ".tgt");
}
- fout << "primaryTarget=" << tgt << std::endl;
- fout << "customization=" << root->GetBinaryDirectory()
- << "/CMakeFiles/custom_rule.bod" << std::endl;
- fout << "customization=" << root->GetBinaryDirectory()
- << "/CMakeFiles/custom_target.bod" << std::endl;
+ /* clang-format off */
+ fout << "primaryTarget=" << tgt << "\n"
+ "customization=" << root->GetBinaryDirectory()
+ << "/CMakeFiles/custom_rule.bod\n"
+ "customization=" << root->GetBinaryDirectory()
+ << "/CMakeFiles/custom_target.bod" << '\n';
+ /* clang-format on */
char const* const customization =
this->GetCMakeInstance()->GetCacheDefinition("GHS_CUSTOMIZATION");
if (nullptr != customization && strlen(customization) > 0) {
- fout << "customization=" << this->TrimQuotes(customization) << std::endl;
+ fout << "customization="
+ << cmGlobalGhsMultiGenerator::TrimQuotes(customization) << '\n';
this->GetCMakeInstance()->MarkCliAsUsed("GHS_CUSTOMIZATION");
}
}
-std::string cmGlobalGhsMultiGenerator::TrimQuotes(std::string const& str)
+std::string cmGlobalGhsMultiGenerator::TrimQuotes(std::string str)
{
- std::string result;
- result.reserve(str.size());
- for (const char* ch = str.c_str(); *ch != '\0'; ++ch) {
- if (*ch != '"') {
- result += *ch;
- }
- }
- return result;
+ cm::erase(str, '"');
+ return str;
}
bool cmGlobalGhsMultiGenerator::TargetCompare::operator()(
diff --git a/Source/cmGlobalGhsMultiGenerator.h b/Source/cmGlobalGhsMultiGenerator.h
index ccfe073..12ca8b6 100644
--- a/Source/cmGlobalGhsMultiGenerator.h
+++ b/Source/cmGlobalGhsMultiGenerator.h
@@ -4,6 +4,7 @@
#define cmGhsMultiGenerator_h
#include <iosfwd>
+#include <memory>
#include <set>
#include <string>
#include <utility>
@@ -28,13 +29,15 @@ public:
cmGlobalGhsMultiGenerator(cmake* cm);
~cmGlobalGhsMultiGenerator() override;
- static cmGlobalGeneratorFactory* NewFactory()
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory()
{
- return new cmGlobalGeneratorSimpleFactory<cmGlobalGhsMultiGenerator>();
+ return std::unique_ptr<cmGlobalGeneratorFactory>(
+ new cmGlobalGeneratorSimpleFactory<cmGlobalGhsMultiGenerator>());
}
//! create the correct local generator
- cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) override;
+ std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
+ cmMakefile* mf) override;
/// @return the name of this generator.
static std::string GetActualName() { return "Green Hills MULTI"; }
@@ -58,7 +61,8 @@ public:
static bool SupportsPlatform() { return true; }
// Toolset / Platform Support
- bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf) override;
+ bool SetGeneratorToolset(std::string const& ts, bool build,
+ cmMakefile* mf) override;
bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf) override;
/**
@@ -107,7 +111,7 @@ private:
std::vector<cmLocalGenerator*>& generators,
std::string& all_target);
- std::string TrimQuotes(std::string const& str);
+ static std::string TrimQuotes(std::string str);
std::string OsDir;
static const char* DEFAULT_BUILD_PROGRAM;
diff --git a/Source/cmGlobalJOMMakefileGenerator.cxx b/Source/cmGlobalJOMMakefileGenerator.cxx
index ff54288..fc3123a 100644
--- a/Source/cmGlobalJOMMakefileGenerator.cxx
+++ b/Source/cmGlobalJOMMakefileGenerator.cxx
@@ -66,7 +66,7 @@ cmGlobalJOMMakefileGenerator::GenerateBuildCommand(
// Since we have full control over the invocation of JOM, let us
// make it quiet.
jomMakeOptions.push_back(this->MakeSilentFlag);
- cmAppend(jomMakeOptions, makeOptions);
+ cm::append(jomMakeOptions, makeOptions);
// JOM does parallel builds by default, the -j is only needed if a specific
// number is given
diff --git a/Source/cmGlobalJOMMakefileGenerator.h b/Source/cmGlobalJOMMakefileGenerator.h
index fc39ddf..9f1ec8b 100644
--- a/Source/cmGlobalJOMMakefileGenerator.h
+++ b/Source/cmGlobalJOMMakefileGenerator.h
@@ -4,6 +4,7 @@
#define cmGlobalJOMMakefileGenerator_h
#include <iosfwd>
+#include <memory>
#include "cmGlobalUnixMakefileGenerator3.h"
@@ -16,9 +17,10 @@ class cmGlobalJOMMakefileGenerator : public cmGlobalUnixMakefileGenerator3
{
public:
cmGlobalJOMMakefileGenerator(cmake* cm);
- static cmGlobalGeneratorFactory* NewFactory()
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory()
{
- return new cmGlobalGeneratorSimpleFactory<cmGlobalJOMMakefileGenerator>();
+ return std::unique_ptr<cmGlobalGeneratorFactory>(
+ new cmGlobalGeneratorSimpleFactory<cmGlobalJOMMakefileGenerator>());
}
//! Get the name for the generator.
std::string GetName() const override
diff --git a/Source/cmGlobalMSYSMakefileGenerator.h b/Source/cmGlobalMSYSMakefileGenerator.h
index d6e4847..b2de4ff 100644
--- a/Source/cmGlobalMSYSMakefileGenerator.h
+++ b/Source/cmGlobalMSYSMakefileGenerator.h
@@ -3,6 +3,8 @@
#ifndef cmGlobalMSYSMakefileGenerator_h
#define cmGlobalMSYSMakefileGenerator_h
+#include <memory>
+
#include "cmGlobalUnixMakefileGenerator3.h"
/** \class cmGlobalMSYSMakefileGenerator
@@ -14,9 +16,10 @@ class cmGlobalMSYSMakefileGenerator : public cmGlobalUnixMakefileGenerator3
{
public:
cmGlobalMSYSMakefileGenerator(cmake* cm);
- static cmGlobalGeneratorFactory* NewFactory()
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory()
{
- return new cmGlobalGeneratorSimpleFactory<cmGlobalMSYSMakefileGenerator>();
+ return std::unique_ptr<cmGlobalGeneratorFactory>(
+ new cmGlobalGeneratorSimpleFactory<cmGlobalMSYSMakefileGenerator>());
}
//! Get the name for the generator.
diff --git a/Source/cmGlobalMinGWMakefileGenerator.h b/Source/cmGlobalMinGWMakefileGenerator.h
index 15297e3..a9f92a1 100644
--- a/Source/cmGlobalMinGWMakefileGenerator.h
+++ b/Source/cmGlobalMinGWMakefileGenerator.h
@@ -3,6 +3,8 @@
#ifndef cmGlobalMinGWMakefileGenerator_h
#define cmGlobalMinGWMakefileGenerator_h
+#include <memory>
+
#include "cmGlobalUnixMakefileGenerator3.h"
/** \class cmGlobalMinGWMakefileGenerator
@@ -14,10 +16,10 @@ class cmGlobalMinGWMakefileGenerator : public cmGlobalUnixMakefileGenerator3
{
public:
cmGlobalMinGWMakefileGenerator(cmake* cm);
- static cmGlobalGeneratorFactory* NewFactory()
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory()
{
- return new cmGlobalGeneratorSimpleFactory<
- cmGlobalMinGWMakefileGenerator>();
+ return std::unique_ptr<cmGlobalGeneratorFactory>(
+ new cmGlobalGeneratorSimpleFactory<cmGlobalMinGWMakefileGenerator>());
}
//! Get the name for the generator.
virtual std::string GetName() const
diff --git a/Source/cmGlobalNMakeMakefileGenerator.cxx b/Source/cmGlobalNMakeMakefileGenerator.cxx
index 2273c00..c4bec23 100644
--- a/Source/cmGlobalNMakeMakefileGenerator.cxx
+++ b/Source/cmGlobalNMakeMakefileGenerator.cxx
@@ -66,7 +66,7 @@ cmGlobalNMakeMakefileGenerator::GenerateBuildCommand(
// Since we have full control over the invocation of nmake, let us
// make it quiet.
nmakeMakeOptions.push_back(this->MakeSilentFlag);
- cmAppend(nmakeMakeOptions, makeOptions);
+ cm::append(nmakeMakeOptions, makeOptions);
return this->cmGlobalUnixMakefileGenerator3::GenerateBuildCommand(
makeProgram, projectName, projectDir, targetNames, config, fast,
diff --git a/Source/cmGlobalNMakeMakefileGenerator.h b/Source/cmGlobalNMakeMakefileGenerator.h
index 4586b77..fdf6006 100644
--- a/Source/cmGlobalNMakeMakefileGenerator.h
+++ b/Source/cmGlobalNMakeMakefileGenerator.h
@@ -4,6 +4,7 @@
#define cmGlobalNMakeMakefileGenerator_h
#include <iosfwd>
+#include <memory>
#include "cmGlobalUnixMakefileGenerator3.h"
@@ -16,10 +17,10 @@ class cmGlobalNMakeMakefileGenerator : public cmGlobalUnixMakefileGenerator3
{
public:
cmGlobalNMakeMakefileGenerator(cmake* cm);
- static cmGlobalGeneratorFactory* NewFactory()
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory()
{
- return new cmGlobalGeneratorSimpleFactory<
- cmGlobalNMakeMakefileGenerator>();
+ return std::unique_ptr<cmGlobalGeneratorFactory>(
+ new cmGlobalGeneratorSimpleFactory<cmGlobalNMakeMakefileGenerator>());
}
//! Get the name for the generator.
std::string GetName() const override
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index da21d6c..843b0f4 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -9,20 +9,22 @@
#include <sstream>
#include <cm/memory>
+#include <cmext/algorithm>
+#include <cmext/memory>
-#include "cmsys/FStream.hxx"
+#include <cm3p/json/reader.h>
+#include <cm3p/json/value.h>
+#include <cm3p/json/writer.h>
-#include "cm_jsoncpp_reader.h"
-#include "cm_jsoncpp_value.h"
-#include "cm_jsoncpp_writer.h"
+#include "cmsys/FStream.hxx"
-#include "cmAlgorithms.h"
#include "cmDocumentationEntry.h"
#include "cmFortranParser.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpressionEvaluationFile.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmLinkLineComputer.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmLocalNinjaGenerator.h"
@@ -42,10 +44,9 @@
#include "cmVersion.h"
#include "cmake.h"
-class cmLinkLineComputer;
-
const char* cmGlobalNinjaGenerator::NINJA_BUILD_FILE = "build.ninja";
-const char* cmGlobalNinjaGenerator::NINJA_RULES_FILE = "rules.ninja";
+const char* cmGlobalNinjaGenerator::NINJA_RULES_FILE =
+ "CMakeFiles/rules.ninja";
const char* cmGlobalNinjaGenerator::INDENT = " ";
#ifdef _WIN32
std::string const cmGlobalNinjaGenerator::SHELL_NOOP = "cd .";
@@ -83,13 +84,15 @@ void cmGlobalNinjaGenerator::WriteComment(std::ostream& os,
os << "# " << comment.substr(lpos) << "\n\n";
}
-cmLinkLineComputer* cmGlobalNinjaGenerator::CreateLinkLineComputer(
+std::unique_ptr<cmLinkLineComputer>
+cmGlobalNinjaGenerator::CreateLinkLineComputer(
cmOutputConverter* outputConverter,
cmStateDirectory const& /* stateDir */) const
{
- return new cmNinjaLinkLineComputer(
- outputConverter,
- this->LocalGenerators[0]->GetStateSnapshot().GetDirectory(), this);
+ return std::unique_ptr<cmLinkLineComputer>(
+ cm::make_unique<cmNinjaLinkLineComputer>(
+ outputConverter,
+ this->LocalGenerators[0]->GetStateSnapshot().GetDirectory(), this));
}
std::string cmGlobalNinjaGenerator::EncodeRuleName(std::string const& name)
@@ -114,6 +117,11 @@ std::string cmGlobalNinjaGenerator::EncodeLiteral(const std::string& lit)
std::string result = lit;
cmSystemTools::ReplaceString(result, "$", "$$");
cmSystemTools::ReplaceString(result, "\n", "$\n");
+ if (this->IsMultiConfig()) {
+ cmSystemTools::ReplaceString(result,
+ cmStrCat('$', this->GetCMakeCFGIntDir()),
+ this->GetCMakeCFGIntDir());
+ }
return result;
}
@@ -139,15 +147,15 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os,
{
// Make sure there is a rule.
if (build.Rule.empty()) {
- cmSystemTools::Error("No rule for WriteBuild! called with comment: " +
- build.Comment);
+ cmSystemTools::Error(cmStrCat(
+ "No rule for WriteBuild! called with comment: ", build.Comment));
return;
}
// Make sure there is at least one output file.
if (build.Outputs.empty()) {
- cmSystemTools::Error(
- "No output files for WriteBuild! called with comment: " + build.Comment);
+ cmSystemTools::Error(cmStrCat(
+ "No output files for WriteBuild! called with comment: ", build.Comment));
return;
}
@@ -158,7 +166,7 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os,
{
// Write explicit outputs
for (std::string const& output : build.Outputs) {
- buildStr += " " + EncodePath(output);
+ buildStr += cmStrCat(' ', EncodePath(output));
if (this->ComputingUnknownDependencies) {
this->CombinedBuildOutputs.insert(output);
}
@@ -167,14 +175,13 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os,
if (!build.ImplicitOuts.empty()) {
buildStr += " |";
for (std::string const& implicitOut : build.ImplicitOuts) {
- buildStr += " " + EncodePath(implicitOut);
+ buildStr += cmStrCat(' ', EncodePath(implicitOut));
}
}
- buildStr += ":";
+ buildStr += ':';
// Write the rule.
- buildStr += " ";
- buildStr += build.Rule;
+ buildStr += cmStrCat(' ', build.Rule);
}
std::string arguments;
@@ -183,14 +190,14 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os,
// Write explicit dependencies.
for (std::string const& explicitDep : build.ExplicitDeps) {
- arguments += " " + EncodePath(explicitDep);
+ arguments += cmStrCat(' ', EncodePath(explicitDep));
}
// Write implicit dependencies.
if (!build.ImplicitDeps.empty()) {
arguments += " |";
for (std::string const& implicitDep : build.ImplicitDeps) {
- arguments += " " + EncodePath(implicitDep);
+ arguments += cmStrCat(' ', EncodePath(implicitDep));
}
}
@@ -198,11 +205,11 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os,
if (!build.OrderOnlyDeps.empty()) {
arguments += " ||";
for (std::string const& orderOnlyDep : build.OrderOnlyDeps) {
- arguments += " " + EncodePath(orderOnlyDep);
+ arguments += cmStrCat(' ', EncodePath(orderOnlyDep));
}
}
- arguments += "\n";
+ arguments += '\n';
}
// Write the variables bound to this build statement.
@@ -248,8 +255,8 @@ void cmGlobalNinjaGenerator::WriteCustomCommandBuild(
const std::string& command, const std::string& description,
const std::string& comment, const std::string& depfile,
const std::string& job_pool, bool uses_terminal, bool restat,
- const cmNinjaDeps& outputs, const cmNinjaDeps& explicitDeps,
- const cmNinjaDeps& orderOnlyDeps)
+ const cmNinjaDeps& outputs, const std::string& config,
+ const cmNinjaDeps& explicitDeps, const cmNinjaDeps& orderOnlyDeps)
{
this->AddCustomCommandRule();
@@ -282,7 +289,11 @@ void cmGlobalNinjaGenerator::WriteCustomCommandBuild(
if (!depfile.empty()) {
vars["depfile"] = depfile;
}
- this->WriteBuild(*this->BuildFileStream, build);
+ if (config.empty()) {
+ this->WriteBuild(*this->GetCommonFileStream(), build);
+ } else {
+ this->WriteBuild(*this->GetImplFileStream(config), build);
+ }
}
if (this->ComputingUnknownDependencies) {
@@ -297,21 +308,22 @@ void cmGlobalNinjaGenerator::WriteCustomCommandBuild(
void cmGlobalNinjaGenerator::AddMacOSXContentRule()
{
cmNinjaRule rule("COPY_OSX_CONTENT");
- rule.Command = CMakeCmd() + " -E copy $in $out";
+ rule.Command = cmStrCat(CMakeCmd(), " -E copy $in $out");
rule.Description = "Copying OS X Content $out";
rule.Comment = "Rule for copying OS X bundle content file.";
this->AddRule(rule);
}
void cmGlobalNinjaGenerator::WriteMacOSXContentBuild(std::string input,
- std::string output)
+ std::string output,
+ const std::string& config)
{
this->AddMacOSXContentRule();
{
cmNinjaBuild build("COPY_OSX_CONTENT");
build.Outputs.push_back(std::move(output));
build.ExplicitDeps.push_back(std::move(input));
- this->WriteBuild(*this->BuildFileStream, build);
+ this->WriteBuild(*this->GetImplFileStream(config), build);
}
}
@@ -321,23 +333,24 @@ void cmGlobalNinjaGenerator::WriteRule(std::ostream& os,
// -- Parameter checks
// Make sure the rule has a name.
if (rule.Name.empty()) {
- cmSystemTools::Error("No name given for WriteRule! called with comment: " +
- rule.Comment);
+ cmSystemTools::Error(cmStrCat(
+ "No name given for WriteRule! called with comment: ", rule.Comment));
return;
}
// Make sure a command is given.
if (rule.Command.empty()) {
- cmSystemTools::Error(
- "No command given for WriteRule! called with comment: " + rule.Comment);
+ cmSystemTools::Error(cmStrCat(
+ "No command given for WriteRule! called with comment: ", rule.Comment));
return;
}
// Make sure response file content is given
if (!rule.RspFile.empty() && rule.RspContent.empty()) {
- cmSystemTools::Error("rspfile but no rspfile_content given for WriteRule! "
- "called with comment: " +
- rule.Comment);
+ cmSystemTools::Error(
+ cmStrCat("rspfile but no rspfile_content given for WriteRule! "
+ "called with comment: ",
+ rule.Comment));
return;
}
@@ -379,9 +392,9 @@ void cmGlobalNinjaGenerator::WriteVariable(std::ostream& os,
{
// Make sure we have a name.
if (name.empty()) {
- cmSystemTools::Error("No name given for WriteVariable! called "
- "with comment: " +
- comment);
+ cmSystemTools::Error(cmStrCat("No name given for WriteVariable! called "
+ "with comment: ",
+ comment));
return;
}
@@ -422,16 +435,16 @@ cmGlobalNinjaGenerator::cmGlobalNinjaGenerator(cmake* cm)
#ifdef _WIN32
cm->GetState()->SetWindowsShell(true);
#endif
- // // Ninja is not ported to non-Unix OS yet.
- // this->ForceUnixPaths = true;
this->FindMakeProgramFile = "CMakeNinjaFindMake.cmake";
}
// Virtual public methods.
-cmLocalGenerator* cmGlobalNinjaGenerator::CreateLocalGenerator(cmMakefile* mf)
+std::unique_ptr<cmLocalGenerator> cmGlobalNinjaGenerator::CreateLocalGenerator(
+ cmMakefile* mf)
{
- return new cmLocalNinjaGenerator(this, mf);
+ return std::unique_ptr<cmLocalGenerator>(
+ cm::make_unique<cmLocalNinjaGenerator>(this, mf));
}
codecvt::Encoding cmGlobalNinjaGenerator::GetMakefileEncoding() const
@@ -470,14 +483,19 @@ void cmGlobalNinjaGenerator::Generate()
msg.str());
return;
}
- if (!this->OpenBuildFileStream()) {
+ if (!this->InspectConfigTypeVariables()) {
+ return;
+ }
+ if (!this->OpenBuildFileStreams()) {
return;
}
if (!this->OpenRulesFileStream()) {
return;
}
- this->TargetDependsClosures.clear();
+ for (auto& it : this->Configs) {
+ it.second.TargetDependsClosures.clear();
+ }
this->InitOutputPathPrefix();
this->TargetAll = this->NinjaOutputPath("all");
@@ -493,19 +511,101 @@ void cmGlobalNinjaGenerator::Generate()
this->cmGlobalGenerator::Generate();
this->WriteAssumedSourceDependencies();
- this->WriteTargetAliases(*this->BuildFileStream);
- this->WriteFolderTargets(*this->BuildFileStream);
- this->WriteUnknownExplicitDependencies(*this->BuildFileStream);
- this->WriteBuiltinTargets(*this->BuildFileStream);
+ this->WriteTargetAliases(*this->GetCommonFileStream());
+ this->WriteFolderTargets(*this->GetCommonFileStream());
+ this->WriteUnknownExplicitDependencies(*this->GetCommonFileStream());
+ this->WriteBuiltinTargets(*this->GetCommonFileStream());
if (cmSystemTools::GetErrorOccuredFlag()) {
this->RulesFileStream->setstate(std::ios::failbit);
- this->BuildFileStream->setstate(std::ios::failbit);
+ for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs()) {
+ this->GetImplFileStream(config)->setstate(std::ios::failbit);
+ this->GetConfigFileStream(config)->setstate(std::ios::failbit);
+ }
+ this->GetCommonFileStream()->setstate(std::ios::failbit);
}
this->CloseCompileCommandsStream();
this->CloseRulesFileStream();
- this->CloseBuildFileStream();
+ this->CloseBuildFileStreams();
+
+#ifdef _WIN32
+ // The ninja tools will not be able to update metadata on Windows
+ // when we are re-generating inside an existing 'ninja' invocation
+ // because the outer tool has the files open for write.
+ if (!this->GetCMakeInstance()->GetRegenerateDuringBuild())
+#endif
+ {
+ this->CleanMetaData();
+ }
+}
+
+void cmGlobalNinjaGenerator::CleanMetaData()
+{
+ auto run_ninja_tool = [this](std::vector<char const*> const& args) {
+ std::vector<std::string> command;
+ command.push_back(this->NinjaCommand);
+ command.emplace_back("-C");
+ command.emplace_back(this->GetCMakeInstance()->GetHomeOutputDirectory());
+ command.emplace_back("-t");
+ for (auto const& arg : args) {
+ command.emplace_back(arg);
+ }
+ std::string error;
+ if (!cmSystemTools::RunSingleCommand(command, nullptr, &error, nullptr,
+ nullptr,
+ cmSystemTools::OUTPUT_NONE)) {
+ this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
+ cmStrCat("Running\n '",
+ cmJoin(command, "' '"),
+ "'\n"
+ "failed with:\n ",
+ error));
+ cmSystemTools::SetFatalErrorOccured();
+ }
+ };
+
+ // Can the tools below expect 'build.ninja' to be loadable?
+ bool const expectBuildManifest =
+ !this->IsMultiConfig() && this->OutputPathPrefix.empty();
+
+ // Skip some ninja tools if they need 'build.ninja' but it is missing.
+ bool const missingBuildManifest = expectBuildManifest &&
+ (this->NinjaSupportsCleanDeadTool ||
+ this->NinjaSupportsUnconditionalRecompactTool) &&
+ !cmSystemTools::FileExists("build.ninja");
+
+ // The `cleandead` tool needs to know about all outputs in the build we just
+ // wrote out. Ninja-Multi doesn't have a single `build.ninja` we can use that
+ // is the union of all generated configurations, so we can't run it reliably
+ // in that case.
+ if (this->NinjaSupportsCleanDeadTool && expectBuildManifest &&
+ !missingBuildManifest) {
+ run_ninja_tool({ "cleandead" });
+ }
+ // The `recompact` tool loads the manifest. As above, we don't have a single
+ // `build.ninja` to load for this in Ninja-Multi. This may be relaxed in the
+ // future pending further investigation into how Ninja works upstream
+ // (ninja#1721).
+ if (this->NinjaSupportsUnconditionalRecompactTool && expectBuildManifest &&
+ !missingBuildManifest) {
+ run_ninja_tool({ "recompact" });
+ }
+ if (this->NinjaSupportsRestatTool && this->OutputPathPrefix.empty()) {
+ // XXX(ninja): We only list `build.ninja` entry files here because CMake
+ // *always* rewrites these files on a reconfigure. If CMake ever gets
+ // smarter about this, all CMake-time created/edited files listed as
+ // outputs for the reconfigure build statement will need to be listed here.
+ cmNinjaDeps outputs;
+ this->AddRebuildManifestOutputs(outputs);
+ std::vector<const char*> args;
+ args.reserve(outputs.size() + 1);
+ args.push_back("restat");
+ for (auto const& output : outputs) {
+ args.push_back(output.c_str());
+ }
+ run_ninja_tool(args);
+ }
}
bool cmGlobalNinjaGenerator::FindMakeProgram(cmMakefile* mf)
@@ -524,10 +624,10 @@ bool cmGlobalNinjaGenerator::FindMakeProgram(cmMakefile* mf)
nullptr,
cmSystemTools::OUTPUT_NONE)) {
mf->IssueMessage(MessageType::FATAL_ERROR,
- "Running\n '" + cmJoin(command, "' '") +
- "'\n"
- "failed with:\n " +
- error);
+ cmStrCat("Running\n '", cmJoin(command, "' '"),
+ "'\n"
+ "failed with:\n ",
+ error));
cmSystemTools::SetFatalErrorOccured();
return false;
}
@@ -569,14 +669,35 @@ void cmGlobalNinjaGenerator::CheckNinjaFeatures()
}
}
}
+ this->NinjaSupportsCleanDeadTool = !cmSystemTools::VersionCompare(
+ cmSystemTools::OP_LESS, this->NinjaVersion.c_str(),
+ RequiredNinjaVersionForCleanDeadTool().c_str());
+ this->NinjaSupportsUnconditionalRecompactTool =
+ !cmSystemTools::VersionCompare(
+ cmSystemTools::OP_LESS, this->NinjaVersion.c_str(),
+ RequiredNinjaVersionForUnconditionalRecompactTool().c_str());
+ this->NinjaSupportsRestatTool = !cmSystemTools::VersionCompare(
+ cmSystemTools::OP_LESS, this->NinjaVersion.c_str(),
+ RequiredNinjaVersionForRestatTool().c_str());
}
bool cmGlobalNinjaGenerator::CheckLanguages(
std::vector<std::string> const& languages, cmMakefile* mf) const
{
- if (cmContains(languages, "Fortran")) {
+ if (cm::contains(languages, "Fortran")) {
return this->CheckFortran(mf);
}
+ if (cm::contains(languages, "Swift")) {
+ const std::string architectures =
+ mf->GetSafeDefinition("CMAKE_OSX_ARCHITECTURES");
+ if (architectures.find_first_of(';') != std::string::npos) {
+ mf->IssueMessage(MessageType::FATAL_ERROR,
+ "multiple values for CMAKE_OSX_ARCHITECTURES not "
+ "supported with Swift");
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+ }
return true;
}
@@ -590,15 +711,8 @@ bool cmGlobalNinjaGenerator::CheckFortran(cmMakefile* mf) const
/* clang-format off */
e <<
"The Ninja generator does not support Fortran using Ninja version\n"
- " " + this->NinjaVersion + "\n"
- "due to lack of required features. "
- "Kitware has implemented the required features and they have been "
- "merged to upstream ninja for inclusion in Ninja 1.10 and higher. "
- "As of this version of CMake, Ninja 1.10 has not been released. "
- "Meanwhile, Kitware maintains a branch of Ninja at:\n"
- " https://github.com/Kitware/ninja/tree/features-for-fortran#readme\n"
- "with the required features. "
- "One may build ninja from that branch to get support for Fortran."
+ " " << this->NinjaVersion << "\n"
+ "due to lack of required features. Ninja 1.10 or higher is required."
;
/* clang-format on */
mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
@@ -609,6 +723,17 @@ bool cmGlobalNinjaGenerator::CheckFortran(cmMakefile* mf) const
void cmGlobalNinjaGenerator::EnableLanguage(
std::vector<std::string> const& langs, cmMakefile* mf, bool optional)
{
+ if (this->IsMultiConfig()) {
+ if (!mf->GetDefinition("CMAKE_CONFIGURATION_TYPES")) {
+ mf->AddCacheDefinition(
+ "CMAKE_CONFIGURATION_TYPES", "Debug;Release;RelWithDebInfo",
+ "Semicolon separated list of supported configuration types, only "
+ "supports Debug, Release, MinSizeRel, and RelWithDebInfo, anything "
+ "else will be ignored",
+ cmStateEnums::STRING);
+ }
+ }
+
this->cmGlobalGenerator::EnableLanguage(langs, mf, optional);
for (std::string const& l : langs) {
if (l == "NONE") {
@@ -650,7 +775,7 @@ std::vector<cmGlobalGenerator::GeneratedMakeCommand>
cmGlobalNinjaGenerator::GenerateBuildCommand(
const std::string& makeProgram, const std::string& /*projectName*/,
const std::string& /*projectDir*/,
- std::vector<std::string> const& targetNames, const std::string& /*config*/,
+ std::vector<std::string> const& targetNames, const std::string& config,
bool /*fast*/, int jobs, bool verbose,
std::vector<std::string> const& makeOptions)
{
@@ -666,6 +791,8 @@ cmGlobalNinjaGenerator::GenerateBuildCommand(
makeCommand.Add("-j", std::to_string(jobs));
}
+ this->AppendNinjaFileArgument(makeCommand, config);
+
makeCommand.Add(makeOptions.begin(), makeOptions.end());
for (const auto& tname : targetNames) {
if (!tname.empty()) {
@@ -707,44 +834,76 @@ void cmGlobalNinjaGenerator::ComputeTargetObjectDirectory(
cmGeneratorTarget* gt) const
{
// Compute full path to object file directory for this target.
- std::string dir =
- cmStrCat(gt->LocalGenerator->GetCurrentBinaryDirectory(), '/',
- gt->LocalGenerator->GetTargetDirectory(gt), '/');
+ std::string dir = cmStrCat(gt->LocalGenerator->GetCurrentBinaryDirectory(),
+ '/', gt->LocalGenerator->GetTargetDirectory(gt),
+ '/', this->GetCMakeCFGIntDir(), '/');
gt->ObjectDirectory = dir;
}
// Private methods
-bool cmGlobalNinjaGenerator::OpenBuildFileStream()
+bool cmGlobalNinjaGenerator::OpenBuildFileStreams()
{
- // Compute Ninja's build file path.
- std::string buildFilePath =
- cmStrCat(this->GetCMakeInstance()->GetHomeOutputDirectory(), '/',
- cmGlobalNinjaGenerator::NINJA_BUILD_FILE);
+ if (!this->OpenFileStream(this->BuildFileStream,
+ cmGlobalNinjaGenerator::NINJA_BUILD_FILE)) {
+ return false;
+ }
+
+ // Write a comment about this file.
+ *this->BuildFileStream
+ << "# This file contains all the build statements describing the\n"
+ << "# compilation DAG.\n\n";
+ return true;
+}
+
+bool cmGlobalNinjaGenerator::OpenFileStream(
+ std::unique_ptr<cmGeneratedFileStream>& stream, const std::string& name)
+{
// Get a stream where to generate things.
- if (!this->BuildFileStream) {
- this->BuildFileStream = cm::make_unique<cmGeneratedFileStream>(
- buildFilePath, false, this->GetMakefileEncoding());
- if (!(*this->BuildFileStream)) {
+ if (!stream) {
+ // Compute Ninja's build file path.
+ std::string path =
+ cmStrCat(this->GetCMakeInstance()->GetHomeOutputDirectory(), '/', name);
+ stream = cm::make_unique<cmGeneratedFileStream>(
+ path, false, this->GetMakefileEncoding());
+ if (!(*stream)) {
// An error message is generated by the constructor if it cannot
// open the file.
return false;
}
+
+ // Write the do not edit header.
+ this->WriteDisclaimer(*stream);
}
- // Write the do not edit header.
- this->WriteDisclaimer(*this->BuildFileStream);
+ return true;
+}
- // Write a comment about this file.
- *this->BuildFileStream
- << "# This file contains all the build statements describing the\n"
- << "# compilation DAG.\n\n";
+cm::optional<std::set<std::string>> cmGlobalNinjaGenerator::ListSubsetWithAll(
+ const std::set<std::string>& all, const std::set<std::string>& defaults,
+ const std::vector<std::string>& items)
+{
+ std::set<std::string> result;
- return true;
+ for (auto const& item : items) {
+ if (item == "all") {
+ if (items.size() == 1) {
+ result = defaults;
+ } else {
+ return cm::nullopt;
+ }
+ } else if (all.count(item)) {
+ result.insert(item);
+ } else {
+ return cm::nullopt;
+ }
+ }
+
+ return cm::make_optional(result);
}
-void cmGlobalNinjaGenerator::CloseBuildFileStream()
+void cmGlobalNinjaGenerator::CloseBuildFileStreams()
{
if (this->BuildFileStream) {
this->BuildFileStream.reset();
@@ -755,25 +914,11 @@ void cmGlobalNinjaGenerator::CloseBuildFileStream()
bool cmGlobalNinjaGenerator::OpenRulesFileStream()
{
- // Compute Ninja's build file path.
- std::string rulesFilePath =
- cmStrCat(this->GetCMakeInstance()->GetHomeOutputDirectory(), '/',
- cmGlobalNinjaGenerator::NINJA_RULES_FILE);
-
- // Get a stream where to generate things.
- if (!this->RulesFileStream) {
- this->RulesFileStream = cm::make_unique<cmGeneratedFileStream>(
- rulesFilePath, false, this->GetMakefileEncoding());
- if (!(*this->RulesFileStream)) {
- // An error message is generated by the constructor if it cannot
- // open the file.
- return false;
- }
+ if (!this->OpenFileStream(this->RulesFileStream,
+ cmGlobalNinjaGenerator::NINJA_RULES_FILE)) {
+ return false;
}
- // Write the do not edit header.
- this->WriteDisclaimer(*this->RulesFileStream);
-
// Write comment about this file.
/* clang-format off */
*this->RulesFileStream
@@ -819,10 +964,10 @@ std::string const& cmGlobalNinjaGenerator::ConvertToNinjaPath(
return f->second;
}
- cmLocalNinjaGenerator* ng =
- static_cast<cmLocalNinjaGenerator*>(this->LocalGenerators[0]);
- std::string const& bin_dir = ng->GetState()->GetBinaryDirectory();
- std::string convPath = ng->MaybeConvertToRelativePath(bin_dir, path);
+ const auto& ng =
+ cm::static_reference_cast<cmLocalNinjaGenerator>(this->LocalGenerators[0]);
+ std::string const& bin_dir = ng.GetState()->GetBinaryDirectory();
+ std::string convPath = ng.MaybeConvertToRelativePath(bin_dir, path);
convPath = this->NinjaOutputPath(convPath);
#ifdef _WIN32
std::replace(convPath.begin(), convPath.end(), '/', '\\');
@@ -831,9 +976,10 @@ std::string const& cmGlobalNinjaGenerator::ConvertToNinjaPath(
.first->second;
}
-void cmGlobalNinjaGenerator::AddAdditionalCleanFile(std::string fileName)
+void cmGlobalNinjaGenerator::AddAdditionalCleanFile(std::string fileName,
+ const std::string& config)
{
- this->AdditionalCleanFiles.emplace(std::move(fileName));
+ this->Configs[config].AdditionalCleanFiles.emplace(std::move(fileName));
}
void cmGlobalNinjaGenerator::AddCXXCompileCommand(
@@ -843,7 +989,8 @@ void cmGlobalNinjaGenerator::AddCXXCompileCommand(
std::string buildFileDir =
this->GetCMakeInstance()->GetHomeOutputDirectory();
if (!this->CompileCommandsStream) {
- std::string buildFilePath = buildFileDir + "/compile_commands.json";
+ std::string buildFilePath =
+ cmStrCat(buildFileDir, "/compile_commands.json");
if (this->ComputingUnknownDependencies) {
this->CombinedBuildOutputs.insert(
this->NinjaOutputPath("compile_commands.json"));
@@ -852,9 +999,9 @@ void cmGlobalNinjaGenerator::AddCXXCompileCommand(
// Get a stream where to generate things.
this->CompileCommandsStream =
cm::make_unique<cmGeneratedFileStream>(buildFilePath);
- *this->CompileCommandsStream << "[";
+ *this->CompileCommandsStream << "[\n";
} else {
- *this->CompileCommandsStream << "," << std::endl;
+ *this->CompileCommandsStream << ",\n";
}
std::string sourceFileName = sourceFile;
@@ -864,7 +1011,7 @@ void cmGlobalNinjaGenerator::AddCXXCompileCommand(
}
/* clang-format off */
- *this->CompileCommandsStream << "\n{\n"
+ *this->CompileCommandsStream << "{\n"
<< R"( "directory": ")"
<< cmGlobalGenerator::EscapeJSON(buildFileDir) << "\",\n"
<< R"( "command": ")"
@@ -901,23 +1048,21 @@ void cmGlobalNinjaGenerator::WriteAssumedSourceDependencies()
"Assume dependencies for generated source file.",
/*depfile*/ "", /*job_pool*/ "",
/*uses_terminal*/ false,
- /*restat*/ true, cmNinjaDeps(1, asd.first),
+ /*restat*/ true, cmNinjaDeps(1, asd.first), "",
cmNinjaDeps(), orderOnlyDeps);
}
}
-std::string OrderDependsTargetForTarget(cmGeneratorTarget const* target)
+std::string cmGlobalNinjaGenerator::OrderDependsTargetForTarget(
+ cmGeneratorTarget const* target, const std::string& /*config*/) const
{
- return "cmake_object_order_depends_target_" + target->GetName();
+ return cmStrCat("cmake_object_order_depends_target_", target->GetName());
}
void cmGlobalNinjaGenerator::AppendTargetOutputs(
cmGeneratorTarget const* target, cmNinjaDeps& outputs,
- cmNinjaTargetDepends depends)
+ const std::string& config, cmNinjaTargetDepends depends)
{
- std::string configName =
- target->Target->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE");
-
// for frameworks, we want the real name, not smple name
// frameworks always appear versioned, and the build.ninja
// will always attempt to manage symbolic links instead
@@ -929,19 +1074,19 @@ void cmGlobalNinjaGenerator::AppendTargetOutputs(
case cmStateEnums::STATIC_LIBRARY:
case cmStateEnums::MODULE_LIBRARY: {
if (depends == DependOnTargetOrdering) {
- outputs.push_back(OrderDependsTargetForTarget(target));
+ outputs.push_back(OrderDependsTargetForTarget(target, config));
break;
}
}
// FALLTHROUGH
case cmStateEnums::EXECUTABLE: {
outputs.push_back(this->ConvertToNinjaPath(target->GetFullPath(
- configName, cmStateEnums::RuntimeBinaryArtifact, realname)));
+ config, cmStateEnums::RuntimeBinaryArtifact, realname)));
break;
}
case cmStateEnums::OBJECT_LIBRARY: {
if (depends == DependOnTargetOrdering) {
- outputs.push_back(OrderDependsTargetForTarget(target));
+ outputs.push_back(OrderDependsTargetForTarget(target, config));
break;
}
}
@@ -949,9 +1094,13 @@ void cmGlobalNinjaGenerator::AppendTargetOutputs(
case cmStateEnums::GLOBAL_TARGET:
case cmStateEnums::UTILITY: {
std::string path =
- target->GetLocalGenerator()->GetCurrentBinaryDirectory() +
- std::string("/") + target->GetName();
- outputs.push_back(this->ConvertToNinjaPath(path));
+ cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(), '/',
+ target->GetName());
+ std::string output = this->ConvertToNinjaPath(path);
+ if (target->Target->IsPerConfig()) {
+ output = this->BuildAlias(output, config);
+ }
+ outputs.push_back(output);
break;
}
@@ -962,15 +1111,17 @@ void cmGlobalNinjaGenerator::AppendTargetOutputs(
void cmGlobalNinjaGenerator::AppendTargetDepends(
cmGeneratorTarget const* target, cmNinjaDeps& outputs,
+ const std::string& config, const std::string& fileConfig,
cmNinjaTargetDepends depends)
{
if (target->GetType() == cmStateEnums::GLOBAL_TARGET) {
// These depend only on other CMake-provided targets, e.g. "all".
- for (BT<std::string> const& util : target->GetUtilities()) {
+ for (BT<std::pair<std::string, bool>> const& util :
+ target->GetUtilities()) {
std::string d =
- target->GetLocalGenerator()->GetCurrentBinaryDirectory() + "/" +
- util.Value;
- outputs.push_back(this->ConvertToNinjaPath(d));
+ cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(), '/',
+ util.Value.first);
+ outputs.push_back(this->BuildAlias(this->ConvertToNinjaPath(d), config));
}
} else {
cmNinjaDeps outs;
@@ -979,29 +1130,36 @@ void cmGlobalNinjaGenerator::AppendTargetDepends(
if (targetDep->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
- this->AppendTargetOutputs(targetDep, outs, depends);
+ if (targetDep.IsCross()) {
+ this->AppendTargetOutputs(targetDep, outs, fileConfig, depends);
+ } else {
+ this->AppendTargetOutputs(targetDep, outs, config, depends);
+ }
}
std::sort(outs.begin(), outs.end());
- cmAppend(outputs, outs);
+ cm::append(outputs, outs);
}
}
void cmGlobalNinjaGenerator::AppendTargetDependsClosure(
- cmGeneratorTarget const* target, cmNinjaDeps& outputs)
+ cmGeneratorTarget const* target, cmNinjaDeps& outputs,
+ const std::string& config)
{
cmNinjaOuts outs;
- this->AppendTargetDependsClosure(target, outs, true);
- cmAppend(outputs, outs);
+ this->AppendTargetDependsClosure(target, outs, config, true);
+ cm::append(outputs, outs);
}
void cmGlobalNinjaGenerator::AppendTargetDependsClosure(
- cmGeneratorTarget const* target, cmNinjaOuts& outputs, bool omit_self)
+ cmGeneratorTarget const* target, cmNinjaOuts& outputs,
+ const std::string& config, bool omit_self)
{
// try to locate the target in the cache
- auto find = this->TargetDependsClosures.lower_bound(target);
+ auto find = this->Configs[config].TargetDependsClosures.lower_bound(target);
- if (find == this->TargetDependsClosures.end() || find->first != target) {
+ if (find == this->Configs[config].TargetDependsClosures.end() ||
+ find->first != target) {
// We now calculate the closure outputs by inspecting the dependent
// targets recursively.
// For that we have to distinguish between a local result set that is only
@@ -1011,15 +1169,16 @@ void cmGlobalNinjaGenerator::AppendTargetDependsClosure(
cmNinjaOuts this_outs; // this will be the new cache entry
for (auto const& dep_target : this->GetTargetDirectDepends(target)) {
- if (dep_target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+ if (dep_target->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
+ (this->EnableCrossConfigBuild() && !dep_target.IsCross())) {
continue;
}
// Collect the dependent targets for _this_ target
- this->AppendTargetDependsClosure(dep_target, this_outs, false);
+ this->AppendTargetDependsClosure(dep_target, this_outs, config, false);
}
- find = this->TargetDependsClosures.emplace_hint(find, target,
- std::move(this_outs));
+ find = this->Configs[config].TargetDependsClosures.emplace_hint(
+ find, target, std::move(this_outs));
}
// now fill the outputs of the final result from the newly generated cache
@@ -1029,29 +1188,56 @@ void cmGlobalNinjaGenerator::AppendTargetDependsClosure(
// finally generate the outputs of the target itself, if applicable
cmNinjaDeps outs;
if (!omit_self) {
- this->AppendTargetOutputs(target, outs);
+ this->AppendTargetOutputs(target, outs, config);
}
outputs.insert(outs.begin(), outs.end());
}
void cmGlobalNinjaGenerator::AddTargetAlias(const std::string& alias,
- cmGeneratorTarget* target)
+ cmGeneratorTarget* target,
+ const std::string& config)
{
- std::string buildAlias = this->NinjaOutputPath(alias);
+ std::string outputPath = this->NinjaOutputPath(alias);
+ std::string buildAlias = this->BuildAlias(outputPath, config);
cmNinjaDeps outputs;
- this->AppendTargetOutputs(target, outputs);
- // Mark the target's outputs as ambiguous to ensure that no other target uses
- // the output as an alias.
+ this->AppendTargetOutputs(target, outputs, config);
+ // Mark the target's outputs as ambiguous to ensure that no other target
+ // uses the output as an alias.
for (std::string const& output : outputs) {
- TargetAliases[output] = nullptr;
+ this->TargetAliases[output].GeneratorTarget = nullptr;
+ this->DefaultTargetAliases[output].GeneratorTarget = nullptr;
+ for (const std::string& config2 :
+ this->Makefiles.front()->GetGeneratorConfigs()) {
+ this->Configs[config2].TargetAliases[output].GeneratorTarget = nullptr;
+ }
}
// Insert the alias into the map. If the alias was already present in the
// map and referred to another target, mark it as ambiguous.
- std::pair<TargetAliasMap::iterator, bool> newAlias =
- TargetAliases.insert(std::make_pair(buildAlias, target));
- if (newAlias.second && newAlias.first->second != target) {
- newAlias.first->second = nullptr;
+ TargetAlias ta;
+ ta.GeneratorTarget = target;
+ ta.Config = config;
+
+ auto newAliasGlobal =
+ this->TargetAliases.insert(std::make_pair(buildAlias, ta));
+ if (newAliasGlobal.second &&
+ newAliasGlobal.first->second.GeneratorTarget != target) {
+ newAliasGlobal.first->second.GeneratorTarget = nullptr;
+ }
+
+ auto newAliasConfig =
+ this->Configs[config].TargetAliases.insert(std::make_pair(outputPath, ta));
+ if (newAliasConfig.second &&
+ newAliasConfig.first->second.GeneratorTarget != target) {
+ newAliasConfig.first->second.GeneratorTarget = nullptr;
+ }
+ if (this->DefaultConfigs.count(config)) {
+ auto newAliasDefaultGlobal =
+ this->DefaultTargetAliases.insert(std::make_pair(outputPath, ta));
+ if (newAliasDefaultGlobal.second &&
+ newAliasDefaultGlobal.first->second.GeneratorTarget != target) {
+ newAliasDefaultGlobal.first->second.GeneratorTarget = nullptr;
+ }
}
}
@@ -1061,10 +1247,10 @@ void cmGlobalNinjaGenerator::WriteTargetAliases(std::ostream& os)
os << "# Target aliases.\n\n";
cmNinjaBuild build("phony");
- build.Outputs.emplace_back("");
- for (auto const& ta : TargetAliases) {
+ build.Outputs.emplace_back();
+ for (auto const& ta : this->TargetAliases) {
// Don't write ambiguous aliases.
- if (!ta.second) {
+ if (!ta.second.GeneratorTarget) {
continue;
}
@@ -1074,13 +1260,69 @@ void cmGlobalNinjaGenerator::WriteTargetAliases(std::ostream& os)
continue;
}
- // Outputs
- build.Outputs[0] = ta.first;
- // Explicit depdendencies
+ build.Outputs.front() = ta.first;
build.ExplicitDeps.clear();
- this->AppendTargetOutputs(ta.second, build.ExplicitDeps);
- // Write
- this->WriteBuild(os, build);
+ if (ta.second.Config == "all") {
+ for (auto const& config : this->CrossConfigs) {
+ this->AppendTargetOutputs(ta.second.GeneratorTarget,
+ build.ExplicitDeps, config);
+ }
+ } else {
+ this->AppendTargetOutputs(ta.second.GeneratorTarget, build.ExplicitDeps,
+ ta.second.Config);
+ }
+ this->WriteBuild(this->EnableCrossConfigBuild() &&
+ (ta.second.Config == "all" ||
+ this->CrossConfigs.count(ta.second.Config))
+ ? os
+ : *this->GetImplFileStream(ta.second.Config),
+ build);
+ }
+
+ if (this->IsMultiConfig()) {
+ for (auto const& config : this->Makefiles.front()->GetGeneratorConfigs()) {
+ for (auto const& ta : this->Configs[config].TargetAliases) {
+ // Don't write ambiguous aliases.
+ if (!ta.second.GeneratorTarget) {
+ continue;
+ }
+
+ // Don't write alias if there is a already a custom command with
+ // matching output
+ if (this->HasCustomCommandOutput(ta.first)) {
+ continue;
+ }
+
+ build.Outputs.front() = ta.first;
+ build.ExplicitDeps.clear();
+ this->AppendTargetOutputs(ta.second.GeneratorTarget,
+ build.ExplicitDeps, config);
+ this->WriteBuild(*this->GetConfigFileStream(config), build);
+ }
+ }
+
+ if (!this->DefaultConfigs.empty()) {
+ for (auto const& ta : this->DefaultTargetAliases) {
+ // Don't write ambiguous aliases.
+ if (!ta.second.GeneratorTarget) {
+ continue;
+ }
+
+ // Don't write alias if there is a already a custom command with
+ // matching output
+ if (this->HasCustomCommandOutput(ta.first)) {
+ continue;
+ }
+
+ build.Outputs.front() = ta.first;
+ build.ExplicitDeps.clear();
+ for (auto const& config : this->DefaultConfigs) {
+ this->AppendTargetOutputs(ta.second.GeneratorTarget,
+ build.ExplicitDeps, config);
+ }
+ this->WriteBuild(*this->GetDefaultFileStream(), build);
+ }
+ }
}
}
@@ -1097,24 +1339,70 @@ void cmGlobalNinjaGenerator::WriteFolderTargets(std::ostream& os)
cmGlobalNinjaGenerator::WriteDivider(os);
std::string const& currentBinaryDir = it.first;
DirectoryTarget const& dt = it.second;
+ std::vector<std::string> configs;
+ dt.LG->GetMakefile()->GetConfigurations(configs, true);
+ if (configs.empty()) {
+ configs.emplace_back();
+ }
// Setup target
- build.Comment = "Folder: " + currentBinaryDir;
- build.Outputs.emplace_back(
- this->ConvertToNinjaPath(currentBinaryDir + "/all"));
- for (DirectoryTarget::Target const& t : dt.Targets) {
- if (!t.ExcludeFromAll) {
- this->AppendTargetOutputs(t.GT, build.ExplicitDeps);
+ cmNinjaDeps configDeps;
+ build.Comment = cmStrCat("Folder: ", currentBinaryDir);
+ build.Outputs.emplace_back();
+ std::string const buildDirAllTarget =
+ this->ConvertToNinjaPath(cmStrCat(currentBinaryDir, "/all"));
+ for (auto const& config : configs) {
+ build.ExplicitDeps.clear();
+ build.Outputs.front() = this->BuildAlias(buildDirAllTarget, config);
+ configDeps.emplace_back(build.Outputs.front());
+ for (DirectoryTarget::Target const& t : dt.Targets) {
+ if (!t.ExcludeFromAll) {
+ this->AppendTargetOutputs(t.GT, build.ExplicitDeps, config);
+ }
}
+ for (DirectoryTarget::Dir const& d : dt.Children) {
+ if (!d.ExcludeFromAll) {
+ build.ExplicitDeps.emplace_back(this->BuildAlias(
+ this->ConvertToNinjaPath(cmStrCat(d.Path, "/all")), config));
+ }
+ }
+ // Write target
+ this->WriteBuild(this->EnableCrossConfigBuild() &&
+ this->CrossConfigs.count(config)
+ ? os
+ : *this->GetImplFileStream(config),
+ build);
}
- for (DirectoryTarget::Dir const& d : dt.Children) {
- if (!d.ExcludeFromAll) {
- build.ExplicitDeps.emplace_back(
- this->ConvertToNinjaPath(d.Path + "/all"));
+
+ // Add shortcut target
+ if (this->IsMultiConfig()) {
+ for (auto const& config : configs) {
+ build.ExplicitDeps = { this->BuildAlias(buildDirAllTarget, config) };
+ build.Outputs.front() = buildDirAllTarget;
+ this->WriteBuild(*this->GetConfigFileStream(config), build);
+ }
+
+ if (!this->DefaultFileConfig.empty()) {
+ build.ExplicitDeps.clear();
+ for (auto const& config : this->DefaultConfigs) {
+ build.ExplicitDeps.push_back(
+ this->BuildAlias(buildDirAllTarget, config));
+ }
+ build.Outputs.front() = buildDirAllTarget;
+ this->WriteBuild(*this->GetDefaultFileStream(), build);
}
}
- // Write target
- this->WriteBuild(os, build);
+
+ // Add target for all configs
+ if (this->EnableCrossConfigBuild()) {
+ build.ExplicitDeps.clear();
+ for (auto const& config : this->CrossConfigs) {
+ build.ExplicitDeps.push_back(
+ this->BuildAlias(buildDirAllTarget, config));
+ }
+ build.Outputs.front() = this->BuildAlias(buildDirAllTarget, "all");
+ this->WriteBuild(os, build);
+ }
}
}
@@ -1148,7 +1436,7 @@ void cmGlobalNinjaGenerator::WriteUnknownExplicitDependencies(std::ostream& os)
// get the list of files that cmake itself has generated as a
// product of configuration.
- for (cmLocalGenerator* lg : this->LocalGenerators) {
+ for (const auto& lg : this->LocalGenerators) {
// get the vector of files created by this makefile and convert them
// to ninja paths, which are all relative in respect to the build directory
for (std::string const& file : lg->GetMakefile()->GetOutputFiles()) {
@@ -1161,8 +1449,7 @@ void cmGlobalNinjaGenerator::WriteUnknownExplicitDependencies(std::ostream& os)
knownDependencies.insert(this->ConvertToNinjaPath(j));
}
}
- for (cmGeneratorExpressionEvaluationFile* li :
- lg->GetMakefile()->GetEvaluationFiles()) {
+ for (const auto& li : lg->GetMakefile()->GetEvaluationFiles()) {
// get all the files created by generator expressions and convert them
// to ninja paths
for (std::string const& evaluationFile : li->GetFiles()) {
@@ -1247,10 +1534,17 @@ void cmGlobalNinjaGenerator::WriteBuiltinTargets(std::ostream& os)
cmGlobalNinjaGenerator::WriteDivider(os);
os << "# Built-in targets\n\n";
- this->WriteTargetDefault(os);
this->WriteTargetRebuildManifest(os);
this->WriteTargetClean(os);
this->WriteTargetHelp(os);
+
+ for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs()) {
+ this->WriteTargetDefault(*this->GetConfigFileStream(config));
+ }
+
+ if (!this->DefaultFileConfig.empty()) {
+ this->WriteTargetDefault(*this->GetDefaultFileStream());
+ }
}
void cmGlobalNinjaGenerator::WriteTargetDefault(std::ostream& os)
@@ -1268,12 +1562,12 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
if (this->GlobalSettingIsOn("CMAKE_SUPPRESS_REGENERATION")) {
return;
}
- cmLocalGenerator* lg = this->LocalGenerators[0];
+ const auto& lg = this->LocalGenerators[0];
{
cmNinjaRule rule("RERUN_CMAKE");
rule.Command =
- cmStrCat(CMakeCmd(), " -S",
+ cmStrCat(CMakeCmd(), " --regenerate-during-build -S",
lg->ConvertToOutputFormat(lg->GetSourceDirectory(),
cmOutputConverter::SHELL),
" -B",
@@ -1287,9 +1581,9 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
cmNinjaBuild reBuild("RERUN_CMAKE");
reBuild.Comment = "Re-run CMake if any of its inputs changed.";
- reBuild.Outputs.push_back(this->NinjaOutputPath(NINJA_BUILD_FILE));
+ this->AddRebuildManifestOutputs(reBuild.Outputs);
- for (cmLocalGenerator* localGen : this->LocalGenerators) {
+ for (const auto& localGen : this->LocalGenerators) {
for (std::string const& fi : localGen->GetMakefile()->GetListFiles()) {
reBuild.ImplicitDeps.push_back(this->ConvertToNinjaPath(fi));
}
@@ -1318,7 +1612,8 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
cmNinjaBuild phonyBuild("phony");
phonyBuild.Comment = "Phony target to force glob verification run.";
- phonyBuild.Outputs.push_back(cm->GetGlobVerifyScript() + "_force");
+ phonyBuild.Outputs.push_back(
+ cmStrCat(cm->GetGlobVerifyScript(), "_force"));
this->WriteBuild(os, phonyBuild);
reBuild.Variables["restat"] = "1";
@@ -1376,14 +1671,14 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
std::string cmGlobalNinjaGenerator::CMakeCmd() const
{
- cmLocalGenerator* lgen = this->LocalGenerators.at(0);
+ const auto& lgen = this->LocalGenerators.at(0);
return lgen->ConvertToOutputFormat(cmSystemTools::GetCMakeCommand(),
cmOutputConverter::SHELL);
}
std::string cmGlobalNinjaGenerator::NinjaCmd() const
{
- cmLocalGenerator* lgen = this->LocalGenerators[0];
+ const auto& lgen = this->LocalGenerators[0];
if (lgen != nullptr) {
return lgen->ConvertToOutputFormat(this->NinjaCommand,
cmOutputConverter::SHELL);
@@ -1413,13 +1708,27 @@ bool cmGlobalNinjaGenerator::SupportsMultilineDepfile() const
bool cmGlobalNinjaGenerator::WriteTargetCleanAdditional(std::ostream& os)
{
- cmLocalGenerator* lgr = this->LocalGenerators.at(0);
+ const auto& lgr = this->LocalGenerators.at(0);
std::string cleanScriptRel = "CMakeFiles/clean_additional.cmake";
std::string cleanScriptAbs =
cmStrCat(lgr->GetBinaryDirectory(), '/', cleanScriptRel);
+ std::vector<std::string> configs;
+ this->Makefiles[0]->GetConfigurations(configs, true);
+ if (configs.empty()) {
+ configs.emplace_back();
+ }
// Check if there are additional files to clean
- if (this->AdditionalCleanFiles.empty()) {
+ bool empty = true;
+ for (auto const& config : configs) {
+ auto const it = this->Configs.find(config);
+ if (it != this->Configs.end() &&
+ !it->second.AdditionalCleanFiles.empty()) {
+ empty = false;
+ break;
+ }
+ }
+ if (empty) {
// Remove cmake clean script file if it exists
cmSystemTools::RemoveFile(cleanScriptAbs);
return false;
@@ -1431,14 +1740,23 @@ bool cmGlobalNinjaGenerator::WriteTargetCleanAdditional(std::ostream& os)
if (!fout) {
return false;
}
- fout << "# Additional clean files\n\n";
- fout << "file(REMOVE_RECURSE\n";
- for (std::string const& acf : this->AdditionalCleanFiles) {
- fout << " "
- << cmOutputConverter::EscapeForCMake(ConvertToNinjaPath(acf))
- << '\n';
+ fout << "# Additional clean files\ncmake_minimum_required(VERSION 3.16)\n";
+ for (auto const& config : configs) {
+ auto const it = this->Configs.find(config);
+ if (it != this->Configs.end() &&
+ !it->second.AdditionalCleanFiles.empty()) {
+ fout << "\nif(\"${CONFIG}\" STREQUAL \"\" OR \"${CONFIG}\" STREQUAL \""
+ << config << "\")\n";
+ fout << " file(REMOVE_RECURSE\n";
+ for (std::string const& acf : it->second.AdditionalCleanFiles) {
+ fout << " "
+ << cmOutputConverter::EscapeForCMake(ConvertToNinjaPath(acf))
+ << '\n';
+ }
+ fout << " )\n";
+ fout << "endif()\n";
+ }
}
- fout << ")\n";
}
// Register clean script file
lgr->GetMakefile()->AddCMakeOutputFile(cleanScriptAbs);
@@ -1447,7 +1765,7 @@ bool cmGlobalNinjaGenerator::WriteTargetCleanAdditional(std::ostream& os)
{
cmNinjaRule rule("CLEAN_ADDITIONAL");
rule.Command = cmStrCat(
- CMakeCmd(), " -P ",
+ CMakeCmd(), " -DCONFIG=$CONFIG -P ",
lgr->ConvertToOutputFormat(this->NinjaOutputPath(cleanScriptRel),
cmOutputConverter::SHELL));
rule.Description = "Cleaning additional files...";
@@ -1459,9 +1777,19 @@ bool cmGlobalNinjaGenerator::WriteTargetCleanAdditional(std::ostream& os)
{
cmNinjaBuild build("CLEAN_ADDITIONAL");
build.Comment = "Clean additional files.";
- build.Outputs.push_back(
- this->NinjaOutputPath(this->GetAdditionalCleanTargetName()));
- WriteBuild(os, build);
+ build.Outputs.emplace_back();
+ for (auto const& config : configs) {
+ build.Outputs.front() = this->BuildAlias(
+ this->NinjaOutputPath(this->GetAdditionalCleanTargetName()), config);
+ build.Variables["CONFIG"] = config;
+ WriteBuild(os, build);
+ }
+ if (this->IsMultiConfig()) {
+ build.Outputs.front() =
+ this->NinjaOutputPath(this->GetAdditionalCleanTargetName());
+ build.Variables["CONFIG"] = "";
+ WriteBuild(os, build);
+ }
}
// Return success
return true;
@@ -1476,22 +1804,113 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
// Write rule
{
cmNinjaRule rule("CLEAN");
- rule.Command = NinjaCmd() + " -t clean";
+ rule.Command = cmStrCat(NinjaCmd(), " $FILE_ARG -t clean $TARGETS");
rule.Description = "Cleaning all built files...";
rule.Comment = "Rule for cleaning all built files.";
WriteRule(*this->RulesFileStream, rule);
}
+ auto const configs = this->Makefiles.front()->GetGeneratorConfigs();
+
// Write build
{
cmNinjaBuild build("CLEAN");
build.Comment = "Clean all the built files.";
- build.Outputs.push_back(this->NinjaOutputPath(this->GetCleanTargetName()));
- if (additionalFiles) {
- build.ExplicitDeps.push_back(
- this->NinjaOutputPath(this->GetAdditionalCleanTargetName()));
+ build.Outputs.emplace_back();
+
+ for (auto const& config : configs) {
+ build.Outputs.front() = this->BuildAlias(
+ this->NinjaOutputPath(this->GetCleanTargetName()), config);
+ if (this->IsMultiConfig()) {
+ build.Variables["TARGETS"] =
+ cmStrCat(this->BuildAlias(GetByproductsForCleanTargetName(), config),
+ " ", GetByproductsForCleanTargetName());
+ }
+ build.ExplicitDeps.clear();
+ if (additionalFiles) {
+ build.ExplicitDeps.push_back(this->BuildAlias(
+ this->NinjaOutputPath(this->GetAdditionalCleanTargetName()),
+ config));
+ }
+ for (auto const& fileConfig : configs) {
+ if (fileConfig != config && !this->EnableCrossConfigBuild()) {
+ continue;
+ }
+ if (this->IsMultiConfig()) {
+ build.Variables["FILE_ARG"] = cmStrCat(
+ "-f ",
+ cmGlobalNinjaMultiGenerator::GetNinjaImplFilename(fileConfig));
+ }
+ this->WriteBuild(*this->GetImplFileStream(fileConfig), build);
+ }
+ }
+
+ if (this->EnableCrossConfigBuild()) {
+ build.Outputs.front() = this->BuildAlias(
+ this->NinjaOutputPath(this->GetCleanTargetName()), "all");
+ build.ExplicitDeps.clear();
+
+ if (additionalFiles) {
+ for (auto const& config : this->CrossConfigs) {
+ build.ExplicitDeps.push_back(this->BuildAlias(
+ this->NinjaOutputPath(this->GetAdditionalCleanTargetName()),
+ config));
+ }
+ }
+
+ std::vector<std::string> byproducts;
+ for (auto const& config : this->CrossConfigs) {
+ byproducts.push_back(
+ this->BuildAlias(GetByproductsForCleanTargetName(), config));
+ }
+ build.Variables["TARGETS"] = cmJoin(byproducts, " ");
+
+ for (auto const& fileConfig : configs) {
+ build.Variables["FILE_ARG"] = cmStrCat(
+ "-f ",
+ cmGlobalNinjaMultiGenerator::GetNinjaImplFilename(fileConfig));
+ this->WriteBuild(*this->GetImplFileStream(fileConfig), build);
+ }
+ }
+ }
+
+ if (this->IsMultiConfig()) {
+ cmNinjaBuild build("phony");
+ build.Outputs.emplace_back(
+ this->NinjaOutputPath(this->GetCleanTargetName()));
+ build.ExplicitDeps.emplace_back();
+
+ for (auto const& config : configs) {
+ build.ExplicitDeps.front() = this->BuildAlias(
+ this->NinjaOutputPath(this->GetCleanTargetName()), config);
+ this->WriteBuild(*this->GetConfigFileStream(config), build);
}
+
+ if (!this->DefaultConfigs.empty()) {
+ build.ExplicitDeps.clear();
+ for (auto const& config : this->DefaultConfigs) {
+ build.ExplicitDeps.push_back(this->BuildAlias(
+ this->NinjaOutputPath(this->GetCleanTargetName()), config));
+ }
+ this->WriteBuild(*this->GetDefaultFileStream(), build);
+ }
+ }
+
+ // Write byproducts
+ if (this->IsMultiConfig()) {
+ cmNinjaBuild build("phony");
+ build.Comment = "Clean byproducts.";
+ build.Outputs.emplace_back(
+ this->ConvertToNinjaPath(GetByproductsForCleanTargetName()));
+ build.ExplicitDeps = this->ByproductsForCleanTarget;
WriteBuild(os, build);
+
+ for (auto const& config : configs) {
+ build.Outputs.front() = this->BuildAlias(
+ this->ConvertToNinjaPath(GetByproductsForCleanTargetName()), config);
+ build.ExplicitDeps = this->Configs[config].ByproductsForCleanTarget;
+ WriteBuild(os, build);
+ }
}
}
@@ -1499,7 +1918,7 @@ void cmGlobalNinjaGenerator::WriteTargetHelp(std::ostream& os)
{
{
cmNinjaRule rule("HELP");
- rule.Command = NinjaCmd() + " -t targets";
+ rule.Command = cmStrCat(NinjaCmd(), " -t targets");
rule.Description = "All primary targets available:";
rule.Comment = "Rule for printing all primary targets available.";
WriteRule(*this->RulesFileStream, rule);
@@ -1526,7 +1945,7 @@ std::string cmGlobalNinjaGenerator::NinjaOutputPath(
if (!this->HasOutputPathPrefix() || cmSystemTools::FileIsFullPath(path)) {
return path;
}
- return this->OutputPathPrefix + path;
+ return cmStrCat(this->OutputPathPrefix, path);
}
void cmGlobalNinjaGenerator::StripNinjaOutputPathPrefixAsSuffix(
@@ -1654,7 +2073,8 @@ int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg,
} else if (cmHasLiteralPrefix(arg, "--lang=")) {
arg_lang = arg.substr(7);
} else {
- cmSystemTools::Error("-E cmake_ninja_depends unknown argument: " + arg);
+ cmSystemTools::Error(
+ cmStrCat("-E cmake_ninja_depends unknown argument: ", arg));
return 1;
}
}
@@ -1725,7 +2145,8 @@ int cmcmd_cmake_ninja_depends(std::vector<std::string>::const_iterator argBeg,
cmGeneratedFileStream ddif(arg_ddi);
ddif << ddi;
if (!ddif) {
- cmSystemTools::Error("-E cmake_ninja_depends failed to write " + arg_ddi);
+ cmSystemTools::Error(
+ cmStrCat("-E cmake_ninja_depends failed to write ", arg_ddi));
return 1;
}
return 0;
@@ -1771,7 +2192,8 @@ std::unique_ptr<cmSourceInfo> cmcmd_cmake_ninja_depends_fortran(
std::set<std::string> defines;
cmFortranParser parser(fc, includes, defines, finfo);
if (!cmFortranParser_FilePush(&parser, arg_pp.c_str())) {
- cmSystemTools::Error("-E cmake_ninja_depends failed to open " + arg_pp);
+ cmSystemTools::Error(
+ cmStrCat("-E cmake_ninja_depends failed to open ", arg_pp));
return nullptr;
}
if (cmFortran_yyparse(parser.Scanner) != 0) {
@@ -1809,11 +2231,9 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
snapshot.GetDirectory().SetRelativePathTopSource(dir_top_src.c_str());
snapshot.GetDirectory().SetRelativePathTopBinary(dir_top_bld.c_str());
auto mfd = cm::make_unique<cmMakefile>(this, snapshot);
- std::unique_ptr<cmLocalNinjaGenerator> lgd(
- static_cast<cmLocalNinjaGenerator*>(
- this->CreateLocalGenerator(mfd.get())));
- this->Makefiles.push_back(mfd.release());
- this->LocalGenerators.push_back(lgd.release());
+ auto lgd = this->CreateLocalGenerator(mfd.get());
+ this->Makefiles.push_back(std::move(mfd));
+ this->LocalGenerators.push_back(std::move(lgd));
}
std::vector<cmDyndepObjectInfo> objects;
@@ -1876,7 +2296,7 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
Json::Value tm = Json::objectValue;
for (cmDyndepObjectInfo const& object : objects) {
for (std::string const& p : object.Provides) {
- std::string const mod = module_dir + p;
+ std::string const mod = cmStrCat(module_dir, p);
mod_files[p] = mod;
tm[p] = mod;
}
@@ -1912,14 +2332,19 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
// 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 =
- cmSystemTools::GetFilenamePath(arg_dd) + "/" + arg_lang + "Modules.json";
+ std::string const target_mods_file = cmStrCat(
+ cmSystemTools::GetFilenamePath(arg_dd), '/', arg_lang, "Modules.json");
cmGeneratedFileStream tmf(target_mods_file);
tmf << tm;
return true;
}
+bool cmGlobalNinjaGenerator::EnableCrossConfigBuild() const
+{
+ return !this->CrossConfigs.empty();
+}
+
int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
std::vector<std::string>::const_iterator argEnd)
{
@@ -1941,7 +2366,8 @@ int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
cmHasLiteralSuffix(arg, ".ddi")) {
arg_ddis.push_back(arg);
} else {
- cmSystemTools::Error("-E cmake_ninja_dyndep unknown argument: " + arg);
+ cmSystemTools::Error(
+ cmStrCat("-E cmake_ninja_dyndep unknown argument: ", arg));
return 1;
}
}
@@ -1977,7 +2403,7 @@ int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
std::string const dir_top_src = tdi["dir-top-src"].asString();
std::string module_dir = tdi["module-dir"].asString();
if (!module_dir.empty() && !cmHasLiteralSuffix(module_dir, "/")) {
- module_dir += "/";
+ module_dir += '/';
}
std::vector<std::string> linked_target_dirs;
Json::Value const& tdi_linked_target_dirs = tdi["linked-target-dirs"];
@@ -1990,13 +2416,271 @@ int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
cmake cm(cmake::RoleInternal, cmState::Unknown);
cm.SetHomeDirectory(dir_top_src);
cm.SetHomeOutputDirectory(dir_top_bld);
- std::unique_ptr<cmGlobalNinjaGenerator> ggd(
- static_cast<cmGlobalNinjaGenerator*>(cm.CreateGlobalGenerator("Ninja")));
+ auto ggd = cm.CreateGlobalGenerator("Ninja");
if (!ggd ||
- !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)) {
+ !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)) {
return 1;
}
return 0;
}
+
+void cmGlobalNinjaGenerator::AppendDirectoryForConfig(
+ const std::string& prefix, const std::string& config,
+ const std::string& suffix, std::string& dir)
+{
+ if (!config.empty() && this->IsMultiConfig()) {
+ dir += cmStrCat(prefix, config, suffix);
+ }
+}
+
+std::set<std::string> cmGlobalNinjaGenerator::GetCrossConfigs(
+ const std::string& fileConfig) const
+{
+ auto result = this->CrossConfigs;
+ result.insert(fileConfig);
+ return result;
+}
+
+const char* cmGlobalNinjaMultiGenerator::NINJA_COMMON_FILE =
+ "CMakeFiles/common.ninja";
+const char* cmGlobalNinjaMultiGenerator::NINJA_FILE_EXTENSION = ".ninja";
+
+cmGlobalNinjaMultiGenerator::cmGlobalNinjaMultiGenerator(cmake* cm)
+ : cmGlobalNinjaGenerator(cm)
+{
+ cm->GetState()->SetIsGeneratorMultiConfig(true);
+ cm->GetState()->SetNinjaMulti(true);
+}
+
+void cmGlobalNinjaMultiGenerator::GetDocumentation(cmDocumentationEntry& entry)
+{
+ entry.Name = cmGlobalNinjaMultiGenerator::GetActualName();
+ entry.Brief = "Generates build-<Config>.ninja files.";
+}
+
+std::string cmGlobalNinjaMultiGenerator::ExpandCFGIntDir(
+ const std::string& str, const std::string& config) const
+{
+ std::string result = str;
+ cmSystemTools::ReplaceString(result, this->GetCMakeCFGIntDir(), config);
+ return result;
+}
+
+bool cmGlobalNinjaMultiGenerator::OpenBuildFileStreams()
+{
+ if (!this->OpenFileStream(this->CommonFileStream,
+ cmGlobalNinjaMultiGenerator::NINJA_COMMON_FILE)) {
+ return false;
+ }
+
+ if (!this->DefaultFileConfig.empty()) {
+ if (!this->OpenFileStream(this->DefaultFileStream, NINJA_BUILD_FILE)) {
+ return false;
+ }
+ *this->DefaultFileStream
+ << "# Build using rules for '" << this->DefaultFileConfig << "'.\n\n"
+ << "include " << GetNinjaImplFilename(this->DefaultFileConfig) << "\n\n";
+ }
+
+ // Write a comment about this file.
+ *this->CommonFileStream
+ << "# This file contains build statements common to all "
+ "configurations.\n\n";
+
+ for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs()) {
+ // Open impl file.
+ if (!this->OpenFileStream(this->ImplFileStreams[config],
+ GetNinjaImplFilename(config))) {
+ return false;
+ }
+
+ // Write a comment about this file.
+ *this->ImplFileStreams[config]
+ << "# This file contains build statements specific to the \"" << config
+ << "\"\n# configuration.\n\n";
+
+ // Open config file.
+ if (!this->OpenFileStream(this->ConfigFileStreams[config],
+ GetNinjaConfigFilename(config))) {
+ return false;
+ }
+
+ // Write a comment about this file.
+ *this->ConfigFileStreams[config]
+ << "# This file contains aliases specific to the \"" << config
+ << "\"\n# configuration.\n\n"
+ << "include " << GetNinjaImplFilename(config) << "\n\n";
+ }
+
+ return true;
+}
+
+void cmGlobalNinjaMultiGenerator::CloseBuildFileStreams()
+{
+ if (this->CommonFileStream) {
+ this->CommonFileStream.reset();
+ } else {
+ cmSystemTools::Error("Common file stream was not open.");
+ }
+
+ if (this->DefaultFileStream) {
+ this->DefaultFileStream.reset();
+ } // No error if it wasn't open
+
+ for (auto const& config : this->Makefiles[0]->GetGeneratorConfigs()) {
+ if (this->ImplFileStreams[config]) {
+ this->ImplFileStreams[config].reset();
+ } else {
+ cmSystemTools::Error(
+ cmStrCat("Impl file stream for \"", config, "\" was not open."));
+ }
+ if (this->ConfigFileStreams[config]) {
+ this->ConfigFileStreams[config].reset();
+ } else {
+ cmSystemTools::Error(
+ cmStrCat("Config file stream for \"", config, "\" was not open."));
+ }
+ }
+}
+
+void cmGlobalNinjaMultiGenerator::AppendNinjaFileArgument(
+ GeneratedMakeCommand& command, const std::string& config) const
+{
+ if (!config.empty()) {
+ command.Add("-f");
+ command.Add(GetNinjaConfigFilename(config));
+ }
+}
+
+std::string cmGlobalNinjaMultiGenerator::GetNinjaImplFilename(
+ const std::string& config)
+{
+ return cmStrCat("CMakeFiles/impl-", config,
+ cmGlobalNinjaMultiGenerator::NINJA_FILE_EXTENSION);
+}
+
+std::string cmGlobalNinjaMultiGenerator::GetNinjaConfigFilename(
+ const std::string& config)
+{
+ return cmStrCat("build-", config,
+ cmGlobalNinjaMultiGenerator::NINJA_FILE_EXTENSION);
+}
+
+void cmGlobalNinjaMultiGenerator::AddRebuildManifestOutputs(
+ cmNinjaDeps& outputs) const
+{
+ for (auto const& config : this->Makefiles.front()->GetGeneratorConfigs()) {
+ outputs.push_back(this->NinjaOutputPath(GetNinjaImplFilename(config)));
+ outputs.push_back(this->NinjaOutputPath(GetNinjaConfigFilename(config)));
+ }
+ if (!this->DefaultFileConfig.empty()) {
+ outputs.push_back(this->NinjaOutputPath(NINJA_BUILD_FILE));
+ }
+}
+
+void cmGlobalNinjaMultiGenerator::GetQtAutoGenConfigs(
+ std::vector<std::string>& configs) const
+{
+ auto const oldSize = configs.size();
+ this->Makefiles.front()->GetConfigurations(configs);
+ if (configs.size() == oldSize) {
+ configs.emplace_back();
+ }
+}
+
+bool cmGlobalNinjaMultiGenerator::InspectConfigTypeVariables()
+{
+ this->GetCMakeInstance()->MarkCliAsUsed("CMAKE_DEFAULT_BUILD_TYPE");
+ this->GetCMakeInstance()->MarkCliAsUsed("CMAKE_CROSS_CONFIGS");
+ this->GetCMakeInstance()->MarkCliAsUsed("CMAKE_DEFAULT_CONFIGS");
+ return this->ReadCacheEntriesForBuild(*this->Makefiles.front()->GetState());
+}
+
+std::string cmGlobalNinjaMultiGenerator::GetDefaultBuildConfig() const
+{
+ return "";
+}
+
+bool cmGlobalNinjaMultiGenerator::ReadCacheEntriesForBuild(
+ const cmState& state)
+{
+ std::vector<std::string> configsVec;
+ cmExpandList(state.GetSafeCacheEntryValue("CMAKE_CONFIGURATION_TYPES"),
+ configsVec);
+ if (configsVec.empty()) {
+ configsVec.emplace_back();
+ }
+ std::set<std::string> configs(configsVec.cbegin(), configsVec.cend());
+
+ this->DefaultFileConfig =
+ state.GetSafeCacheEntryValue("CMAKE_DEFAULT_BUILD_TYPE");
+ if (this->DefaultFileConfig.empty()) {
+ this->DefaultFileConfig = configsVec.front();
+ }
+ if (!configs.count(this->DefaultFileConfig)) {
+ std::ostringstream msg;
+ msg << "The configuration specified by "
+ << "CMAKE_DEFAULT_BUILD_TYPE (" << this->DefaultFileConfig
+ << ") is not present in CMAKE_CONFIGURATION_TYPES";
+ this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
+ msg.str());
+ return false;
+ }
+
+ std::vector<std::string> crossConfigsVec;
+ cmExpandList(state.GetSafeCacheEntryValue("CMAKE_CROSS_CONFIGS"),
+ crossConfigsVec);
+ auto crossConfigs = ListSubsetWithAll(configs, configs, crossConfigsVec);
+ if (!crossConfigs) {
+ std::ostringstream msg;
+ msg << "CMAKE_CROSS_CONFIGS is not a subset of "
+ << "CMAKE_CONFIGURATION_TYPES";
+ this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
+ msg.str());
+ return false;
+ }
+ this->CrossConfigs = *crossConfigs;
+
+ auto defaultConfigsString =
+ state.GetSafeCacheEntryValue("CMAKE_DEFAULT_CONFIGS");
+ if (defaultConfigsString.empty()) {
+ defaultConfigsString = this->DefaultFileConfig;
+ }
+ if (!defaultConfigsString.empty() &&
+ defaultConfigsString != this->DefaultFileConfig &&
+ (this->DefaultFileConfig.empty() || this->CrossConfigs.empty())) {
+ std::ostringstream msg;
+ msg << "CMAKE_DEFAULT_CONFIGS cannot be used without "
+ << "CMAKE_DEFAULT_BUILD_TYPE or CMAKE_CROSS_CONFIGS";
+ this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
+ msg.str());
+ return false;
+ }
+
+ std::vector<std::string> defaultConfigsVec;
+ cmExpandList(defaultConfigsString, defaultConfigsVec);
+ if (!this->DefaultFileConfig.empty()) {
+ auto defaultConfigs =
+ ListSubsetWithAll(this->GetCrossConfigs(this->DefaultFileConfig),
+ this->CrossConfigs, defaultConfigsVec);
+ if (!defaultConfigs) {
+ std::ostringstream msg;
+ msg << "CMAKE_DEFAULT_CONFIGS is not a subset of CMAKE_CROSS_CONFIGS";
+ this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
+ msg.str());
+ return false;
+ }
+ this->DefaultConfigs = *defaultConfigs;
+ }
+
+ return true;
+}
+
+std::string cmGlobalNinjaMultiGenerator::OrderDependsTargetForTarget(
+ cmGeneratorTarget const* target, const std::string& config) const
+{
+ return cmStrCat("cmake_object_order_depends_target_", target->GetName(), '_',
+ cmSystemTools::UpperCase(config));
+}
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index 244e9fd..b89fb8f 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -15,6 +15,8 @@
#include <utility>
#include <vector>
+#include <cm/optional>
+
#include "cm_codecvt.hxx"
#include "cmGeneratedFileStream.h"
@@ -22,6 +24,7 @@
#include "cmGlobalGeneratorFactory.h"
#include "cmNinjaTypes.h"
#include "cmPolicies.h"
+#include "cmStringAlgorithms.h"
class cmCustomCommand;
class cmGeneratorTarget;
@@ -29,6 +32,7 @@ class cmLinkLineComputer;
class cmLocalGenerator;
class cmMakefile;
class cmOutputConverter;
+class cmState;
class cmStateDirectory;
class cmake;
struct cmDocumentationEntry;
@@ -73,10 +77,10 @@ public:
static void WriteDivider(std::ostream& os);
static std::string EncodeRuleName(std::string const& name);
- static std::string EncodeLiteral(const std::string& lit);
+ std::string EncodeLiteral(const std::string& lit);
std::string EncodePath(const std::string& path);
- cmLinkLineComputer* CreateLinkLineComputer(
+ std::unique_ptr<cmLinkLineComputer> CreateLinkLineComputer(
cmOutputConverter* outputConverter,
cmStateDirectory const& stateDir) const override;
@@ -111,11 +115,12 @@ public:
const std::string& command, const std::string& description,
const std::string& comment, const std::string& depfile,
const std::string& pool, bool uses_terminal, bool restat,
- const cmNinjaDeps& outputs,
+ const cmNinjaDeps& outputs, const std::string& config,
const cmNinjaDeps& explicitDeps = cmNinjaDeps(),
const cmNinjaDeps& orderOnlyDeps = cmNinjaDeps());
- void WriteMacOSXContentBuild(std::string input, std::string output);
+ void WriteMacOSXContentBuild(std::string input, std::string output,
+ const std::string& config);
/**
* Write a rule statement to @a os.
@@ -151,12 +156,14 @@ public:
public:
cmGlobalNinjaGenerator(cmake* cm);
- static cmGlobalGeneratorFactory* NewFactory()
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory()
{
- return new cmGlobalGeneratorSimpleFactory<cmGlobalNinjaGenerator>();
+ return std::unique_ptr<cmGlobalGeneratorFactory>(
+ new cmGlobalGeneratorSimpleFactory<cmGlobalNinjaGenerator>());
}
- cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) override;
+ std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
+ cmMakefile* mf) override;
std::string GetName() const override
{
@@ -204,7 +211,26 @@ public:
}
const char* GetCleanTargetName() const override { return "clean"; }
- cmGeneratedFileStream* GetBuildFileStream() const
+ bool SupportsCustomCommandDepfile() const override { return true; }
+
+ virtual cmGeneratedFileStream* GetImplFileStream(
+ const std::string& /*config*/) const
+ {
+ return this->BuildFileStream.get();
+ }
+
+ virtual cmGeneratedFileStream* GetConfigFileStream(
+ const std::string& /*config*/) const
+ {
+ return this->BuildFileStream.get();
+ }
+
+ virtual cmGeneratedFileStream* GetDefaultFileStream() const
+ {
+ return this->BuildFileStream.get();
+ }
+
+ virtual cmGeneratedFileStream* GetCommonFileStream() const
{
return this->BuildFileStream.get();
}
@@ -231,12 +257,17 @@ public:
MapToNinjaPathImpl MapToNinjaPath() { return { this }; }
// -- Additional clean files
- void AddAdditionalCleanFile(std::string fileName);
+ void AddAdditionalCleanFile(std::string fileName, const std::string& config);
const char* GetAdditionalCleanTargetName() const
{
return "CMakeFiles/clean.additional";
}
+ static const char* GetByproductsForCleanTargetName()
+ {
+ return "CMakeFiles/cmake_byproducts_for_clean_target";
+ }
+
void AddCXXCompileCommand(const std::string& commandLine,
const std::string& sourceFile);
@@ -260,9 +291,9 @@ public:
/// Called when we have seen the given custom command. Returns true
/// if we has seen it before.
- bool SeenCustomCommand(cmCustomCommand const* cc)
+ bool SeenCustomCommand(cmCustomCommand const* cc, const std::string& config)
{
- return !this->CustomCommands.insert(cc).second;
+ return !this->Configs[config].CustomCommands.insert(cc).second;
}
/// Called when we have seen the given custom command output.
@@ -284,25 +315,43 @@ public:
ASD.insert(deps.begin(), deps.end());
}
+ virtual std::string OrderDependsTargetForTarget(
+ cmGeneratorTarget const* target, const std::string& config) const;
+
void AppendTargetOutputs(
cmGeneratorTarget const* target, cmNinjaDeps& outputs,
+ const std::string& config,
cmNinjaTargetDepends depends = DependOnTargetArtifact);
void AppendTargetDepends(
cmGeneratorTarget const* target, cmNinjaDeps& outputs,
+ const std::string& config, const std::string& fileConfig,
cmNinjaTargetDepends depends = DependOnTargetArtifact);
void AppendTargetDependsClosure(cmGeneratorTarget const* target,
- cmNinjaDeps& outputs);
+ cmNinjaDeps& outputs,
+ const std::string& config);
void AppendTargetDependsClosure(cmGeneratorTarget const* target,
- cmNinjaOuts& outputs, bool omit_self);
+ cmNinjaOuts& outputs,
+ const std::string& config, bool omit_self);
+
+ void AppendDirectoryForConfig(const std::string& prefix,
+ const std::string& config,
+ const std::string& suffix,
+ std::string& dir) override;
- const std::vector<cmLocalGenerator*>& GetLocalGenerators() const
+ virtual void AppendNinjaFileArgument(GeneratedMakeCommand& /*command*/,
+ const std::string& /*config*/) const
{
- return LocalGenerators;
+ }
+
+ virtual void AddRebuildManifestOutputs(cmNinjaDeps& outputs) const
+ {
+ outputs.push_back(this->NinjaOutputPath(NINJA_BUILD_FILE));
}
int GetRuleCmdLength(const std::string& name) { return RuleCmdLength[name]; }
- void AddTargetAlias(const std::string& alias, cmGeneratorTarget* target);
+ void AddTargetAlias(const std::string& alias, cmGeneratorTarget* target,
+ const std::string& config);
void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const override;
@@ -316,6 +365,12 @@ public:
return "1.9";
}
static std::string RequiredNinjaVersionForDyndeps() { return "1.10"; }
+ static std::string RequiredNinjaVersionForRestatTool() { return "1.10"; }
+ static std::string RequiredNinjaVersionForUnconditionalRecompactTool()
+ {
+ return "1.10";
+ }
+ static std::string RequiredNinjaVersionForCleanDeadTool() { return "1.10"; }
bool SupportsConsolePool() const;
bool SupportsImplicitOuts() const;
bool SupportsManifestRestat() const;
@@ -335,11 +390,52 @@ public:
std::vector<std::string> const& linked_target_dirs,
std::string const& arg_lang);
+ virtual std::string BuildAlias(const std::string& alias,
+ const std::string& /*config*/) const
+ {
+ return alias;
+ }
+
+ virtual std::string ConfigDirectory(const std::string& /*config*/) const
+ {
+ return "";
+ }
+
+ cmNinjaDeps& GetByproductsForCleanTarget()
+ {
+ return this->ByproductsForCleanTarget;
+ }
+
+ cmNinjaDeps& GetByproductsForCleanTarget(const std::string& config)
+ {
+ return this->Configs[config].ByproductsForCleanTarget;
+ }
+
+ bool EnableCrossConfigBuild() const;
+
+ std::set<std::string> GetCrossConfigs(const std::string& config) const;
+
protected:
void Generate() override;
bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() const override { return true; }
+ virtual bool OpenBuildFileStreams();
+ virtual void CloseBuildFileStreams();
+
+ bool OpenFileStream(std::unique_ptr<cmGeneratedFileStream>& stream,
+ const std::string& name);
+
+ static cm::optional<std::set<std::string>> ListSubsetWithAll(
+ const std::set<std::string>& all, const std::set<std::string>& defaults,
+ const std::vector<std::string>& items);
+
+ virtual bool InspectConfigTypeVariables() { return true; }
+
+ std::set<std::string> CrossConfigs;
+ std::set<std::string> DefaultConfigs;
+ std::string DefaultFileConfig;
+
private:
std::string GetEditCacheCommand() const override;
bool FindMakeProgram(cmMakefile* mf) override;
@@ -348,13 +444,11 @@ private:
cmMakefile* mf) const override;
bool CheckFortran(cmMakefile* mf) const;
- bool OpenBuildFileStream();
- void CloseBuildFileStream();
-
void CloseCompileCommandsStream();
bool OpenRulesFileStream();
void CloseRulesFileStream();
+ void CleanMetaData();
/// Write the common disclaimer text at the top of each build file.
void WriteDisclaimer(std::ostream& os);
@@ -395,9 +489,6 @@ private:
bool UsingGCCOnWindows = false;
- /// The set of custom commands we have seen.
- std::set<cmCustomCommand const*> CustomCommands;
-
/// The set of custom command outputs we have seen.
std::set<std::string> CustomCommandOutputs;
@@ -416,10 +507,14 @@ private:
/// The mapping from source file to assumed dependencies.
std::map<std::string, std::set<std::string>> AssumedSourceDependencies;
- using TargetAliasMap = std::map<std::string, cmGeneratorTarget*>;
+ struct TargetAlias
+ {
+ cmGeneratorTarget* GeneratorTarget;
+ std::string Config;
+ };
+ using TargetAliasMap = std::map<std::string, TargetAlias>;
TargetAliasMap TargetAliases;
-
- std::map<cmGeneratorTarget const*, cmNinjaOuts> TargetDependsClosures;
+ TargetAliasMap DefaultTargetAliases;
/// the local cache for calls to ConvertToNinjaPath
mutable std::unordered_map<std::string, std::string> ConvertToNinjaPathCache;
@@ -431,6 +526,9 @@ private:
bool NinjaSupportsManifestRestat = false;
bool NinjaSupportsMultilineDepfile = false;
bool NinjaSupportsDyndeps = false;
+ bool NinjaSupportsRestatTool = false;
+ bool NinjaSupportsUnconditionalRecompactTool = false;
+ bool NinjaSupportsCleanDeadTool = false;
private:
void InitOutputPathPrefix();
@@ -438,7 +536,128 @@ private:
std::string OutputPathPrefix;
std::string TargetAll;
std::string CMakeCacheFile;
- std::set<std::string> AdditionalCleanFiles;
+
+ struct ByConfig
+ {
+ std::set<std::string> AdditionalCleanFiles;
+
+ /// The set of custom commands we have seen.
+ std::set<cmCustomCommand const*> CustomCommands;
+
+ std::map<cmGeneratorTarget const*, cmNinjaOuts> TargetDependsClosures;
+
+ TargetAliasMap TargetAliases;
+
+ cmNinjaDeps ByproductsForCleanTarget;
+ };
+ std::map<std::string, ByConfig> Configs;
+
+ cmNinjaDeps ByproductsForCleanTarget;
+};
+
+class cmGlobalNinjaMultiGenerator : public cmGlobalNinjaGenerator
+{
+public:
+ /// The default name of Ninja's common file. Typically: common.ninja.
+ static const char* NINJA_COMMON_FILE;
+ /// The default file extension to use for per-config Ninja files.
+ static const char* NINJA_FILE_EXTENSION;
+
+ cmGlobalNinjaMultiGenerator(cmake* cm);
+ bool IsMultiConfig() const override { return true; }
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory()
+ {
+ return std::unique_ptr<cmGlobalGeneratorFactory>(
+ new cmGlobalGeneratorSimpleFactory<cmGlobalNinjaMultiGenerator>());
+ }
+
+ static void GetDocumentation(cmDocumentationEntry& entry);
+
+ std::string GetName() const override
+ {
+ return cmGlobalNinjaMultiGenerator::GetActualName();
+ }
+
+ static std::string GetActualName() { return "Ninja Multi-Config"; }
+
+ std::string BuildAlias(const std::string& alias,
+ const std::string& config) const override
+ {
+ if (config.empty()) {
+ return alias;
+ }
+ return cmStrCat(alias, ":", config);
+ }
+
+ std::string ConfigDirectory(const std::string& config) const override
+ {
+ if (!config.empty()) {
+ return cmStrCat('/', config);
+ }
+ return "";
+ }
+
+ const char* GetCMakeCFGIntDir() const override { return "${CONFIGURATION}"; }
+
+ std::string ExpandCFGIntDir(const std::string& str,
+ const std::string& config) const override;
+
+ cmGeneratedFileStream* GetImplFileStream(
+ const std::string& config) const override
+ {
+ return this->ImplFileStreams.at(config).get();
+ }
+
+ cmGeneratedFileStream* GetConfigFileStream(
+ const std::string& config) const override
+ {
+ return this->ConfigFileStreams.at(config).get();
+ }
+
+ cmGeneratedFileStream* GetDefaultFileStream() const override
+ {
+ return this->DefaultFileStream.get();
+ }
+
+ cmGeneratedFileStream* GetCommonFileStream() const override
+ {
+ return this->CommonFileStream.get();
+ }
+
+ void AppendNinjaFileArgument(GeneratedMakeCommand& command,
+ const std::string& config) const override;
+
+ static std::string GetNinjaImplFilename(const std::string& config);
+ static std::string GetNinjaConfigFilename(const std::string& config);
+
+ void AddRebuildManifestOutputs(cmNinjaDeps& outputs) const override;
+
+ void GetQtAutoGenConfigs(std::vector<std::string>& configs) const override;
+
+ bool InspectConfigTypeVariables() override;
+
+ std::string GetDefaultBuildConfig() const override;
+
+ bool ReadCacheEntriesForBuild(const cmState& state) override;
+
+ bool SupportsDefaultBuildType() const override { return true; }
+ bool SupportsCrossConfigs() const override { return true; }
+ bool SupportsDefaultConfigs() const override { return true; }
+
+ std::string OrderDependsTargetForTarget(
+ cmGeneratorTarget const* target, const std::string& config) const override;
+
+protected:
+ bool OpenBuildFileStreams() override;
+ void CloseBuildFileStreams() override;
+
+private:
+ std::map<std::string, std::unique_ptr<cmGeneratedFileStream>>
+ ImplFileStreams;
+ std::map<std::string, std::unique_ptr<cmGeneratedFileStream>>
+ ConfigFileStreams;
+ std::unique_ptr<cmGeneratedFileStream> CommonFileStream;
+ std::unique_ptr<cmGeneratedFileStream> DefaultFileStream;
};
#endif // ! cmGlobalNinjaGenerator_h
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index 4c2d69f..5363ea5 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -8,8 +8,9 @@
#include <utility>
#include <cm/memory>
+#include <cmext/algorithm>
+#include <cmext/memory>
-#include "cmAlgorithms.h"
#include "cmDocumentationEntry.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
@@ -40,7 +41,6 @@ cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3(cmake* cm)
#else
this->UseLinkScript = true;
#endif
- this->CommandDatabase = nullptr;
this->IncludeDirective = "include";
this->DefineWindowsNULL = false;
@@ -48,6 +48,8 @@ cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3(cmake* cm)
this->UnixCD = true;
}
+cmGlobalUnixMakefileGenerator3::~cmGlobalUnixMakefileGenerator3() = default;
+
void cmGlobalUnixMakefileGenerator3::EnableLanguage(
std::vector<std::string> const& languages, cmMakefile* mf, bool optional)
{
@@ -61,10 +63,11 @@ void cmGlobalUnixMakefileGenerator3::EnableLanguage(
}
//! Create a local generator appropriate to this Global Generator
-cmLocalGenerator* cmGlobalUnixMakefileGenerator3::CreateLocalGenerator(
- cmMakefile* mf)
+std::unique_ptr<cmLocalGenerator>
+cmGlobalUnixMakefileGenerator3::CreateLocalGenerator(cmMakefile* mf)
{
- return new cmLocalUnixMakefileGenerator3(this, mf);
+ return std::unique_ptr<cmLocalGenerator>(
+ cm::make_unique<cmLocalUnixMakefileGenerator3>(this, mf));
}
void cmGlobalUnixMakefileGenerator3::GetDocumentation(
@@ -114,6 +117,12 @@ void cmGlobalUnixMakefileGenerator3::ComputeTargetObjectDirectory(
gt->ObjectDirectory = dir;
}
+bool cmGlobalUnixMakefileGenerator3::CanEscapeOctothorpe() const
+{
+ // Make tools that use UNIX-style '/' paths also support '\' escaping.
+ return this->ForceUnixPaths;
+}
+
void cmGlobalUnixMakefileGenerator3::Configure()
{
// Initialize CMAKE_EDIT_COMMAND cache entry.
@@ -144,21 +153,20 @@ void cmGlobalUnixMakefileGenerator3::Generate()
for (auto& pmi : this->ProgressMap) {
pmi.second.WriteProgressVariables(total, current);
}
- for (cmLocalGenerator* lg : this->LocalGenerators) {
+ for (const auto& lg : this->LocalGenerators) {
std::string markFileName =
cmStrCat(lg->GetCurrentBinaryDirectory(), "/CMakeFiles/progress.marks");
cmGeneratedFileStream markFile(markFileName);
- markFile << this->CountProgressMarksInAll(lg) << "\n";
+ markFile << this->CountProgressMarksInAll(*lg) << "\n";
}
// write the main makefile
this->WriteMainMakefile2();
this->WriteMainCMakefile();
- if (this->CommandDatabase != nullptr) {
- *this->CommandDatabase << std::endl << "]";
- delete this->CommandDatabase;
- this->CommandDatabase = nullptr;
+ if (this->CommandDatabase) {
+ *this->CommandDatabase << "\n]";
+ this->CommandDatabase.reset();
}
}
@@ -166,26 +174,26 @@ void cmGlobalUnixMakefileGenerator3::AddCXXCompileCommand(
const std::string& sourceFile, const std::string& workingDirectory,
const std::string& compileCommand)
{
- if (this->CommandDatabase == nullptr) {
+ if (!this->CommandDatabase) {
std::string commandDatabaseName =
this->GetCMakeInstance()->GetHomeOutputDirectory() +
"/compile_commands.json";
- this->CommandDatabase = new cmGeneratedFileStream(commandDatabaseName);
- *this->CommandDatabase << "[" << std::endl;
+ this->CommandDatabase =
+ cm::make_unique<cmGeneratedFileStream>(commandDatabaseName);
+ *this->CommandDatabase << "[\n";
} else {
- *this->CommandDatabase << "," << std::endl;
+ *this->CommandDatabase << ",\n";
}
- *this->CommandDatabase << "{" << std::endl
+ *this->CommandDatabase << "{\n"
<< R"( "directory": ")"
<< cmGlobalGenerator::EscapeJSON(workingDirectory)
- << "\"," << std::endl
+ << "\",\n"
<< R"( "command": ")"
<< cmGlobalGenerator::EscapeJSON(compileCommand)
- << "\"," << std::endl
+ << "\",\n"
<< R"( "file": ")"
- << cmGlobalGenerator::EscapeJSON(sourceFile) << "\""
- << std::endl
- << "}";
+ << cmGlobalGenerator::EscapeJSON(sourceFile)
+ << "\"\n}";
}
void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
@@ -203,11 +211,11 @@ void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
}
// get a local generator for some useful methods
- cmLocalUnixMakefileGenerator3* lg =
- static_cast<cmLocalUnixMakefileGenerator3*>(this->LocalGenerators[0]);
+ auto& lg = cm::static_reference_cast<cmLocalUnixMakefileGenerator3>(
+ this->LocalGenerators[0]);
// Write the do not edit header.
- lg->WriteDisclaimer(makefileStream);
+ lg.WriteDisclaimer(makefileStream);
// Write the main entry point target. This must be the VERY first
// target so that make with no arguments will run it.
@@ -217,10 +225,10 @@ void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
depends.emplace_back("all");
// Write the rule.
- lg->WriteMakeRule(makefileStream,
- "Default target executed when no arguments are "
- "given to make.",
- "default_target", depends, no_commands, true);
+ lg.WriteMakeRule(makefileStream,
+ "Default target executed when no arguments are "
+ "given to make.",
+ "default_target", depends, no_commands, true);
depends.clear();
@@ -231,7 +239,7 @@ void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
}
// Write out the "special" stuff
- lg->WriteSpecialTargetsTop(makefileStream);
+ lg.WriteSpecialTargetsTop(makefileStream);
// Write the directory level rules.
for (auto const& it : this->ComputeDirectoryTargets()) {
@@ -239,13 +247,14 @@ void cmGlobalUnixMakefileGenerator3::WriteMainMakefile2()
}
// Write the target convenience rules
- for (cmLocalGenerator* localGen : this->LocalGenerators) {
+ for (const auto& localGen : this->LocalGenerators) {
this->WriteConvenienceRules2(
- makefileStream, static_cast<cmLocalUnixMakefileGenerator3*>(localGen));
+ makefileStream,
+ cm::static_reference_cast<cmLocalUnixMakefileGenerator3>(localGen));
}
// Write special bottom targets
- lg->WriteSpecialTargetsBottom(makefileStream);
+ lg.WriteSpecialTargetsBottom(makefileStream);
}
void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
@@ -268,12 +277,14 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
std::string makefileName =
cmStrCat(this->GetCMakeInstance()->GetHomeOutputDirectory(), "/Makefile");
- // get a local generator for some useful methods
- cmLocalUnixMakefileGenerator3* lg =
- static_cast<cmLocalUnixMakefileGenerator3*>(this->LocalGenerators[0]);
+ {
+ // get a local generator for some useful methods
+ auto& lg = cm::static_reference_cast<cmLocalUnixMakefileGenerator3>(
+ this->LocalGenerators[0]);
- // Write the do not edit header.
- lg->WriteDisclaimer(cmakefileStream);
+ // Write the do not edit header.
+ lg.WriteDisclaimer(cmakefileStream);
+ }
// Save the generator name
cmakefileStream << "# The generator used is:\n"
@@ -282,9 +293,9 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
// for each cmMakefile get its list of dependencies
std::vector<std::string> lfiles;
- for (cmLocalGenerator* localGen : this->LocalGenerators) {
+ for (const auto& localGen : this->LocalGenerators) {
// Get the list of files contributing to this generation step.
- cmAppend(lfiles, localGen->GetMakefile()->GetListFiles());
+ cm::append(lfiles, localGen->GetMakefile()->GetListFiles());
}
cmake* cm = this->GetCMakeInstance();
@@ -300,59 +311,60 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
lfiles.erase(new_end, lfiles.end());
#endif
- // reset lg to the first makefile
- lg = static_cast<cmLocalUnixMakefileGenerator3*>(this->LocalGenerators[0]);
-
- std::string currentBinDir = lg->GetCurrentBinaryDirectory();
- // Save the list to the cmake file.
- cmakefileStream
- << "# The top level Makefile was generated from the following files:\n"
- << "set(CMAKE_MAKEFILE_DEPENDS\n"
- << " \"CMakeCache.txt\"\n";
- for (std::string const& f : lfiles) {
- cmakefileStream << " \""
- << lg->MaybeConvertToRelativePath(currentBinDir, f)
- << "\"\n";
- }
- cmakefileStream << " )\n\n";
-
- // Build the path to the cache check file.
- std::string check =
- cmStrCat(this->GetCMakeInstance()->GetHomeOutputDirectory(),
- "/CMakeFiles/cmake.check_cache");
-
- // Set the corresponding makefile in the cmake file.
- cmakefileStream << "# The corresponding makefile is:\n"
- << "set(CMAKE_MAKEFILE_OUTPUTS\n"
- << " \""
- << lg->MaybeConvertToRelativePath(currentBinDir,
- makefileName)
- << "\"\n"
- << " \""
- << lg->MaybeConvertToRelativePath(currentBinDir, check)
- << "\"\n";
- cmakefileStream << " )\n\n";
-
- const std::string binDir = lg->GetBinaryDirectory();
-
- // CMake must rerun if a byproduct is missing.
{
- cmakefileStream << "# Byproducts of CMake generate step:\n"
- << "set(CMAKE_MAKEFILE_PRODUCTS\n";
- for (std::string const& outfile : lg->GetMakefile()->GetOutputFiles()) {
+ // reset lg to the first makefile
+ const auto& lg = cm::static_reference_cast<cmLocalUnixMakefileGenerator3>(
+ this->LocalGenerators[0]);
+
+ const std::string& currentBinDir = lg.GetCurrentBinaryDirectory();
+ // Save the list to the cmake file.
+ cmakefileStream
+ << "# The top level Makefile was generated from the following files:\n"
+ << "set(CMAKE_MAKEFILE_DEPENDS\n"
+ << " \"CMakeCache.txt\"\n";
+ for (std::string const& f : lfiles) {
cmakefileStream << " \""
- << lg->MaybeConvertToRelativePath(binDir, outfile)
+ << lg.MaybeConvertToRelativePath(currentBinDir, f)
<< "\"\n";
}
+ cmakefileStream << " )\n\n";
- // add in all the directory information files
+ // Build the path to the cache check file.
+ std::string check =
+ cmStrCat(this->GetCMakeInstance()->GetHomeOutputDirectory(),
+ "/CMakeFiles/cmake.check_cache");
+
+ // Set the corresponding makefile in the cmake file.
+ cmakefileStream << "# The corresponding makefile is:\n"
+ << "set(CMAKE_MAKEFILE_OUTPUTS\n"
+ << " \""
+ << lg.MaybeConvertToRelativePath(currentBinDir,
+ makefileName)
+ << "\"\n"
+ << " \""
+ << lg.MaybeConvertToRelativePath(currentBinDir, check)
+ << "\"\n";
+ cmakefileStream << " )\n\n";
+
+ const std::string& binDir = lg.GetBinaryDirectory();
+
+ // CMake must rerun if a byproduct is missing.
+ cmakefileStream << "# Byproducts of CMake generate step:\n"
+ << "set(CMAKE_MAKEFILE_PRODUCTS\n";
+
+ // add in any byproducts and all the directory information files
std::string tmpStr;
- for (cmLocalGenerator* localGen : this->LocalGenerators) {
- lg = static_cast<cmLocalUnixMakefileGenerator3*>(localGen);
- tmpStr = cmStrCat(lg->GetCurrentBinaryDirectory(),
+ for (const auto& localGen : this->LocalGenerators) {
+ for (std::string const& outfile :
+ localGen->GetMakefile()->GetOutputFiles()) {
+ cmakefileStream << " \""
+ << lg.MaybeConvertToRelativePath(binDir, outfile)
+ << "\"\n";
+ }
+ tmpStr = cmStrCat(localGen->GetCurrentBinaryDirectory(),
"/CMakeFiles/CMakeDirectoryInformation.cmake");
cmakefileStream << " \""
- << lg->MaybeConvertToRelativePath(binDir, tmpStr)
+ << localGen->MaybeConvertToRelativePath(binDir, tmpStr)
<< "\"\n";
}
cmakefileStream << " )\n\n";
@@ -364,26 +376,24 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
void cmGlobalUnixMakefileGenerator3::WriteMainCMakefileLanguageRules(
cmGeneratedFileStream& cmakefileStream,
- std::vector<cmLocalGenerator*>& lGenerators)
+ std::vector<std::unique_ptr<cmLocalGenerator>>& lGenerators)
{
- cmLocalUnixMakefileGenerator3* lg;
-
// now list all the target info files
cmakefileStream << "# Dependency information for all targets:\n";
cmakefileStream << "set(CMAKE_DEPEND_INFO_FILES\n";
- for (cmLocalGenerator* lGenerator : lGenerators) {
- lg = static_cast<cmLocalUnixMakefileGenerator3*>(lGenerator);
+ for (const auto& lGenerator : lGenerators) {
+ const auto& lg =
+ cm::static_reference_cast<cmLocalUnixMakefileGenerator3>(lGenerator);
// for all of out targets
- for (cmGeneratorTarget* tgt : lg->GetGeneratorTargets()) {
+ for (const auto& tgt : lg.GetGeneratorTargets()) {
if ((tgt->GetType() == cmStateEnums::EXECUTABLE) ||
(tgt->GetType() == cmStateEnums::STATIC_LIBRARY) ||
(tgt->GetType() == cmStateEnums::SHARED_LIBRARY) ||
(tgt->GetType() == cmStateEnums::MODULE_LIBRARY) ||
(tgt->GetType() == cmStateEnums::OBJECT_LIBRARY) ||
(tgt->GetType() == cmStateEnums::UTILITY)) {
- cmGeneratorTarget* gt = tgt;
- std::string tname =
- cmStrCat(lg->GetRelativeTargetDirectory(gt), "/DependInfo.cmake");
+ std::string tname = cmStrCat(lg.GetRelativeTargetDirectory(tgt.get()),
+ "/DependInfo.cmake");
cmSystemTools::ConvertToUnixSlashes(tname);
cmakefileStream << " \"" << tname << "\"\n";
}
@@ -476,6 +486,78 @@ void cmGlobalUnixMakefileGenerator3::WriteDirectoryRules2(
}
}
+namespace {
+std::string ConvertToMakefilePathForUnix(std::string const& path)
+{
+ std::string result;
+ result.reserve(path.size());
+ for (char c : path) {
+ switch (c) {
+ case '=':
+ // We provide 'EQUALS = =' to encode '=' in a non-assignment case.
+ result.append("$(EQUALS)");
+ break;
+ case '$':
+ result.append("$$");
+ break;
+ case '\\':
+ case ' ':
+ case '#':
+ result.push_back('\\');
+ CM_FALLTHROUGH;
+ default:
+ result.push_back(c);
+ break;
+ }
+ }
+ return result;
+}
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+std::string ConvertToMakefilePathForWindows(std::string const& path)
+{
+ bool const quote = path.find_first_of(" #") != std::string::npos;
+ std::string result;
+ result.reserve(path.size() + (quote ? 2 : 0));
+ if (quote) {
+ result.push_back('"');
+ }
+ for (char c : path) {
+ switch (c) {
+ case '=':
+ // We provide 'EQUALS = =' to encode '=' in a non-assignment case.
+ result.append("$(EQUALS)");
+ break;
+ case '$':
+ result.append("$$");
+ break;
+ case '/':
+ result.push_back('\\');
+ break;
+ default:
+ result.push_back(c);
+ break;
+ }
+ }
+ if (quote) {
+ result.push_back('"');
+ }
+ return result;
+}
+#endif
+}
+
+std::string cmGlobalUnixMakefileGenerator3::ConvertToMakefilePath(
+ std::string const& path) const
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ if (!this->ForceUnixPaths) {
+ return ConvertToMakefilePathForWindows(path);
+ }
+#endif
+ return ConvertToMakefilePathForUnix(path);
+}
+
std::vector<cmGlobalGenerator::GeneratedMakeCommand>
cmGlobalUnixMakefileGenerator3::GenerateBuildCommand(
const std::string& makeProgram, const std::string& /*projectName*/,
@@ -487,7 +569,7 @@ cmGlobalUnixMakefileGenerator3::GenerateBuildCommand(
std::unique_ptr<cmMakefile> mfu;
cmMakefile* mf;
if (!this->Makefiles.empty()) {
- mf = this->Makefiles[0];
+ mf = this->Makefiles[0].get();
} else {
cmStateSnapshot snapshot = this->CMakeInstance->GetCurrentSnapshot();
snapshot.GetDirectory().SetCurrentSource(
@@ -545,11 +627,11 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules(
}
// write the target convenience rules
- for (cmLocalGenerator* localGen : this->LocalGenerators) {
- cmLocalUnixMakefileGenerator3* lg =
- static_cast<cmLocalUnixMakefileGenerator3*>(localGen);
+ for (const auto& localGen : this->LocalGenerators) {
+ auto& lg =
+ cm::static_reference_cast<cmLocalUnixMakefileGenerator3>(localGen);
// for each target Generate the rule files for each target.
- for (cmGeneratorTarget* gtarget : lg->GetGeneratorTargets()) {
+ for (const auto& gtarget : lg.GetGeneratorTargets()) {
// Don't emit the same rule twice (e.g. two targets with the same
// simple name)
int type = gtarget->GetType();
@@ -564,23 +646,23 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules(
(type == cmStateEnums::OBJECT_LIBRARY) ||
(type == cmStateEnums::UTILITY))) {
// Add a rule to build the target by name.
- lg->WriteDivider(ruleFileStream);
+ lg.WriteDivider(ruleFileStream);
ruleFileStream << "# Target rules for targets named " << name
<< "\n\n";
// Write the rule.
commands.clear();
std::string tmp = "CMakeFiles/Makefile2";
- commands.push_back(lg->GetRecursiveMakeCall(tmp, name));
+ commands.push_back(lg.GetRecursiveMakeCall(tmp, name));
depends.clear();
if (regenerate) {
depends.emplace_back("cmake_check_build_system");
}
- lg->WriteMakeRule(ruleFileStream, "Build rule for target.", name,
- depends, commands, true);
+ lg.WriteMakeRule(ruleFileStream, "Build rule for target.", name,
+ depends, commands, true);
// Add a fast rule to build the target
- std::string localName = lg->GetRelativeTargetDirectory(gtarget);
+ std::string localName = lg.GetRelativeTargetDirectory(gtarget.get());
std::string makefileName;
makefileName = cmStrCat(localName, "/build.make");
depends.clear();
@@ -588,23 +670,23 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules(
std::string makeTargetName = cmStrCat(localName, "/build");
localName = cmStrCat(name, "/fast");
commands.push_back(
- lg->GetRecursiveMakeCall(makefileName, makeTargetName));
- lg->WriteMakeRule(ruleFileStream, "fast build rule for target.",
- localName, depends, commands, true);
+ lg.GetRecursiveMakeCall(makefileName, makeTargetName));
+ lg.WriteMakeRule(ruleFileStream, "fast build rule for target.",
+ localName, depends, commands, true);
// Add a local name for the rule to relink the target before
// installation.
- if (gtarget->NeedRelinkBeforeInstall(lg->GetConfigName())) {
- makeTargetName =
- cmStrCat(lg->GetRelativeTargetDirectory(gtarget), "/preinstall");
+ if (gtarget->NeedRelinkBeforeInstall(lg.GetConfigName())) {
+ makeTargetName = cmStrCat(
+ lg.GetRelativeTargetDirectory(gtarget.get()), "/preinstall");
localName = cmStrCat(name, "/preinstall");
depends.clear();
commands.clear();
commands.push_back(
- lg->GetRecursiveMakeCall(makefileName, makeTargetName));
- lg->WriteMakeRule(ruleFileStream,
- "Manual pre-install relink rule for target.",
- localName, depends, commands, true);
+ lg.GetRecursiveMakeCall(makefileName, makeTargetName));
+ lg.WriteMakeRule(ruleFileStream,
+ "Manual pre-install relink rule for target.",
+ localName, depends, commands, true);
}
}
}
@@ -612,7 +694,7 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules(
}
void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
- std::ostream& ruleFileStream, cmLocalUnixMakefileGenerator3* lg)
+ std::ostream& ruleFileStream, cmLocalUnixMakefileGenerator3& lg)
{
std::vector<std::string> depends;
std::vector<std::string> commands;
@@ -625,7 +707,7 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
}
// for each target Generate the rule files for each target.
- for (cmGeneratorTarget* gtarget : lg->GetGeneratorTargets()) {
+ for (const auto& gtarget : lg.GetGeneratorTargets()) {
int type = gtarget->GetType();
std::string name = gtarget->GetName();
if (!name.empty() &&
@@ -637,31 +719,31 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
(type == cmStateEnums::UTILITY))) {
std::string makefileName;
// Add a rule to build the target by name.
- localName = lg->GetRelativeTargetDirectory(gtarget);
+ localName = lg.GetRelativeTargetDirectory(gtarget.get());
makefileName = cmStrCat(localName, "/build.make");
- lg->WriteDivider(ruleFileStream);
+ lg.WriteDivider(ruleFileStream);
ruleFileStream << "# Target rules for target " << localName << "\n\n";
commands.clear();
makeTargetName = cmStrCat(localName, "/depend");
commands.push_back(
- lg->GetRecursiveMakeCall(makefileName, makeTargetName));
+ lg.GetRecursiveMakeCall(makefileName, makeTargetName));
makeTargetName = cmStrCat(localName, "/build");
commands.push_back(
- lg->GetRecursiveMakeCall(makefileName, makeTargetName));
+ lg.GetRecursiveMakeCall(makefileName, makeTargetName));
// Write the rule.
localName += "/all";
depends.clear();
cmLocalUnixMakefileGenerator3::EchoProgress progress;
- progress.Dir = cmStrCat(lg->GetBinaryDirectory(), "/CMakeFiles");
+ progress.Dir = cmStrCat(lg.GetBinaryDirectory(), "/CMakeFiles");
{
std::ostringstream progressArg;
const char* sep = "";
- for (unsigned long progFile : this->ProgressMap[gtarget].Marks) {
+ for (unsigned long progFile : this->ProgressMap[gtarget.get()].Marks) {
progressArg << sep << progFile;
sep = ",";
}
@@ -669,20 +751,20 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
}
bool targetMessages = true;
- if (const char* tgtMsg =
+ if (cmProp tgtMsg =
this->GetCMakeInstance()->GetState()->GetGlobalProperty(
"TARGET_MESSAGES")) {
- targetMessages = cmIsOn(tgtMsg);
+ targetMessages = cmIsOn(*tgtMsg);
}
if (targetMessages) {
- lg->AppendEcho(commands, "Built target " + name,
- cmLocalUnixMakefileGenerator3::EchoNormal, &progress);
+ lg.AppendEcho(commands, "Built target " + name,
+ cmLocalUnixMakefileGenerator3::EchoNormal, &progress);
}
- this->AppendGlobalTargetDepends(depends, gtarget);
- lg->WriteMakeRule(ruleFileStream, "All Build rule for target.",
- localName, depends, commands, true);
+ this->AppendGlobalTargetDepends(depends, gtarget.get());
+ lg.WriteMakeRule(ruleFileStream, "All Build rule for target.", localName,
+ depends, commands, true);
// Write the rule.
commands.clear();
@@ -692,22 +774,21 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
std::ostringstream progCmd;
progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start ";
// # in target
- progCmd << lg->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(progress.Dir),
- cmOutputConverter::SHELL);
+ progCmd << lg.ConvertToOutputFormat(progress.Dir,
+ cmOutputConverter::SHELL);
//
std::set<cmGeneratorTarget const*> emitted;
- progCmd << " " << this->CountProgressMarksInTarget(gtarget, emitted);
+ progCmd << " "
+ << this->CountProgressMarksInTarget(gtarget.get(), emitted);
commands.push_back(progCmd.str());
}
std::string tmp = "CMakeFiles/Makefile2";
- commands.push_back(lg->GetRecursiveMakeCall(tmp, localName));
+ commands.push_back(lg.GetRecursiveMakeCall(tmp, localName));
{
std::ostringstream progCmd;
progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # 0
- progCmd << lg->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(progress.Dir),
- cmOutputConverter::SHELL);
+ progCmd << lg.ConvertToOutputFormat(progress.Dir,
+ cmOutputConverter::SHELL);
progCmd << " 0";
commands.push_back(progCmd.str());
}
@@ -715,39 +796,39 @@ void cmGlobalUnixMakefileGenerator3::WriteConvenienceRules2(
if (regenerate) {
depends.emplace_back("cmake_check_build_system");
}
- localName = cmStrCat(lg->GetRelativeTargetDirectory(gtarget), "/rule");
- lg->WriteMakeRule(ruleFileStream,
- "Build rule for subdir invocation for target.",
- localName, depends, commands, true);
+ localName =
+ cmStrCat(lg.GetRelativeTargetDirectory(gtarget.get()), "/rule");
+ lg.WriteMakeRule(ruleFileStream,
+ "Build rule for subdir invocation for target.",
+ localName, depends, commands, true);
// Add a target with the canonical name (no prefix, suffix or path).
commands.clear();
depends.clear();
depends.push_back(localName);
- lg->WriteMakeRule(ruleFileStream, "Convenience name for target.", name,
- depends, commands, true);
+ lg.WriteMakeRule(ruleFileStream, "Convenience name for target.", name,
+ depends, commands, true);
// Add rules to prepare the target for installation.
- if (gtarget->NeedRelinkBeforeInstall(lg->GetConfigName())) {
- localName =
- cmStrCat(lg->GetRelativeTargetDirectory(gtarget), "/preinstall");
+ if (gtarget->NeedRelinkBeforeInstall(lg.GetConfigName())) {
+ localName = cmStrCat(lg.GetRelativeTargetDirectory(gtarget.get()),
+ "/preinstall");
depends.clear();
commands.clear();
- commands.push_back(lg->GetRecursiveMakeCall(makefileName, localName));
- lg->WriteMakeRule(ruleFileStream,
- "Pre-install relink rule for target.", localName,
- depends, commands, true);
+ commands.push_back(lg.GetRecursiveMakeCall(makefileName, localName));
+ lg.WriteMakeRule(ruleFileStream, "Pre-install relink rule for target.",
+ localName, depends, commands, true);
}
// add the clean rule
- localName = lg->GetRelativeTargetDirectory(gtarget);
+ localName = lg.GetRelativeTargetDirectory(gtarget.get());
makeTargetName = cmStrCat(localName, "/clean");
depends.clear();
commands.clear();
commands.push_back(
- lg->GetRecursiveMakeCall(makefileName, makeTargetName));
- lg->WriteMakeRule(ruleFileStream, "clean rule for target.",
- makeTargetName, depends, commands, true);
+ lg.GetRecursiveMakeCall(makefileName, makeTargetName));
+ lg.WriteMakeRule(ruleFileStream, "clean rule for target.",
+ makeTargetName, depends, commands, true);
commands.clear();
}
}
@@ -759,8 +840,8 @@ void cmGlobalUnixMakefileGenerator3::InitializeProgressMarks()
{
this->DirectoryTargetsMap.clear();
// Loop over all targets in all local generators.
- for (cmLocalGenerator* lg : this->LocalGenerators) {
- for (cmGeneratorTarget* gt : lg->GetGeneratorTargets()) {
+ for (const auto& lg : this->LocalGenerators) {
+ for (const auto& gt : lg->GetGeneratorTargets()) {
cmLocalGenerator* tlg = gt->GetLocalGenerator();
if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
@@ -778,12 +859,13 @@ void cmGlobalUnixMakefileGenerator3::InitializeProgressMarks()
// This local generator includes the target.
std::set<cmGeneratorTarget const*>& targetSet =
this->DirectoryTargetsMap[csnp];
- targetSet.insert(gt);
+ targetSet.insert(gt.get());
// Add dependencies of the included target. An excluded
// target may still be included if it is a dependency of a
// non-excluded target.
- for (cmTargetDepend const& tgtdep : this->GetTargetDirectDepends(gt)) {
+ for (cmTargetDepend const& tgtdep :
+ this->GetTargetDirectDepends(gt.get())) {
targetSet.insert(tgtdep);
}
}
@@ -808,12 +890,12 @@ size_t cmGlobalUnixMakefileGenerator3::CountProgressMarksInTarget(
}
size_t cmGlobalUnixMakefileGenerator3::CountProgressMarksInAll(
- cmLocalGenerator* lg)
+ const cmLocalGenerator& lg)
{
size_t count = 0;
std::set<cmGeneratorTarget const*> emitted;
for (cmGeneratorTarget const* target :
- this->DirectoryTargetsMap[lg->GetStateSnapshot()]) {
+ this->DirectoryTargetsMap[lg.GetStateSnapshot()]) {
count += this->CountProgressMarksInTarget(target, emitted);
}
return count;
@@ -885,33 +967,48 @@ void cmGlobalUnixMakefileGenerator3::WriteHelpRule(
// Keep track of targets already listed.
std::set<std::string> emittedTargets;
+ std::set<std::string> utility_targets;
+ std::set<std::string> globals_targets;
+ std::set<std::string> project_targets;
// for each local generator
- for (cmLocalGenerator* localGen : this->LocalGenerators) {
- cmLocalUnixMakefileGenerator3* lg2 =
- static_cast<cmLocalUnixMakefileGenerator3*>(localGen);
+ for (const auto& localGen : this->LocalGenerators) {
+ const auto& lg2 =
+ cm::static_reference_cast<cmLocalUnixMakefileGenerator3>(localGen);
// for the passed in makefile or if this is the top Makefile wripte out
// the targets
- if (lg2 == lg || lg->IsRootMakefile()) {
+ if (&lg2 == lg || lg->IsRootMakefile()) {
// for each target Generate the rule files for each target.
- for (cmGeneratorTarget* target : lg2->GetGeneratorTargets()) {
+ for (const auto& target : lg2.GetGeneratorTargets()) {
cmStateEnums::TargetType type = target->GetType();
if ((type == cmStateEnums::EXECUTABLE) ||
(type == cmStateEnums::STATIC_LIBRARY) ||
(type == cmStateEnums::SHARED_LIBRARY) ||
(type == cmStateEnums::MODULE_LIBRARY) ||
- (type == cmStateEnums::OBJECT_LIBRARY) ||
- (type == cmStateEnums::GLOBAL_TARGET) ||
- (type == cmStateEnums::UTILITY)) {
- std::string const& name = target->GetName();
- if (emittedTargets.insert(name).second) {
- path = cmStrCat("... ", name);
- lg->AppendEcho(commands, path);
- }
+ (type == cmStateEnums::OBJECT_LIBRARY)) {
+ project_targets.insert(target->GetName());
+ } else if (type == cmStateEnums::GLOBAL_TARGET) {
+ globals_targets.insert(target->GetName());
+ } else if (type == cmStateEnums::UTILITY) {
+ utility_targets.insert(target->GetName());
}
}
}
}
+
+ for (std::string const& name : globals_targets) {
+ path = cmStrCat("... ", name);
+ lg->AppendEcho(commands, path);
+ }
+ for (std::string const& name : utility_targets) {
+ path = cmStrCat("... ", name);
+ lg->AppendEcho(commands, path);
+ }
+ for (std::string const& name : project_targets) {
+ path = cmStrCat("... ", name);
+ lg->AppendEcho(commands, path);
+ }
+
for (std::string const& o : lg->GetLocalHelp()) {
path = cmStrCat("... ", o);
lg->AppendEcho(commands, path);
diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h
index 79db30e..1caa4b7 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.h
+++ b/Source/cmGlobalUnixMakefileGenerator3.h
@@ -8,6 +8,7 @@
#include <cstddef>
#include <iosfwd>
#include <map>
+#include <memory>
#include <set>
#include <string>
#include <vector>
@@ -61,12 +62,19 @@ class cmGlobalUnixMakefileGenerator3 : public cmGlobalCommonGenerator
{
public:
cmGlobalUnixMakefileGenerator3(cmake* cm);
- static cmGlobalGeneratorFactory* NewFactory()
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory()
{
- return new cmGlobalGeneratorSimpleFactory<
- cmGlobalUnixMakefileGenerator3>();
+ return std::unique_ptr<cmGlobalGeneratorFactory>(
+ new cmGlobalGeneratorSimpleFactory<cmGlobalUnixMakefileGenerator3>());
}
+ ~cmGlobalUnixMakefileGenerator3() override;
+
+ cmGlobalUnixMakefileGenerator3(const cmGlobalUnixMakefileGenerator3&) =
+ delete;
+ cmGlobalUnixMakefileGenerator3& operator=(
+ const cmGlobalUnixMakefileGenerator3&) = delete;
+
//! Get the name for the generator.
std::string GetName() const override
{
@@ -89,7 +97,8 @@ public:
/** Get the documentation entry for this generator. */
static void GetDocumentation(cmDocumentationEntry& entry);
- cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) override;
+ std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
+ cmMakefile* mf) override;
/**
* Try to determine system information such as shared library
@@ -107,8 +116,9 @@ public:
*/
void Generate() override;
- void WriteMainCMakefileLanguageRules(cmGeneratedFileStream& cmakefileStream,
- std::vector<cmLocalGenerator*>&);
+ void WriteMainCMakefileLanguageRules(
+ cmGeneratedFileStream& cmakefileStream,
+ std::vector<std::unique_ptr<cmLocalGenerator>>&);
// write out the help rule listing the valid targets
void WriteHelpRule(std::ostream& ruleFileStream,
@@ -126,6 +136,12 @@ public:
or dependencies. */
std::string GetEmptyRuleHackDepends() { return this->EmptyRuleHackDepends; }
+ /**
+ * Convert a file path to a Makefile target or dependency with
+ * escaping and quoting suitable for the generator's make tool.
+ */
+ std::string ConvertToMakefilePath(std::string const& path) const;
+
// change the build command for speed
std::vector<GeneratedMakeCommand> GenerateBuildCommand(
const std::string& makeProgram, const std::string& projectName,
@@ -147,6 +163,9 @@ public:
/** Does the make tool tolerate .DELETE_ON_ERROR? */
virtual bool AllowDeleteOnError() const { return true; }
+ /** Does the make tool interpret '\#' as '#'? */
+ virtual bool CanEscapeOctothorpe() const;
+
bool IsIPOSupported() const override { return true; }
void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const override;
@@ -161,7 +180,7 @@ protected:
void WriteMainCMakefile();
void WriteConvenienceRules2(std::ostream& ruleFileStream,
- cmLocalUnixMakefileGenerator3*);
+ cmLocalUnixMakefileGenerator3&);
void WriteDirectoryRule2(std::ostream& ruleFileStream,
DirectoryTarget const& dt, const char* pass,
@@ -227,9 +246,9 @@ protected:
size_t CountProgressMarksInTarget(
cmGeneratorTarget const* target,
std::set<cmGeneratorTarget const*>& emitted);
- size_t CountProgressMarksInAll(cmLocalGenerator* lg);
+ size_t CountProgressMarksInAll(const cmLocalGenerator& lg);
- cmGeneratedFileStream* CommandDatabase;
+ std::unique_ptr<cmGeneratedFileStream> CommandDatabase;
private:
const char* GetBuildIgnoreErrorsFlag() const override { return "-i"; }
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index f6472ab..5dac072 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -4,12 +4,14 @@
#include <algorithm>
+#include <cm/memory>
+
+#include <cm3p/json/reader.h>
+
#include "cmsys/FStream.hxx"
#include "cmsys/Glob.hxx"
#include "cmsys/RegularExpression.hxx"
-#include "cm_jsoncpp_reader.h"
-
#include "cmAlgorithms.h"
#include "cmDocumentationEntry.h"
#include "cmGeneratorTarget.h"
@@ -17,6 +19,7 @@
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmSourceFile.h"
+#include "cmStringAlgorithms.h"
#include "cmVersion.h"
#include "cmVisualStudioSlnData.h"
#include "cmVisualStudioSlnParser.h"
@@ -26,6 +29,16 @@
static const char vs10generatorName[] = "Visual Studio 10 2010";
static std::map<std::string, std::vector<cmIDEFlagTable>> loadedFlagJsonFiles;
+static void ConvertToWindowsSlashes(std::string& s)
+{
+ // first convert all of the slashes
+ for (auto& ch : s) {
+ if (ch == '/') {
+ ch = '\\';
+ }
+ }
+}
+
// Map generator name without year to name with year.
static const char* cmVS10GenName(const std::string& name, std::string& genName)
{
@@ -45,27 +58,30 @@ class cmGlobalVisualStudio10Generator::Factory
: public cmGlobalGeneratorFactory
{
public:
- cmGlobalGenerator* CreateGlobalGenerator(const std::string& name,
- cmake* cm) const override
+ std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
+ const std::string& name, cmake* cm) const override
{
std::string genName;
const char* p = cmVS10GenName(name, genName);
if (!p) {
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
if (!*p) {
- return new cmGlobalVisualStudio10Generator(cm, genName, "");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudio10Generator(cm, genName, ""));
}
if (*p++ != ' ') {
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
if (strcmp(p, "Win64") == 0) {
- return new cmGlobalVisualStudio10Generator(cm, genName, "x64");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudio10Generator(cm, genName, "x64"));
}
if (strcmp(p, "IA64") == 0) {
- return new cmGlobalVisualStudio10Generator(cm, genName, "Itanium");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudio10Generator(cm, genName, "Itanium"));
}
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
void GetDocumentation(cmDocumentationEntry& entry) const override
@@ -105,9 +121,10 @@ public:
std::string GetDefaultPlatformName() const override { return "Win32"; }
};
-cmGlobalGeneratorFactory* cmGlobalVisualStudio10Generator::NewFactory()
+std::unique_ptr<cmGlobalGeneratorFactory>
+cmGlobalVisualStudio10Generator::NewFactory()
{
- return new Factory;
+ return std::unique_ptr<cmGlobalGeneratorFactory>(new Factory);
}
cmGlobalVisualStudio10Generator::cmGlobalVisualStudio10Generator(
@@ -193,7 +210,7 @@ static void cmCudaToolVersion(std::string& s)
}
bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
- std::string const& ts, cmMakefile* mf)
+ std::string const& ts, bool build, cmMakefile* mf)
{
if (this->SystemIsWindowsCE && ts.empty() &&
this->DefaultPlatformToolset.empty()) {
@@ -208,7 +225,11 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
return false;
}
- if (!this->FindVCTargetsPath(mf)) {
+ if (build) {
+ return true;
+ }
+
+ if (this->CustomVCTargetsPath.empty() && !this->FindVCTargetsPath(mf)) {
return false;
}
@@ -293,7 +314,7 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
version.clear();
}
- if (version.find(this->GetPlatformToolsetString()) != 0) {
+ if (!cmHasPrefix(version, this->GetPlatformToolsetString())) {
std::ostringstream e;
/* clang-format off */
e <<
@@ -355,6 +376,11 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
if (const char* cudaDir = this->GetPlatformToolsetCudaCustomDir()) {
mf->AddDefinition("CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR", cudaDir);
}
+ if (const char* vcTargetsDir = this->GetCustomVCTargetsPath()) {
+ mf->AddDefinition("CMAKE_VS_PLATFORM_TOOLSET_VCTARGETS_CUSTOM_DIR",
+ vcTargetsDir);
+ }
+
return true;
}
@@ -448,6 +474,11 @@ bool cmGlobalVisualStudio10Generator::ProcessGeneratorToolsetField(
this->GeneratorToolsetVersion = value;
return true;
}
+ if (key == "VCTargetsPath") {
+ this->CustomVCTargetsPath = value;
+ ConvertToWindowsSlashes(this->CustomVCTargetsPath);
+ return true;
+ }
return false;
}
@@ -556,10 +587,11 @@ std::string cmGlobalVisualStudio10Generator::SelectWindowsCEToolset() const
}
//! Create a local generator appropriate to this Global Generator
-cmLocalGenerator* cmGlobalVisualStudio10Generator::CreateLocalGenerator(
- cmMakefile* mf)
+std::unique_ptr<cmLocalGenerator>
+cmGlobalVisualStudio10Generator::CreateLocalGenerator(cmMakefile* mf)
{
- return new cmLocalVisualStudio10Generator(this, mf);
+ return std::unique_ptr<cmLocalGenerator>(
+ cm::make_unique<cmLocalVisualStudio10Generator>(this, mf));
}
void cmGlobalVisualStudio10Generator::Generate()
@@ -590,7 +622,7 @@ void cmGlobalVisualStudio10Generator::Generate()
"To avoid this problem CMake must use a full path for this file "
"which then triggers the VS 10 property dialog bug.";
/* clang-format on */
- lg->IssueMessage(MessageType::WARNING, e.str().c_str());
+ lg->IssueMessage(MessageType::WARNING, e.str());
}
}
@@ -609,6 +641,14 @@ void cmGlobalVisualStudio10Generator::EnableLanguage(
cmGlobalVisualStudio8Generator::EnableLanguage(lang, mf, optional);
}
+const char* cmGlobalVisualStudio10Generator::GetCustomVCTargetsPath() const
+{
+ if (this->CustomVCTargetsPath.empty()) {
+ return nullptr;
+ }
+ return this->CustomVCTargetsPath.c_str();
+}
+
const char* cmGlobalVisualStudio10Generator::GetPlatformToolset() const
{
std::string const& toolset = this->GetPlatformToolsetString();
@@ -803,7 +843,7 @@ bool cmGlobalVisualStudio10Generator::FindVCTargetsPath(cmMakefile* mf)
// Prepare the work directory.
if (!cmSystemTools::MakeDirectory(wd)) {
std::string e = "Failed to make directory:\n " + wd;
- mf->IssueMessage(MessageType::FATAL_ERROR, e.c_str());
+ mf->IssueMessage(MessageType::FATAL_ERROR, e);
cmSystemTools::SetFatalErrorOccured();
return false;
}
@@ -924,7 +964,7 @@ bool cmGlobalVisualStudio10Generator::FindVCTargetsPath(cmMakefile* mf)
if (ret != 0) {
e << "Exit code: " << ret << "\n";
}
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str().c_str());
+ mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
cmSystemTools::SetFatalErrorOccured();
return false;
}
@@ -1098,8 +1138,7 @@ std::string cmGlobalVisualStudio10Generator::GenerateRuleFile(
// Hide them away under the CMakeFiles directory.
std::string ruleDir = cmStrCat(
this->GetCMakeInstance()->GetHomeOutputDirectory(), "/CMakeFiles/",
- cmSystemTools::ComputeStringMD5(
- cmSystemTools::GetFilenamePath(output).c_str()));
+ cmSystemTools::ComputeStringMD5(cmSystemTools::GetFilenamePath(output)));
std::string ruleFile =
cmStrCat(ruleDir, '/', cmSystemTools::GetFilenameName(output), ".rule");
return ruleFile;
@@ -1293,7 +1332,7 @@ cmIDEFlagTable const* cmGlobalVisualStudio10Generator::LoadFlagTable(
e << "JSON flag table \"" << filename <<
"\" could not be loaded.\n";
/* clang-format on */
- mf->IssueMessage(MessageType::FATAL_ERROR, e.str().c_str());
+ mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
}
return ret;
}
diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h
index 56f1193..f659ff3 100644
--- a/Source/cmGlobalVisualStudio10Generator.h
+++ b/Source/cmGlobalVisualStudio10Generator.h
@@ -3,6 +3,8 @@
#ifndef cmGlobalVisualStudio10Generator_h
#define cmGlobalVisualStudio10Generator_h
+#include <memory>
+
#include "cmGlobalVisualStudio8Generator.h"
#include "cmVisualStudio10ToolsetOptions.h"
@@ -14,13 +16,14 @@
class cmGlobalVisualStudio10Generator : public cmGlobalVisualStudio8Generator
{
public:
- static cmGlobalGeneratorFactory* NewFactory();
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory();
bool MatchesGeneratorName(const std::string& name) const override;
bool SetSystemName(std::string const& s, cmMakefile* mf) override;
bool SetGeneratorPlatform(std::string const& p, cmMakefile* mf) override;
- bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf) override;
+ bool SetGeneratorToolset(std::string const& ts, bool build,
+ cmMakefile* mf) override;
std::vector<GeneratedMakeCommand> GenerateBuildCommand(
const std::string& makeProgram, const std::string& projectName,
@@ -30,7 +33,8 @@ public:
std::vector<std::string>()) override;
//! create the correct local generator
- cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) override;
+ std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
+ cmMakefile* mf) override;
/**
* Try to determine system information such as shared library
@@ -45,6 +49,9 @@ public:
bool IsNsightTegra() const;
std::string GetNsightTegraVersion() const;
+ /** The vctargets path for the target platform. */
+ const char* GetCustomVCTargetsPath() const;
+
/** The toolset name for the target platform. */
const char* GetPlatformToolset() const;
std::string const& GetPlatformToolsetString() const;
@@ -157,6 +164,7 @@ protected:
std::string GeneratorToolset;
std::string GeneratorToolsetVersion;
std::string GeneratorToolsetHostArchitecture;
+ std::string GeneratorToolsetCustomVCTargetsDir;
std::string GeneratorToolsetCuda;
std::string GeneratorToolsetCudaCustomDir;
std::string DefaultPlatformToolset;
@@ -209,6 +217,7 @@ private:
bool ParseGeneratorToolset(std::string const& ts, cmMakefile* mf);
+ std::string CustomVCTargetsPath;
std::string VCTargetsPath;
bool FindVCTargetsPath(cmMakefile* mf);
diff --git a/Source/cmGlobalVisualStudio11Generator.cxx b/Source/cmGlobalVisualStudio11Generator.cxx
index 4b74ef1..a385375 100644
--- a/Source/cmGlobalVisualStudio11Generator.cxx
+++ b/Source/cmGlobalVisualStudio11Generator.cxx
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalVisualStudio11Generator.h"
+#include <utility>
+
#include "cmAlgorithms.h"
#include "cmDocumentationEntry.h"
#include "cmLocalVisualStudio10Generator.h"
@@ -28,38 +30,41 @@ class cmGlobalVisualStudio11Generator::Factory
: public cmGlobalGeneratorFactory
{
public:
- cmGlobalGenerator* CreateGlobalGenerator(const std::string& name,
- cmake* cm) const override
+ std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
+ const std::string& name, cmake* cm) const override
{
std::string genName;
const char* p = cmVS11GenName(name, genName);
if (!p) {
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
if (!*p) {
- return new cmGlobalVisualStudio11Generator(cm, genName, "");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudio11Generator(cm, genName, ""));
}
if (*p++ != ' ') {
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
if (strcmp(p, "Win64") == 0) {
- return new cmGlobalVisualStudio11Generator(cm, genName, "x64");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudio11Generator(cm, genName, "x64"));
}
if (strcmp(p, "ARM") == 0) {
- return new cmGlobalVisualStudio11Generator(cm, genName, "ARM");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudio11Generator(cm, genName, "ARM"));
}
std::set<std::string> installedSDKs =
cmGlobalVisualStudio11Generator::GetInstalledWindowsCESDKs();
if (installedSDKs.find(p) == installedSDKs.end()) {
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
- cmGlobalVisualStudio11Generator* ret =
- new cmGlobalVisualStudio11Generator(cm, name, p);
+ auto ret = std::unique_ptr<cmGlobalVisualStudio11Generator>(
+ new cmGlobalVisualStudio11Generator(cm, name, p));
ret->WindowsCEVersion = "8.00";
- return ret;
+ return std::unique_ptr<cmGlobalGenerator>(std::move(ret));
}
void GetDocumentation(cmDocumentationEntry& entry) const override
@@ -113,9 +118,10 @@ public:
std::string GetDefaultPlatformName() const override { return "Win32"; }
};
-cmGlobalGeneratorFactory* cmGlobalVisualStudio11Generator::NewFactory()
+std::unique_ptr<cmGlobalGeneratorFactory>
+cmGlobalVisualStudio11Generator::NewFactory()
{
- return new Factory;
+ return std::unique_ptr<cmGlobalGeneratorFactory>(new Factory);
}
cmGlobalVisualStudio11Generator::cmGlobalVisualStudio11Generator(
diff --git a/Source/cmGlobalVisualStudio11Generator.h b/Source/cmGlobalVisualStudio11Generator.h
index f8cce18..5f1ff73 100644
--- a/Source/cmGlobalVisualStudio11Generator.h
+++ b/Source/cmGlobalVisualStudio11Generator.h
@@ -6,6 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <iosfwd>
+#include <memory>
#include <set>
#include <string>
@@ -20,7 +21,7 @@ class cmake;
class cmGlobalVisualStudio11Generator : public cmGlobalVisualStudio10Generator
{
public:
- static cmGlobalGeneratorFactory* NewFactory();
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory();
bool MatchesGeneratorName(const std::string& name) const override;
diff --git a/Source/cmGlobalVisualStudio12Generator.cxx b/Source/cmGlobalVisualStudio12Generator.cxx
index d9702c9..5a27994 100644
--- a/Source/cmGlobalVisualStudio12Generator.cxx
+++ b/Source/cmGlobalVisualStudio12Generator.cxx
@@ -28,27 +28,30 @@ class cmGlobalVisualStudio12Generator::Factory
: public cmGlobalGeneratorFactory
{
public:
- cmGlobalGenerator* CreateGlobalGenerator(const std::string& name,
- cmake* cm) const override
+ std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
+ const std::string& name, cmake* cm) const override
{
std::string genName;
const char* p = cmVS12GenName(name, genName);
if (!p) {
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
if (!*p) {
- return new cmGlobalVisualStudio12Generator(cm, genName, "");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudio12Generator(cm, genName, ""));
}
if (*p++ != ' ') {
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
if (strcmp(p, "Win64") == 0) {
- return new cmGlobalVisualStudio12Generator(cm, genName, "x64");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudio12Generator(cm, genName, "x64"));
}
if (strcmp(p, "ARM") == 0) {
- return new cmGlobalVisualStudio12Generator(cm, genName, "ARM");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudio12Generator(cm, genName, "ARM"));
}
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
void GetDocumentation(cmDocumentationEntry& entry) const override
@@ -88,9 +91,10 @@ public:
std::string GetDefaultPlatformName() const override { return "Win32"; }
};
-cmGlobalGeneratorFactory* cmGlobalVisualStudio12Generator::NewFactory()
+std::unique_ptr<cmGlobalGeneratorFactory>
+cmGlobalVisualStudio12Generator::NewFactory()
{
- return new Factory;
+ return std::unique_ptr<cmGlobalGeneratorFactory>(new Factory);
}
cmGlobalVisualStudio12Generator::cmGlobalVisualStudio12Generator(
diff --git a/Source/cmGlobalVisualStudio12Generator.h b/Source/cmGlobalVisualStudio12Generator.h
index 53b7091..bdd40ff 100644
--- a/Source/cmGlobalVisualStudio12Generator.h
+++ b/Source/cmGlobalVisualStudio12Generator.h
@@ -6,6 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <iosfwd>
+#include <memory>
#include <string>
#include "cmGlobalVisualStudio11Generator.h"
@@ -18,7 +19,7 @@ class cmake;
class cmGlobalVisualStudio12Generator : public cmGlobalVisualStudio11Generator
{
public:
- static cmGlobalGeneratorFactory* NewFactory();
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory();
bool MatchesGeneratorName(const std::string& name) const override;
diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx
index cd48474..f549b6a 100644
--- a/Source/cmGlobalVisualStudio14Generator.cxx
+++ b/Source/cmGlobalVisualStudio14Generator.cxx
@@ -2,7 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalVisualStudio14Generator.h"
-#include "cmAlgorithms.h"
+#include <cm/vector>
+
#include "cmDocumentationEntry.h"
#include "cmLocalVisualStudio10Generator.h"
#include "cmMakefile.h"
@@ -28,27 +29,30 @@ class cmGlobalVisualStudio14Generator::Factory
: public cmGlobalGeneratorFactory
{
public:
- cmGlobalGenerator* CreateGlobalGenerator(const std::string& name,
- cmake* cm) const override
+ std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
+ const std::string& name, cmake* cm) const override
{
std::string genName;
const char* p = cmVS14GenName(name, genName);
if (!p) {
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
if (!*p) {
- return new cmGlobalVisualStudio14Generator(cm, genName, "");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudio14Generator(cm, genName, ""));
}
if (*p++ != ' ') {
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
if (strcmp(p, "Win64") == 0) {
- return new cmGlobalVisualStudio14Generator(cm, genName, "x64");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudio14Generator(cm, genName, "x64"));
}
if (strcmp(p, "ARM") == 0) {
- return new cmGlobalVisualStudio14Generator(cm, genName, "ARM");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudio14Generator(cm, genName, "ARM"));
}
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
void GetDocumentation(cmDocumentationEntry& entry) const override
@@ -88,9 +92,10 @@ public:
std::string GetDefaultPlatformName() const override { return "Win32"; }
};
-cmGlobalGeneratorFactory* cmGlobalVisualStudio14Generator::NewFactory()
+std::unique_ptr<cmGlobalGeneratorFactory>
+cmGlobalVisualStudio14Generator::NewFactory()
{
- return new Factory;
+ return std::unique_ptr<cmGlobalGeneratorFactory>(new Factory);
}
cmGlobalVisualStudio14Generator::cmGlobalVisualStudio14Generator(
@@ -299,7 +304,7 @@ std::string cmGlobalVisualStudio14Generator::GetWindows10SDKVersion()
// Skip SDKs that do not contain <um/windows.h> because that indicates that
// only the UCRT MSIs were installed for them.
- cmEraseIf(sdks, NoWindowsH());
+ cm::erase_if(sdks, NoWindowsH());
// Only use the filename, which will be the SDK version.
for (std::string& i : sdks) {
@@ -309,7 +314,7 @@ std::string cmGlobalVisualStudio14Generator::GetWindows10SDKVersion()
// Skip SDKs that cannot be used with our toolset.
std::string maxVersion = this->GetWindows10SDKMaxVersion();
if (!maxVersion.empty()) {
- cmEraseIf(sdks, WindowsSDKTooRecent(maxVersion));
+ cm::erase_if(sdks, WindowsSDKTooRecent(maxVersion));
}
// Sort the results to make sure we select the most recent one.
diff --git a/Source/cmGlobalVisualStudio14Generator.h b/Source/cmGlobalVisualStudio14Generator.h
index 6e12d3e..ccc2917 100644
--- a/Source/cmGlobalVisualStudio14Generator.h
+++ b/Source/cmGlobalVisualStudio14Generator.h
@@ -6,6 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <iosfwd>
+#include <memory>
#include <string>
#include "cmGlobalVisualStudio12Generator.h"
@@ -18,7 +19,7 @@ class cmake;
class cmGlobalVisualStudio14Generator : public cmGlobalVisualStudio12Generator
{
public:
- static cmGlobalGeneratorFactory* NewFactory();
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory();
bool MatchesGeneratorName(const std::string& name) const override;
diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx
index e8e9ece..7ada325 100644
--- a/Source/cmGlobalVisualStudio71Generator.cxx
+++ b/Source/cmGlobalVisualStudio71Generator.cxx
@@ -87,11 +87,11 @@ void cmGlobalVisualStudio71Generator::WriteSolutionConfigurations(
// the libraries it uses are also done here
void cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout,
const std::string& dspname,
- const char* dir,
+ const std::string& dir,
cmGeneratorTarget const* t)
{
// check to see if this is a fortran build
- const char* ext = ".vcproj";
+ std::string ext = ".vcproj";
const char* project =
"Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"";
if (this->TargetIsFortranOnly(t)) {
@@ -102,14 +102,14 @@ void cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout,
ext = ".csproj";
project = "Project(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"";
}
- const char* targetExt = t->GetProperty("GENERATOR_FILE_NAME_EXT");
+ cmProp targetExt = t->GetProperty("GENERATOR_FILE_NAME_EXT");
if (targetExt) {
- ext = targetExt;
+ ext = *targetExt;
}
std::string guid = this->GetGUID(dspname);
fout << project << dspname << "\", \"" << this->ConvertToSolutionPath(dir)
- << (dir[0] ? "\\" : "") << dspname << ext << "\", \"{" << guid
+ << (!dir.empty() ? "\\" : "") << dspname << ext << "\", \"{" << guid
<< "}\"\n";
fout << "\tProjectSection(ProjectDependencies) = postProject\n";
this->WriteProjectDepends(fout, dspname, dir, t);
@@ -138,7 +138,7 @@ void cmGlobalVisualStudio71Generator::WriteProject(std::ostream& fout,
// Note, that dependencies from executables to
// the libraries it uses are also done here
void cmGlobalVisualStudio71Generator::WriteProjectDepends(
- std::ostream& fout, const std::string&, const char*,
+ std::ostream& fout, const std::string&, const std::string&,
cmGeneratorTarget const* target)
{
VSDependSet const& depends = this->VSTargetDepends[target];
@@ -156,8 +156,9 @@ void cmGlobalVisualStudio71Generator::WriteProjectDepends(
// Write a dsp file into the SLN file, Note, that dependencies from
// executables to the libraries it uses are also done here
void cmGlobalVisualStudio71Generator::WriteExternalProject(
- std::ostream& fout, const std::string& name, const char* location,
- const char* typeGuid, const std::set<BT<std::string>>& depends)
+ std::ostream& fout, const std::string& name, const std::string& location,
+ const char* typeGuid,
+ const std::set<BT<std::pair<std::string, bool>>>& depends)
{
fout << "Project(\"{"
<< (typeGuid ? typeGuid : this->ExternalProjectType(location))
@@ -169,8 +170,8 @@ void cmGlobalVisualStudio71Generator::WriteExternalProject(
// project instead of in the global section
if (!depends.empty()) {
fout << "\tProjectSection(ProjectDependencies) = postProject\n";
- for (BT<std::string> const& it : depends) {
- std::string const& dep = it.Value;
+ for (BT<std::pair<std::string, bool>> const& it : depends) {
+ std::string const& dep = it.Value.first;
if (!dep.empty()) {
fout << "\t\t{" << this->GetGUID(dep) << "} = {" << this->GetGUID(dep)
<< "}\n";
@@ -197,9 +198,9 @@ void cmGlobalVisualStudio71Generator::WriteProjectConfigurations(
std::vector<std::string> mapConfig;
const char* dstConfig = i.c_str();
if (target.GetProperty("EXTERNAL_MSPROJECT")) {
- if (const char* m = target.GetProperty("MAP_IMPORTED_CONFIG_" +
- cmSystemTools::UpperCase(i))) {
- cmExpandList(m, mapConfig);
+ if (cmProp m = target.GetProperty("MAP_IMPORTED_CONFIG_" +
+ cmSystemTools::UpperCase(i))) {
+ cmExpandList(*m, mapConfig);
if (!mapConfig.empty()) {
dstConfig = mapConfig[0].c_str();
}
diff --git a/Source/cmGlobalVisualStudio71Generator.h b/Source/cmGlobalVisualStudio71Generator.h
index 85755af..7eadaf3 100644
--- a/Source/cmGlobalVisualStudio71Generator.h
+++ b/Source/cmGlobalVisualStudio71Generator.h
@@ -22,18 +22,20 @@ protected:
virtual void WriteSolutionConfigurations(
std::ostream& fout, std::vector<std::string> const& configs);
void WriteProject(std::ostream& fout, const std::string& name,
- const char* path, const cmGeneratorTarget* t) override;
+ const std::string& path,
+ const cmGeneratorTarget* t) override;
void WriteProjectDepends(std::ostream& fout, const std::string& name,
- const char* path,
+ const std::string& path,
cmGeneratorTarget const* t) override;
void WriteProjectConfigurations(
std::ostream& fout, const std::string& name,
cmGeneratorTarget const& target, std::vector<std::string> const& configs,
const std::set<std::string>& configsPartOfDefaultBuild,
const std::string& platformMapping = "") override;
- void WriteExternalProject(std::ostream& fout, const std::string& name,
- const char* path, const char* typeGuid,
- const std::set<BT<std::string>>& depends) override;
+ void WriteExternalProject(
+ std::ostream& fout, const std::string& name, const std::string& path,
+ const char* typeGuid,
+ const std::set<BT<std::pair<std::string, bool>>>& depends) override;
// Folders are not supported by VS 7.1.
bool UseFolderProperty() const override { return false; }
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index 40b214c..428c748 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -2,8 +2,10 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalVisualStudio7Generator.h"
+#include <utility>
#include <vector>
+#include <cm/memory>
#include <cm/string_view>
#include <windows.h>
@@ -126,7 +128,7 @@ void cmGlobalVisualStudio7Generator::EnableLanguage(
// does not know about.
std::string extraPath;
if (cmSystemTools::GetEnv("CMAKE_MSVCIDE_RUN_PATH", extraPath)) {
- mf->AddCacheDefinition("CMAKE_MSVCIDE_RUN_PATH", extraPath.c_str(),
+ mf->AddCacheDefinition("CMAKE_MSVCIDE_RUN_PATH", extraPath,
"Saved environment variable CMAKE_MSVCIDE_RUN_PATH",
cmStateEnums::STATIC);
}
@@ -184,7 +186,7 @@ std::string cmGlobalVisualStudio7Generator::FindDevEnvCommand()
}
const char* cmGlobalVisualStudio7Generator::ExternalProjectType(
- const char* location)
+ const std::string& location)
{
std::string extension = cmSystemTools::GetFilenameLastExtension(location);
if (extension == ".vbproj") {
@@ -263,12 +265,11 @@ cmGlobalVisualStudio7Generator::GenerateBuildCommand(
}
//! Create a local generator appropriate to this Global Generator
-cmLocalGenerator* cmGlobalVisualStudio7Generator::CreateLocalGenerator(
- cmMakefile* mf)
+std::unique_ptr<cmLocalGenerator>
+cmGlobalVisualStudio7Generator::CreateLocalGenerator(cmMakefile* mf)
{
- cmLocalVisualStudio7Generator* lg =
- new cmLocalVisualStudio7Generator(this, mf);
- return lg;
+ auto lg = cm::make_unique<cmLocalVisualStudio7Generator>(this, mf);
+ return std::unique_ptr<cmLocalGenerator>(std::move(lg));
}
#if !defined(CMAKE_BOOTSTRAP)
@@ -300,7 +301,7 @@ void cmGlobalVisualStudio7Generator::Generate()
if (!cmSystemTools::GetErrorOccuredFlag() &&
!this->LocalGenerators.empty()) {
this->CallVisualStudioMacro(MacroReload,
- GetSLNFile(this->LocalGenerators[0]));
+ GetSLNFile(this->LocalGenerators[0].get()));
}
}
@@ -341,19 +342,19 @@ void cmGlobalVisualStudio7Generator::WriteTargetConfigurations(
if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
- const char* expath = target->GetProperty("EXTERNAL_MSPROJECT");
+ cmProp expath = target->GetProperty("EXTERNAL_MSPROJECT");
if (expath) {
std::set<std::string> allConfigurations(configs.begin(), configs.end());
- const char* mapping = target->GetProperty("VS_PLATFORM_MAPPING");
- this->WriteProjectConfigurations(fout, target->GetName().c_str(),
- *target, configs, allConfigurations,
- mapping ? mapping : "");
+ cmProp mapping = target->GetProperty("VS_PLATFORM_MAPPING");
+ this->WriteProjectConfigurations(fout, target->GetName(), *target,
+ configs, allConfigurations,
+ mapping ? *mapping : "");
} else {
const std::set<std::string>& configsPartOfDefaultBuild =
this->IsPartOfDefaultBuild(configs, projectTargets, target);
- const char* vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
+ cmProp vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
if (vcprojName) {
- this->WriteProjectConfigurations(fout, vcprojName, *target, configs,
+ this->WriteProjectConfigurations(fout, *vcprojName, *target, configs,
configsPartOfDefaultBuild);
}
}
@@ -374,25 +375,26 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
bool written = false;
// handle external vc project files
- const char* expath = target->GetProperty("EXTERNAL_MSPROJECT");
+ cmProp expath = target->GetProperty("EXTERNAL_MSPROJECT");
if (expath) {
std::string project = target->GetName();
- std::string location = expath;
+ std::string location = *expath;
- this->WriteExternalProject(fout, project.c_str(), location.c_str(),
- target->GetProperty("VS_PROJECT_TYPE"),
+ cmProp p = target->GetProperty("VS_PROJECT_TYPE");
+ this->WriteExternalProject(fout, project, location,
+ p ? p->c_str() : nullptr,
target->GetUtilities());
written = true;
} else {
- const char* vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
+ cmProp vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
if (vcprojName) {
cmLocalGenerator* lg = target->GetLocalGenerator();
std::string dir = lg->GetCurrentBinaryDirectory();
- dir = root->MaybeConvertToRelativePath(rootBinaryDir, dir.c_str());
+ dir = root->MaybeConvertToRelativePath(rootBinaryDir, dir);
if (dir == ".") {
dir.clear(); // msbuild cannot handle ".\" prefix
}
- this->WriteProject(fout, vcprojName, dir.c_str(), target);
+ this->WriteProject(fout, *vcprojName, dir, target);
written = true;
}
}
@@ -437,11 +439,11 @@ void cmGlobalVisualStudio7Generator::WriteTargetDepends(
if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
- const char* vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
+ cmProp vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
if (vcprojName) {
std::string dir =
target->GetLocalGenerator()->GetCurrentSourceDirectory();
- this->WriteProjectDepends(fout, vcprojName, dir.c_str(), target);
+ this->WriteProjectDepends(fout, *vcprojName, dir, target);
}
}
}
@@ -482,7 +484,7 @@ void cmGlobalVisualStudio7Generator::WriteFoldersContent(std::ostream& fout)
}
std::string cmGlobalVisualStudio7Generator::ConvertToSolutionPath(
- const char* path)
+ const std::string& path)
{
// Convert to backslashes. Do not use ConvertToOutputPath because
// we will add quoting ourselves, and we know these projects always
@@ -504,13 +506,13 @@ void cmGlobalVisualStudio7Generator::WriteSLNGlobalSections(
const std::vector<std::string> propKeys =
root->GetMakefile()->GetPropertyKeys();
for (std::string const& it : propKeys) {
- if (it.find("VS_GLOBAL_SECTION_") == 0) {
+ if (cmHasLiteralPrefix(it, "VS_GLOBAL_SECTION_")) {
std::string sectionType;
std::string name = it.substr(18);
- if (name.find("PRE_") == 0) {
+ if (cmHasLiteralPrefix(name, "PRE_")) {
name = name.substr(4);
sectionType = "preSolution";
- } else if (name.find("POST_") == 0) {
+ } else if (cmHasLiteralPrefix(name, "POST_")) {
name = name.substr(5);
sectionType = "postSolution";
} else
@@ -525,8 +527,8 @@ void cmGlobalVisualStudio7Generator::WriteSLNGlobalSections(
extensibilityAddInsOverridden = true;
}
fout << "\tGlobalSection(" << name << ") = " << sectionType << "\n";
- std::vector<std::string> keyValuePairs =
- cmExpandedList(root->GetMakefile()->GetProperty(it));
+ cmProp p = root->GetMakefile()->GetProperty(it);
+ std::vector<std::string> keyValuePairs = cmExpandedList(p ? *p : "");
for (std::string const& itPair : keyValuePairs) {
const std::string::size_type posEqual = itPair.find('=');
if (posEqual != std::string::npos) {
@@ -675,7 +677,8 @@ std::set<std::string> cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild(
for (std::string const& i : configs) {
const char* propertyValue =
target->Target->GetMakefile()->GetDefinition(propertyName);
- if (cmIsOn(cmGeneratorExpression::Evaluate(
+ if (propertyValue &&
+ cmIsOn(cmGeneratorExpression::Evaluate(
propertyValue, target->GetLocalGenerator(), i))) {
activeConfigs.insert(i);
}
diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h
index 7a9fcef..6cc1cf8 100644
--- a/Source/cmGlobalVisualStudio7Generator.h
+++ b/Source/cmGlobalVisualStudio7Generator.h
@@ -3,6 +3,8 @@
#ifndef cmGlobalVisualStudio7Generator_h
#define cmGlobalVisualStudio7Generator_h
+#include <memory>
+
#include "cmGlobalGeneratorFactory.h"
#include "cmGlobalVisualStudioGenerator.h"
@@ -20,7 +22,8 @@ public:
~cmGlobalVisualStudio7Generator();
//! Create a local generator appropriate to this Global Generator
- cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) override;
+ std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
+ cmMakefile* mf) override;
#if !defined(CMAKE_BOOTSTRAP)
Json::Value GetJson() const override;
@@ -107,16 +110,17 @@ protected:
std::string const& GetDevEnvCommand();
virtual std::string FindDevEnvCommand();
- static const char* ExternalProjectType(const char* location);
+ static const char* ExternalProjectType(const std::string& location);
virtual void OutputSLNFile(cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators);
virtual void WriteSLNFile(std::ostream& fout, cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators) = 0;
virtual void WriteProject(std::ostream& fout, const std::string& name,
- const char* path, const cmGeneratorTarget* t) = 0;
+ const std::string& path,
+ const cmGeneratorTarget* t) = 0;
virtual void WriteProjectDepends(std::ostream& fout, const std::string& name,
- const char* path,
+ const std::string& path,
cmGeneratorTarget const* t) = 0;
virtual void WriteProjectConfigurations(
std::ostream& fout, const std::string& name,
@@ -138,10 +142,11 @@ protected:
OrderedTargetDependSet const& projectTargets);
virtual void WriteExternalProject(
- std::ostream& fout, const std::string& name, const char* path,
- const char* typeGuid, const std::set<BT<std::string>>& dependencies) = 0;
+ std::ostream& fout, const std::string& name, const std::string& path,
+ const char* typeGuid,
+ const std::set<BT<std::pair<std::string, bool>>>& dependencies) = 0;
- std::string ConvertToSolutionPath(const char* path);
+ std::string ConvertToSolutionPath(const std::string& path);
std::set<std::string> IsPartOfDefaultBuild(
std::vector<std::string> const& configs,
diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx
index 8e6125b..29ca154 100644
--- a/Source/cmGlobalVisualStudio8Generator.cxx
+++ b/Source/cmGlobalVisualStudio8Generator.cxx
@@ -2,6 +2,9 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalVisualStudio8Generator.h"
+#include <cm/memory>
+#include <cmext/memory>
+
#include "cmCustomCommand.h"
#include "cmCustomCommandLines.h"
#include "cmDocumentationEntry.h"
@@ -96,21 +99,22 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
return false;
}
- std::vector<cmLocalGenerator*> const& generators = this->LocalGenerators;
- cmLocalVisualStudio7Generator* lg =
- static_cast<cmLocalVisualStudio7Generator*>(generators[0]);
- cmMakefile* mf = lg->GetMakefile();
+ std::vector<std::unique_ptr<cmLocalGenerator>> const& generators =
+ this->LocalGenerators;
+ auto& lg =
+ cm::static_reference_cast<cmLocalVisualStudio7Generator>(generators[0]);
const char* no_working_directory = nullptr;
std::vector<std::string> no_byproducts;
std::vector<std::string> no_depends;
cmCustomCommandLines no_commands;
- cmTarget* tgt = mf->AddUtilityCommand(
- CMAKE_CHECK_BUILD_SYSTEM_TARGET, cmCommandOrigin::Generator, false,
- no_working_directory, no_byproducts, no_depends, no_commands);
+ cmTarget* tgt = lg.AddUtilityCommand(CMAKE_CHECK_BUILD_SYSTEM_TARGET, false,
+ no_working_directory, no_byproducts,
+ no_depends, no_commands);
- cmGeneratorTarget* gt = new cmGeneratorTarget(tgt, lg);
- lg->AddGeneratorTarget(gt);
+ auto ptr = cm::make_unique<cmGeneratorTarget>(tgt, &lg);
+ auto gt = ptr.get();
+ lg.AddGeneratorTarget(std::move(ptr));
// Organize in the "predefined targets" folder:
//
@@ -128,7 +132,7 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
stampList);
std::string stampFile;
cmGeneratedFileStream fout(stampListFile.c_str());
- for (cmLocalGenerator const* gi : generators) {
+ for (const auto& gi : generators) {
stampFile = cmStrCat(gi->GetMakefile()->GetCurrentBinaryDirectory(),
"/CMakeFiles/generate.stamp");
fout << stampFile << "\n";
@@ -138,11 +142,14 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
// Add a custom rule to re-run CMake if any input files changed.
{
+ // The custom rule runs cmake so set UTF-8 pipes.
+ bool stdPipesUTF8 = true;
+
// Collect the input files used to generate all targets in this
// project.
std::vector<std::string> listFiles;
- for (cmLocalGenerator* gen : generators) {
- cmAppend(listFiles, gen->GetMakefile()->GetListFiles());
+ for (const auto& gen : generators) {
+ cm::append(listFiles, gen->GetMakefile()->GetListFiles());
}
// Add a custom prebuild target to run the VerifyGlobs script.
@@ -153,10 +160,10 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
std::vector<std::string> byproducts;
byproducts.push_back(cm->GetGlobVerifyStamp());
- mf->AddCustomCommandToTarget(
+ lg.AddCustomCommandToTarget(
CMAKE_CHECK_BUILD_SYSTEM_TARGET, byproducts, no_depends,
verifyCommandLines, cmCustomCommandType::PRE_BUILD,
- "Checking File Globs", no_working_directory, false);
+ "Checking File Globs", no_working_directory, stdPipesUTF8);
// Ensure ZERO_CHECK always runs in Visual Studio using MSBuild,
// otherwise the prebuild command will not be run.
@@ -171,10 +178,10 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
listFiles.erase(new_end, listFiles.end());
// Create a rule to re-run CMake.
- std::string argS = cmStrCat("-S", lg->GetSourceDirectory());
- std::string argB = cmStrCat("-B", lg->GetBinaryDirectory());
+ std::string argS = cmStrCat("-S", lg.GetSourceDirectory());
+ std::string argB = cmStrCat("-B", lg.GetBinaryDirectory());
std::string const sln =
- lg->GetBinaryDirectory() + "/" + lg->GetProjectName() + ".sln";
+ lg.GetBinaryDirectory() + "/" + lg.GetProjectName() + ".sln";
cmCustomCommandLines commandLines = cmMakeSingleCommandLine(
{ cmSystemTools::GetCMakeCommand(), argS, argB, "--check-stamp-list",
stampList, "--vs-solution-file", sln });
@@ -185,10 +192,11 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
// (this could be avoided with per-target source files)
std::string no_main_dependency;
cmImplicitDependsList no_implicit_depends;
- if (cmSourceFile* file = mf->AddCustomCommandToOutput(
+ if (cmSourceFile* file = lg.AddCustomCommandToOutput(
stamps, no_byproducts, listFiles, no_main_dependency,
no_implicit_depends, commandLines, "Checking Build System",
- no_working_directory, true, false)) {
+ no_working_directory, true, false, false, false, "", "",
+ stdPipesUTF8)) {
gt->AddSource(file->ResolveFullPath());
} else {
cmSystemTools::Error("Error adding rule for " + stamps[0]);
@@ -203,12 +211,11 @@ void cmGlobalVisualStudio8Generator::AddExtraIDETargets()
cmGlobalVisualStudio7Generator::AddExtraIDETargets();
if (this->AddCheckTarget()) {
for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i) {
- const std::vector<cmGeneratorTarget*>& tgts =
- this->LocalGenerators[i]->GetGeneratorTargets();
+ const auto& tgts = this->LocalGenerators[i]->GetGeneratorTargets();
// All targets depend on the build-system check target.
- for (cmGeneratorTarget const* ti : tgts) {
+ for (const auto& ti : tgts) {
if (ti->GetName() != CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
- ti->Target->AddUtility(CMAKE_CHECK_BUILD_SYSTEM_TARGET);
+ ti->Target->AddUtility(CMAKE_CHECK_BUILD_SYSTEM_TARGET, false);
}
}
}
@@ -237,9 +244,9 @@ void cmGlobalVisualStudio8Generator::WriteProjectConfigurations(
std::vector<std::string> mapConfig;
const char* dstConfig = i.c_str();
if (target.GetProperty("EXTERNAL_MSPROJECT")) {
- if (const char* m = target.GetProperty("MAP_IMPORTED_CONFIG_" +
- cmSystemTools::UpperCase(i))) {
- cmExpandList(m, mapConfig);
+ if (cmProp m = target.GetProperty("MAP_IMPORTED_CONFIG_" +
+ cmSystemTools::UpperCase(i))) {
+ cmExpandList(*m, mapConfig);
if (!mapConfig.empty()) {
dstConfig = mapConfig[0].c_str();
}
@@ -272,23 +279,31 @@ void cmGlobalVisualStudio8Generator::WriteProjectConfigurations(
bool cmGlobalVisualStudio8Generator::NeedsDeploy(
cmGeneratorTarget const& target, const char* config) const
{
- cmStateEnums::TargetType type = target.GetType();
- bool noDeploy = DeployInhibited(target, config);
- return !noDeploy &&
- (type == cmStateEnums::EXECUTABLE ||
- type == cmStateEnums::SHARED_LIBRARY) &&
- this->TargetSystemSupportsDeployment();
-}
+ cmStateEnums::TargetType const type = target.GetType();
+ if (type != cmStateEnums::EXECUTABLE &&
+ type != cmStateEnums::SHARED_LIBRARY) {
+ // deployment only valid on executables and shared libraries.
+ return false;
+ }
-bool cmGlobalVisualStudio8Generator::DeployInhibited(
- cmGeneratorTarget const& target, const char* config) const
-{
- bool rVal = false;
- if (const char* prop = target.GetProperty("VS_NO_SOLUTION_DEPLOY")) {
- rVal = cmIsOn(
- cmGeneratorExpression::Evaluate(prop, target.LocalGenerator, config));
+ if (cmProp prop = target.GetProperty("VS_SOLUTION_DEPLOY")) {
+ // If set, it dictates behavior
+ return cmIsOn(
+ cmGeneratorExpression::Evaluate(*prop, target.LocalGenerator, config));
}
- return rVal;
+
+ // To be deprecated, disable deployment even if target supports it.
+ if (cmProp prop = target.GetProperty("VS_NO_SOLUTION_DEPLOY")) {
+ if (cmIsOn(cmGeneratorExpression::Evaluate(*prop, target.LocalGenerator,
+ config))) {
+ // If true, always disable deployment
+ return false;
+ }
+ }
+
+ // Legacy behavior, enabled deployment based on 'hard-coded' target
+ // platforms.
+ return this->TargetSystemSupportsDeployment();
}
bool cmGlobalVisualStudio8Generator::TargetSystemSupportsDeployment() const
@@ -304,7 +319,7 @@ bool cmGlobalVisualStudio8Generator::ComputeTargetDepends()
}
void cmGlobalVisualStudio8Generator::WriteProjectDepends(
- std::ostream& fout, const std::string&, const char*,
+ std::ostream& fout, const std::string&, const std::string&,
cmGeneratorTarget const* gt)
{
TargetDependSet const& unordered = this->GetTargetDirectDepends(gt);
@@ -322,9 +337,10 @@ bool cmGlobalVisualStudio8Generator::NeedLinkLibraryDependencies(
cmGeneratorTarget* target)
{
// Look for utility dependencies that magically link.
- for (BT<std::string> const& ui : target->GetUtilities()) {
+ for (BT<std::pair<std::string, bool>> const& ui : target->GetUtilities()) {
if (cmGeneratorTarget* depTarget =
- target->GetLocalGenerator()->FindGeneratorTargetToUse(ui.Value)) {
+ target->GetLocalGenerator()->FindGeneratorTargetToUse(
+ ui.Value.first)) {
if (depTarget->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
depTarget->GetProperty("EXTERNAL_MSPROJECT")) {
// This utility dependency names an external .vcproj target.
diff --git a/Source/cmGlobalVisualStudio8Generator.h b/Source/cmGlobalVisualStudio8Generator.h
index 352bc3c..6ce67d3 100644
--- a/Source/cmGlobalVisualStudio8Generator.h
+++ b/Source/cmGlobalVisualStudio8Generator.h
@@ -57,10 +57,6 @@ protected:
virtual bool NeedsDeploy(cmGeneratorTarget const& target,
const char* config) const;
- /** Returns true if deployment has been disabled in cmake file. */
- bool DeployInhibited(cmGeneratorTarget const& target,
- const char* config) const;
-
/** Returns true if the target system support debugging deployment. */
virtual bool TargetSystemSupportsDeployment() const;
@@ -74,7 +70,7 @@ protected:
const std::string& platformMapping = "") override;
bool ComputeTargetDepends() override;
void WriteProjectDepends(std::ostream& fout, const std::string& name,
- const char* path,
+ const std::string& path,
const cmGeneratorTarget* t) override;
bool UseFolderProperty() const override;
diff --git a/Source/cmGlobalVisualStudio9Generator.cxx b/Source/cmGlobalVisualStudio9Generator.cxx
index 6e61d26..9f73c15 100644
--- a/Source/cmGlobalVisualStudio9Generator.cxx
+++ b/Source/cmGlobalVisualStudio9Generator.cxx
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalVisualStudio9Generator.h"
+#include <utility>
+
#include "cmDocumentationEntry.h"
#include "cmLocalVisualStudio7Generator.h"
#include "cmMakefile.h"
@@ -13,43 +15,46 @@ static const char vs9generatorName[] = "Visual Studio 9 2008";
class cmGlobalVisualStudio9Generator::Factory : public cmGlobalGeneratorFactory
{
public:
- cmGlobalGenerator* CreateGlobalGenerator(const std::string& name,
- cmake* cm) const override
+ std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
+ const std::string& name, cmake* cm) const override
{
if (strncmp(name.c_str(), vs9generatorName,
sizeof(vs9generatorName) - 1) != 0) {
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
const char* p = name.c_str() + sizeof(vs9generatorName) - 1;
if (p[0] == '\0') {
- return new cmGlobalVisualStudio9Generator(cm, name, "");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudio9Generator(cm, name, ""));
}
if (p[0] != ' ') {
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
++p;
if (!strcmp(p, "IA64")) {
- return new cmGlobalVisualStudio9Generator(cm, name, "Itanium");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudio9Generator(cm, name, "Itanium"));
}
if (!strcmp(p, "Win64")) {
- return new cmGlobalVisualStudio9Generator(cm, name, "x64");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudio9Generator(cm, name, "x64"));
}
cmVisualStudioWCEPlatformParser parser(p);
parser.ParseVersion("9.0");
if (!parser.Found()) {
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
- cmGlobalVisualStudio9Generator* ret =
- new cmGlobalVisualStudio9Generator(cm, name, p);
+ auto ret = std::unique_ptr<cmGlobalVisualStudio9Generator>(
+ new cmGlobalVisualStudio9Generator(cm, name, p));
ret->WindowsCEVersion = parser.GetOSVersion();
- return ret;
+ return std::unique_ptr<cmGlobalGenerator>(std::move(ret));
}
void GetDocumentation(cmDocumentationEntry& entry) const override
@@ -103,9 +108,10 @@ public:
std::string GetDefaultPlatformName() const override { return "Win32"; }
};
-cmGlobalGeneratorFactory* cmGlobalVisualStudio9Generator::NewFactory()
+std::unique_ptr<cmGlobalGeneratorFactory>
+cmGlobalVisualStudio9Generator::NewFactory()
{
- return new Factory;
+ return std::unique_ptr<cmGlobalGeneratorFactory>(new Factory);
}
cmGlobalVisualStudio9Generator::cmGlobalVisualStudio9Generator(
diff --git a/Source/cmGlobalVisualStudio9Generator.h b/Source/cmGlobalVisualStudio9Generator.h
index 7bebfd6..53318a6 100644
--- a/Source/cmGlobalVisualStudio9Generator.h
+++ b/Source/cmGlobalVisualStudio9Generator.h
@@ -3,6 +3,8 @@
#ifndef cmGlobalVisualStudio9Generator_h
#define cmGlobalVisualStudio9Generator_h
+#include <memory>
+
#include "cmGlobalVisualStudio8Generator.h"
/** \class cmGlobalVisualStudio9Generator
@@ -13,7 +15,7 @@
class cmGlobalVisualStudio9Generator : public cmGlobalVisualStudio8Generator
{
public:
- static cmGlobalGeneratorFactory* NewFactory();
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory();
/**
* Where does this version of Visual Studio look for macros for the
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index ed0cba7..28bd1ca 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -7,6 +7,7 @@
#include <iostream>
#include <cm/iterator>
+#include <cm/memory>
#include <windows.h>
@@ -196,12 +197,12 @@ void cmGlobalVisualStudioGenerator::AddExtraIDETargets()
if (!gen.empty()) {
// Use no actual command lines so that the target itself is not
// considered always out of date.
- cmTarget* allBuild = gen[0]->GetMakefile()->AddUtilityCommand(
- "ALL_BUILD", cmCommandOrigin::Generator, true, no_working_dir,
- no_byproducts, no_depends, no_commands, false, "Build all projects");
+ cmTarget* allBuild = gen[0]->AddUtilityCommand(
+ "ALL_BUILD", true, no_working_dir, no_byproducts, no_depends,
+ no_commands, false, "Build all projects");
- cmGeneratorTarget* gt = new cmGeneratorTarget(allBuild, gen[0]);
- gen[0]->AddGeneratorTarget(gt);
+ gen[0]->AddGeneratorTarget(
+ cm::make_unique<cmGeneratorTarget>(allBuild, gen[0]));
//
// Organize in the "predefined targets" folder:
@@ -212,13 +213,13 @@ void cmGlobalVisualStudioGenerator::AddExtraIDETargets()
// Now make all targets depend on the ALL_BUILD target
for (cmLocalGenerator const* i : gen) {
- for (cmGeneratorTarget* tgt : i->GetGeneratorTargets()) {
+ for (const auto& tgt : i->GetGeneratorTargets()) {
if (tgt->GetType() == cmStateEnums::GLOBAL_TARGET ||
tgt->IsImported()) {
continue;
}
- if (!this->IsExcluded(gen[0], tgt)) {
- allBuild->AddUtility(tgt->GetName());
+ if (!this->IsExcluded(gen[0], tgt.get())) {
+ allBuild->AddUtility(tgt->GetName(), false);
}
}
}
@@ -307,7 +308,7 @@ void cmGlobalVisualStudioGenerator::CallVisualStudioMacro(
if (!dir.empty()) {
std::string macrosFile = dir + "/CMakeMacros/" CMAKE_VSMACROS_FILENAME;
std::string nextSubkeyName;
- if (cmSystemTools::FileExists(macrosFile.c_str()) &&
+ if (cmSystemTools::FileExists(macrosFile) &&
IsVisualStudioMacrosFileRegistered(
macrosFile, this->GetUserMacrosRegKeyBase(), nextSubkeyName)) {
if (m == MacroReload) {
@@ -389,8 +390,8 @@ bool cmGlobalVisualStudioGenerator::ComputeTargetDepends()
}
for (auto const& it : this->ProjectMap) {
for (const cmLocalGenerator* i : it.second) {
- for (cmGeneratorTarget* ti : i->GetGeneratorTargets()) {
- this->ComputeVSTargetDepends(ti);
+ for (const auto& ti : i->GetGeneratorTargets()) {
+ this->ComputeVSTargetDepends(ti.get());
}
}
}
@@ -506,9 +507,9 @@ std::string cmGlobalVisualStudioGenerator::GetUtilityDepend(
std::string cmGlobalVisualStudioGenerator::GetStartupProjectName(
cmLocalGenerator const* root) const
{
- const char* n = root->GetMakefile()->GetProperty("VS_STARTUP_PROJECT");
- if (n && *n) {
- std::string startup = n;
+ cmProp n = root->GetMakefile()->GetProperty("VS_STARTUP_PROJECT");
+ if (n && !n->empty()) {
+ std::string startup = *n;
if (this->FindTarget(startup)) {
return startup;
} else {
@@ -592,7 +593,7 @@ bool IsVisualStudioMacrosFileRegistered(const std::string& macrosFile,
std::string filepath;
std::string filepathname;
std::string filepathpath;
- if (cmSystemTools::FileExists(fullname.c_str())) {
+ if (cmSystemTools::FileExists(fullname)) {
filename = cmSystemTools::GetFilenameName(fullname);
filepath = cmSystemTools::GetFilenamePath(fullname);
filepathname = cmSystemTools::GetFilenameName(filepath);
@@ -799,27 +800,17 @@ void RegisterVisualStudioMacros(const std::string& macrosFile,
bool cmGlobalVisualStudioGenerator::TargetIsFortranOnly(
cmGeneratorTarget const* gt)
{
- // check to see if this is a fortran build
- {
- // Issue diagnostic if the source files depend on the config.
- std::vector<cmSourceFile*> sources;
- if (!gt->GetConfigCommonSourceFiles(sources)) {
- return false;
- }
- }
-
// If there's only one source language, Fortran has to be used
// in order for the sources to compile.
- std::set<std::string> languages;
- gt->GetLanguages(languages, "");
+ std::set<std::string> languages = gt->GetAllConfigCompileLanguages();
// Consider an explicit linker language property, but *not* the
// computed linker language that may depend on linked targets.
// This allows the project to control the language choice in
// a target with none of its own sources, e.g. when also using
// object libraries.
- const char* linkLang = gt->GetProperty("LINKER_LANGUAGE");
- if (linkLang && *linkLang) {
- languages.insert(linkLang);
+ cmProp linkLang = gt->GetProperty("LINKER_LANGUAGE");
+ if (linkLang && !linkLang->empty()) {
+ languages.insert(*linkLang);
}
// Intel Fortran .vfproj files do support the resource compiler.
@@ -926,7 +917,7 @@ void cmGlobalVisualStudioGenerator::AddSymbolExportCommand(
std::string objFile = it;
// replace $(ConfigurationName) in the object names
cmSystemTools::ReplaceString(objFile, this->GetCMakeCFGIntDir(),
- configName.c_str());
+ configName);
if (cmHasLiteralSuffix(objFile, ".obj")) {
fout << objFile << "\n";
}
@@ -939,9 +930,10 @@ void cmGlobalVisualStudioGenerator::AddSymbolExportCommand(
cmCustomCommandLines commandLines = cmMakeSingleCommandLine(
{ cmakeCommand, "-E", "__create_def", mdi->DefFile, objs_file });
- cmCustomCommand command(gt->Target->GetMakefile(), outputs, empty, empty,
- commandLines, "Auto build dll exports", ".");
- commands.push_back(command);
+ cmCustomCommand command(outputs, empty, empty, commandLines,
+ gt->Target->GetMakefile()->GetBacktrace(),
+ "Auto build dll exports", ".", true);
+ commands.push_back(std::move(command));
}
static bool OpenSolution(std::string sln)
diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h
index 4f2007f..29a5c2c 100644
--- a/Source/cmGlobalVisualStudioGenerator.h
+++ b/Source/cmGlobalVisualStudioGenerator.h
@@ -150,6 +150,8 @@ public:
bool Open(const std::string& bindir, const std::string& projectName,
bool dryRun) override;
+ bool IsVisualStudio() const override { return true; }
+
protected:
cmGlobalVisualStudioGenerator(cmake* cm,
std::string const& platformInGeneratorName);
diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.cxx b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
index a371633..13ae32a 100644
--- a/Source/cmGlobalVisualStudioVersionedGenerator.cxx
+++ b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
@@ -121,30 +121,33 @@ class cmGlobalVisualStudioVersionedGenerator::Factory15
: public cmGlobalGeneratorFactory
{
public:
- cmGlobalGenerator* CreateGlobalGenerator(const std::string& name,
- cmake* cm) const override
+ std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
+ const std::string& name, cmake* cm) const override
{
std::string genName;
const char* p = cmVS15GenName(name, genName);
if (!p) {
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
if (!*p) {
- return new cmGlobalVisualStudioVersionedGenerator(
- cmGlobalVisualStudioGenerator::VS15, cm, genName, "");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudioVersionedGenerator(
+ cmGlobalVisualStudioGenerator::VS15, cm, genName, ""));
}
if (*p++ != ' ') {
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
if (strcmp(p, "Win64") == 0) {
- return new cmGlobalVisualStudioVersionedGenerator(
- cmGlobalVisualStudioGenerator::VS15, cm, genName, "x64");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudioVersionedGenerator(
+ cmGlobalVisualStudioGenerator::VS15, cm, genName, "x64"));
}
if (strcmp(p, "ARM") == 0) {
- return new cmGlobalVisualStudioVersionedGenerator(
- cmGlobalVisualStudioGenerator::VS15, cm, genName, "ARM");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudioVersionedGenerator(
+ cmGlobalVisualStudioGenerator::VS15, cm, genName, "ARM"));
}
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
void GetDocumentation(cmDocumentationEntry& entry) const override
@@ -185,10 +188,10 @@ public:
std::string GetDefaultPlatformName() const override { return "Win32"; }
};
-cmGlobalGeneratorFactory*
+std::unique_ptr<cmGlobalGeneratorFactory>
cmGlobalVisualStudioVersionedGenerator::NewFactory15()
{
- return new Factory15;
+ return std::unique_ptr<cmGlobalGeneratorFactory>(new Factory15);
}
static const char vs16generatorName[] = "Visual Studio 16 2019";
@@ -212,19 +215,20 @@ class cmGlobalVisualStudioVersionedGenerator::Factory16
: public cmGlobalGeneratorFactory
{
public:
- cmGlobalGenerator* CreateGlobalGenerator(const std::string& name,
- cmake* cm) const override
+ std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
+ const std::string& name, cmake* cm) const override
{
std::string genName;
const char* p = cmVS16GenName(name, genName);
if (!p) {
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
if (!*p) {
- return new cmGlobalVisualStudioVersionedGenerator(
- cmGlobalVisualStudioGenerator::VS16, cm, genName, "");
+ return std::unique_ptr<cmGlobalGenerator>(
+ new cmGlobalVisualStudioVersionedGenerator(
+ cmGlobalVisualStudioGenerator::VS16, cm, genName, ""));
}
- return 0;
+ return std::unique_ptr<cmGlobalGenerator>();
}
void GetDocumentation(cmDocumentationEntry& entry) const override
@@ -265,10 +269,10 @@ public:
}
};
-cmGlobalGeneratorFactory*
+std::unique_ptr<cmGlobalGeneratorFactory>
cmGlobalVisualStudioVersionedGenerator::NewFactory16()
{
- return new Factory16;
+ return std::unique_ptr<cmGlobalGeneratorFactory>(new Factory16);
}
cmGlobalVisualStudioVersionedGenerator::cmGlobalVisualStudioVersionedGenerator(
diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.h b/Source/cmGlobalVisualStudioVersionedGenerator.h
index 466816b..abb6095 100644
--- a/Source/cmGlobalVisualStudioVersionedGenerator.h
+++ b/Source/cmGlobalVisualStudioVersionedGenerator.h
@@ -6,6 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <iosfwd>
+#include <memory>
#include <string>
#include "cmGlobalVisualStudio14Generator.h"
@@ -19,8 +20,8 @@ class cmGlobalVisualStudioVersionedGenerator
: public cmGlobalVisualStudio14Generator
{
public:
- static cmGlobalGeneratorFactory* NewFactory15();
- static cmGlobalGeneratorFactory* NewFactory16();
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory15();
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory16();
bool MatchesGeneratorName(const std::string& name) const override;
diff --git a/Source/cmGlobalWatcomWMakeGenerator.cxx b/Source/cmGlobalWatcomWMakeGenerator.cxx
index 308ddda..d6a7afa 100644
--- a/Source/cmGlobalWatcomWMakeGenerator.cxx
+++ b/Source/cmGlobalWatcomWMakeGenerator.cxx
@@ -19,7 +19,7 @@ cmGlobalWatcomWMakeGenerator::cmGlobalWatcomWMakeGenerator(cmake* cm)
#endif
this->ToolSupportsColor = true;
this->NeedSymbolicMark = true;
- this->EmptyRuleHackCommand = "@cd .";
+ this->EmptyRuleHackCommand = "@%null";
#ifdef _WIN32
cm->GetState()->SetWindowsShell(true);
#endif
@@ -44,6 +44,16 @@ void cmGlobalWatcomWMakeGenerator::EnableLanguage(
this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional);
}
+bool cmGlobalWatcomWMakeGenerator::SetSystemName(std::string const& s,
+ cmMakefile* mf)
+{
+ if (mf->GetSafeDefinition("CMAKE_SYSTEM_PROCESSOR") == "I86") {
+ mf->AddDefinition("CMAKE_GENERATOR_CC", "wcl");
+ mf->AddDefinition("CMAKE_GENERATOR_CXX", "wcl");
+ }
+ return this->cmGlobalUnixMakefileGenerator3::SetSystemName(s, mf);
+}
+
void cmGlobalWatcomWMakeGenerator::GetDocumentation(
cmDocumentationEntry& entry)
{
diff --git a/Source/cmGlobalWatcomWMakeGenerator.h b/Source/cmGlobalWatcomWMakeGenerator.h
index 64ace13..c47127f 100644
--- a/Source/cmGlobalWatcomWMakeGenerator.h
+++ b/Source/cmGlobalWatcomWMakeGenerator.h
@@ -6,6 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <iosfwd>
+#include <memory>
#include <string>
#include <vector>
@@ -25,9 +26,10 @@ class cmGlobalWatcomWMakeGenerator : public cmGlobalUnixMakefileGenerator3
{
public:
cmGlobalWatcomWMakeGenerator(cmake* cm);
- static cmGlobalGeneratorFactory* NewFactory()
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory()
{
- return new cmGlobalGeneratorSimpleFactory<cmGlobalWatcomWMakeGenerator>();
+ return std::unique_ptr<cmGlobalGeneratorFactory>(
+ new cmGlobalGeneratorSimpleFactory<cmGlobalWatcomWMakeGenerator>());
}
//! Get the name for the generator.
std::string GetName() const override
@@ -39,6 +41,9 @@ public:
/** Get the documentation entry for this generator. */
static void GetDocumentation(cmDocumentationEntry& entry);
+ /** Tell the generator about the target system. */
+ bool SetSystemName(std::string const& s, cmMakefile* mf) override;
+
/**
* Try to determine system information such as shared library
* extension, pthreads, byte order etc.
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index aee475b..cda3338 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -2,17 +2,19 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGlobalXCodeGenerator.h"
+#include <algorithm>
#include <cassert>
#include <cstdio>
#include <cstring>
#include <iomanip>
#include <sstream>
+#include <utility>
#include <cm/memory>
+#include <cmext/algorithm>
#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
@@ -31,6 +33,7 @@
#include "cmSourceGroup.h"
#include "cmState.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmXCode21Object.h"
@@ -129,8 +132,8 @@ public:
class cmGlobalXCodeGenerator::Factory : public cmGlobalGeneratorFactory
{
public:
- cmGlobalGenerator* CreateGlobalGenerator(const std::string& name,
- cmake* cm) const override;
+ std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
+ const std::string& name, cmake* cm) const override;
void GetDocumentation(cmDocumentationEntry& entry) const override
{
@@ -179,16 +182,17 @@ cmGlobalXCodeGenerator::cmGlobalXCodeGenerator(
cm->GetState()->SetIsGeneratorMultiConfig(true);
}
-cmGlobalGeneratorFactory* cmGlobalXCodeGenerator::NewFactory()
+std::unique_ptr<cmGlobalGeneratorFactory> cmGlobalXCodeGenerator::NewFactory()
{
- return new Factory;
+ return std::unique_ptr<cmGlobalGeneratorFactory>(new Factory);
}
-cmGlobalGenerator* cmGlobalXCodeGenerator::Factory::CreateGlobalGenerator(
- const std::string& name, cmake* cm) const
+std::unique_ptr<cmGlobalGenerator>
+cmGlobalXCodeGenerator::Factory::CreateGlobalGenerator(const std::string& name,
+ cmake* cm) const
{
if (name != GetActualName()) {
- return nullptr;
+ return std::unique_ptr<cmGlobalGenerator>();
}
#if !defined(CMAKE_BOOTSTRAP)
cmXcodeVersionParser parser;
@@ -224,16 +228,17 @@ cmGlobalGenerator* cmGlobalXCodeGenerator::Factory::CreateGlobalGenerator(
if (version_number < 50) {
cm->IssueMessage(MessageType::FATAL_ERROR,
"Xcode " + version_string + " not supported.");
- return nullptr;
+ return std::unique_ptr<cmGlobalGenerator>();
}
- auto gg = cm::make_unique<cmGlobalXCodeGenerator>(cm, version_string,
- version_number);
- return gg.release();
+ return std::unique_ptr<cmGlobalGenerator>(
+ cm::make_unique<cmGlobalXCodeGenerator>(cm, version_string,
+ version_number));
#else
std::cerr << "CMake should be built with cmake to use Xcode, "
"default to Xcode 1.5\n";
- return new cmGlobalXCodeGenerator(cm);
+ return std::unique_ptr<cmGlobalGenerator>(
+ cm::make_unique<cmGlobalXCodeGenerator>(cm));
#endif
}
@@ -267,7 +272,7 @@ std::string cmGlobalXCodeGenerator::FindXcodeBuildCommand()
}
bool cmGlobalXCodeGenerator::SetGeneratorToolset(std::string const& ts,
- cmMakefile* mf)
+ bool build, cmMakefile* mf)
{
if (ts.find_first_of(",=") != std::string::npos) {
std::ostringstream e;
@@ -283,6 +288,9 @@ bool cmGlobalXCodeGenerator::SetGeneratorToolset(std::string const& ts,
return false;
}
this->GeneratorToolset = ts;
+ if (build) {
+ return true;
+ }
if (!this->GeneratorToolset.empty()) {
mf->AddDefinition("CMAKE_XCODE_PLATFORM_TOOLSET", this->GeneratorToolset);
}
@@ -354,7 +362,7 @@ cmGlobalXCodeGenerator::GenerateBuildCommand(
std::string projectArg = cmStrCat(projectName, ".xcodeproj");
makeCommand.Add(projectArg);
}
- if (cmContains(targetNames, "clean")) {
+ if (cm::contains(targetNames, "clean")) {
makeCommand.Add("clean");
makeCommand.Add("-target", "ALL_BUILD");
} else {
@@ -388,9 +396,11 @@ cmGlobalXCodeGenerator::GenerateBuildCommand(
}
//! Create a local generator appropriate to this Global Generator
-cmLocalGenerator* cmGlobalXCodeGenerator::CreateLocalGenerator(cmMakefile* mf)
+std::unique_ptr<cmLocalGenerator> cmGlobalXCodeGenerator::CreateLocalGenerator(
+ cmMakefile* mf)
{
- return new cmLocalXCodeGenerator(this, mf);
+ return std::unique_ptr<cmLocalGenerator>(
+ cm::make_unique<cmLocalXCodeGenerator>(this, mf));
}
void cmGlobalXCodeGenerator::AddExtraIDETargets()
@@ -409,10 +419,10 @@ void cmGlobalXCodeGenerator::ComputeTargetOrder()
{
size_t index = 0;
auto const& lgens = this->GetLocalGenerators();
- for (cmLocalGenerator* lgen : lgens) {
- auto const& targets = lgen->GetGeneratorTargets();
- for (cmGeneratorTarget const* gt : targets) {
- this->ComputeTargetOrder(gt, index);
+ for (auto const& lgen : lgens) {
+ const auto& targets = lgen->GetGeneratorTargets();
+ for (const auto& gt : targets) {
+ this->ComputeTargetOrder(gt.get(), index);
}
}
assert(index == this->TargetOrderIndex.size());
@@ -496,20 +506,16 @@ std::string cmGlobalXCodeGenerator::PostBuildMakeTarget(
void cmGlobalXCodeGenerator::AddExtraTargets(
cmLocalGenerator* root, std::vector<cmLocalGenerator*>& gens)
{
- cmMakefile* mf = root->GetMakefile();
-
const char* no_working_directory = nullptr;
std::vector<std::string> no_byproducts;
std::vector<std::string> no_depends;
// Add ALL_BUILD
- cmTarget* allbuild = mf->AddUtilityCommand(
- "ALL_BUILD", cmCommandOrigin::Generator, true, no_working_directory,
- no_byproducts, no_depends,
+ cmTarget* allbuild = root->AddUtilityCommand(
+ "ALL_BUILD", true, no_working_directory, no_byproducts, no_depends,
cmMakeSingleCommandLine({ "echo", "Build all projects" }));
- cmGeneratorTarget* allBuildGt = new cmGeneratorTarget(allbuild, root);
- root->AddGeneratorTarget(allBuildGt);
+ root->AddGeneratorTarget(cm::make_unique<cmGeneratorTarget>(allbuild, root));
// Add XCODE depend helper
std::string dir = root->GetCurrentBinaryDirectory();
@@ -520,52 +526,53 @@ void cmGlobalXCodeGenerator::AddExtraTargets(
// Add ZERO_CHECK
bool regenerate = !this->GlobalSettingIsOn("CMAKE_SUPPRESS_REGENERATION");
bool generateTopLevelProjectOnly =
- mf->IsOn("CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY");
+ root->GetMakefile()->IsOn("CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY");
bool isTopLevel =
!root->GetStateSnapshot().GetBuildsystemDirectoryParent().IsValid();
- if (regenerate && (isTopLevel || !generateTopLevelProjectOnly)) {
+ bool isGenerateProject = isTopLevel || !generateTopLevelProjectOnly;
+ if (regenerate && isGenerateProject) {
this->CreateReRunCMakeFile(root, gens);
std::string file =
this->ConvertToRelativeForMake(this->CurrentReRunCMakeMakefile);
cmSystemTools::ReplaceString(file, "\\ ", " ");
- cmTarget* check = mf->AddUtilityCommand(
- CMAKE_CHECK_BUILD_SYSTEM_TARGET, cmCommandOrigin::Generator, true,
- no_working_directory, no_byproducts, no_depends,
- cmMakeSingleCommandLine({ "make", "-f", file }));
+ cmTarget* check =
+ root->AddUtilityCommand(CMAKE_CHECK_BUILD_SYSTEM_TARGET, true,
+ no_working_directory, no_byproducts, no_depends,
+ cmMakeSingleCommandLine({ "make", "-f", file }));
- cmGeneratorTarget* checkGt = new cmGeneratorTarget(check, root);
- root->AddGeneratorTarget(checkGt);
+ root->AddGeneratorTarget(cm::make_unique<cmGeneratorTarget>(check, root));
}
// now make the allbuild depend on all the non-utility targets
// in the project
for (auto& gen : gens) {
- for (auto target : gen->GetGeneratorTargets()) {
+ for (const auto& target : gen->GetGeneratorTargets()) {
if (target->GetType() == cmStateEnums::GLOBAL_TARGET) {
continue;
}
if (regenerate &&
(target->GetName() != CMAKE_CHECK_BUILD_SYSTEM_TARGET)) {
- target->Target->AddUtility(CMAKE_CHECK_BUILD_SYSTEM_TARGET);
+ target->Target->AddUtility(CMAKE_CHECK_BUILD_SYSTEM_TARGET, false);
}
// make all exe, shared libs and modules
// run the depend check makefile as a post build rule
// this will make sure that when the next target is built
// things are up-to-date
- if (target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
+ if (isGenerateProject &&
+ target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
commandLines.front().back() = // fill placeholder
this->PostBuildMakeTarget(target->GetName(), "$(CONFIGURATION)");
- gen->GetMakefile()->AddCustomCommandToTarget(
+ gen->AddCustomCommandToTarget(
target->GetName(), no_byproducts, no_depends, commandLines,
cmCustomCommandType::POST_BUILD, "Depend check for xcode",
dir.c_str(), true, false, "", "", false,
cmObjectLibraryCommands::Accept);
}
- if (!this->IsExcluded(gens[0], target)) {
- allbuild->AddUtility(target->GetName());
+ if (!this->IsExcluded(gens[0], target.get())) {
+ allbuild->AddUtility(target->GetName(), false);
}
}
}
@@ -576,7 +583,7 @@ void cmGlobalXCodeGenerator::CreateReRunCMakeFile(
{
std::vector<std::string> lfiles;
for (auto gen : gens) {
- cmAppend(lfiles, gen->GetMakefile()->GetListFiles());
+ cm::append(lfiles, gen->GetMakefile()->GetListFiles());
}
// sort the array
@@ -636,7 +643,8 @@ void cmGlobalXCodeGenerator::CreateReRunCMakeFile(
<< "\n";
}
-static bool objectIdLessThan(cmXCodeObject* l, cmXCodeObject* r)
+static bool objectIdLessThan(const std::unique_ptr<cmXCodeObject>& l,
+ const std::unique_ptr<cmXCodeObject>& r)
{
return l->GetId() < r->GetId();
}
@@ -650,9 +658,6 @@ void cmGlobalXCodeGenerator::SortXCodeObjects()
void cmGlobalXCodeGenerator::ClearXCodeObjects()
{
this->TargetDoneSet.clear();
- for (auto& obj : this->XCodeObjects) {
- delete obj;
- }
this->XCodeObjects.clear();
this->XCodeObjectIDs.clear();
this->XCodeObjectMap.clear();
@@ -662,7 +667,7 @@ void cmGlobalXCodeGenerator::ClearXCodeObjects()
this->FileRefs.clear();
}
-void cmGlobalXCodeGenerator::addObject(cmXCodeObject* obj)
+void cmGlobalXCodeGenerator::addObject(std::unique_ptr<cmXCodeObject> obj)
{
if (obj->GetType() == cmXCodeObject::OBJECT) {
const std::string& id = obj->GetId();
@@ -677,22 +682,24 @@ void cmGlobalXCodeGenerator::addObject(cmXCodeObject* obj)
this->XCodeObjectIDs.insert(id);
}
- this->XCodeObjects.push_back(obj);
+ this->XCodeObjects.push_back(std::move(obj));
}
cmXCodeObject* cmGlobalXCodeGenerator::CreateObject(
cmXCodeObject::PBXType ptype)
{
- cmXCodeObject* obj = new cmXCode21Object(ptype, cmXCodeObject::OBJECT);
- this->addObject(obj);
- return obj;
+ auto obj = cm::make_unique<cmXCode21Object>(ptype, cmXCodeObject::OBJECT);
+ auto ptr = obj.get();
+ this->addObject(std::move(obj));
+ return ptr;
}
cmXCodeObject* cmGlobalXCodeGenerator::CreateObject(cmXCodeObject::Type type)
{
- cmXCodeObject* obj = new cmXCodeObject(cmXCodeObject::None, type);
- this->addObject(obj);
- return obj;
+ auto obj = cm::make_unique<cmXCodeObject>(cmXCodeObject::None, type);
+ auto ptr = obj.get();
+ this->addObject(std::move(obj));
+ return ptr;
}
cmXCodeObject* cmGlobalXCodeGenerator::CreateString(const std::string& s)
@@ -762,11 +769,15 @@ public:
XCodeGeneratorExpressionInterpreter& operator=(
XCodeGeneratorExpressionInterpreter const&) = delete;
- using cmGeneratorExpressionInterpreter::Evaluate;
-
const std::string& Evaluate(const char* expression,
const std::string& property)
{
+ return this->Evaluate(std::string(expression ? expression : ""), property);
+ }
+
+ const std::string& Evaluate(const std::string& expression,
+ const std::string& property)
+ {
const std::string& processed =
this->cmGeneratorExpressionInterpreter::Evaluate(expression, property);
if (this->CompiledGeneratorExpression->GetHadContextSensitiveCondition()) {
@@ -797,7 +808,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
// Add flags from target and source file properties.
std::string flags;
- const char* srcfmt = sf->GetProperty("Fortran_FORMAT");
+ std::string const& srcfmt = sf->GetSafeProperty("Fortran_FORMAT");
switch (cmOutputConverter::GetFortranFormat(srcfmt)) {
case cmOutputConverter::FortranFormatFixed:
flags = "-fixed " + flags;
@@ -809,22 +820,22 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
break;
}
const std::string COMPILE_FLAGS("COMPILE_FLAGS");
- if (const char* cflags = sf->GetProperty(COMPILE_FLAGS)) {
- lg->AppendFlags(flags, genexInterpreter.Evaluate(cflags, COMPILE_FLAGS));
+ if (cmProp cflags = sf->GetProperty(COMPILE_FLAGS)) {
+ lg->AppendFlags(flags, genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS));
}
const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
- if (const char* coptions = sf->GetProperty(COMPILE_OPTIONS)) {
+ if (cmProp coptions = sf->GetProperty(COMPILE_OPTIONS)) {
lg->AppendCompileOptions(
- flags, genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS));
+ flags, genexInterpreter.Evaluate(*coptions, COMPILE_OPTIONS));
}
// Add per-source definitions.
BuildObjectListOrString flagsBuild(this, false);
const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS");
- if (const char* compile_defs = sf->GetProperty(COMPILE_DEFINITIONS)) {
+ if (cmProp compile_defs = sf->GetProperty(COMPILE_DEFINITIONS)) {
this->AppendDefines(
flagsBuild,
- genexInterpreter.Evaluate(compile_defs, COMPILE_DEFINITIONS).c_str(),
+ genexInterpreter.Evaluate(*compile_defs, COMPILE_DEFINITIONS).c_str(),
true);
}
@@ -842,9 +853,9 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
// Add per-source include directories.
std::vector<std::string> includes;
const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
- if (const char* cincludes = sf->GetProperty(INCLUDE_DIRECTORIES)) {
+ if (cmProp cincludes = sf->GetProperty(INCLUDE_DIRECTORIES)) {
lg->AppendIncludeDirectories(
- includes, genexInterpreter.Evaluate(cincludes, INCLUDE_DIRECTORIES),
+ includes, genexInterpreter.Evaluate(*cincludes, INCLUDE_DIRECTORIES),
*sf);
}
lg->AppendFlags(flags, lg->GetIncludeFlags(includes, gtgt, lang, true));
@@ -873,10 +884,10 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
}
// Add user-specified file attributes.
- const char* extraFileAttributes = sf->GetProperty("XCODE_FILE_ATTRIBUTES");
+ cmProp extraFileAttributes = sf->GetProperty("XCODE_FILE_ATTRIBUTES");
if (extraFileAttributes) {
// Expand the list of attributes.
- std::vector<std::string> attributes = cmExpandedList(extraFileAttributes);
+ std::vector<std::string> attributes = cmExpandedList(*extraFileAttributes);
// Store the attributes.
for (const auto& attribute : attributes) {
@@ -898,7 +909,7 @@ void cmGlobalXCodeGenerator::AddXCodeProjBuildRule(
"/CMakeLists.txt");
cmSourceFile* srcCMakeLists = target->Makefile->GetOrCreateSource(
listfile, false, cmSourceFileLocationKind::Known);
- if (!cmContains(sources, srcCMakeLists)) {
+ if (!cm::contains(sources, srcCMakeLists)) {
sources.push_back(srcCMakeLists);
}
}
@@ -987,11 +998,11 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeFileReferenceFromPath(
bool useLastKnownFileType = false;
std::string fileType;
if (sf) {
- if (const char* e = sf->GetProperty("XCODE_EXPLICIT_FILE_TYPE")) {
- fileType = e;
- } else if (const char* l = sf->GetProperty("XCODE_LAST_KNOWN_FILE_TYPE")) {
+ if (cmProp e = sf->GetProperty("XCODE_EXPLICIT_FILE_TYPE")) {
+ fileType = *e;
+ } else if (cmProp l = sf->GetProperty("XCODE_LAST_KNOWN_FILE_TYPE")) {
useLastKnownFileType = true;
- fileType = l;
+ fileType = *l;
}
}
if (fileType.empty()) {
@@ -1093,8 +1104,8 @@ bool cmGlobalXCodeGenerator::CreateXCodeTargets(
cmLocalGenerator* gen, std::vector<cmXCodeObject*>& targets)
{
this->SetCurrentLocalGenerator(gen);
- std::vector<cmGeneratorTarget*> gts =
- this->CurrentLocalGenerator->GetGeneratorTargets();
+ std::vector<cmGeneratorTarget*> gts;
+ cm::append(gts, this->CurrentLocalGenerator->GetGeneratorTargets());
std::sort(gts.begin(), gts.end(),
[this](cmGeneratorTarget const* l, cmGeneratorTarget const* r) {
return this->TargetOrderIndex[l] < this->TargetOrderIndex[r];
@@ -1364,11 +1375,11 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget(
void cmGlobalXCodeGenerator::ForceLinkerLanguages()
{
- for (auto localGenerator : this->LocalGenerators) {
+ for (const auto& localGenerator : this->LocalGenerators) {
// All targets depend on the build-system check target.
- for (auto tgt : localGenerator->GetGeneratorTargets()) {
+ for (const auto& tgt : localGenerator->GetGeneratorTargets()) {
// This makes sure all targets link using the proper language.
- this->ForceLinkerLanguage(tgt);
+ this->ForceLinkerLanguage(tgt.get());
}
}
}
@@ -1414,8 +1425,8 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmGeneratorTarget* gtgt)
bool cmGlobalXCodeGenerator::IsHeaderFile(cmSourceFile* sf)
{
- return cmContains(this->CMakeInstance->GetHeaderExtensions(),
- sf->GetExtension());
+ return cm::contains(this->CMakeInstance->GetHeaderExtensions(),
+ sf->GetExtension());
}
cmXCodeObject* cmGlobalXCodeGenerator::CreateBuildPhase(
@@ -1456,16 +1467,17 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(
cmStrCat("$<TARGET_SONAME_FILE:", gtgt->GetName(), '>');
std::string str_link_file =
cmStrCat("$<TARGET_LINKER_FILE:", gtgt->GetName(), '>');
+ bool stdPipesUTF8 = true;
cmCustomCommandLines cmd = cmMakeSingleCommandLine(
{ cmSystemTools::GetCMakeCommand(), "-E", "cmake_symlink_library",
str_file, str_so_file, str_link_file });
- cmCustomCommand command(this->CurrentMakefile, std::vector<std::string>(),
- std::vector<std::string>(),
- std::vector<std::string>(), cmd,
- "Creating symlinks", "");
+ cmCustomCommand command(
+ std::vector<std::string>(), std::vector<std::string>(),
+ std::vector<std::string>(), cmd, this->CurrentMakefile->GetBacktrace(),
+ "Creating symlinks", "", stdPipesUTF8);
- postbuild.push_back(command);
+ postbuild.push_back(std::move(command));
}
std::vector<cmSourceFile*> classes;
@@ -1853,18 +1865,18 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
if (gtgt->GetType() == cmStateEnums::OBJECT_LIBRARY ||
gtgt->GetType() == cmStateEnums::STATIC_LIBRARY) {
this->CurrentLocalGenerator->GetStaticLibraryFlags(
- extraLinkOptions, cmSystemTools::UpperCase(configName), llang, gtgt);
+ extraLinkOptions, configName, llang, gtgt);
} else {
- const char* targetLinkFlags = gtgt->GetProperty("LINK_FLAGS");
+ cmProp targetLinkFlags = gtgt->GetProperty("LINK_FLAGS");
if (targetLinkFlags) {
this->CurrentLocalGenerator->AppendFlags(extraLinkOptions,
- targetLinkFlags);
+ *targetLinkFlags);
}
if (!configName.empty()) {
std::string linkFlagsVar =
cmStrCat("LINK_FLAGS_", cmSystemTools::UpperCase(configName));
- if (const char* linkFlags = gtgt->GetProperty(linkFlagsVar)) {
- this->CurrentLocalGenerator->AppendFlags(extraLinkOptions, linkFlags);
+ if (cmProp linkFlags = gtgt->GetProperty(linkFlagsVar)) {
+ this->CurrentLocalGenerator->AppendFlags(extraLinkOptions, *linkFlags);
}
}
std::vector<std::string> opts;
@@ -1900,8 +1912,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
std::string pnsuffix;
gtgt->GetFullNameComponents(pnprefix, pnbase, pnsuffix, configName);
- const char* version = gtgt->GetProperty("VERSION");
- const char* soversion = gtgt->GetProperty("SOVERSION");
+ cmProp version = gtgt->GetProperty("VERSION");
+ cmProp soversion = gtgt->GetProperty("SOVERSION");
if (!gtgt->HasSOName(configName) || gtgt->IsFrameworkOnApple()) {
version = nullptr;
soversion = nullptr;
@@ -1917,9 +1929,9 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
std::string soName = pnbase;
if (version && soversion) {
realName += ".";
- realName += version;
+ realName += *version;
soName += ".";
- soName += soversion;
+ soName += *soversion;
}
// Set attributes to specify the proper name for the target.
@@ -1965,10 +1977,10 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
std::string fw_version = gtgt->GetFrameworkVersion();
buildSettings->AddAttribute("FRAMEWORK_VERSION",
this->CreateString(fw_version));
- const char* ext = gtgt->GetProperty("BUNDLE_EXTENSION");
+ cmProp ext = gtgt->GetProperty("BUNDLE_EXTENSION");
if (ext) {
buildSettings->AddAttribute("WRAPPER_EXTENSION",
- this->CreateString(ext));
+ this->CreateString(*ext));
}
std::string plist = this->ComputeInfoPListLocation(gtgt);
@@ -2006,10 +2018,10 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
extraLinkOptions += " ";
extraLinkOptions += createFlags;
}
- const char* ext = gtgt->GetProperty("BUNDLE_EXTENSION");
+ cmProp ext = gtgt->GetProperty("BUNDLE_EXTENSION");
if (ext) {
buildSettings->AddAttribute("WRAPPER_EXTENSION",
- this->CreateString(ext));
+ this->CreateString(*ext));
}
std::string plist = this->ComputeInfoPListLocation(gtgt);
// Xcode will create the final version of Info.plist at build time,
@@ -2040,10 +2052,10 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
std::string fw_version = gtgt->GetFrameworkVersion();
buildSettings->AddAttribute("FRAMEWORK_VERSION",
this->CreateString(fw_version));
- const char* ext = gtgt->GetProperty("BUNDLE_EXTENSION");
+ cmProp ext = gtgt->GetProperty("BUNDLE_EXTENSION");
if (ext) {
buildSettings->AddAttribute("WRAPPER_EXTENSION",
- this->CreateString(ext));
+ this->CreateString(*ext));
}
std::string plist = this->ComputeInfoPListLocation(gtgt);
@@ -2079,10 +2091,10 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
// Handle bundles and normal executables separately.
if (gtgt->GetPropertyAsBool("MACOSX_BUNDLE")) {
- const char* ext = gtgt->GetProperty("BUNDLE_EXTENSION");
+ cmProp ext = gtgt->GetProperty("BUNDLE_EXTENSION");
if (ext) {
buildSettings->AddAttribute("WRAPPER_EXTENSION",
- this->CreateString(ext));
+ this->CreateString(*ext));
}
std::string plist = this->ComputeInfoPListLocation(gtgt);
// Xcode will create the final version of Info.plist at build time,
@@ -2277,7 +2289,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
// Add Fortran source format attribute if property is set.
const char* format = nullptr;
- const char* tgtfmt = gtgt->GetProperty("Fortran_FORMAT");
+ std::string const& tgtfmt = gtgt->GetSafeProperty("Fortran_FORMAT");
switch (cmOutputConverter::GetFortranFormat(tgtfmt)) {
case cmOutputConverter::FortranFormatFixed:
format = "fixed";
@@ -2353,9 +2365,6 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
buildSettings->AddAttribute("SECTORDER_FLAGS", this->CreateString(""));
buildSettings->AddAttribute("USE_HEADERMAP", this->CreateString("NO"));
cmXCodeObject* group = this->CreateObject(cmXCodeObject::OBJECT_LIST);
- group->AddObject(this->CreateString("-Wmost"));
- group->AddObject(this->CreateString("-Wno-four-char-constants"));
- group->AddObject(this->CreateString("-Wno-unknown-pragmas"));
group->AddObject(this->CreateString("$(inherited)"));
buildSettings->AddAttribute("WARNING_CFLAGS", group);
@@ -2365,8 +2374,9 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
int minor;
int patch;
- // VERSION -> current_version
- gtgt->GetTargetVersion(false, major, minor, patch);
+ // MACHO_CURRENT_VERSION or VERSION -> current_version
+ gtgt->GetTargetVersionFallback("MACHO_CURRENT_VERSION", "VERSION", major,
+ minor, patch);
std::ostringstream v;
// Xcode always wants at least 1.0.0 or nothing
@@ -2376,8 +2386,9 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
buildSettings->AddAttribute("DYLIB_CURRENT_VERSION",
this->CreateString(v.str()));
- // SOVERSION -> compatibility_version
- gtgt->GetTargetVersion(true, major, minor, patch);
+ // MACHO_COMPATIBILITY_VERSION or SOVERSION -> compatibility_version
+ gtgt->GetTargetVersionFallback("MACHO_COMPATIBILITY_VERSION", "SOVERSION",
+ major, minor, patch);
std::ostringstream vso;
// Xcode always wants at least 1.0.0 or nothing
@@ -2401,12 +2412,13 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
// Convert "XCODE_ATTRIBUTE_*" properties directly.
{
for (auto const& prop : gtgt->GetPropertyKeys()) {
- if (prop.find("XCODE_ATTRIBUTE_") == 0) {
+ if (cmHasLiteralPrefix(prop, "XCODE_ATTRIBUTE_")) {
std::string attribute = prop.substr(16);
this->FilterConfigurationAttribute(configName, attribute);
if (!attribute.empty()) {
+ std::string const& pr = gtgt->GetSafeProperty(prop);
std::string processed = cmGeneratorExpression::Evaluate(
- gtgt->GetProperty(prop), this->CurrentLocalGenerator, configName);
+ pr, this->CurrentLocalGenerator, configName);
buildSettings->AddAttribute(attribute,
this->CreateString(processed));
}
@@ -2525,8 +2537,8 @@ const char* cmGlobalXCodeGenerator::GetTargetLinkFlagsVar(
const char* cmGlobalXCodeGenerator::GetTargetFileType(
cmGeneratorTarget* target)
{
- if (const char* e = target->GetProperty("XCODE_EXPLICIT_FILE_TYPE")) {
- return e;
+ if (cmProp e = target->GetProperty("XCODE_EXPLICIT_FILE_TYPE")) {
+ return e->c_str();
}
switch (target->GetType()) {
@@ -2558,8 +2570,8 @@ const char* cmGlobalXCodeGenerator::GetTargetFileType(
const char* cmGlobalXCodeGenerator::GetTargetProductType(
cmGeneratorTarget* target)
{
- if (const char* e = target->GetProperty("XCODE_PRODUCT_TYPE")) {
- return e;
+ if (cmProp e = target->GetProperty("XCODE_PRODUCT_TYPE")) {
+ return e->c_str();
}
switch (target->GetType()) {
@@ -2834,7 +2846,7 @@ bool cmGlobalXCodeGenerator::CreateGroups(
for (auto& generator : generators) {
cmMakefile* mf = generator->GetMakefile();
std::vector<cmSourceGroup> sourceGroups = mf->GetSourceGroups();
- for (auto gtgt : generator->GetGeneratorTargets()) {
+ for (const auto& gtgt : generator->GetGeneratorTargets()) {
// Same skipping logic here as in CreateXCodeTargets so that we do not
// end up with (empty anyhow) ZERO_CHECK, install, or test source
// groups:
@@ -2849,11 +2861,12 @@ bool cmGlobalXCodeGenerator::CreateGroups(
continue;
}
- auto addSourceToGroup = [this, mf, gtgt,
+ auto addSourceToGroup = [this, mf, &gtgt,
&sourceGroups](std::string const& source) {
cmSourceGroup* sourceGroup = mf->FindSourceGroup(source, sourceGroups);
- cmXCodeObject* pbxgroup = this->CreateOrGetPBXGroup(gtgt, sourceGroup);
- std::string key = GetGroupMapKeyFromPath(gtgt, source);
+ cmXCodeObject* pbxgroup =
+ this->CreateOrGetPBXGroup(gtgt.get(), sourceGroup);
+ std::string key = GetGroupMapKeyFromPath(gtgt.get(), source);
this->GroupMap[key] = pbxgroup;
};
@@ -2879,7 +2892,7 @@ bool cmGlobalXCodeGenerator::CreateGroups(
// Add the Info.plist we are about to generate for an App Bundle.
if (gtgt->GetPropertyAsBool("MACOSX_BUNDLE")) {
- std::string plist = this->ComputeInfoPListLocation(gtgt);
+ std::string plist = this->ComputeInfoPListLocation(gtgt.get());
cmSourceFile* sf = gtgt->Makefile->GetOrCreateSource(
plist, true, cmSourceFileLocationKind::Known);
addSourceToGroup(sf->ResolveFullPath());
@@ -3135,12 +3148,12 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects(
// Put this last so it can override existing settings
// Convert "CMAKE_XCODE_ATTRIBUTE_*" variables directly.
for (const auto& var : this->CurrentMakefile->GetDefinitions()) {
- if (var.find("CMAKE_XCODE_ATTRIBUTE_") == 0) {
+ if (cmHasLiteralPrefix(var, "CMAKE_XCODE_ATTRIBUTE_")) {
std::string attribute = var.substr(22);
this->FilterConfigurationAttribute(config.first, attribute);
if (!attribute.empty()) {
std::string processed = cmGeneratorExpression::Evaluate(
- this->CurrentMakefile->GetDefinition(var),
+ this->CurrentMakefile->GetSafeDefinition(var),
this->CurrentLocalGenerator, config.first);
buildSettingsForCfg->AddAttribute(attribute,
this->CreateString(processed));
@@ -3384,7 +3397,7 @@ bool cmGlobalXCodeGenerator::OutputXCodeSharedSchemes(
// collect all tests for the targets
std::map<std::string, cmXCodeScheme::TestObjects> testables;
- for (auto obj : this->XCodeObjects) {
+ for (const auto& obj : this->XCodeObjects) {
if (obj->GetType() != cmXCodeObject::OBJECT ||
obj->GetIsA() != cmXCodeObject::PBXNativeTarget) {
continue;
@@ -3394,12 +3407,12 @@ bool cmGlobalXCodeGenerator::OutputXCodeSharedSchemes(
continue;
}
- const char* testee = obj->GetTarget()->GetProperty("XCTEST_TESTEE");
+ cmProp testee = obj->GetTarget()->GetProperty("XCTEST_TESTEE");
if (!testee) {
continue;
}
- testables[testee].push_back(obj);
+ testables[*testee].push_back(obj.get());
}
// generate scheme
@@ -3408,14 +3421,14 @@ bool cmGlobalXCodeGenerator::OutputXCodeSharedSchemes(
// Since the lowest available Xcode version for testing was 6.4,
// I'm setting this as a limit then
if (this->XcodeVersion >= 64) {
- for (auto obj : this->XCodeObjects) {
+ for (const auto& obj : this->XCodeObjects) {
if (obj->GetType() == cmXCodeObject::OBJECT &&
(obj->GetIsA() == cmXCodeObject::PBXNativeTarget ||
obj->GetIsA() == cmXCodeObject::PBXAggregateTarget) &&
(root->GetMakefile()->GetCMakeInstance()->GetIsInTryCompile() ||
obj->GetTarget()->GetPropertyAsBool("XCODE_GENERATE_SCHEME"))) {
const std::string& targetName = obj->GetTarget()->GetName();
- cmXCodeScheme schm(obj, testables[targetName],
+ cmXCodeScheme schm(root, obj.get(), testables[targetName],
this->CurrentConfigurationTypes,
this->XcodeVersion);
schm.WriteXCodeSharedScheme(xcProjDir,
@@ -3541,7 +3554,7 @@ std::string cmGlobalXCodeGenerator::RelativeToBinary(const std::string& p)
std::string cmGlobalXCodeGenerator::XCodeEscapePath(const std::string& p)
{
- if (p.find(' ') != std::string::npos) {
+ if (p.find_first_of(" []") != std::string::npos) {
std::string t = cmStrCat('"', p, '"');
return t;
}
@@ -3687,15 +3700,14 @@ bool cmGlobalXCodeGenerator::HasKnownObjectFileLocation(
bool cmGlobalXCodeGenerator::UseEffectivePlatformName(cmMakefile* mf) const
{
- const char* epnValue =
- this->GetCMakeInstance()->GetState()->GetGlobalProperty(
- "XCODE_EMIT_EFFECTIVE_PLATFORM_NAME");
+ cmProp epnValue = this->GetCMakeInstance()->GetState()->GetGlobalProperty(
+ "XCODE_EMIT_EFFECTIVE_PLATFORM_NAME");
if (!epnValue) {
return mf->PlatformIsAppleEmbedded();
}
- return cmIsOn(epnValue);
+ return cmIsOn(*epnValue);
}
bool cmGlobalXCodeGenerator::ShouldStripResourcePath(cmMakefile*) const
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index af905d0..e380f1c 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -7,6 +7,7 @@
#include <iosfwd>
#include <map>
+#include <memory>
#include <set>
#include <string>
#include <vector>
@@ -34,7 +35,11 @@ class cmGlobalXCodeGenerator : public cmGlobalGenerator
public:
cmGlobalXCodeGenerator(cmake* cm, std::string const& version_string,
unsigned int version_number);
- static cmGlobalGeneratorFactory* NewFactory();
+ static std::unique_ptr<cmGlobalGeneratorFactory> NewFactory();
+
+ cmGlobalXCodeGenerator(const cmGlobalXCodeGenerator&) = delete;
+ const cmGlobalXCodeGenerator& operator=(const cmGlobalXCodeGenerator&) =
+ delete;
//! Get the name for the generator.
std::string GetName() const override
@@ -47,7 +52,8 @@ public:
static void GetDocumentation(cmDocumentationEntry& entry);
//! Create a local generator appropriate to this Global Generator
- cmLocalGenerator* CreateLocalGenerator(cmMakefile* mf) override;
+ std::unique_ptr<cmLocalGenerator> CreateLocalGenerator(
+ cmMakefile* mf) override;
/**
* Try to determine system information such as shared library
@@ -103,7 +109,8 @@ public:
bool ShouldStripResourcePath(cmMakefile*) const override;
- bool SetGeneratorToolset(std::string const& ts, cmMakefile* mf) override;
+ bool SetGeneratorToolset(std::string const& ts, bool build,
+ cmMakefile* mf) override;
void AppendFlag(std::string& flags, std::string const& flag) const;
protected:
@@ -246,7 +253,7 @@ protected:
unsigned int XcodeVersion;
std::string VersionString;
std::set<std::string> XCodeObjectIDs;
- std::vector<cmXCodeObject*> XCodeObjects;
+ std::vector<std::unique_ptr<cmXCodeObject>> XCodeObjects;
cmXCodeObject* RootObject;
private:
@@ -270,7 +277,7 @@ private:
void ComputeArchitectures(cmMakefile* mf);
void ComputeObjectDirArch(cmMakefile* mf);
- void addObject(cmXCodeObject* obj);
+ void addObject(std::unique_ptr<cmXCodeObject> obj);
std::string PostBuildMakeTarget(std::string const& tName,
std::string const& configName);
cmXCodeObject* MainGroupChildren;
diff --git a/Source/cmGraphAdjacencyList.h b/Source/cmGraphAdjacencyList.h
index 5ed6af4..4e1f128 100644
--- a/Source/cmGraphAdjacencyList.h
+++ b/Source/cmGraphAdjacencyList.h
@@ -18,9 +18,10 @@
class cmGraphEdge
{
public:
- cmGraphEdge(int n, bool s, cmListFileBacktrace bt)
+ cmGraphEdge(int n, bool s, bool c, cmListFileBacktrace bt)
: Dest(n)
, Strong(s)
+ , Cross(c)
, Backtrace(std::move(bt))
{
}
@@ -28,11 +29,14 @@ public:
bool IsStrong() const { return this->Strong; }
+ bool IsCross() const { return this->Cross; }
+
cmListFileBacktrace const& GetBacktrace() const { return this->Backtrace; }
private:
int Dest;
bool Strong;
+ bool Cross;
cmListFileBacktrace Backtrace;
};
struct cmGraphEdgeList : public std::vector<cmGraphEdge>
diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx
index e0d545d..0fcda4e 100644
--- a/Source/cmGraphVizWriter.cxx
+++ b/Source/cmGraphVizWriter.cxx
@@ -2,174 +2,190 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGraphVizWriter.h"
-#include <cstddef>
+#include <cctype>
#include <iostream>
#include <memory>
-#include <sstream>
+#include <set>
#include <utility>
+#include <cm/memory>
+
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmLinkItem.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStateSnapshot.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#include "cmTarget.h"
#include "cmake.h"
namespace {
-enum LinkLibraryScopeType
-{
- LLT_SCOPE_PUBLIC,
- LLT_SCOPE_PRIVATE,
- LLT_SCOPE_INTERFACE
-};
-const char* const GRAPHVIZ_PRIVATE_EDEGE_STYLE = "dashed";
-const char* const GRAPHVIZ_INTERFACE_EDEGE_STYLE = "dotted";
+char const* const GRAPHVIZ_EDGE_STYLE_PUBLIC = "solid";
+char const* const GRAPHVIZ_EDGE_STYLE_INTERFACE = "dashed";
+char const* const GRAPHVIZ_EDGE_STYLE_PRIVATE = "dotted";
-std::string getLinkLibraryStyle(const LinkLibraryScopeType& type)
-{
- std::string style;
- switch (type) {
- case LLT_SCOPE_PRIVATE:
- style = "[style = " + std::string(GRAPHVIZ_PRIVATE_EDEGE_STYLE) + "]";
- break;
- case LLT_SCOPE_INTERFACE:
- style = "[style = " + std::string(GRAPHVIZ_INTERFACE_EDEGE_STYLE) + "]";
- break;
- default:
- break;
- }
- return style;
-}
+char const* const GRAPHVIZ_NODE_SHAPE_EXECUTABLE = "egg"; // egg-xecutable
+
+// Normal libraries.
+char const* const GRAPHVIZ_NODE_SHAPE_LIBRARY_STATIC = "octagon";
+char const* const GRAPHVIZ_NODE_SHAPE_LIBRARY_SHARED = "doubleoctagon";
+char const* const GRAPHVIZ_NODE_SHAPE_LIBRARY_MODULE = "tripleoctagon";
-const char* getShapeForTarget(const cmGeneratorTarget* target)
+char const* const GRAPHVIZ_NODE_SHAPE_LIBRARY_INTERFACE = "pentagon";
+char const* const GRAPHVIZ_NODE_SHAPE_LIBRARY_OBJECT = "hexagon";
+char const* const GRAPHVIZ_NODE_SHAPE_LIBRARY_UNKNOWN = "septagon";
+
+char const* const GRAPHVIZ_NODE_SHAPE_UTILITY = "box";
+
+const char* getShapeForTarget(const cmLinkItem& item)
{
- if (!target) {
- return "ellipse";
+ if (item.Target == nullptr) {
+ return GRAPHVIZ_NODE_SHAPE_LIBRARY_UNKNOWN;
}
- switch (target->GetType()) {
+ switch (item.Target->GetType()) {
case cmStateEnums::EXECUTABLE:
- return "house";
+ return GRAPHVIZ_NODE_SHAPE_EXECUTABLE;
case cmStateEnums::STATIC_LIBRARY:
- return "diamond";
+ return GRAPHVIZ_NODE_SHAPE_LIBRARY_STATIC;
case cmStateEnums::SHARED_LIBRARY:
- return "polygon";
+ return GRAPHVIZ_NODE_SHAPE_LIBRARY_SHARED;
case cmStateEnums::MODULE_LIBRARY:
- return "octagon";
+ return GRAPHVIZ_NODE_SHAPE_LIBRARY_MODULE;
+ case cmStateEnums::OBJECT_LIBRARY:
+ return GRAPHVIZ_NODE_SHAPE_LIBRARY_OBJECT;
+ case cmStateEnums::UTILITY:
+ return GRAPHVIZ_NODE_SHAPE_UTILITY;
+ case cmStateEnums::INTERFACE_LIBRARY:
+ return GRAPHVIZ_NODE_SHAPE_LIBRARY_INTERFACE;
+ case cmStateEnums::UNKNOWN_LIBRARY:
default:
- break;
+ return GRAPHVIZ_NODE_SHAPE_LIBRARY_UNKNOWN;
}
+}
+}
- return "box";
+cmGraphVizWriter::cmGraphVizWriter(std::string const& fileName,
+ const cmGlobalGenerator* globalGenerator)
+ : FileName(fileName)
+ , GlobalFileStream(fileName)
+ , GraphName(globalGenerator->GetSafeGlobalSetting("CMAKE_PROJECT_NAME"))
+ , GraphHeader("node [\n fontsize = \"12\"\n];")
+ , GraphNodePrefix("node")
+ , GlobalGenerator(globalGenerator)
+ , NextNodeId(0)
+ , GenerateForExecutables(true)
+ , GenerateForStaticLibs(true)
+ , GenerateForSharedLibs(true)
+ , GenerateForModuleLibs(true)
+ , GenerateForInterfaceLibs(true)
+ , GenerateForObjectLibs(true)
+ , GenerateForUnknownLibs(true)
+ , GenerateForCustomTargets(false)
+ , GenerateForExternals(true)
+ , GeneratePerTarget(true)
+ , GenerateDependers(true)
+{
}
-std::map<std::string, LinkLibraryScopeType> getScopedLinkLibrariesFromTarget(
- cmTarget* Target, const cmGlobalGenerator* globalGenerator)
+cmGraphVizWriter::~cmGraphVizWriter()
{
- char sep = ';';
- std::map<std::string, LinkLibraryScopeType> tokens;
- size_t start = 0;
- size_t end = 0;
+ this->WriteFooter(this->GlobalFileStream);
- const char* pInterfaceLinkLibraries =
- Target->GetProperty("INTERFACE_LINK_LIBRARIES");
- const char* pLinkLibraries = Target->GetProperty("LINK_LIBRARIES");
+ for (auto& fileStream : this->PerTargetFileStreams) {
+ this->WriteFooter(*fileStream.second);
+ }
- if (!pInterfaceLinkLibraries && !pLinkLibraries) {
- return tokens; // target is not linked against any other libraries
+ for (auto& fileStream : this->TargetDependersFileStreams) {
+ this->WriteFooter(*fileStream.second);
}
+}
- // make sure we don't touch a null-ptr
- auto interfaceLinkLibraries =
- std::string(pInterfaceLinkLibraries ? pInterfaceLinkLibraries : "");
- auto linkLibraries = std::string(pLinkLibraries ? pLinkLibraries : "");
+void cmGraphVizWriter::VisitGraph(std::string const&)
+{
+ this->WriteHeader(GlobalFileStream, this->GraphName);
+ this->WriteLegend(GlobalFileStream);
+}
- // first extract interfaceLinkLibraries
- while (start < interfaceLinkLibraries.length()) {
+void cmGraphVizWriter::OnItem(cmLinkItem const& item)
+{
+ if (this->ItemExcluded(item)) {
+ return;
+ }
- if ((end = interfaceLinkLibraries.find(sep, start)) == std::string::npos) {
- end = interfaceLinkLibraries.length();
- }
+ NodeNames[item.AsStr()] = cmStrCat(GraphNodePrefix, NextNodeId);
+ ++NextNodeId;
- std::string element = interfaceLinkLibraries.substr(start, end - start);
- if (globalGenerator->IsAlias(element)) {
- const auto tgt = globalGenerator->FindTarget(element);
- if (tgt) {
- element = tgt->GetName();
- }
- }
+ this->WriteNode(this->GlobalFileStream, item);
- if (std::string::npos == element.find("$<LINK_ONLY:", 0)) {
- // we assume first, that this library is an interface library.
- // if we find it again in the linklibraries property, we promote it to an
- // public library.
- tokens[element] = LLT_SCOPE_INTERFACE;
- } else {
- // this is an private linked static library.
- // we take care of this case in the second iterator.
- }
- start = end + 1;
+ if (this->GeneratePerTarget) {
+ this->CreateTargetFile(this->PerTargetFileStreams, item);
}
- // second extract linkLibraries
- start = 0;
- while (start < linkLibraries.length()) {
-
- if ((end = linkLibraries.find(sep, start)) == std::string::npos) {
- end = linkLibraries.length();
- }
+ if (this->GenerateDependers) {
+ this->CreateTargetFile(this->TargetDependersFileStreams, item,
+ ".dependers");
+ }
+}
- std::string element = linkLibraries.substr(start, end - start);
- if (globalGenerator->IsAlias(element)) {
- const auto tgt = globalGenerator->FindTarget(element);
- if (tgt) {
- element = tgt->GetName();
- }
- }
+void cmGraphVizWriter::CreateTargetFile(FileStreamMap& fileStreamMap,
+ cmLinkItem const& item,
+ std::string const& fileNameSuffix)
+{
+ auto const pathSafeItemName = PathSafeString(item.AsStr());
+ auto const perTargetFileName =
+ cmStrCat(this->FileName, '.', pathSafeItemName, fileNameSuffix);
+ auto perTargetFileStream =
+ cm::make_unique<cmGeneratedFileStream>(perTargetFileName);
- if (tokens.find(element) == tokens.end()) {
- // this library is not found in interfaceLinkLibraries but in
- // linkLibraries.
- // this results in a private linked library.
- tokens[element] = LLT_SCOPE_PRIVATE;
- } else if (LLT_SCOPE_INTERFACE == tokens[element]) {
- // this library is found in interfaceLinkLibraries and linkLibraries.
- // this results in a public linked library.
- tokens[element] = LLT_SCOPE_PUBLIC;
- } else {
- // private and public linked libraries should not be changed anymore.
- }
+ this->WriteHeader(*perTargetFileStream, item.AsStr());
+ this->WriteNode(*perTargetFileStream, item);
- start = end + 1;
- }
+ fileStreamMap.emplace(item.AsStr(), std::move(perTargetFileStream));
+}
- return tokens;
+void cmGraphVizWriter::OnDirectLink(cmLinkItem const& depender,
+ cmLinkItem const& dependee,
+ DependencyType dt)
+{
+ this->VisitLink(depender, dependee, true, GetEdgeStyle(dt));
}
+
+void cmGraphVizWriter::OnIndirectLink(cmLinkItem const& depender,
+ cmLinkItem const& dependee)
+{
+ this->VisitLink(depender, dependee, false);
}
-cmGraphVizWriter::cmGraphVizWriter(const cmGlobalGenerator* globalGenerator)
- : GraphType("digraph")
- , GraphName("GG")
- , GraphHeader("node [\n fontsize = \"12\"\n];")
- , GraphNodePrefix("node")
- , GlobalGenerator(globalGenerator)
- , LocalGenerators(globalGenerator->GetLocalGenerators())
- , GenerateForExecutables(true)
- , GenerateForStaticLibs(true)
- , GenerateForSharedLibs(true)
- , GenerateForModuleLibs(true)
- , GenerateForInterface(true)
- , GenerateForExternals(true)
- , GeneratePerTarget(true)
- , GenerateDependers(true)
- , HaveTargetsAndLibs(false)
+void cmGraphVizWriter::VisitLink(cmLinkItem const& depender,
+ cmLinkItem const& dependee, bool isDirectLink,
+ std::string const& scopeType)
{
+ if (this->ItemExcluded(depender) || this->ItemExcluded(dependee)) {
+ return;
+ }
+
+ if (!isDirectLink) {
+ return;
+ }
+
+ this->WriteConnection(this->GlobalFileStream, depender, dependee, scopeType);
+
+ if (this->GeneratePerTarget) {
+ auto fileStream = PerTargetFileStreams[depender.AsStr()].get();
+ this->WriteNode(*fileStream, dependee);
+ this->WriteConnection(*fileStream, depender, dependee, scopeType);
+ }
+
+ if (this->GenerateDependers) {
+ auto fileStream = TargetDependersFileStreams[dependee.AsStr()].get();
+ this->WriteNode(*fileStream, depender);
+ this->WriteConnection(*fileStream, depender, dependee, scopeType);
+ }
}
void cmGraphVizWriter::ReadSettings(
@@ -208,7 +224,6 @@ void cmGraphVizWriter::ReadSettings(
} \
} while (false)
- __set_if_set(this->GraphType, "GRAPHVIZ_GRAPH_TYPE");
__set_if_set(this->GraphName, "GRAPHVIZ_GRAPH_NAME");
__set_if_set(this->GraphHeader, "GRAPHVIZ_GRAPH_HEADER");
__set_if_set(this->GraphNodePrefix, "GRAPHVIZ_NODE_PREFIX");
@@ -225,7 +240,10 @@ void cmGraphVizWriter::ReadSettings(
__set_bool_if_set(this->GenerateForStaticLibs, "GRAPHVIZ_STATIC_LIBS");
__set_bool_if_set(this->GenerateForSharedLibs, "GRAPHVIZ_SHARED_LIBS");
__set_bool_if_set(this->GenerateForModuleLibs, "GRAPHVIZ_MODULE_LIBS");
- __set_bool_if_set(this->GenerateForInterface, "GRAPHVIZ_INTERFACE");
+ __set_bool_if_set(this->GenerateForInterfaceLibs, "GRAPHVIZ_INTERFACE_LIBS");
+ __set_bool_if_set(this->GenerateForObjectLibs, "GRAPHVIZ_OBJECT_LIBS");
+ __set_bool_if_set(this->GenerateForUnknownLibs, "GRAPHVIZ_UNKNOWN_LIBS");
+ __set_bool_if_set(this->GenerateForCustomTargets, "GRAPHVIZ_CUSTOM_TARGETS");
__set_bool_if_set(this->GenerateForExternals, "GRAPHVIZ_EXTERNAL_LIBS");
__set_bool_if_set(this->GeneratePerTarget, "GRAPHVIZ_GENERATE_PER_TARGET");
__set_bool_if_set(this->GenerateDependers, "GRAPHVIZ_GENERATE_DEPENDERS");
@@ -248,329 +266,162 @@ void cmGraphVizWriter::ReadSettings(
}
}
-// Iterate over all targets and write for each one a graph which shows
-// which other targets depend on it.
-void cmGraphVizWriter::WriteTargetDependersFiles(const std::string& fileName)
+void cmGraphVizWriter::Write()
{
- if (!this->GenerateDependers) {
- return;
- }
-
- this->CollectTargetsAndLibs();
-
- for (auto const& ptr : this->TargetPtrs) {
- if (ptr.second == nullptr) {
- continue;
- }
-
- if (!this->GenerateForTargetType(ptr.second->GetType())) {
- continue;
- }
-
- std::string currentFilename =
- cmStrCat(fileName, '.', ptr.first, ".dependers");
-
- cmGeneratedFileStream str(currentFilename);
- if (!str) {
- return;
+ auto gg = this->GlobalGenerator;
+
+ this->VisitGraph(gg->GetName());
+
+ // We want to traverse in a determined order, such that the output is always
+ // the same for a given project (this makes tests reproducible, etc.)
+ std::set<cmGeneratorTarget const*, cmGeneratorTarget::StrictTargetComparison>
+ sortedGeneratorTargets;
+
+ for (const auto& lg : gg->GetLocalGenerators()) {
+ for (const auto& gt : lg->GetGeneratorTargets()) {
+ // Reserved targets have inconsistent names across platforms (e.g. 'all'
+ // vs. 'ALL_BUILD'), which can disrupt the traversal ordering.
+ // We don't need or want them anyway.
+ if (!cmGlobalGenerator::IsReservedTarget(gt->GetName())) {
+ sortedGeneratorTargets.insert(gt.get());
+ }
}
-
- std::set<std::string> insertedConnections;
- std::set<std::string> insertedNodes;
-
- std::cout << "Writing " << currentFilename << "..." << std::endl;
- this->WriteHeader(str);
-
- this->WriteDependerConnections(ptr.first, insertedNodes,
- insertedConnections, str);
-
- this->WriteFooter(str);
- }
-}
-
-// Iterate over all targets and write for each one a graph which shows
-// on which targets it depends.
-void cmGraphVizWriter::WritePerTargetFiles(const std::string& fileName)
-{
- if (!this->GeneratePerTarget) {
- return;
}
- this->CollectTargetsAndLibs();
-
- for (auto const& ptr : this->TargetPtrs) {
- if (ptr.second == nullptr) {
- continue;
- }
-
- if (!this->GenerateForTargetType(ptr.second->GetType())) {
- continue;
- }
-
- std::set<std::string> insertedConnections;
- std::set<std::string> insertedNodes;
-
- std::string currentFilename = cmStrCat(fileName, '.', ptr.first);
- cmGeneratedFileStream str(currentFilename);
- if (!str) {
- return;
- }
-
- std::cout << "Writing " << currentFilename << "..." << std::endl;
- this->WriteHeader(str);
-
- this->WriteConnections(ptr.first, insertedNodes, insertedConnections, str);
- this->WriteFooter(str);
+ for (auto const gt : sortedGeneratorTargets) {
+ auto item = cmLinkItem(gt, false, gt->GetBacktrace());
+ this->VisitItem(item);
}
}
-void cmGraphVizWriter::WriteGlobalFile(const std::string& fileName)
+void cmGraphVizWriter::WriteHeader(cmGeneratedFileStream& fs,
+ const std::string& name)
{
- this->CollectTargetsAndLibs();
-
- cmGeneratedFileStream str(fileName);
- if (!str) {
- return;
- }
- this->WriteHeader(str);
-
- std::cout << "Writing " << fileName << "..." << std::endl;
-
- std::set<std::string> insertedConnections;
- std::set<std::string> insertedNodes;
-
- for (auto const& ptr : this->TargetPtrs) {
- if (ptr.second == nullptr) {
- continue;
- }
-
- if (!this->GenerateForTargetType(ptr.second->GetType())) {
- continue;
- }
-
- this->WriteConnections(ptr.first, insertedNodes, insertedConnections, str);
- }
- this->WriteFooter(str);
+ auto const escapedGraphName = EscapeForDotFile(name);
+ fs << "digraph \"" << escapedGraphName << "\" {\n"
+ << this->GraphHeader << '\n';
}
-void cmGraphVizWriter::WriteHeader(cmGeneratedFileStream& str) const
+void cmGraphVizWriter::WriteFooter(cmGeneratedFileStream& fs)
{
- str << this->GraphType << " \"" << this->GraphName << "\" {" << std::endl;
- str << this->GraphHeader << std::endl;
+ fs << "}\n";
}
-void cmGraphVizWriter::WriteFooter(cmGeneratedFileStream& str) const
+void cmGraphVizWriter::WriteLegend(cmGeneratedFileStream& fs)
{
- str << "}" << std::endl;
+ // Note that the subgraph name must start with "cluster", as done here, to
+ // make Graphviz layout engines do the right thing and keep the nodes
+ // together.
+ /* clang-format off */
+ fs << "subgraph clusterLegend {\n"
+ " label = \"Legend\";\n"
+ // Set the color of the box surrounding the legend.
+ " color = black;\n"
+ // We use invisible edges just to enforce the layout.
+ " edge [ style = invis ];\n"
+ // Nodes.
+ " legendNode0 [ label = \"Executable\", shape = "
+ << GRAPHVIZ_NODE_SHAPE_EXECUTABLE << " ];\n"
+ " legendNode1 [ label = \"Static Library\", shape = "
+ << GRAPHVIZ_NODE_SHAPE_LIBRARY_STATIC << " ];\n"
+ " legendNode2 [ label = \"Shared Library\", shape = "
+ << GRAPHVIZ_NODE_SHAPE_LIBRARY_SHARED << " ];\n"
+ " legendNode3 [ label = \"Module Library\", shape = "
+ << GRAPHVIZ_NODE_SHAPE_LIBRARY_MODULE << " ];\n"
+ " legendNode4 [ label = \"Interface Library\", shape = "
+ << GRAPHVIZ_NODE_SHAPE_LIBRARY_INTERFACE << " ];\n"
+ " legendNode5 [ label = \"Object Library\", shape = "
+ << GRAPHVIZ_NODE_SHAPE_LIBRARY_OBJECT << " ];\n"
+ " legendNode6 [ label = \"Unknown Library\", shape = "
+ << GRAPHVIZ_NODE_SHAPE_LIBRARY_UNKNOWN << " ];\n"
+ " legendNode7 [ label = \"Custom Target\", shape = "
+ << GRAPHVIZ_NODE_SHAPE_UTILITY << " ];\n"
+ // Edges.
+ // Some of those are dummy (invisible) edges to enforce a layout.
+ " legendNode0 -> legendNode1 [ style = "
+ << GRAPHVIZ_EDGE_STYLE_PUBLIC << " ];\n"
+ " legendNode0 -> legendNode2 [ style = "
+ << GRAPHVIZ_EDGE_STYLE_PUBLIC << " ];\n"
+ " legendNode0 -> legendNode3;\n"
+ " legendNode1 -> legendNode4 [ label = \"Interface\", style = "
+ << GRAPHVIZ_EDGE_STYLE_INTERFACE << " ];\n"
+ " legendNode2 -> legendNode5 [ label = \"Private\", style = "
+ << GRAPHVIZ_EDGE_STYLE_PRIVATE << " ];\n"
+ " legendNode3 -> legendNode6 [ style = "
+ << GRAPHVIZ_EDGE_STYLE_PUBLIC << " ];\n"
+ " legendNode0 -> legendNode7;\n"
+ "}\n";
+ /* clang-format off */
}
-void cmGraphVizWriter::WriteConnections(
- const std::string& targetName, std::set<std::string>& insertedNodes,
- std::set<std::string>& insertedConnections, cmGeneratedFileStream& str) const
+void cmGraphVizWriter::WriteNode(cmGeneratedFileStream& fs,
+ cmLinkItem const& item)
{
- auto targetPtrIt = this->TargetPtrs.find(targetName);
-
- if (targetPtrIt == this->TargetPtrs.end()) // not found at all
- {
- return;
- }
-
- this->WriteNode(targetName, targetPtrIt->second, insertedNodes, str);
-
- if (targetPtrIt->second == nullptr) // it's an external library
- {
- return;
- }
+ auto const& itemName = item.AsStr();
+ auto const& nodeName = this->NodeNames[itemName];
- std::string myNodeName = this->TargetNamesNodes.find(targetName)->second;
- std::map<std::string, LinkLibraryScopeType> ll =
- getScopedLinkLibrariesFromTarget(targetPtrIt->second->Target,
- GlobalGenerator);
+ auto const itemNameWithAliases = ItemNameWithAliases(itemName);
+ auto const escapedLabel = EscapeForDotFile(itemNameWithAliases);
- for (auto const& llit : ll) {
- const std::string& libName = llit.first;
- auto libNameIt = this->TargetNamesNodes.find(libName);
-
- // can happen e.g. if GRAPHVIZ_TARGET_IGNORE_REGEX is used
- if (libNameIt == this->TargetNamesNodes.end()) {
- continue;
- }
-
- std::string connectionName = cmStrCat(myNodeName, '-', libNameIt->second);
- if (insertedConnections.find(connectionName) ==
- insertedConnections.end()) {
- insertedConnections.insert(connectionName);
- this->WriteNode(libName, this->TargetPtrs.find(libName)->second,
- insertedNodes, str);
-
- str << " \"" << myNodeName << "\" -> \"" << libNameIt->second << "\"";
+ fs << " \"" << nodeName << "\" [ label = \"" << escapedLabel
+ << "\", shape = " << getShapeForTarget(item) << " ];\n";
+}
- str << getLinkLibraryStyle(llit.second);
+void cmGraphVizWriter::WriteConnection(cmGeneratedFileStream& fs,
+ cmLinkItem const& depender,
+ cmLinkItem const& dependee,
+ std::string const& edgeStyle)
+{
+ auto const& dependerName = depender.AsStr();
+ auto const& dependeeName = dependee.AsStr();
- str << " // " << targetName << " -> " << libName << std::endl;
- this->WriteConnections(libName, insertedNodes, insertedConnections, str);
- }
- }
+ fs << " \"" << this->NodeNames[dependerName] << "\" -> \""
+ << this->NodeNames[dependeeName] << "\" "
+ << edgeStyle
+ << " // " << dependerName << " -> " << dependeeName << '\n';
}
-void cmGraphVizWriter::WriteDependerConnections(
- const std::string& targetName, std::set<std::string>& insertedNodes,
- std::set<std::string>& insertedConnections, cmGeneratedFileStream& str) const
+bool cmGraphVizWriter::ItemExcluded(cmLinkItem const& item)
{
- auto targetPtrIt = this->TargetPtrs.find(targetName);
+ auto const itemName = item.AsStr();
- if (targetPtrIt == this->TargetPtrs.end()) // not found at all
- {
- return;
+ if (this->ItemNameFilteredOut(itemName)) {
+ return true;
}
- this->WriteNode(targetName, targetPtrIt->second, insertedNodes, str);
-
- if (targetPtrIt->second == nullptr) // it's an external library
- {
- return;
+ if (item.Target == nullptr) {
+ return !this->GenerateForExternals;
}
- std::string myNodeName = this->TargetNamesNodes.find(targetName)->second;
-
- // now search who links against me
- for (auto const& tptr : this->TargetPtrs) {
- if (tptr.second == nullptr) {
- continue;
- }
-
- if (!this->GenerateForTargetType(tptr.second->GetType())) {
- continue;
- }
-
- // Now we have a target, check whether it links against targetName.
- // If so, draw a connection, and then continue with dependers on that one.
- std::map<std::string, LinkLibraryScopeType> ll =
- getScopedLinkLibrariesFromTarget(tptr.second->Target, GlobalGenerator);
-
- for (auto const& llit : ll) {
- if (llit.first == targetName) {
- // So this target links against targetName.
- auto dependerNodeNameIt = this->TargetNamesNodes.find(tptr.first);
-
- if (dependerNodeNameIt != this->TargetNamesNodes.end()) {
- std::string connectionName =
- cmStrCat(dependerNodeNameIt->second, '-', myNodeName);
-
- if (insertedConnections.find(connectionName) ==
- insertedConnections.end()) {
- insertedConnections.insert(connectionName);
- this->WriteNode(tptr.first, tptr.second, insertedNodes, str);
-
- str << " \"" << dependerNodeNameIt->second << "\" -> \""
- << myNodeName << "\"";
- str << " // " << targetName << " -> " << tptr.first << std::endl;
- str << getLinkLibraryStyle(llit.second);
- this->WriteDependerConnections(tptr.first, insertedNodes,
- insertedConnections, str);
- }
- }
- break;
- }
+ if (item.Target->GetType() == cmStateEnums::UTILITY) {
+ if (cmHasLiteralPrefix(itemName, "Nightly") ||
+ cmHasLiteralPrefix(itemName, "Continuous") ||
+ cmHasLiteralPrefix(itemName, "Experimental")) {
+ return true;
}
}
-}
-
-void cmGraphVizWriter::WriteNode(const std::string& targetName,
- const cmGeneratorTarget* target,
- std::set<std::string>& insertedNodes,
- cmGeneratedFileStream& str) const
-{
- if (insertedNodes.find(targetName) == insertedNodes.end()) {
- insertedNodes.insert(targetName);
- auto nameIt = this->TargetNamesNodes.find(targetName);
- str << " \"" << nameIt->second << "\" [ label=\"" << targetName
- << "\" shape=\"" << getShapeForTarget(target) << "\"];" << std::endl;
+ if (item.Target->IsImported() && !this->GenerateForExternals) {
+ return true;
}
-}
-void cmGraphVizWriter::CollectTargetsAndLibs()
-{
- if (!this->HaveTargetsAndLibs) {
- this->HaveTargetsAndLibs = true;
- int cnt = this->CollectAllTargets();
- if (this->GenerateForExternals) {
- this->CollectAllExternalLibs(cnt);
- }
- }
+ return !this->TargetTypeEnabled(item.Target->GetType());
}
-int cmGraphVizWriter::CollectAllTargets()
+bool cmGraphVizWriter::ItemNameFilteredOut(std::string const& itemName)
{
- int cnt = 0;
- // First pass get the list of all cmake targets
- for (cmLocalGenerator* lg : this->LocalGenerators) {
- const std::vector<cmGeneratorTarget*>& targets = lg->GetGeneratorTargets();
- for (cmGeneratorTarget* target : targets) {
- const std::string& realTargetName = target->GetName();
- if (this->IgnoreThisTarget(realTargetName)) {
- // Skip ignored targets
- continue;
- }
- // std::cout << "Found target: " << tit->first << std::endl;
- std::ostringstream ostr;
- ostr << this->GraphNodePrefix << cnt++;
- this->TargetNamesNodes[realTargetName] = ostr.str();
- this->TargetPtrs[realTargetName] = target;
- }
+ if (itemName == ">") {
+ // FIXME: why do we even receive such a target here?
+ return true;
}
- return cnt;
-}
-
-int cmGraphVizWriter::CollectAllExternalLibs(int cnt)
-{
- // Ok, now find all the stuff we link to that is not in cmake
- for (cmLocalGenerator* lg : this->LocalGenerators) {
- const std::vector<cmGeneratorTarget*>& targets = lg->GetGeneratorTargets();
- for (cmGeneratorTarget* target : targets) {
- const std::string& realTargetName = target->GetName();
- if (this->IgnoreThisTarget(realTargetName)) {
- // Skip ignored targets
- continue;
- }
- const cmTarget::LinkLibraryVectorType* ll =
- &(target->Target->GetOriginalLinkLibraries());
- for (auto const& llit : *ll) {
- std::string libName = llit.first;
- if (this->IgnoreThisTarget(libName)) {
- // Skip ignored targets
- continue;
- }
-
- if (GlobalGenerator->IsAlias(libName)) {
- const auto tgt = GlobalGenerator->FindTarget(libName);
- if (tgt) {
- libName = tgt->GetName();
- }
- }
-
- auto tarIt = this->TargetPtrs.find(libName);
- if (tarIt == this->TargetPtrs.end()) {
- std::ostringstream ostr;
- ostr << this->GraphNodePrefix << cnt++;
- this->TargetNamesNodes[libName] = ostr.str();
- this->TargetPtrs[libName] = nullptr;
- // str << " \"" << ostr << "\" [ label=\"" << libName
- // << "\" shape=\"ellipse\"];" << std::endl;
- }
- }
- }
+ if (cmGlobalGenerator::IsReservedTarget(itemName)) {
+ return true;
}
- return cnt;
-}
-bool cmGraphVizWriter::IgnoreThisTarget(const std::string& name)
-{
for (cmsys::RegularExpression& regEx : this->TargetsToIgnoreRegex) {
if (regEx.is_valid()) {
- if (regEx.find(name)) {
+ if (regEx.find(itemName)) {
return true;
}
}
@@ -579,7 +430,7 @@ bool cmGraphVizWriter::IgnoreThisTarget(const std::string& name)
return false;
}
-bool cmGraphVizWriter::GenerateForTargetType(
+bool cmGraphVizWriter::TargetTypeEnabled(
cmStateEnums::TargetType targetType) const
{
switch (targetType) {
@@ -592,9 +443,73 @@ bool cmGraphVizWriter::GenerateForTargetType(
case cmStateEnums::MODULE_LIBRARY:
return this->GenerateForModuleLibs;
case cmStateEnums::INTERFACE_LIBRARY:
- return this->GenerateForInterface;
+ return this->GenerateForInterfaceLibs;
+ case cmStateEnums::OBJECT_LIBRARY:
+ return this->GenerateForObjectLibs;
+ case cmStateEnums::UNKNOWN_LIBRARY:
+ return this->GenerateForUnknownLibs;
+ case cmStateEnums::UTILITY:
+ return this->GenerateForCustomTargets;
+ case cmStateEnums::GLOBAL_TARGET:
+ // Built-in targets like edit_cache, etc.
+ // We don't need/want those in the dot file.
+ return false;
default:
break;
}
return false;
}
+
+std::string cmGraphVizWriter::ItemNameWithAliases(
+ std::string const& itemName) const
+{
+ auto nameWithAliases = itemName;
+
+ for (auto const& lg : this->GlobalGenerator->GetLocalGenerators()) {
+ for (auto const& aliasTargets : lg->GetMakefile()->GetAliasTargets()) {
+ if (aliasTargets.second == itemName) {
+ nameWithAliases += "\\n(" + aliasTargets.first + ")";
+ }
+ }
+ }
+
+ return nameWithAliases;
+}
+
+std::string cmGraphVizWriter::GetEdgeStyle(DependencyType dt)
+{
+ std::string style;
+ switch (dt) {
+ case DependencyType::LinkPrivate:
+ style = "[ style = " + std::string(GRAPHVIZ_EDGE_STYLE_PRIVATE) + " ]";
+ break;
+ case DependencyType::LinkInterface:
+ style = "[ style = " + std::string(GRAPHVIZ_EDGE_STYLE_INTERFACE) + " ]";
+ break;
+ default:
+ break;
+ }
+ return style;
+}
+
+std::string cmGraphVizWriter::EscapeForDotFile(std::string const& str)
+{
+ return cmSystemTools::EscapeChars(str.data(), "\"");
+}
+
+std::string cmGraphVizWriter::PathSafeString(std::string const& str)
+{
+ std::string pathSafeStr;
+
+ // We'll only keep alphanumerical characters, plus the following ones that
+ // are common, and safe on all platforms:
+ auto const extra_chars = std::set<char>{ '.', '-', '_' };
+
+ for (char c : str) {
+ if (std::isalnum(c) || extra_chars.find(c) != extra_chars.cend()) {
+ pathSafeStr += c;
+ }
+ }
+
+ return pathSafeStr;
+}
diff --git a/Source/cmGraphVizWriter.h b/Source/cmGraphVizWriter.h
index 9c3051f..578660d 100644
--- a/Source/cmGraphVizWriter.h
+++ b/Source/cmGraphVizWriter.h
@@ -6,87 +6,106 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <map>
-#include <set>
+#include <memory>
#include <string>
#include <vector>
#include "cmsys/RegularExpression.hxx"
+#include "cmGeneratedFileStream.h"
+#include "cmLinkItemGraphVisitor.h"
#include "cmStateTypes.h"
-class cmGeneratedFileStream;
-class cmGeneratorTarget;
-class cmLocalGenerator;
+class cmLinkItem;
class cmGlobalGenerator;
/** This class implements writing files for graphviz (dot) for graphs
* representing the dependencies between the targets in the project. */
-class cmGraphVizWriter
+class cmGraphVizWriter : public cmLinkItemGraphVisitor
{
public:
- cmGraphVizWriter(const cmGlobalGenerator* globalGenerator);
+ cmGraphVizWriter(std::string const& fileName,
+ const cmGlobalGenerator* globalGenerator);
+ ~cmGraphVizWriter() override;
+
+ void VisitGraph(std::string const& name) override;
+
+ void OnItem(cmLinkItem const& item) override;
+
+ void OnDirectLink(cmLinkItem const& depender, cmLinkItem const& dependee,
+ DependencyType dt) override;
+
+ void OnIndirectLink(cmLinkItem const& depender,
+ cmLinkItem const& dependee) override;
void ReadSettings(const std::string& settingsFileName,
const std::string& fallbackSettingsFileName);
- void WritePerTargetFiles(const std::string& fileName);
- void WriteTargetDependersFiles(const std::string& fileName);
+ void Write();
+
+private:
+ using FileStreamMap =
+ std::map<std::string, std::unique_ptr<cmGeneratedFileStream>>;
+
+ void VisitLink(cmLinkItem const& depender, cmLinkItem const& dependee,
+ bool isDirectLink, std::string const& scopeType = "");
+
+ void WriteHeader(cmGeneratedFileStream& fs, std::string const& name);
- void WriteGlobalFile(const std::string& fileName);
+ void WriteFooter(cmGeneratedFileStream& fs);
-protected:
- void CollectTargetsAndLibs();
+ void WriteLegend(cmGeneratedFileStream& fs);
- int CollectAllTargets();
+ void WriteNode(cmGeneratedFileStream& fs, cmLinkItem const& item);
- int CollectAllExternalLibs(int cnt);
+ void CreateTargetFile(FileStreamMap& fileStreamMap, cmLinkItem const& target,
+ std::string const& fileNameSuffix = "");
- void WriteHeader(cmGeneratedFileStream& str) const;
+ void WriteConnection(cmGeneratedFileStream& fs,
+ cmLinkItem const& dependerTargetName,
+ cmLinkItem const& dependeeTargetName,
+ std::string const& edgeStyle);
- void WriteConnections(const std::string& targetName,
- std::set<std::string>& insertedNodes,
- std::set<std::string>& insertedConnections,
- cmGeneratedFileStream& str) const;
+ bool ItemExcluded(cmLinkItem const& item);
+ bool ItemNameFilteredOut(std::string const& itemName);
+ bool TargetTypeEnabled(cmStateEnums::TargetType targetType) const;
- void WriteDependerConnections(const std::string& targetName,
- std::set<std::string>& insertedNodes,
- std::set<std::string>& insertedConnections,
- cmGeneratedFileStream& str) const;
+ std::string ItemNameWithAliases(std::string const& itemName) const;
- void WriteNode(const std::string& targetName,
- const cmGeneratorTarget* target,
- std::set<std::string>& insertedNodes,
- cmGeneratedFileStream& str) const;
+ static std::string GetEdgeStyle(DependencyType dt);
- void WriteFooter(cmGeneratedFileStream& str) const;
+ static std::string EscapeForDotFile(std::string const& str);
- bool IgnoreThisTarget(const std::string& name);
+ static std::string PathSafeString(std::string const& str);
- bool GenerateForTargetType(cmStateEnums::TargetType targetType) const;
+ std::string FileName;
+ cmGeneratedFileStream GlobalFileStream;
+ FileStreamMap PerTargetFileStreams;
+ FileStreamMap TargetDependersFileStreams;
- std::string GraphType;
std::string GraphName;
std::string GraphHeader;
std::string GraphNodePrefix;
std::vector<cmsys::RegularExpression> TargetsToIgnoreRegex;
- const cmGlobalGenerator* GlobalGenerator;
- const std::vector<cmLocalGenerator*>& LocalGenerators;
+ cmGlobalGenerator const* GlobalGenerator;
- std::map<std::string, const cmGeneratorTarget*> TargetPtrs;
- // maps from the actual target names to node names in dot:
- std::map<std::string, std::string> TargetNamesNodes;
+ int NextNodeId;
+ // maps from the actual item names to node names in dot:
+ std::map<std::string, std::string> NodeNames;
bool GenerateForExecutables;
bool GenerateForStaticLibs;
bool GenerateForSharedLibs;
bool GenerateForModuleLibs;
- bool GenerateForInterface;
+ bool GenerateForInterfaceLibs;
+ bool GenerateForObjectLibs;
+ bool GenerateForUnknownLibs;
+ bool GenerateForCustomTargets;
bool GenerateForExternals;
bool GeneratePerTarget;
bool GenerateDependers;
- bool HaveTargetsAndLibs;
};
#endif
diff --git a/Source/cmIDEOptions.cxx b/Source/cmIDEOptions.cxx
index 71326d2..b53319f 100644
--- a/Source/cmIDEOptions.cxx
+++ b/Source/cmIDEOptions.cxx
@@ -4,6 +4,8 @@
#include <iterator>
+#include <cmext/algorithm>
+
#include <string.h>
#include "cmsys/String.h"
@@ -173,7 +175,7 @@ void cmIDEOptions::AddDefines(std::string const& defines)
}
void cmIDEOptions::AddDefines(const std::vector<std::string>& defines)
{
- cmAppend(this->Defines, defines);
+ cm::append(this->Defines, defines);
}
std::vector<std::string> const& cmIDEOptions::GetDefines() const
@@ -195,7 +197,7 @@ void cmIDEOptions::AddIncludes(std::string const& includes)
}
void cmIDEOptions::AddIncludes(const std::vector<std::string>& includes)
{
- cmAppend(this->Includes, includes);
+ cm::append(this->Includes, includes);
}
std::vector<std::string> const& cmIDEOptions::GetIncludes() const
diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx
index 290e064..5808f90 100644
--- a/Source/cmIfCommand.cxx
+++ b/Source/cmIfCommand.cxx
@@ -7,8 +7,7 @@
#include <cm/memory>
#include <cm/string_view>
-
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
#include "cmConditionEvaluator.h"
#include "cmExecutionStatus.h"
diff --git a/Source/cmIncludeCommand.cxx b/Source/cmIncludeCommand.cxx
index 14264f4..ae801bb 100644
--- a/Source/cmIncludeCommand.cxx
+++ b/Source/cmIncludeCommand.cxx
@@ -2,7 +2,9 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmIncludeCommand.h"
+#include <map>
#include <sstream>
+#include <utility>
#include "cmExecutionStatus.h"
#include "cmGlobalGenerator.h"
@@ -16,6 +18,11 @@
bool cmIncludeCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
+ static std::map<std::string, cmPolicies::PolicyID> DeprecatedModules;
+ if (DeprecatedModules.empty()) {
+ DeprecatedModules["Documentation"] = cmPolicies::CMP0106;
+ }
+
if (args.empty() || args.size() > 4) {
status.SetError("called with wrong number of arguments. "
"include() only takes one file.");
@@ -65,9 +72,35 @@ bool cmIncludeCommand(std::vector<std::string> const& args,
}
if (!cmSystemTools::FileIsFullPath(fname)) {
+ bool system = false;
// Not a path. Maybe module.
std::string module = cmStrCat(fname, ".cmake");
- std::string mfile = status.GetMakefile().GetModulesFile(module);
+ std::string mfile = status.GetMakefile().GetModulesFile(module, system);
+
+ if (system) {
+ auto ModulePolicy = DeprecatedModules.find(fname);
+ if (ModulePolicy != DeprecatedModules.end()) {
+ cmPolicies::PolicyStatus PolicyStatus =
+ status.GetMakefile().GetPolicyStatus(ModulePolicy->second);
+ switch (PolicyStatus) {
+ case cmPolicies::WARN: {
+ status.GetMakefile().IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat(cmPolicies::GetPolicyWarning(ModulePolicy->second),
+ "\n"));
+ CM_FALLTHROUGH;
+ }
+ case cmPolicies::OLD:
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ mfile = "";
+ break;
+ }
+ }
+ }
+
if (!mfile.empty()) {
fname = mfile;
}
diff --git a/Source/cmIncludeDirectoryCommand.cxx b/Source/cmIncludeDirectoryCommand.cxx
index 170aea1..b408f72 100644
--- a/Source/cmIncludeDirectoryCommand.cxx
+++ b/Source/cmIncludeDirectoryCommand.cxx
@@ -6,7 +6,8 @@
#include <set>
#include <utility>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmMakefile.h"
@@ -58,9 +59,9 @@ bool cmIncludeDirectoryCommand(std::vector<std::string> const& args,
GetIncludes(mf, *i, includes);
if (before) {
- cmAppend(beforeIncludes, includes);
+ cm::append(beforeIncludes, includes);
} else {
- cmAppend(afterIncludes, includes);
+ cm::append(afterIncludes, includes);
}
if (system) {
systemIncludes.insert(includes.begin(), includes.end());
diff --git a/Source/cmIncludeExternalMSProjectCommand.cxx b/Source/cmIncludeExternalMSProjectCommand.cxx
index fa1e8bc..5b532ce 100644
--- a/Source/cmIncludeExternalMSProjectCommand.cxx
+++ b/Source/cmIncludeExternalMSProjectCommand.cxx
@@ -77,28 +77,27 @@ bool cmIncludeExternalMSProjectCommand(std::vector<std::string> const& args,
if (!customGuid.empty()) {
std::string guidVariable = utility_name + "_GUID_CMAKE";
- mf.GetCMakeInstance()->AddCacheEntry(guidVariable.c_str(),
- customGuid.c_str(), "Stored GUID",
+ mf.GetCMakeInstance()->AddCacheEntry(guidVariable, customGuid.c_str(),
+ "Stored GUID",
cmStateEnums::INTERNAL);
}
// Create a target instance for this utility.
- cmTarget* target =
- mf.AddNewTarget(cmStateEnums::UTILITY, utility_name.c_str());
+ cmTarget* target = mf.AddNewTarget(cmStateEnums::UTILITY, utility_name);
if (mf.GetPropertyAsBool("EXCLUDE_FROM_ALL")) {
target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
}
- target->SetProperty("GENERATOR_FILE_NAME", utility_name.c_str());
- target->SetProperty("EXTERNAL_MSPROJECT", path.c_str());
+ target->SetProperty("GENERATOR_FILE_NAME", utility_name);
+ target->SetProperty("EXTERNAL_MSPROJECT", path);
if (!customType.empty())
- target->SetProperty("VS_PROJECT_TYPE", customType.c_str());
+ target->SetProperty("VS_PROJECT_TYPE", customType);
if (!platformMapping.empty())
- target->SetProperty("VS_PLATFORM_MAPPING", platformMapping.c_str());
+ target->SetProperty("VS_PLATFORM_MAPPING", platformMapping);
for (std::string const& d : depends) {
- target->AddUtility(d.c_str());
+ target->AddUtility(d, false);
}
}
#endif
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index e511196..ac57bc2 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -8,11 +8,10 @@
#include <utility>
#include <cm/memory>
+#include <cmext/string_view>
#include "cmsys/Glob.hxx"
-#include "cm_static_string_view.hxx"
-
#include "cmArgumentParser.h"
#include "cmExecutionStatus.h"
#include "cmExportSet.h"
@@ -85,7 +84,7 @@ public:
std::string DefaultComponentName;
};
-cmInstallTargetGenerator* CreateInstallTargetGenerator(
+std::unique_ptr<cmInstallTargetGenerator> CreateInstallTargetGenerator(
cmTarget& target, const cmInstallCommandArguments& args, bool impLib,
cmListFileBacktrace const& backtrace, const std::string& destination,
bool forceOpt = false, bool namelink = false)
@@ -93,18 +92,17 @@ cmInstallTargetGenerator* CreateInstallTargetGenerator(
cmInstallGenerator::MessageLevel message =
cmInstallGenerator::SelectMessageLevel(target.GetMakefile());
target.SetHaveInstallRule(true);
- const char* component = namelink ? args.GetNamelinkComponent().c_str()
- : args.GetComponent().c_str();
- auto g = new cmInstallTargetGenerator(
- target.GetName(), destination.c_str(), impLib,
- args.GetPermissions().c_str(), args.GetConfigurations(), component,
- message, args.GetExcludeFromAll(), args.GetOptional() || forceOpt,
- backtrace);
- target.AddInstallGenerator(g);
+ const std::string& component =
+ namelink ? args.GetNamelinkComponent() : args.GetComponent();
+ auto g = cm::make_unique<cmInstallTargetGenerator>(
+ target.GetName(), destination, impLib, args.GetPermissions(),
+ args.GetConfigurations(), component, message, args.GetExcludeFromAll(),
+ args.GetOptional() || forceOpt, backtrace);
+ target.AddInstallGenerator(g.get());
return g;
}
-cmInstallTargetGenerator* CreateInstallTargetGenerator(
+std::unique_ptr<cmInstallTargetGenerator> CreateInstallTargetGenerator(
cmTarget& target, const cmInstallCommandArguments& args, bool impLib,
cmListFileBacktrace const& backtrace, bool forceOpt = false,
bool namelink = false)
@@ -114,20 +112,20 @@ cmInstallTargetGenerator* CreateInstallTargetGenerator(
namelink);
}
-cmInstallFilesGenerator* CreateInstallFilesGenerator(
+std::unique_ptr<cmInstallFilesGenerator> CreateInstallFilesGenerator(
cmMakefile* mf, const std::vector<std::string>& absFiles,
const cmInstallCommandArguments& args, bool programs,
const std::string& destination)
{
cmInstallGenerator::MessageLevel message =
cmInstallGenerator::SelectMessageLevel(mf);
- return new cmInstallFilesGenerator(
- absFiles, destination.c_str(), programs, args.GetPermissions().c_str(),
- args.GetConfigurations(), args.GetComponent().c_str(), message,
- args.GetExcludeFromAll(), args.GetRename().c_str(), args.GetOptional());
+ return cm::make_unique<cmInstallFilesGenerator>(
+ absFiles, destination, programs, args.GetPermissions(),
+ args.GetConfigurations(), args.GetComponent(), message,
+ args.GetExcludeFromAll(), args.GetRename(), args.GetOptional());
}
-cmInstallFilesGenerator* CreateInstallFilesGenerator(
+std::unique_ptr<cmInstallFilesGenerator> CreateInstallFilesGenerator(
cmMakefile* mf, const std::vector<std::string>& absFiles,
const cmInstallCommandArguments& args, bool programs)
{
@@ -196,13 +194,15 @@ bool HandleScriptMode(std::vector<std::string> const& args,
status.SetError("given a directory as value of SCRIPT argument.");
return false;
}
- helper.Makefile->AddInstallGenerator(new cmInstallScriptGenerator(
- script.c_str(), false, component.c_str(), exclude_from_all));
+ helper.Makefile->AddInstallGenerator(
+ cm::make_unique<cmInstallScriptGenerator>(script, false, component,
+ exclude_from_all));
} else if (doing_code) {
doing_code = false;
std::string const& code = arg;
- helper.Makefile->AddInstallGenerator(new cmInstallScriptGenerator(
- code.c_str(), true, component.c_str(), exclude_from_all));
+ helper.Makefile->AddInstallGenerator(
+ cm::make_unique<cmInstallScriptGenerator>(code, true, component,
+ exclude_from_all));
}
}
@@ -449,16 +449,16 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
for (cmTarget* ti : targets) {
// Handle each target type.
cmTarget& target = *ti;
- cmInstallTargetGenerator* archiveGenerator = nullptr;
- cmInstallTargetGenerator* libraryGenerator = nullptr;
- cmInstallTargetGenerator* namelinkGenerator = nullptr;
- cmInstallTargetGenerator* runtimeGenerator = nullptr;
- cmInstallTargetGenerator* objectGenerator = nullptr;
- cmInstallTargetGenerator* frameworkGenerator = nullptr;
- cmInstallTargetGenerator* bundleGenerator = nullptr;
- cmInstallFilesGenerator* privateHeaderGenerator = nullptr;
- cmInstallFilesGenerator* publicHeaderGenerator = nullptr;
- cmInstallFilesGenerator* resourceGenerator = nullptr;
+ std::unique_ptr<cmInstallTargetGenerator> archiveGenerator;
+ std::unique_ptr<cmInstallTargetGenerator> libraryGenerator;
+ std::unique_ptr<cmInstallTargetGenerator> namelinkGenerator;
+ std::unique_ptr<cmInstallTargetGenerator> runtimeGenerator;
+ std::unique_ptr<cmInstallTargetGenerator> objectGenerator;
+ std::unique_ptr<cmInstallTargetGenerator> frameworkGenerator;
+ std::unique_ptr<cmInstallTargetGenerator> bundleGenerator;
+ std::unique_ptr<cmInstallFilesGenerator> privateHeaderGenerator;
+ std::unique_ptr<cmInstallFilesGenerator> publicHeaderGenerator;
+ std::unique_ptr<cmInstallFilesGenerator> resourceGenerator;
// Avoid selecting default destinations for PUBLIC_HEADER and
// PRIVATE_HEADER if any artifacts are specified.
@@ -491,7 +491,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
target, runtimeArgs, false, helper.Makefile->GetBacktrace());
artifactsSpecified = true;
}
- if ((archiveGenerator == nullptr) && (runtimeGenerator == nullptr)) {
+ if (!archiveGenerator && !runtimeGenerator) {
archiveGenerator = CreateInstallTargetGenerator(
target, archiveArgs, true, helper.Makefile->GetBacktrace(),
helper.GetArchiveDestination(nullptr));
@@ -660,7 +660,6 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
// Nothing to do. An INTERFACE_LIBRARY can be installed, but the
// only effect of that is to make it exportable. It installs no
// other files itself.
- break;
default:
// This should never happen due to the above type check.
// Ignore the case.
@@ -679,9 +678,9 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
}
if (createInstallGeneratorsForTargetFileSets && !namelinkOnly) {
- const char* files = target.GetProperty("PRIVATE_HEADER");
- if ((files) && (*files)) {
- std::vector<std::string> relFiles = cmExpandedList(files);
+ cmProp files = target.GetProperty("PRIVATE_HEADER");
+ if (files && !files->empty()) {
+ std::vector<std::string> relFiles = cmExpandedList(*files);
std::vector<std::string> absFiles;
if (!helper.MakeFilesFullPath("PRIVATE_HEADER", relFiles, absFiles)) {
return false;
@@ -702,8 +701,8 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
}
files = target.GetProperty("PUBLIC_HEADER");
- if ((files) && (*files)) {
- std::vector<std::string> relFiles = cmExpandedList(files);
+ if (files && !files->empty()) {
+ std::vector<std::string> relFiles = cmExpandedList(*files);
std::vector<std::string> absFiles;
if (!helper.MakeFilesFullPath("PUBLIC_HEADER", relFiles, absFiles)) {
return false;
@@ -724,8 +723,8 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
}
files = target.GetProperty("RESOURCE");
- if ((files) && (*files)) {
- std::vector<std::string> relFiles = cmExpandedList(files);
+ if (files && !files->empty()) {
+ std::vector<std::string> relFiles = cmExpandedList(*files);
std::vector<std::string> absFiles;
if (!helper.MakeFilesFullPath("RESOURCE", relFiles, absFiles)) {
return false;
@@ -744,43 +743,18 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
}
}
- // Keep track of whether we're installing anything in each category
- installsArchive = installsArchive || archiveGenerator != nullptr;
- installsLibrary = installsLibrary || libraryGenerator != nullptr;
- installsNamelink = installsNamelink || namelinkGenerator != nullptr;
- installsRuntime = installsRuntime || runtimeGenerator != nullptr;
- installsObject = installsObject || objectGenerator != nullptr;
- installsFramework = installsFramework || frameworkGenerator != nullptr;
- installsBundle = installsBundle || bundleGenerator != nullptr;
- installsPrivateHeader =
- installsPrivateHeader || privateHeaderGenerator != nullptr;
- installsPublicHeader =
- installsPublicHeader || publicHeaderGenerator != nullptr;
- installsResource = installsResource || resourceGenerator;
-
- helper.Makefile->AddInstallGenerator(archiveGenerator);
- helper.Makefile->AddInstallGenerator(libraryGenerator);
- helper.Makefile->AddInstallGenerator(namelinkGenerator);
- helper.Makefile->AddInstallGenerator(runtimeGenerator);
- helper.Makefile->AddInstallGenerator(objectGenerator);
- helper.Makefile->AddInstallGenerator(frameworkGenerator);
- helper.Makefile->AddInstallGenerator(bundleGenerator);
- helper.Makefile->AddInstallGenerator(privateHeaderGenerator);
- helper.Makefile->AddInstallGenerator(publicHeaderGenerator);
- helper.Makefile->AddInstallGenerator(resourceGenerator);
-
// Add this install rule to an export if one was specified and
// this is not a namelink-only rule.
if (!exports.empty() && !namelinkOnly) {
auto te = cm::make_unique<cmTargetExport>();
te->TargetName = target.GetName();
- te->ArchiveGenerator = archiveGenerator;
- te->BundleGenerator = bundleGenerator;
- te->FrameworkGenerator = frameworkGenerator;
- te->HeaderGenerator = publicHeaderGenerator;
- te->LibraryGenerator = libraryGenerator;
- te->RuntimeGenerator = runtimeGenerator;
- te->ObjectsGenerator = objectGenerator;
+ te->ArchiveGenerator = archiveGenerator.get();
+ te->BundleGenerator = bundleGenerator.get();
+ te->FrameworkGenerator = frameworkGenerator.get();
+ te->HeaderGenerator = publicHeaderGenerator.get();
+ te->LibraryGenerator = libraryGenerator.get();
+ te->RuntimeGenerator = runtimeGenerator.get();
+ te->ObjectsGenerator = objectGenerator.get();
te->InterfaceIncludeDirectories =
cmJoin(includesArgs.GetIncludeDirs(), ";");
@@ -788,6 +762,29 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
->GetExportSets()[exports]
.AddTargetExport(std::move(te));
}
+
+ // Keep track of whether we're installing anything in each category
+ installsArchive = installsArchive || archiveGenerator;
+ installsLibrary = installsLibrary || libraryGenerator;
+ installsNamelink = installsNamelink || namelinkGenerator;
+ installsRuntime = installsRuntime || runtimeGenerator;
+ installsObject = installsObject || objectGenerator;
+ installsFramework = installsFramework || frameworkGenerator;
+ installsBundle = installsBundle || bundleGenerator;
+ installsPrivateHeader = installsPrivateHeader || privateHeaderGenerator;
+ installsPublicHeader = installsPublicHeader || publicHeaderGenerator;
+ installsResource = installsResource || resourceGenerator;
+
+ helper.Makefile->AddInstallGenerator(std::move(archiveGenerator));
+ helper.Makefile->AddInstallGenerator(std::move(libraryGenerator));
+ helper.Makefile->AddInstallGenerator(std::move(namelinkGenerator));
+ helper.Makefile->AddInstallGenerator(std::move(runtimeGenerator));
+ helper.Makefile->AddInstallGenerator(std::move(objectGenerator));
+ helper.Makefile->AddInstallGenerator(std::move(frameworkGenerator));
+ helper.Makefile->AddInstallGenerator(std::move(bundleGenerator));
+ helper.Makefile->AddInstallGenerator(std::move(privateHeaderGenerator));
+ helper.Makefile->AddInstallGenerator(std::move(publicHeaderGenerator));
+ helper.Makefile->AddInstallGenerator(std::move(resourceGenerator));
}
// Tell the global generator about any installation component names
@@ -975,7 +972,7 @@ bool HandleDirectoryMode(std::vector<std::string> const& args,
bool exclude_from_all = false;
bool message_never = false;
std::vector<std::string> dirs;
- const char* destination = nullptr;
+ const std::string* destination = nullptr;
std::string permissions_file;
std::string permissions_dir;
std::vector<std::string> configurations;
@@ -1134,7 +1131,7 @@ bool HandleDirectoryMode(std::vector<std::string> const& args,
} else if (doing == DoingConfigurations) {
configurations.push_back(args[i]);
} else if (doing == DoingDestination) {
- destination = args[i].c_str();
+ destination = &args[i];
doing = DoingNone;
} else if (doing == DoingType) {
if (allowedTypes.count(args[i]) == 0) {
@@ -1220,7 +1217,7 @@ bool HandleDirectoryMode(std::vector<std::string> const& args,
return false;
}
destinationStr = helper.GetDestinationForType(nullptr, type);
- destination = destinationStr.c_str();
+ destination = &destinationStr;
} else if (!type.empty()) {
status.SetError(cmStrCat(args[0],
" given both TYPE and DESTINATION "
@@ -1232,10 +1229,10 @@ bool HandleDirectoryMode(std::vector<std::string> const& args,
cmInstallGenerator::SelectMessageLevel(helper.Makefile, message_never);
// Create the directory install generator.
- helper.Makefile->AddInstallGenerator(new cmInstallDirectoryGenerator(
- dirs, destination, permissions_file.c_str(), permissions_dir.c_str(),
- configurations, component.c_str(), message, exclude_from_all,
- literal_args.c_str(), optional));
+ helper.Makefile->AddInstallGenerator(
+ cm::make_unique<cmInstallDirectoryGenerator>(
+ dirs, *destination, permissions_file, permissions_dir, configurations,
+ component, message, exclude_from_all, literal_args, optional));
// Tell the global generator about any installation component names
// specified.
@@ -1323,12 +1320,11 @@ bool HandleExportAndroidMKMode(std::vector<std::string> const& args,
cmInstallGenerator::SelectMessageLevel(helper.Makefile);
// Create the export install generator.
- cmInstallExportGenerator* exportGenerator = new cmInstallExportGenerator(
- &exportSet, ica.GetDestination().c_str(), ica.GetPermissions().c_str(),
- ica.GetConfigurations(), ica.GetComponent().c_str(), message,
- ica.GetExcludeFromAll(), fname.c_str(), name_space.c_str(), exportOld,
- true);
- helper.Makefile->AddInstallGenerator(exportGenerator);
+ helper.Makefile->AddInstallGenerator(
+ cm::make_unique<cmInstallExportGenerator>(
+ &exportSet, ica.GetDestination(), ica.GetPermissions(),
+ ica.GetConfigurations(), ica.GetComponent(), message,
+ ica.GetExcludeFromAll(), fname, name_space, exportOld, true));
return true;
#else
@@ -1437,12 +1433,11 @@ bool HandleExportMode(std::vector<std::string> const& args,
cmInstallGenerator::SelectMessageLevel(helper.Makefile);
// Create the export install generator.
- cmInstallExportGenerator* exportGenerator = new cmInstallExportGenerator(
- &exportSet, ica.GetDestination().c_str(), ica.GetPermissions().c_str(),
- ica.GetConfigurations(), ica.GetComponent().c_str(), message,
- ica.GetExcludeFromAll(), fname.c_str(), name_space.c_str(), exportOld,
- false);
- helper.Makefile->AddInstallGenerator(exportGenerator);
+ helper.Makefile->AddInstallGenerator(
+ cm::make_unique<cmInstallExportGenerator>(
+ &exportSet, ica.GetDestination(), ica.GetPermissions(),
+ ica.GetConfigurations(), ica.GetComponent(), message,
+ ica.GetExcludeFromAll(), fname, name_space, exportOld, false));
return true;
}
diff --git a/Source/cmInstallCommandArguments.cxx b/Source/cmInstallCommandArguments.cxx
index 31ba63f..a034689 100644
--- a/Source/cmInstallCommandArguments.cxx
+++ b/Source/cmInstallCommandArguments.cxx
@@ -4,7 +4,7 @@
#include <utility>
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
#include "cmRange.h"
#include "cmSystemTools.h"
diff --git a/Source/cmInstallDirectoryGenerator.cxx b/Source/cmInstallDirectoryGenerator.cxx
index 259c7f7..175e7cf 100644
--- a/Source/cmInstallDirectoryGenerator.cxx
+++ b/Source/cmInstallDirectoryGenerator.cxx
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmInstallDirectoryGenerator.h"
+#include <utility>
+
#include "cmGeneratorExpression.h"
#include "cmInstallType.h"
#include "cmLocalGenerator.h"
@@ -10,18 +12,18 @@
#include "cmSystemTools.h"
cmInstallDirectoryGenerator::cmInstallDirectoryGenerator(
- std::vector<std::string> const& dirs, const char* dest,
- const char* file_permissions, const char* dir_permissions,
- std::vector<std::string> const& configurations, const char* component,
- MessageLevel message, bool exclude_from_all, const char* literal_args,
+ std::vector<std::string> const& dirs, std::string const& dest,
+ std::string file_permissions, std::string dir_permissions,
+ std::vector<std::string> const& configurations, std::string const& component,
+ MessageLevel message, bool exclude_from_all, std::string literal_args,
bool optional)
: cmInstallGenerator(dest, configurations, component, message,
exclude_from_all)
, LocalGenerator(nullptr)
, Directories(dirs)
- , FilePermissions(file_permissions)
- , DirPermissions(dir_permissions)
- , LiteralArguments(literal_args)
+ , FilePermissions(std::move(file_permissions))
+ , DirPermissions(std::move(dir_permissions))
+ , LiteralArguments(std::move(literal_args))
, Optional(optional)
{
// We need per-config actions if destination have generator expressions.
diff --git a/Source/cmInstallDirectoryGenerator.h b/Source/cmInstallDirectoryGenerator.h
index 84c0694..bec89df 100644
--- a/Source/cmInstallDirectoryGenerator.h
+++ b/Source/cmInstallDirectoryGenerator.h
@@ -21,12 +21,13 @@ class cmInstallDirectoryGenerator : public cmInstallGenerator
{
public:
cmInstallDirectoryGenerator(std::vector<std::string> const& dirs,
- const char* dest, const char* file_permissions,
- const char* dir_permissions,
+ std::string const& dest,
+ std::string file_permissions,
+ std::string dir_permissions,
std::vector<std::string> const& configurations,
- const char* component, MessageLevel message,
- bool exclude_from_all, const char* literal_args,
- bool optional = false);
+ std::string const& component,
+ MessageLevel message, bool exclude_from_all,
+ std::string literal_args, bool optional = false);
~cmInstallDirectoryGenerator() override;
bool Compute(cmLocalGenerator* lg) override;
@@ -41,11 +42,11 @@ protected:
Indent indent,
std::vector<std::string> const& dirs);
cmLocalGenerator* LocalGenerator;
- std::vector<std::string> Directories;
- std::string FilePermissions;
- std::string DirPermissions;
- std::string LiteralArguments;
- bool Optional;
+ std::vector<std::string> const Directories;
+ std::string const FilePermissions;
+ std::string const DirPermissions;
+ std::string const LiteralArguments;
+ bool const Optional;
};
#endif
diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx
index cba68be..6e3508c 100644
--- a/Source/cmInstallExportGenerator.cxx
+++ b/Source/cmInstallExportGenerator.cxx
@@ -7,6 +7,8 @@
#include <sstream>
#include <utility>
+#include <cm/memory>
+
#ifndef CMAKE_BOOTSTRAP
# include "cmExportInstallAndroidMKGenerator.h"
#endif
@@ -18,33 +20,30 @@
#include "cmSystemTools.h"
cmInstallExportGenerator::cmInstallExportGenerator(
- cmExportSet* exportSet, const char* destination,
- const char* file_permissions, std::vector<std::string> const& configurations,
- const char* component, MessageLevel message, bool exclude_from_all,
- const char* filename, const char* name_space, bool exportOld, bool android)
+ 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)
: cmInstallGenerator(destination, configurations, component, message,
exclude_from_all)
, ExportSet(exportSet)
- , FilePermissions(file_permissions)
- , FileName(filename)
- , Namespace(name_space)
+ , FilePermissions(std::move(file_permissions))
+ , FileName(std::move(filename))
+ , Namespace(std::move(name_space))
, ExportOld(exportOld)
, LocalGenerator(nullptr)
{
if (android) {
#ifndef CMAKE_BOOTSTRAP
- this->EFGen = new cmExportInstallAndroidMKGenerator(this);
+ this->EFGen = cm::make_unique<cmExportInstallAndroidMKGenerator>(this);
#endif
} else {
- this->EFGen = new cmExportInstallFileGenerator(this);
+ this->EFGen = cm::make_unique<cmExportInstallFileGenerator>(this);
}
exportSet->AddInstallation(this);
}
-cmInstallExportGenerator::~cmInstallExportGenerator()
-{
- delete this->EFGen;
-}
+cmInstallExportGenerator::~cmInstallExportGenerator() = default;
bool cmInstallExportGenerator::Compute(cmLocalGenerator* lg)
{
diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h
index f44127e..43dd00d 100644
--- a/Source/cmInstallExportGenerator.h
+++ b/Source/cmInstallExportGenerator.h
@@ -7,6 +7,7 @@
#include <cstddef>
#include <iosfwd>
+#include <memory>
#include <string>
#include <vector>
@@ -23,15 +24,19 @@ class cmLocalGenerator;
class cmInstallExportGenerator : public cmInstallGenerator
{
public:
- cmInstallExportGenerator(cmExportSet* exportSet, const char* dest,
- const char* file_permissions,
+ cmInstallExportGenerator(cmExportSet* exportSet, std::string const& dest,
+ std::string file_permissions,
const std::vector<std::string>& configurations,
- const char* component, MessageLevel message,
- bool exclude_from_all, const char* filename,
- const char* name_space, bool exportOld,
+ std::string const& component, MessageLevel message,
+ bool exclude_from_all, std::string filename,
+ std::string name_space, bool exportOld,
bool android);
+ cmInstallExportGenerator(const cmInstallExportGenerator&) = delete;
~cmInstallExportGenerator() override;
+ cmInstallExportGenerator& operator=(const cmInstallExportGenerator&) =
+ delete;
+
cmExportSet* GetExportSet() { return this->ExportSet; }
bool Compute(cmLocalGenerator* lg) override;
@@ -52,16 +57,16 @@ protected:
void ComputeTempDir();
size_t GetMaxConfigLength() const;
- cmExportSet* ExportSet;
- std::string FilePermissions;
- std::string FileName;
- std::string Namespace;
- bool ExportOld;
+ cmExportSet* const ExportSet;
+ std::string const FilePermissions;
+ std::string const FileName;
+ std::string const Namespace;
+ bool const ExportOld;
cmLocalGenerator* LocalGenerator;
std::string TempDir;
std::string MainImportFile;
- cmExportInstallFileGenerator* EFGen;
+ std::unique_ptr<cmExportInstallFileGenerator> EFGen;
};
#endif
diff --git a/Source/cmInstallFilesCommand.cxx b/Source/cmInstallFilesCommand.cxx
index d623943..3c59f01 100644
--- a/Source/cmInstallFilesCommand.cxx
+++ b/Source/cmInstallFilesCommand.cxx
@@ -2,16 +2,21 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmInstallFilesCommand.h"
+#include <cm/memory>
+
#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
#include "cmInstallFilesGenerator.h"
#include "cmInstallGenerator.h"
+#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmRange.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+class cmListFileBacktrace;
+
static std::string FindInstallSource(cmMakefile& makefile, const char* name);
static void CreateInstallGenerator(cmMakefile& makefile,
std::string const& dest,
@@ -43,9 +48,10 @@ bool cmInstallFilesCommand(std::vector<std::string> const& args,
CreateInstallGenerator(mf, dest, files);
} else {
std::vector<std::string> finalArgs(args.begin() + 1, args.end());
- mf.AddFinalAction([dest, finalArgs](cmMakefile& makefile) {
- FinalAction(makefile, dest, finalArgs);
- });
+ mf.AddGeneratorAction(
+ [dest, finalArgs](cmLocalGenerator& lg, const cmListFileBacktrace&) {
+ FinalAction(*lg.GetMakefile(), dest, finalArgs);
+ });
}
mf.GetGlobalGenerator()->AddInstallComponent(
@@ -109,17 +115,17 @@ static void CreateInstallGenerator(cmMakefile& makefile,
}
// Use a file install generator.
- const char* no_permissions = "";
- const char* no_rename = "";
+ const std::string no_permissions;
+ const std::string no_rename;
bool no_exclude_from_all = false;
std::string no_component =
makefile.GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME");
std::vector<std::string> no_configurations;
cmInstallGenerator::MessageLevel message =
cmInstallGenerator::SelectMessageLevel(&makefile);
- makefile.AddInstallGenerator(new cmInstallFilesGenerator(
- files, destination.c_str(), false, no_permissions, no_configurations,
- no_component.c_str(), message, no_exclude_from_all, no_rename));
+ makefile.AddInstallGenerator(cm::make_unique<cmInstallFilesGenerator>(
+ files, destination, false, no_permissions, no_configurations, no_component,
+ message, no_exclude_from_all, no_rename));
}
/**
diff --git a/Source/cmInstallFilesGenerator.cxx b/Source/cmInstallFilesGenerator.cxx
index f5b69a5..ad2f84e 100644
--- a/Source/cmInstallFilesGenerator.cxx
+++ b/Source/cmInstallFilesGenerator.cxx
@@ -2,6 +2,8 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmInstallFilesGenerator.h"
+#include <utility>
+
#include "cmGeneratorExpression.h"
#include "cmInstallType.h"
#include "cmStringAlgorithms.h"
@@ -9,16 +11,17 @@
class cmLocalGenerator;
cmInstallFilesGenerator::cmInstallFilesGenerator(
- std::vector<std::string> const& files, const char* dest, bool programs,
- const char* file_permissions, std::vector<std::string> const& configurations,
- const char* component, MessageLevel message, bool exclude_from_all,
- const char* rename, bool optional)
+ std::vector<std::string> const& files, std::string const& dest,
+ bool programs, std::string file_permissions,
+ std::vector<std::string> const& configurations, std::string const& component,
+ MessageLevel message, bool exclude_from_all, std::string rename,
+ bool optional)
: cmInstallGenerator(dest, configurations, component, message,
exclude_from_all)
, LocalGenerator(nullptr)
, Files(files)
- , FilePermissions(file_permissions)
- , Rename(rename)
+ , FilePermissions(std::move(file_permissions))
+ , Rename(std::move(rename))
, Programs(programs)
, Optional(optional)
{
diff --git a/Source/cmInstallFilesGenerator.h b/Source/cmInstallFilesGenerator.h
index a680037..8266603 100644
--- a/Source/cmInstallFilesGenerator.h
+++ b/Source/cmInstallFilesGenerator.h
@@ -21,11 +21,11 @@ class cmInstallFilesGenerator : public cmInstallGenerator
{
public:
cmInstallFilesGenerator(std::vector<std::string> const& files,
- const char* dest, bool programs,
- const char* file_permissions,
+ std::string const& dest, bool programs,
+ std::string file_permissions,
std::vector<std::string> const& configurations,
- const char* component, MessageLevel message,
- bool exclude_from_all, const char* rename,
+ std::string const& component, MessageLevel message,
+ bool exclude_from_all, std::string rename,
bool optional = false);
~cmInstallFilesGenerator() override;
@@ -42,11 +42,11 @@ protected:
std::vector<std::string> const& files);
cmLocalGenerator* LocalGenerator;
- std::vector<std::string> Files;
- std::string FilePermissions;
- std::string Rename;
- bool Programs;
- bool Optional;
+ std::vector<std::string> const Files;
+ std::string const FilePermissions;
+ std::string const Rename;
+ bool const Programs;
+ bool const Optional;
};
#endif
diff --git a/Source/cmInstallGenerator.cxx b/Source/cmInstallGenerator.cxx
index ec17361..0665895 100644
--- a/Source/cmInstallGenerator.cxx
+++ b/Source/cmInstallGenerator.cxx
@@ -3,16 +3,17 @@
#include "cmInstallGenerator.h"
#include <ostream>
+#include <utility>
#include "cmMakefile.h"
#include "cmSystemTools.h"
cmInstallGenerator::cmInstallGenerator(
- const char* destination, std::vector<std::string> const& configurations,
- const char* component, MessageLevel message, bool exclude_from_all)
+ std::string destination, std::vector<std::string> const& configurations,
+ std::string component, MessageLevel message, bool exclude_from_all)
: cmScriptGenerator("CMAKE_INSTALL_CONFIG_NAME", configurations)
- , Destination(destination ? destination : "")
- , Component(component ? component : "")
+ , Destination(std::move(destination))
+ , Component(std::move(component))
, Message(message)
, ExcludeFromAll(exclude_from_all)
{
@@ -139,8 +140,8 @@ void cmInstallGenerator::AddInstallRule(
os << ")\n";
}
-std::string cmInstallGenerator::CreateComponentTest(const char* component,
- bool exclude_from_all)
+std::string cmInstallGenerator::CreateComponentTest(
+ const std::string& component, bool exclude_from_all)
{
std::string result = R"("x${CMAKE_INSTALL_COMPONENT}x" STREQUAL "x)";
result += component;
@@ -158,7 +159,7 @@ void cmInstallGenerator::GenerateScript(std::ostream& os)
// Begin this block of installation.
std::string component_test =
- this->CreateComponentTest(this->Component.c_str(), this->ExcludeFromAll);
+ this->CreateComponentTest(this->Component, this->ExcludeFromAll);
os << indent << "if(" << component_test << ")\n";
// Generate the script possibly with per-configuration code.
diff --git a/Source/cmInstallGenerator.h b/Source/cmInstallGenerator.h
index 024027d..d786d24 100644
--- a/Source/cmInstallGenerator.h
+++ b/Source/cmInstallGenerator.h
@@ -30,9 +30,9 @@ public:
MessageNever
};
- cmInstallGenerator(const char* destination,
+ cmInstallGenerator(std::string destination,
std::vector<std::string> const& configurations,
- const char* component, MessageLevel message,
+ std::string component, MessageLevel message,
bool exclude_from_all);
~cmInstallGenerator() override;
@@ -65,14 +65,14 @@ public:
protected:
void GenerateScript(std::ostream& os) override;
- std::string CreateComponentTest(const char* component,
+ std::string CreateComponentTest(const std::string& component,
bool exclude_from_all);
// Information shared by most generator types.
- std::string Destination;
- std::string Component;
- MessageLevel Message;
- bool ExcludeFromAll;
+ std::string const Destination;
+ std::string const Component;
+ MessageLevel const Message;
+ bool const ExcludeFromAll;
};
#endif
diff --git a/Source/cmInstallProgramsCommand.cxx b/Source/cmInstallProgramsCommand.cxx
index 6bb4409..be07fd4 100644
--- a/Source/cmInstallProgramsCommand.cxx
+++ b/Source/cmInstallProgramsCommand.cxx
@@ -2,15 +2,20 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmInstallProgramsCommand.h"
+#include <cm/memory>
+
#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
#include "cmInstallFilesGenerator.h"
#include "cmInstallGenerator.h"
+#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+class cmListFileBacktrace;
+
static void FinalAction(cmMakefile& makefile, std::string const& dest,
std::vector<std::string> const& args);
static std::string FindInstallSource(cmMakefile& makefile, const char* name);
@@ -33,9 +38,10 @@ bool cmInstallProgramsCommand(std::vector<std::string> const& args,
std::string const& dest = args[0];
std::vector<std::string> const finalArgs(args.begin() + 1, args.end());
- mf.AddFinalAction([dest, finalArgs](cmMakefile& makefile) {
- FinalAction(makefile, dest, finalArgs);
- });
+ mf.AddGeneratorAction(
+ [dest, finalArgs](cmLocalGenerator& lg, const cmListFileBacktrace&) {
+ FinalAction(*lg.GetMakefile(), dest, finalArgs);
+ });
return true;
}
@@ -83,17 +89,17 @@ static void FinalAction(cmMakefile& makefile, std::string const& dest,
}
// Use a file install generator.
- const char* no_permissions = "";
- const char* no_rename = "";
+ const std::string no_permissions;
+ const std::string no_rename;
bool no_exclude_from_all = false;
std::string no_component =
makefile.GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME");
std::vector<std::string> no_configurations;
cmInstallGenerator::MessageLevel message =
cmInstallGenerator::SelectMessageLevel(&makefile);
- makefile.AddInstallGenerator(new cmInstallFilesGenerator(
- files, destination.c_str(), true, no_permissions, no_configurations,
- no_component.c_str(), message, no_exclude_from_all, no_rename));
+ makefile.AddInstallGenerator(cm::make_unique<cmInstallFilesGenerator>(
+ files, destination, true, no_permissions, no_configurations, no_component,
+ message, no_exclude_from_all, no_rename));
}
/**
diff --git a/Source/cmInstallScriptGenerator.cxx b/Source/cmInstallScriptGenerator.cxx
index ea29455..7cdf3b4 100644
--- a/Source/cmInstallScriptGenerator.cxx
+++ b/Source/cmInstallScriptGenerator.cxx
@@ -3,6 +3,7 @@
#include "cmInstallScriptGenerator.h"
#include <ostream>
+#include <utility>
#include <vector>
#include "cmGeneratorExpression.h"
@@ -11,13 +12,12 @@
#include "cmPolicies.h"
#include "cmScriptGenerator.h"
-cmInstallScriptGenerator::cmInstallScriptGenerator(const char* script,
- bool code,
- const char* component,
- bool exclude_from_all)
- : cmInstallGenerator(nullptr, std::vector<std::string>(), component,
+cmInstallScriptGenerator::cmInstallScriptGenerator(
+ std::string script, bool code, std::string const& component,
+ bool exclude_from_all)
+ : cmInstallGenerator("", std::vector<std::string>(), component,
MessageDefault, exclude_from_all)
- , Script(script)
+ , Script(std::move(script))
, Code(code)
, AllowGenex(false)
{
diff --git a/Source/cmInstallScriptGenerator.h b/Source/cmInstallScriptGenerator.h
index 7efa321..0a9c4ba 100644
--- a/Source/cmInstallScriptGenerator.h
+++ b/Source/cmInstallScriptGenerator.h
@@ -19,8 +19,9 @@ class cmLocalGenerator;
class cmInstallScriptGenerator : public cmInstallGenerator
{
public:
- cmInstallScriptGenerator(const char* script, bool code,
- const char* component, bool exclude_from_all);
+ cmInstallScriptGenerator(std::string script, bool code,
+ std::string const& component,
+ bool exclude_from_all);
~cmInstallScriptGenerator() override;
bool Compute(cmLocalGenerator* lg) override;
@@ -32,8 +33,8 @@ protected:
void AddScriptInstallRule(std::ostream& os, Indent indent,
std::string const& script);
- std::string Script;
- bool Code;
+ std::string const Script;
+ bool const Code;
cmLocalGenerator* LocalGenerator;
bool AllowGenex;
};
diff --git a/Source/cmInstallSubdirectoryGenerator.cxx b/Source/cmInstallSubdirectoryGenerator.cxx
index 8a0fefa..12bc92b 100644
--- a/Source/cmInstallSubdirectoryGenerator.cxx
+++ b/Source/cmInstallSubdirectoryGenerator.cxx
@@ -2,7 +2,9 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmInstallSubdirectoryGenerator.h"
+#include <memory>
#include <sstream>
+#include <utility>
#include <vector>
#include "cmLocalGenerator.h"
@@ -12,11 +14,11 @@
#include "cmSystemTools.h"
cmInstallSubdirectoryGenerator::cmInstallSubdirectoryGenerator(
- cmMakefile* makefile, const char* binaryDirectory, bool excludeFromAll)
- : cmInstallGenerator(nullptr, std::vector<std::string>(), nullptr,
- MessageDefault, excludeFromAll)
+ cmMakefile* makefile, std::string binaryDirectory, bool excludeFromAll)
+ : cmInstallGenerator("", std::vector<std::string>(), "", MessageDefault,
+ excludeFromAll)
, Makefile(makefile)
- , BinaryDirectory(binaryDirectory)
+ , BinaryDirectory(std::move(binaryDirectory))
{
}
@@ -24,7 +26,7 @@ cmInstallSubdirectoryGenerator::~cmInstallSubdirectoryGenerator() = default;
bool cmInstallSubdirectoryGenerator::HaveInstall()
{
- for (auto generator : this->Makefile->GetInstallGenerators()) {
+ for (const auto& generator : this->Makefile->GetInstallGenerators()) {
if (generator->HaveInstall()) {
return true;
}
diff --git a/Source/cmInstallSubdirectoryGenerator.h b/Source/cmInstallSubdirectoryGenerator.h
index b99bdd5..f9cd0f1 100644
--- a/Source/cmInstallSubdirectoryGenerator.h
+++ b/Source/cmInstallSubdirectoryGenerator.h
@@ -20,7 +20,7 @@ class cmInstallSubdirectoryGenerator : public cmInstallGenerator
{
public:
cmInstallSubdirectoryGenerator(cmMakefile* makefile,
- const char* binaryDirectory,
+ std::string binaryDirectory,
bool excludeFromAll);
~cmInstallSubdirectoryGenerator() override;
@@ -33,8 +33,8 @@ public:
protected:
void GenerateScript(std::ostream& os) override;
- cmMakefile* Makefile;
- std::string BinaryDirectory;
+ cmMakefile* const Makefile;
+ std::string const BinaryDirectory;
cmLocalGenerator* LocalGenerator;
};
diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
index aa92fa7..37d8c28 100644
--- a/Source/cmInstallTargetGenerator.cxx
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -24,16 +24,18 @@
#include "cmTarget.h"
#include "cmake.h"
+using cmProp = const std::string*; // just to silence IWYU
+
cmInstallTargetGenerator::cmInstallTargetGenerator(
- std::string targetName, const char* dest, bool implib,
- const char* file_permissions, std::vector<std::string> const& configurations,
- const char* component, MessageLevel message, bool exclude_from_all,
+ std::string targetName, std::string const& dest, bool implib,
+ 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)
, TargetName(std::move(targetName))
, Target(nullptr)
- , FilePermissions(file_permissions)
+ , FilePermissions(std::move(file_permissions))
, ImportLibrary(implib)
, Optional(optional)
, Backtrace(std::move(backtrace))
@@ -133,8 +135,10 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(
cmMakefile const* mf = this->Target->Target->GetMakefile();
// Get App Bundle Extension
- const char* ext = this->Target->GetProperty("BUNDLE_EXTENSION");
- if (!ext) {
+ std::string ext;
+ if (cmProp p = this->Target->GetProperty("BUNDLE_EXTENSION")) {
+ ext = *p;
+ } else {
ext = "app";
}
@@ -554,7 +558,8 @@ void cmInstallTargetGenerator::AddInstallNamePatchRule(
// components of the install_name field then we need to create a
// mapping to be applied after installation.
std::string for_build = tgt->GetInstallNameDirForBuildTree(config);
- std::string for_install = tgt->GetInstallNameDirForInstallTree();
+ std::string for_install = tgt->GetInstallNameDirForInstallTree(
+ config, "${CMAKE_INSTALL_PREFIX}");
if (for_build != for_install) {
// The directory portions differ. Append the filename to
// create the mapping.
@@ -577,7 +582,8 @@ void cmInstallTargetGenerator::AddInstallNamePatchRule(
if (this->Target->GetType() == cmStateEnums::SHARED_LIBRARY) {
std::string for_build =
this->Target->GetInstallNameDirForBuildTree(config);
- std::string for_install = this->Target->GetInstallNameDirForInstallTree();
+ std::string for_install = this->Target->GetInstallNameDirForInstallTree(
+ config, "${CMAKE_INSTALL_PREFIX}");
if (this->Target->IsFrameworkOnApple() && for_install.empty()) {
// Frameworks seem to have an id corresponding to their own full
diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h
index 8730454..e21001f 100644
--- a/Source/cmInstallTargetGenerator.h
+++ b/Source/cmInstallTargetGenerator.h
@@ -23,11 +23,11 @@ class cmInstallTargetGenerator : public cmInstallGenerator
{
public:
cmInstallTargetGenerator(
- std::string targetName, const char* dest, bool implib,
- const char* file_permissions,
- std::vector<std::string> const& configurations, const char* component,
- MessageLevel message, bool exclude_from_all, bool optional,
- cmListFileBacktrace backtrace = cmListFileBacktrace());
+ std::string targetName, std::string const& dest, bool implib,
+ std::string file_permissions,
+ std::vector<std::string> const& configurations,
+ std::string const& component, MessageLevel message, bool exclude_from_all,
+ bool optional, cmListFileBacktrace backtrace = cmListFileBacktrace());
~cmInstallTargetGenerator() override;
/** Select the policy for installing shared library linkable name
@@ -106,13 +106,13 @@ protected:
const std::string& toDestDirPath);
void IssueCMP0095Warning(const std::string& unescapedRpath);
- std::string TargetName;
+ std::string const TargetName;
cmGeneratorTarget* Target;
- std::string FilePermissions;
+ std::string const FilePermissions;
NamelinkModeType NamelinkMode;
- bool ImportLibrary;
- bool Optional;
- cmListFileBacktrace Backtrace;
+ bool const ImportLibrary;
+ bool const Optional;
+ cmListFileBacktrace const Backtrace;
};
#endif
diff --git a/Source/cmInstalledFile.cxx b/Source/cmInstalledFile.cxx
index eabe590..32395d1 100644
--- a/Source/cmInstalledFile.cxx
+++ b/Source/cmInstalledFile.cxx
@@ -4,7 +4,6 @@
#include <utility>
-#include "cmAlgorithms.h"
#include "cmGeneratorExpression.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
@@ -12,17 +11,11 @@
cmInstalledFile::cmInstalledFile() = default;
-cmInstalledFile::~cmInstalledFile()
-{
- delete NameExpression;
-}
+cmInstalledFile::~cmInstalledFile() = default;
cmInstalledFile::Property::Property() = default;
-cmInstalledFile::Property::~Property()
-{
- cmDeleteAll(this->ValueExpressions);
-}
+cmInstalledFile::Property::~Property() = default;
void cmInstalledFile::SetName(cmMakefile* mf, const std::string& name)
{
@@ -30,7 +23,7 @@ void cmInstalledFile::SetName(cmMakefile* mf, const std::string& name)
cmGeneratorExpression ge(backtrace);
this->Name = name;
- this->NameExpression = ge.Parse(name).release();
+ this->NameExpression = ge.Parse(name);
}
std::string const& cmInstalledFile::GetName() const
@@ -49,7 +42,8 @@ void cmInstalledFile::RemoveProperty(const std::string& prop)
}
void cmInstalledFile::SetProperty(cmMakefile const* mf,
- const std::string& prop, const char* value)
+ const std::string& prop,
+ const std::string& value)
{
this->RemoveProperty(prop);
this->AppendProperty(mf, prop, value);
@@ -57,13 +51,14 @@ void cmInstalledFile::SetProperty(cmMakefile const* mf,
void cmInstalledFile::AppendProperty(cmMakefile const* mf,
const std::string& prop,
- const char* value, bool /*asString*/)
+ const std::string& value,
+ bool /*asString*/)
{
cmListFileBacktrace backtrace = mf->GetBacktrace();
cmGeneratorExpression ge(backtrace);
Property& property = this->Properties[prop];
- property.ValueExpressions.push_back(ge.Parse(value).release());
+ property.ValueExpressions.push_back(ge.Parse(value));
}
bool cmInstalledFile::HasProperty(const std::string& prop) const
@@ -84,7 +79,7 @@ bool cmInstalledFile::GetProperty(const std::string& prop,
std::string output;
std::string separator;
- for (auto ve : property.ValueExpressions) {
+ for (const auto& ve : property.ValueExpressions) {
output += separator;
output += ve->GetInput();
separator = ";";
diff --git a/Source/cmInstalledFile.h b/Source/cmInstalledFile.h
index ee809ee..07f7081 100644
--- a/Source/cmInstalledFile.h
+++ b/Source/cmInstalledFile.h
@@ -24,7 +24,7 @@ public:
using CompiledGeneratorExpressionPtrType =
std::unique_ptr<cmCompiledGeneratorExpression>;
- using ExpressionVectorType = std::vector<cmCompiledGeneratorExpression*>;
+ using ExpressionVectorType = std::vector<CompiledGeneratorExpressionPtrType>;
struct Property
{
@@ -49,10 +49,10 @@ public:
void RemoveProperty(const std::string& prop);
void SetProperty(cmMakefile const* mf, const std::string& prop,
- const char* value);
+ const std::string& value);
void AppendProperty(cmMakefile const* mf, const std::string& prop,
- const char* value, bool asString = false);
+ const std::string& value, bool asString = false);
bool HasProperty(const std::string& prop) const;
@@ -73,7 +73,7 @@ public:
private:
std::string Name;
- cmCompiledGeneratorExpression* NameExpression = nullptr;
+ CompiledGeneratorExpressionPtrType NameExpression;
PropertyMapType Properties;
};
diff --git a/Source/cmJsonObjects.cxx b/Source/cmJsonObjects.cxx
index b23ab43..a4f78bc 100644
--- a/Source/cmJsonObjects.cxx
+++ b/Source/cmJsonObjects.cxx
@@ -8,13 +8,15 @@
#include <functional>
#include <limits>
#include <map>
+#include <memory>
#include <set>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
@@ -43,7 +45,7 @@ namespace {
std::vector<std::string> getConfigurations(const cmake* cm)
{
std::vector<std::string> configurations;
- auto makefiles = cm->GetGlobalGenerator()->GetMakefiles();
+ const auto& makefiles = cm->GetGlobalGenerator()->GetMakefiles();
if (makefiles.empty()) {
return configurations;
}
@@ -82,13 +84,14 @@ void cmGetCMakeInputs(const cmGlobalGenerator* gg,
std::vector<std::string>* tmpFiles)
{
const std::string cmakeRootDir = cmSystemTools::GetCMakeRoot() + '/';
- std::vector<cmMakefile*> const& makefiles = gg->GetMakefiles();
- for (cmMakefile const* mf : makefiles) {
+ auto const& makefiles = gg->GetMakefiles();
+ for (const auto& mf : makefiles) {
for (std::string const& lf : mf->GetListFiles()) {
const std::string startOfFile = lf.substr(0, cmakeRootDir.size());
const bool isInternal = (startOfFile == cmakeRootDir);
- const bool isTemporary = !isInternal && (lf.find(buildDir + '/') == 0);
+ const bool isTemporary =
+ !isInternal && (cmHasPrefix(lf, buildDir + '/'));
std::string toAdd = lf;
if (!sourceDir.empty()) {
@@ -272,14 +275,14 @@ static Json::Value DumpSourceFilesList(
std::string compileFlags = ld.Flags;
const std::string COMPILE_FLAGS("COMPILE_FLAGS");
- if (const char* cflags = file->GetProperty(COMPILE_FLAGS)) {
+ if (cmProp cflags = file->GetProperty(COMPILE_FLAGS)) {
lg->AppendFlags(compileFlags,
- genexInterpreter.Evaluate(cflags, COMPILE_FLAGS));
+ genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS));
}
const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
- if (const char* coptions = file->GetProperty(COMPILE_OPTIONS)) {
+ if (cmProp coptions = file->GetProperty(COMPILE_OPTIONS)) {
lg->AppendCompileOptions(
- compileFlags, genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS));
+ compileFlags, genexInterpreter.Evaluate(*coptions, COMPILE_OPTIONS));
}
fileData.Flags = compileFlags;
@@ -287,9 +290,9 @@ static Json::Value DumpSourceFilesList(
std::vector<std::string> includes;
const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
- if (const char* cincludes = file->GetProperty(INCLUDE_DIRECTORIES)) {
+ if (cmProp cincludes = file->GetProperty(INCLUDE_DIRECTORIES)) {
const std::string& evaluatedIncludes =
- genexInterpreter.Evaluate(cincludes, INCLUDE_DIRECTORIES);
+ genexInterpreter.Evaluate(*cincludes, INCLUDE_DIRECTORIES);
lg->AppendIncludeDirectories(includes, evaluatedIncludes, *file);
for (const auto& include : includes) {
@@ -306,17 +309,17 @@ static Json::Value DumpSourceFilesList(
const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS");
std::set<std::string> defines;
- if (const char* defs = file->GetProperty(COMPILE_DEFINITIONS)) {
+ if (cmProp defs = file->GetProperty(COMPILE_DEFINITIONS)) {
lg->AppendDefines(
- defines, genexInterpreter.Evaluate(defs, COMPILE_DEFINITIONS));
+ defines, genexInterpreter.Evaluate(*defs, COMPILE_DEFINITIONS));
}
const std::string defPropName =
"COMPILE_DEFINITIONS_" + cmSystemTools::UpperCase(config);
- if (const char* config_defs = file->GetProperty(defPropName)) {
+ if (cmProp config_defs = file->GetProperty(defPropName)) {
lg->AppendDefines(
defines,
- genexInterpreter.Evaluate(config_defs, COMPILE_DEFINITIONS));
+ genexInterpreter.Evaluate(*config_defs, COMPILE_DEFINITIONS));
}
defines.insert(ld.Defines.begin(), ld.Defines.end());
@@ -485,10 +488,10 @@ static Json::Value DumpTarget(cmGeneratorTarget* target,
result[kHAS_INSTALL_RULE] = true;
Json::Value installPaths = Json::arrayValue;
- auto targetGenerators = target->Makefile->GetInstallGenerators();
- for (auto installGenerator : targetGenerators) {
+ for (const auto& installGenerator :
+ target->Makefile->GetInstallGenerators()) {
auto installTargetGenerator =
- dynamic_cast<cmInstallTargetGenerator*>(installGenerator);
+ dynamic_cast<cmInstallTargetGenerator*>(installGenerator.get());
if (installTargetGenerator != nullptr &&
installTargetGenerator->GetTarget()->Target == target->Target) {
auto dest = installTargetGenerator->GetDestination(config);
@@ -601,7 +604,7 @@ static Json::Value DumpTargetsList(
std::vector<cmGeneratorTarget*> targetList;
for (auto const& lgIt : generators) {
- cmAppend(targetList, lgIt->GetGeneratorTargets());
+ cm::append(targetList, lgIt->GetGeneratorTargets());
}
std::sort(targetList.begin(), targetList.end());
@@ -641,9 +644,9 @@ static Json::Value DumpProjectList(const cmake* cm, std::string const& config)
// associated generators.
bool hasInstallRule = false;
for (const auto generator : projectIt.second) {
- for (const auto installGen :
+ for (const auto& installGen :
generator->GetMakefile()->GetInstallGenerators()) {
- if (!dynamic_cast<cmInstallSubdirectoryGenerator*>(installGen)) {
+ if (!dynamic_cast<cmInstallSubdirectoryGenerator*>(installGen.get())) {
hasInstallRule = true;
break;
}
diff --git a/Source/cmJsonObjects.h b/Source/cmJsonObjects.h
index 64291cc..2fd4b26 100644
--- a/Source/cmJsonObjects.h
+++ b/Source/cmJsonObjects.h
@@ -8,7 +8,7 @@
#include <string>
#include <vector>
-#include "cm_jsoncpp_value.h"
+#include <cm3p/json/value.h>
class cmake;
class cmGlobalGenerator;
diff --git a/Source/cmLinkItem.cxx b/Source/cmLinkItem.cxx
index 91eb183..4e50d70 100644
--- a/Source/cmLinkItem.cxx
+++ b/Source/cmLinkItem.cxx
@@ -8,14 +8,17 @@
cmLinkItem::cmLinkItem() = default;
-cmLinkItem::cmLinkItem(std::string n, cmListFileBacktrace bt)
+cmLinkItem::cmLinkItem(std::string n, bool c, cmListFileBacktrace bt)
: String(std::move(n))
+ , Cross(c)
, Backtrace(std::move(bt))
{
}
-cmLinkItem::cmLinkItem(cmGeneratorTarget const* t, cmListFileBacktrace bt)
+cmLinkItem::cmLinkItem(cmGeneratorTarget const* t, bool c,
+ cmListFileBacktrace bt)
: Target(t)
+ , Cross(c)
, Backtrace(std::move(bt))
{
}
@@ -39,12 +42,16 @@ bool operator<(cmLinkItem const& l, cmLinkItem const& r)
return false;
}
// Order among strings.
- return l.String < r.String;
+ if (l.String < r.String) {
+ return true;
+ }
+ // Order among cross-config.
+ return l.Cross < r.Cross;
}
bool operator==(cmLinkItem const& l, cmLinkItem const& r)
{
- return l.Target == r.Target && l.String == r.String;
+ return l.Target == r.Target && l.String == r.String && l.Cross == r.Cross;
}
std::ostream& operator<<(std::ostream& os, cmLinkItem const& item)
diff --git a/Source/cmLinkItem.h b/Source/cmLinkItem.h
index 2d9378b..3d92935 100644
--- a/Source/cmLinkItem.h
+++ b/Source/cmLinkItem.h
@@ -10,7 +10,8 @@
#include <string>
#include <vector>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmListFileCache.h"
#include "cmSystemTools.h"
#include "cmTargetLinkLibraryType.h"
@@ -24,10 +25,11 @@ class cmLinkItem
public:
cmLinkItem();
- cmLinkItem(std::string s, cmListFileBacktrace bt);
- cmLinkItem(cmGeneratorTarget const* t, cmListFileBacktrace bt);
+ cmLinkItem(std::string s, bool c, cmListFileBacktrace bt);
+ cmLinkItem(cmGeneratorTarget const* t, bool c, cmListFileBacktrace bt);
std::string const& AsStr() const;
cmGeneratorTarget const* Target = nullptr;
+ bool Cross = false;
cmListFileBacktrace Backtrace;
friend bool operator<(cmLinkItem const& l, cmLinkItem const& r);
friend bool operator==(cmLinkItem const& l, cmLinkItem const& r);
@@ -52,6 +54,9 @@ struct cmLinkImplementationLibraries
// Libraries linked directly in other configurations.
// Needed only for OLD behavior of CMP0003.
std::vector<cmLinkItem> WrongConfigLibraries;
+
+ // Whether the list depends on a genex referencing the configuration.
+ bool HadContextSensitiveCondition = false;
};
struct cmLinkInterfaceLibraries
@@ -61,6 +66,9 @@ struct cmLinkInterfaceLibraries
// Whether the list depends on a genex referencing the head target.
bool HadHeadSensitiveCondition = false;
+
+ // Whether the list depends on a genex referencing the configuration.
+ bool HadContextSensitiveCondition = false;
};
struct cmLinkInterface : public cmLinkInterfaceLibraries
@@ -80,6 +88,9 @@ struct cmLinkInterface : public cmLinkInterfaceLibraries
std::vector<cmLinkItem> WrongConfigLibraries;
bool ImplementationIsInterface = false;
+
+ // Whether the list depends on a link language genex.
+ bool HadLinkLanguageSensitiveCondition = false;
};
struct cmOptionalLinkInterface : public cmLinkInterface
@@ -99,6 +110,9 @@ struct cmLinkImplementation : public cmLinkImplementationLibraries
{
// Languages whose runtime libraries must be linked.
std::vector<std::string> Languages;
+
+ // Whether the list depends on a link language genex.
+ bool HadLinkLanguageSensitiveCondition = false;
};
// Cache link implementation computation from each configuration.
@@ -120,7 +134,7 @@ inline cmTargetLinkLibraryType CMP0003_ComputeLinkType(
// Check if any entry in the list matches this configuration.
std::string configUpper = cmSystemTools::UpperCase(config);
- if (cmContains(debugConfigs, configUpper)) {
+ if (cm::contains(debugConfigs, configUpper)) {
return DEBUG_LibraryType;
}
// The current configuration is not a debug configuration.
diff --git a/Source/cmLinkItemGraphVisitor.cxx b/Source/cmLinkItemGraphVisitor.cxx
new file mode 100644
index 0000000..acc23c8
--- /dev/null
+++ b/Source/cmLinkItemGraphVisitor.cxx
@@ -0,0 +1,142 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmLinkItemGraphVisitor.h"
+
+#include <map>
+#include <utility>
+#include <vector>
+
+#include "cmGeneratorTarget.h"
+#include "cmLinkItem.h"
+#include "cmMakefile.h"
+
+void cmLinkItemGraphVisitor::VisitItem(cmLinkItem const& item)
+{
+ if (this->ItemVisited(item)) {
+ return;
+ }
+
+ this->OnItem(item);
+
+ this->VisitLinks(item, item);
+}
+
+void cmLinkItemGraphVisitor::VisitLinks(cmLinkItem const& item,
+ cmLinkItem const& rootItem)
+{
+ if (this->LinkVisited(item, rootItem)) {
+ return;
+ }
+
+ if (item.Target == nullptr) {
+ return;
+ }
+
+ for (auto const& config : item.Target->Makefile->GetGeneratorConfigs()) {
+ this->VisitLinks(item, rootItem, config);
+ }
+}
+
+void cmLinkItemGraphVisitor::VisitLinks(cmLinkItem const& item,
+ cmLinkItem const& rootItem,
+ std::string const& config)
+{
+ auto const& target = *item.Target;
+
+ DependencyMap dependencies;
+ cmLinkItemGraphVisitor::GetDependencies(target, config, dependencies);
+
+ for (auto const& d : dependencies) {
+ auto const& dependency = d.second;
+ auto const& dependencyType = dependency.first;
+ auto const& dependee = dependency.second;
+ this->VisitItem(dependee);
+
+ if (this->LinkVisited(item, dependee)) {
+ continue;
+ }
+
+ this->OnDirectLink(item, dependee, dependencyType);
+
+ if (rootItem.AsStr() != item.AsStr()) {
+ this->OnIndirectLink(rootItem, dependee);
+ }
+
+ // Visit all the direct and indirect links.
+ this->VisitLinks(dependee, dependee);
+ this->VisitLinks(dependee, item);
+ this->VisitLinks(dependee, rootItem);
+ }
+}
+
+bool cmLinkItemGraphVisitor::ItemVisited(cmLinkItem const& item)
+{
+ auto& collection = this->VisitedItems;
+
+ bool const visited = collection.find(item.AsStr()) != collection.cend();
+
+ if (!visited) {
+ collection.insert(item.AsStr());
+ }
+
+ return visited;
+}
+
+bool cmLinkItemGraphVisitor::LinkVisited(cmLinkItem const& depender,
+ cmLinkItem const& dependee)
+{
+ auto const link = std::make_pair<>(depender.AsStr(), dependee.AsStr());
+
+ bool const linkVisited =
+ this->VisitedLinks.find(link) != this->VisitedLinks.cend();
+
+ if (!linkVisited) {
+ this->VisitedLinks.insert(link);
+ }
+
+ return linkVisited;
+}
+
+void cmLinkItemGraphVisitor::GetDependencies(cmGeneratorTarget const& target,
+ std::string const& config,
+ DependencyMap& dependencies)
+{
+ auto implementationLibraries = target.GetLinkImplementationLibraries(config);
+ if (implementationLibraries != nullptr) {
+ for (auto const& lib : implementationLibraries->Libraries) {
+ auto const& name = lib.AsStr();
+ dependencies[name] = Dependency(DependencyType::LinkPrivate, lib);
+ }
+ }
+
+ auto interfaceLibraries =
+ target.GetLinkInterfaceLibraries(config, &target, true);
+ if (interfaceLibraries != nullptr) {
+ for (auto const& lib : interfaceLibraries->Libraries) {
+ auto const& name = lib.AsStr();
+ if (dependencies.find(name) != dependencies.cend()) {
+ dependencies[name] = Dependency(DependencyType::LinkPublic, lib);
+ } else {
+ dependencies[name] = Dependency(DependencyType::LinkInterface, lib);
+ }
+ }
+ }
+
+ std::vector<cmGeneratorTarget*> objectLibraries;
+ target.GetObjectLibrariesCMP0026(objectLibraries);
+ for (auto const& lib : objectLibraries) {
+ auto const& name = lib->GetName();
+ if (dependencies.find(name) == dependencies.cend()) {
+ auto objectItem = cmLinkItem(lib, false, lib->GetBacktrace());
+ dependencies[name] = Dependency(DependencyType::Object, objectItem);
+ }
+ }
+
+ auto const& utilityItems = target.GetUtilityItems();
+ for (auto const& item : utilityItems) {
+ auto const& name = item.AsStr();
+ if (dependencies.find(name) == dependencies.cend()) {
+ dependencies[name] = Dependency(DependencyType::Utility, item);
+ }
+ }
+}
diff --git a/Source/cmLinkItemGraphVisitor.h b/Source/cmLinkItemGraphVisitor.h
new file mode 100644
index 0000000..21dc659
--- /dev/null
+++ b/Source/cmLinkItemGraphVisitor.h
@@ -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. */
+#ifndef cmLinkItemGraphVisitor_h
+#define cmLinkItemGraphVisitor_h
+
+#include <map>
+#include <set>
+#include <string>
+#include <utility>
+
+#include "cmLinkItem.h"
+
+class cmGeneratorTarget;
+
+/** \class cmLinkItemGraphVisitor
+ * \brief Visits a graph of linked items.
+ *
+ * Allows to visit items and dependency links (direct and indirect) between
+ * those items.
+ * This abstract class takes care of the graph traversal, making sure that:
+ * - it terminates even in the presence of cycles;
+ * - it visits every object once (and only once);
+ * - it visits the objects in the same order every time.
+ *
+ * Children classes only have to implement OnItem() etc. to handle whatever
+ * logic they care about.
+ */
+class cmLinkItemGraphVisitor
+{
+public:
+ virtual ~cmLinkItemGraphVisitor() = default;
+
+ virtual void VisitGraph(std::string const& name) = 0;
+
+ void VisitItem(cmLinkItem const& item);
+
+protected:
+ enum class DependencyType
+ {
+ LinkInterface,
+ LinkPublic,
+ LinkPrivate,
+ Object,
+ Utility
+ };
+
+ virtual void OnItem(cmLinkItem const& item) = 0;
+
+ virtual void OnDirectLink(cmLinkItem const& depender,
+ cmLinkItem const& dependee, DependencyType dt) = 0;
+
+ virtual void OnIndirectLink(cmLinkItem const& depender,
+ cmLinkItem const& dependee) = 0;
+
+private:
+ std::set<std::string> VisitedItems;
+
+ std::set<std::pair<std::string, std::string>> VisitedLinks;
+
+ void VisitLinks(cmLinkItem const& item, cmLinkItem const& rootItem);
+ void VisitLinks(cmLinkItem const& item, cmLinkItem const& rootItem,
+ std::string const& config);
+
+ using Dependency = std::pair<DependencyType, cmLinkItem>;
+ using DependencyMap = std::map<std::string, Dependency>;
+
+ bool ItemVisited(cmLinkItem const& item);
+ bool LinkVisited(cmLinkItem const& depender, cmLinkItem const& dependee);
+
+ static void GetDependencies(cmGeneratorTarget const& target,
+ std::string const& config,
+ DependencyMap& dependencies);
+};
+
+#endif
diff --git a/Source/cmLinkLibrariesCommand.cxx b/Source/cmLinkLibrariesCommand.cxx
index cb63ceb..2b8f836 100644
--- a/Source/cmLinkLibrariesCommand.cxx
+++ b/Source/cmLinkLibrariesCommand.cxx
@@ -32,7 +32,7 @@ bool cmLinkLibrariesCommand(std::vector<std::string> const& args,
}
mf.AppendProperty("LINK_LIBRARIES", "optimized");
}
- mf.AppendProperty("LINK_LIBRARIES", i->c_str());
+ mf.AppendProperty("LINK_LIBRARIES", *i);
}
return true;
diff --git a/Source/cmLinkLineComputer.cxx b/Source/cmLinkLineComputer.cxx
index 3fc41cf..480c005 100644
--- a/Source/cmLinkLineComputer.cxx
+++ b/Source/cmLinkLineComputer.cxx
@@ -22,6 +22,7 @@ cmLinkLineComputer::cmLinkLineComputer(cmOutputConverter* outputConverter,
, OutputConverter(outputConverter)
, ForResponse(false)
, UseWatcomQuote(false)
+ , UseNinjaMulti(false)
, Relink(false)
{
}
@@ -33,6 +34,11 @@ void cmLinkLineComputer::SetUseWatcomQuote(bool useWatcomQuote)
this->UseWatcomQuote = useWatcomQuote;
}
+void cmLinkLineComputer::SetUseNinjaMulti(bool useNinjaMulti)
+{
+ this->UseNinjaMulti = useNinjaMulti;
+}
+
void cmLinkLineComputer::SetForResponse(bool forResponse)
{
this->ForResponse = forResponse;
@@ -92,10 +98,14 @@ void cmLinkLineComputer::ComputeLinkLibs(
std::string cmLinkLineComputer::ConvertToOutputFormat(std::string const& input)
{
- cmOutputConverter::OutputFormat shellFormat = (this->ForResponse)
- ? cmOutputConverter::RESPONSE
- : ((this->UseWatcomQuote) ? cmOutputConverter::WATCOMQUOTE
- : cmOutputConverter::SHELL);
+ cmOutputConverter::OutputFormat shellFormat = cmOutputConverter::SHELL;
+ if (this->ForResponse) {
+ shellFormat = cmOutputConverter::RESPONSE;
+ } else if (this->UseWatcomQuote) {
+ shellFormat = cmOutputConverter::WATCOMQUOTE;
+ } else if (this->UseNinjaMulti) {
+ shellFormat = cmOutputConverter::NINJAMULTI;
+ }
return this->OutputConverter->ConvertToOutputFormat(input, shellFormat);
}
@@ -103,10 +113,14 @@ std::string cmLinkLineComputer::ConvertToOutputFormat(std::string const& input)
std::string cmLinkLineComputer::ConvertToOutputForExisting(
std::string const& input)
{
- cmOutputConverter::OutputFormat shellFormat = (this->ForResponse)
- ? cmOutputConverter::RESPONSE
- : ((this->UseWatcomQuote) ? cmOutputConverter::WATCOMQUOTE
- : cmOutputConverter::SHELL);
+ cmOutputConverter::OutputFormat shellFormat = cmOutputConverter::SHELL;
+ if (this->ForResponse) {
+ shellFormat = cmOutputConverter::RESPONSE;
+ } else if (this->UseWatcomQuote) {
+ shellFormat = cmOutputConverter::WATCOMQUOTE;
+ } else if (this->UseNinjaMulti) {
+ shellFormat = cmOutputConverter::NINJAMULTI;
+ }
return this->OutputConverter->ConvertToOutputForExisting(input, shellFormat);
}
diff --git a/Source/cmLinkLineComputer.h b/Source/cmLinkLineComputer.h
index f426976..df42468 100644
--- a/Source/cmLinkLineComputer.h
+++ b/Source/cmLinkLineComputer.h
@@ -28,6 +28,7 @@ public:
cmLinkLineComputer& operator=(cmLinkLineComputer const&) = delete;
void SetUseWatcomQuote(bool useWatcomQuote);
+ void SetUseNinjaMulti(bool useNinjaMulti);
void SetForResponse(bool forResponse);
void SetRelink(bool relink);
@@ -69,6 +70,7 @@ protected:
bool ForResponse;
bool UseWatcomQuote;
+ bool UseNinjaMulti;
bool Relink;
};
diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx
index 65ed34c..eebf328 100644
--- a/Source/cmLinkLineDeviceComputer.cxx
+++ b/Source/cmLinkLineDeviceComputer.cxx
@@ -6,7 +6,8 @@
#include <set>
#include <utility>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmComputeLinkInformation.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
@@ -176,11 +177,11 @@ bool requireDeviceLinking(cmGeneratorTarget& target, cmLocalGenerator& lg,
return false;
}
- if (const char* resolveDeviceSymbols =
+ if (cmProp resolveDeviceSymbols =
target.GetProperty("CUDA_RESOLVE_DEVICE_SYMBOLS")) {
// If CUDA_RESOLVE_DEVICE_SYMBOLS has been explicitly set we need
// to honor the value no matter what it is.
- return cmIsOn(resolveDeviceSymbols);
+ return cmIsOn(*resolveDeviceSymbols);
}
// Determine if we have any dependencies that require
@@ -188,10 +189,10 @@ bool requireDeviceLinking(cmGeneratorTarget& target, cmLocalGenerator& lg,
cmGeneratorTarget::LinkClosure const* closure =
target.GetLinkClosure(config);
- if (cmContains(closure->Languages, "CUDA")) {
- if (const char* separableCompilation =
+ if (cm::contains(closure->Languages, "CUDA")) {
+ if (cmProp separableCompilation =
target.GetProperty("CUDA_SEPARABLE_COMPILATION")) {
- if (cmIsOn(separableCompilation)) {
+ if (cmIsOn(*separableCompilation)) {
bool doDeviceLinking = false;
switch (target.GetType()) {
case cmStateEnums::SHARED_LIBRARY:
diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx
index 5200a16..edec613 100644
--- a/Source/cmListCommand.cxx
+++ b/Source/cmListCommand.cxx
@@ -16,11 +16,11 @@
#include <vector>
#include <cm/memory>
+#include <cmext/algorithm>
+#include <cmext/string_view>
#include "cmsys/RegularExpression.hxx"
-#include "cm_static_string_view.hxx"
-
#include "cmAlgorithms.h"
#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
@@ -66,7 +66,7 @@ bool GetList(std::vector<std::string>& list, const std::string& var,
// expand the variable into a list
cmExpandList(listString, list, true);
// if no empty elements then just return
- if (!cmContains(list, std::string())) {
+ if (!cm::contains(list, std::string())) {
return true;
}
// if we have empty elements we need to check policy CMP0007
@@ -1051,6 +1051,7 @@ public:
UNINITIALIZED,
STRING,
FILE_BASENAME,
+ NATURAL,
};
enum class CaseSensitivity
{
@@ -1074,10 +1075,25 @@ protected:
: nullptr;
}
+ using ComparisonFunction =
+ std::function<bool(const std::string&, const std::string&)>;
+ ComparisonFunction GetComparisonFunction(Compare compare)
+ {
+ if (compare == Compare::NATURAL) {
+ return std::function<bool(const std::string&, const std::string&)>(
+ [](const std::string& x, const std::string& y) {
+ return cmSystemTools::strverscmp(x, y) < 0;
+ });
+ }
+ return std::function<bool(const std::string&, const std::string&)>(
+ [](const std::string& x, const std::string& y) { return x < y; });
+ }
+
public:
cmStringSorter(Compare compare, CaseSensitivity caseSensitivity,
Order desc = Order::ASCENDING)
: filters{ GetCompareFilter(compare), GetCaseFilter(caseSensitivity) }
+ , sortMethod(GetComparisonFunction(compare))
, descending(desc == Order::DESCENDING)
{
}
@@ -1099,15 +1115,16 @@ public:
std::string bf = ApplyFilter(b);
bool result;
if (descending) {
- result = bf < af;
+ result = sortMethod(bf, af);
} else {
- result = af < bf;
+ result = sortMethod(af, bf);
}
return result;
}
protected:
StringFilter filters[2] = { nullptr, nullptr };
+ ComparisonFunction sortMethod;
bool descending;
};
@@ -1142,6 +1159,8 @@ bool HandleSortCommand(std::vector<std::string> const& args,
sortCompare = cmStringSorter::Compare::STRING;
} else if (argument == "FILE_BASENAME") {
sortCompare = cmStringSorter::Compare::FILE_BASENAME;
+ } else if (argument == "NATURAL") {
+ sortCompare = cmStringSorter::Compare::NATURAL;
} else {
std::string error =
cmStrCat(messageHint, "value \"", argument, "\" for option \"",
diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx
index 47679c9..7ebb02f 100644
--- a/Source/cmListFileCache.cxx
+++ b/Source/cmListFileCache.cxx
@@ -26,13 +26,15 @@ cmCommandContext::cmCommandName& cmCommandContext::cmCommandName::operator=(
struct cmListFileParser
{
cmListFileParser(cmListFile* lf, cmListFileBacktrace lfbt,
- cmMessenger* messenger, const char* filename);
+ cmMessenger* messenger);
~cmListFileParser();
cmListFileParser(const cmListFileParser&) = delete;
cmListFileParser& operator=(const cmListFileParser&) = delete;
void IssueFileOpenError(std::string const& text) const;
void IssueError(std::string const& text) const;
- bool ParseFile();
+ bool ParseFile(const char* filename);
+ bool ParseString(const char* str, const char* virtual_filename);
+ bool Parse();
bool ParseFunction(const char* name, long line);
bool AddArgument(cmListFileLexer_Token* token,
cmListFileArgument::Delimiter delim);
@@ -51,12 +53,11 @@ struct cmListFileParser
};
cmListFileParser::cmListFileParser(cmListFile* lf, cmListFileBacktrace lfbt,
- cmMessenger* messenger,
- const char* filename)
+ cmMessenger* messenger)
: ListFile(lf)
, Backtrace(std::move(lfbt))
, Messenger(messenger)
- , FileName(filename)
+ , FileName(nullptr)
, Lexer(cmListFileLexer_New())
{
}
@@ -83,8 +84,10 @@ void cmListFileParser::IssueError(const std::string& text) const
cmSystemTools::SetFatalErrorOccured();
}
-bool cmListFileParser::ParseFile()
+bool cmListFileParser::ParseFile(const char* filename)
{
+ this->FileName = filename;
+
// Open the file.
cmListFileLexer_BOM bom;
if (!cmListFileLexer_SetFileName(this->Lexer, this->FileName, &bom)) {
@@ -107,6 +110,24 @@ bool cmListFileParser::ParseFile()
return false;
}
+ return Parse();
+}
+
+bool cmListFileParser::ParseString(const char* str,
+ const char* virtual_filename)
+{
+ this->FileName = virtual_filename;
+
+ if (!cmListFileLexer_SetString(this->Lexer, str)) {
+ this->IssueFileOpenError("cmListFileCache: cannot allocate buffer.");
+ return false;
+ }
+
+ return Parse();
+}
+
+bool cmListFileParser::Parse()
+{
// Use a simple recursive-descent parser to process the token
// stream.
bool haveNewline = true;
@@ -155,8 +176,22 @@ bool cmListFile::ParseFile(const char* filename, cmMessenger* messenger,
bool parseError = false;
{
- cmListFileParser parser(this, lfbt, messenger, filename);
- parseError = !parser.ParseFile();
+ cmListFileParser parser(this, lfbt, messenger);
+ parseError = !parser.ParseFile(filename);
+ }
+
+ return !parseError;
+}
+
+bool cmListFile::ParseString(const char* str, const char* virtual_filename,
+ cmMessenger* messenger,
+ const cmListFileBacktrace& lfbt)
+{
+ bool parseError = false;
+
+ {
+ cmListFileParser parser(this, lfbt, messenger);
+ parseError = !parser.ParseString(str, virtual_filename);
}
return !parseError;
diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h
index 9cae827..89902ff 100644
--- a/Source/cmListFileCache.h
+++ b/Source/cmListFileCache.h
@@ -184,6 +184,9 @@ struct cmListFile
bool ParseFile(const char* path, cmMessenger* messenger,
cmListFileBacktrace const& lfbt);
+ bool ParseString(const char* str, const char* virtual_filename,
+ cmMessenger* messenger, cmListFileBacktrace const& lfbt);
+
std::vector<cmListFileFunction> Functions;
};
diff --git a/Source/cmLoadCacheCommand.cxx b/Source/cmLoadCacheCommand.cxx
index 1184bcb..d49e711 100644
--- a/Source/cmLoadCacheCommand.cxx
+++ b/Source/cmLoadCacheCommand.cxx
@@ -24,12 +24,20 @@ bool cmLoadCacheCommand(std::vector<std::string> const& args,
{
if (args.empty()) {
status.SetError("called with wrong number of arguments.");
+ return false;
}
if (args.size() >= 2 && args[1] == "READ_WITH_PREFIX") {
return ReadWithPrefix(args, status);
}
+ if (status.GetMakefile().GetCMakeInstance()->GetWorkingMode() ==
+ cmake::SCRIPT_MODE) {
+ status.SetError(
+ "Only load_cache(READ_WITH_PREFIX) may be used in script mode");
+ return false;
+ }
+
// Cache entries to be excluded from the import list.
// If this set is empty, all cache entries are brought in
// and they can not be overridden.
diff --git a/Source/cmLoadCommandCommand.cxx b/Source/cmLoadCommandCommand.cxx
index 23ace64..5790e16 100644
--- a/Source/cmLoadCommandCommand.cxx
+++ b/Source/cmLoadCommandCommand.cxx
@@ -1,5 +1,15 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
+
+#if !defined(_WIN32) && !defined(__sun)
+// POSIX APIs are needed
+# define _POSIX_C_SOURCE 200809L
+#endif
+#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__)
+// For isascii
+# define _XOPEN_SOURCE 700
+#endif
+
#include "cmLoadCommandCommand.h"
#include <csignal>
@@ -14,6 +24,7 @@
#include "cmCommand.h"
#include "cmDynamicLoader.h"
#include "cmExecutionStatus.h"
+#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
@@ -25,6 +36,8 @@
# include <malloc.h> /* for malloc/free on QNX */
#endif
+class cmListFileBacktrace;
+
namespace {
const char* LastName = nullptr;
@@ -158,8 +171,10 @@ bool cmLoadedCommand::InitialPass(std::vector<std::string> const& args,
if (result) {
if (this->Impl->FinalPass) {
auto impl = this->Impl;
- this->Makefile->AddFinalAction(
- [impl](cmMakefile& makefile) { impl->DoFinalPass(&makefile); });
+ this->Makefile->AddGeneratorAction(
+ [impl](cmLocalGenerator& lg, const cmListFileBacktrace&) {
+ impl->DoFinalPass(lg.GetMakefile());
+ });
}
return true;
}
diff --git a/Source/cmLocalCommonGenerator.cxx b/Source/cmLocalCommonGenerator.cxx
index f86955d..278ec8b 100644
--- a/Source/cmLocalCommonGenerator.cxx
+++ b/Source/cmLocalCommonGenerator.cxx
@@ -17,13 +17,9 @@ cmLocalCommonGenerator::cmLocalCommonGenerator(cmGlobalGenerator* gg,
: cmLocalGenerator(gg, mf)
, WorkingDirectory(std::move(wd))
{
- // Store the configuration name that will be generated.
- if (const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE")) {
- // Use the build type given by the user.
- this->ConfigName = config;
- } else {
- // No configuration type given.
- this->ConfigName.clear();
+ this->Makefile->GetConfigurations(this->ConfigNames);
+ if (this->ConfigNames.empty()) {
+ this->ConfigNames.emplace_back();
}
}
@@ -54,6 +50,15 @@ std::string cmLocalCommonGenerator::GetTargetFortranFlags(
this->Makefile->GetRequiredDefinition("CMAKE_Fortran_MODDIR_FLAG"),
mod_dir);
this->AppendFlags(flags, modflag);
+ // Some compilers do not search their own module output directory
+ // for using other modules. Add an include directory explicitly
+ // for consistency with compilers that do search it.
+ std::string incflag =
+ this->Makefile->GetSafeDefinition("CMAKE_Fortran_MODDIR_INCLUDE_FLAG");
+ if (!incflag.empty()) {
+ incflag = cmStrCat(incflag, mod_dir);
+ this->AppendFlags(flags, incflag);
+ }
}
// If there is a separate module path flag then duplicate the
diff --git a/Source/cmLocalCommonGenerator.h b/Source/cmLocalCommonGenerator.h
index eaef6ab..378ca63 100644
--- a/Source/cmLocalCommonGenerator.h
+++ b/Source/cmLocalCommonGenerator.h
@@ -7,6 +7,7 @@
#include <map>
#include <string>
+#include <vector>
#include "cmLocalGenerator.h"
@@ -25,7 +26,10 @@ public:
std::string wd);
~cmLocalCommonGenerator() override;
- std::string const& GetConfigName() const { return this->ConfigName; }
+ std::vector<std::string> const& GetConfigNames() const
+ {
+ return this->ConfigNames;
+ }
std::string GetWorkingDirectory() const { return this->WorkingDirectory; }
@@ -39,7 +43,7 @@ public:
protected:
std::string WorkingDirectory;
- std::string ConfigName;
+ std::vector<std::string> ConfigNames;
friend class cmCommonTargetGenerator;
};
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index af92e1b..f29c682 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -2,9 +2,23 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmLocalGenerator.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdio>
+#include <cstdlib>
+#include <initializer_list>
+#include <iterator>
+#include <sstream>
+#include <unordered_set>
+#include <utility>
+#include <vector>
+
+#include <cm/memory>
+#include <cm/string_view>
+#include <cmext/algorithm>
+
#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
@@ -19,7 +33,6 @@
#include "cmInstallScriptGenerator.h"
#include "cmInstallTargetGenerator.h"
#include "cmLinkLineComputer.h"
-#include "cmLinkLineDeviceComputer.h"
#include "cmMakefile.h"
#include "cmRulePlaceholderExpander.h"
#include "cmSourceFile.h"
@@ -40,20 +53,6 @@
# include "cmCryptoHash.h"
#endif
-#include <algorithm>
-#include <cassert>
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-#include <initializer_list>
-#include <iterator>
-#include <sstream>
-#include <unordered_set>
-#include <utility>
-#include <vector>
-
-#include <cm/string_view>
-
#if defined(__HAIKU__)
# include <FindDirectory.h>
# include <StorageDefs.h>
@@ -129,6 +128,28 @@ cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile)
this->LinkerSysroot = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT");
}
+ if (std::string const* appleArchSysroots =
+ this->Makefile->GetDef("CMAKE_APPLE_ARCH_SYSROOTS")) {
+ std::string const& appleArchs =
+ this->Makefile->GetSafeDefinition("CMAKE_OSX_ARCHITECTURES");
+ std::vector<std::string> archs;
+ std::vector<std::string> sysroots;
+ cmExpandList(appleArchs, archs);
+ cmExpandList(*appleArchSysroots, sysroots, true);
+ if (archs.size() == sysroots.size()) {
+ for (size_t i = 0; i < archs.size(); ++i) {
+ this->AppleArchSysroots[archs[i]] = sysroots[i];
+ }
+ } else {
+ std::string const e =
+ cmStrCat("CMAKE_APPLE_ARCH_SYSROOTS:\n ", *appleArchSysroots,
+ "\n"
+ "is not the same length as CMAKE_OSX_ARCHITECTURES:\n ",
+ appleArchs);
+ this->IssueMessage(MessageType::FATAL_ERROR, e);
+ }
+ }
+
for (std::string const& lang : enabledLanguages) {
if (lang == "NONE") {
continue;
@@ -181,11 +202,7 @@ cmRulePlaceholderExpander* cmLocalGenerator::CreateRulePlaceholderExpander()
this->LinkerSysroot);
}
-cmLocalGenerator::~cmLocalGenerator()
-{
- cmDeleteAll(this->GeneratorTargets);
- cmDeleteAll(this->OwnedImportedGeneratorTargets);
-}
+cmLocalGenerator::~cmLocalGenerator() = default;
void cmLocalGenerator::IssueMessage(MessageType t,
std::string const& text) const
@@ -263,8 +280,8 @@ static void MoveSystemIncludesToEnd(std::vector<BT<std::string>>& includeDirs,
void cmLocalGenerator::TraceDependencies()
{
// Generate the rule files for each target.
- const std::vector<cmGeneratorTarget*>& targets = this->GetGeneratorTargets();
- for (cmGeneratorTarget* target : targets) {
+ const auto& targets = this->GetGeneratorTargets();
+ for (const auto& target : targets) {
if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
@@ -290,36 +307,40 @@ void cmLocalGenerator::GenerateTestFiles()
cmGeneratedFileStream fout(file);
fout.SetCopyIfDifferent(true);
- fout << "# CMake generated Testfile for " << std::endl
- << "# Source directory: "
- << this->StateSnapshot.GetDirectory().GetCurrentSource() << std::endl
- << "# Build directory: "
- << this->StateSnapshot.GetDirectory().GetCurrentBinary() << std::endl
- << "# " << std::endl
- << "# This file includes the relevant testing commands "
- << "required for " << std::endl
- << "# testing this directory and lists subdirectories to "
- << "be tested as well." << std::endl;
-
- const char* testIncludeFile =
- this->Makefile->GetProperty("TEST_INCLUDE_FILE");
+ fout << "# CMake generated Testfile for \n"
+ "# Source directory: "
+ << this->StateSnapshot.GetDirectory().GetCurrentSource()
+ << "\n"
+ "# Build directory: "
+ << this->StateSnapshot.GetDirectory().GetCurrentBinary()
+ << "\n"
+ "# \n"
+ "# This file includes the relevant testing commands "
+ "required for \n"
+ "# testing this directory and lists subdirectories to "
+ "be tested as well.\n";
+
+ std::string resourceSpecFile =
+ this->Makefile->GetSafeDefinition("CTEST_RESOURCE_SPEC_FILE");
+ if (!resourceSpecFile.empty()) {
+ fout << "set(CTEST_RESOURCE_SPEC_FILE \"" << resourceSpecFile << "\")\n";
+ }
+
+ cmProp testIncludeFile = this->Makefile->GetProperty("TEST_INCLUDE_FILE");
if (testIncludeFile) {
- fout << "include(\"" << testIncludeFile << "\")" << std::endl;
+ fout << "include(\"" << *testIncludeFile << "\")\n";
}
- const char* testIncludeFiles =
- this->Makefile->GetProperty("TEST_INCLUDE_FILES");
+ cmProp testIncludeFiles = this->Makefile->GetProperty("TEST_INCLUDE_FILES");
if (testIncludeFiles) {
- std::vector<std::string> includesList = cmExpandedList(testIncludeFiles);
+ std::vector<std::string> includesList = cmExpandedList(*testIncludeFiles);
for (std::string const& i : includesList) {
- fout << "include(\"" << i << "\")" << std::endl;
+ fout << "include(\"" << i << "\")\n";
}
}
// Ask each test generator to write its code.
- std::vector<cmTestGenerator*> const& testers =
- this->Makefile->GetTestGenerators();
- for (cmTestGenerator* tester : testers) {
+ for (const auto& tester : this->Makefile->GetTestGenerators()) {
tester->Compute(this);
tester->Generate(fout, config, configurationTypes);
}
@@ -331,18 +352,18 @@ void cmLocalGenerator::GenerateTestFiles()
std::string outP = i.GetDirectory().GetCurrentBinary();
outP = this->MaybeConvertToRelativePath(parentBinDir, outP);
outP = cmOutputConverter::EscapeForCMake(outP);
- fout << "subdirs(" << outP << ")" << std::endl;
+ fout << "subdirs(" << outP << ")\n";
}
// Add directory labels property
const char* directoryLabels =
this->Makefile->GetDefinition("CMAKE_DIRECTORY_LABELS");
- const char* labels = this->Makefile->GetProperty("LABELS");
+ cmProp labels = this->Makefile->GetProperty("LABELS");
if (labels || directoryLabels) {
fout << "set_directory_properties(PROPERTIES LABELS ";
if (labels) {
- fout << cmOutputConverter::EscapeForCMake(labels);
+ fout << cmOutputConverter::EscapeForCMake(*labels);
}
if (labels && directoryLabels) {
fout << ";";
@@ -350,7 +371,7 @@ void cmLocalGenerator::GenerateTestFiles()
if (directoryLabels) {
fout << cmOutputConverter::EscapeForCMake(directoryLabels);
}
- fout << ")" << std::endl;
+ fout << ")\n";
}
}
@@ -365,9 +386,7 @@ void cmLocalGenerator::CreateEvaluationFileOutputs()
void cmLocalGenerator::CreateEvaluationFileOutputs(std::string const& config)
{
- std::vector<cmGeneratorExpressionEvaluationFile*> ef =
- this->Makefile->GetEvaluationFiles();
- for (cmGeneratorExpressionEvaluationFile* geef : ef) {
+ for (const auto& geef : this->Makefile->GetEvaluationFiles()) {
geef->CreateOutputFile(this, config);
}
}
@@ -375,8 +394,7 @@ void cmLocalGenerator::CreateEvaluationFileOutputs(std::string const& config)
void cmLocalGenerator::ProcessEvaluationFiles(
std::vector<std::string>& generatedFiles)
{
- for (cmGeneratorExpressionEvaluationFile* geef :
- this->Makefile->GetEvaluationFiles()) {
+ for (const auto& geef : this->Makefile->GetEvaluationFiles()) {
geef->Generate(this);
if (cmSystemTools::GetFatalErrorOccured()) {
return;
@@ -395,7 +413,7 @@ void cmLocalGenerator::ProcessEvaluationFiles(
return;
}
- cmAppend(generatedFiles, files);
+ cm::append(generatedFiles, files);
std::inplace_merge(generatedFiles.begin(),
generatedFiles.end() - files.size(),
generatedFiles.end());
@@ -474,16 +492,17 @@ void cmLocalGenerator::GenerateInstallRules()
fout.SetCopyIfDifferent(true);
// Write the header.
+ /* clang-format off */
fout << "# Install script for directory: "
- << this->StateSnapshot.GetDirectory().GetCurrentSource() << std::endl
- << std::endl;
- fout << "# Set the install prefix" << std::endl
- << "if(NOT DEFINED CMAKE_INSTALL_PREFIX)" << std::endl
- << " set(CMAKE_INSTALL_PREFIX \"" << prefix << "\")" << std::endl
- << "endif()" << std::endl
+ << this->StateSnapshot.GetDirectory().GetCurrentSource()
+ << "\n\n"
+ "# Set the install prefix\n"
+ "if(NOT DEFINED CMAKE_INSTALL_PREFIX)\n"
+ " set(CMAKE_INSTALL_PREFIX \"" << prefix << "\")\n"
+ "endif()\n"
<< R"(string(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX )"
- << "\"${CMAKE_INSTALL_PREFIX}\")" << std::endl
- << std::endl;
+ << "\"${CMAKE_INSTALL_PREFIX}\")\n\n";
+ /* clang-format on */
// Write support code for generating per-configuration install rules.
/* clang-format off */
@@ -557,20 +576,84 @@ void cmLocalGenerator::GenerateInstallRules()
/* clang-format on */
}
+ // Write out CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM so that
+ // installed code that uses `file(GET_RUNTIME_DEPENDENCIES)`
+ // has same platform variable as when running cmake
+ if (const char* platform = this->Makefile->GetDefinition(
+ "CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM")) {
+ /* clang-format off */
+ fout <<
+ "# Set default install directory permissions.\n"
+ "if(NOT DEFINED CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM)\n"
+ " set(CMAKE_GET_RUNTIME_DEPENDENCIES_PLATFORM \""
+ << platform << "\")\n"
+ "endif()\n"
+ "\n";
+ /* clang-format on */
+ }
+
+ // Write out CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL so that
+ // installed code that uses `file(GET_RUNTIME_DEPENDENCIES)`
+ // has same tool selected as when running cmake
+ if (const char* command =
+ this->Makefile->GetDefinition("CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL")) {
+ /* clang-format off */
+ fout <<
+ "# Set default install directory permissions.\n"
+ "if(NOT DEFINED CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL)\n"
+ " set(CMAKE_GET_RUNTIME_DEPENDENCIES_TOOL \""
+ << command << "\")\n"
+ "endif()\n"
+ "\n";
+ /* clang-format on */
+ }
+
+ // Write out CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND so that
+ // installed code that uses `file(GET_RUNTIME_DEPENDENCIES)`
+ // has same path to the tool as when running cmake
+ if (const char* command = this->Makefile->GetDefinition(
+ "CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND")) {
+ /* clang-format off */
+ fout <<
+ "# Set default install directory permissions.\n"
+ "if(NOT DEFINED CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND)\n"
+ " set(CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND \""
+ << command << "\")\n"
+ "endif()\n"
+ "\n";
+ /* clang-format on */
+ }
+
+ // Write out CMAKE_OBJDUMP so that installed code that uses
+ // `file(GET_RUNTIME_DEPENDENCIES)` and hasn't specified
+ // CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND has consistent
+ // logic to fallback to CMAKE_OBJDUMP when `objdump` is
+ // not on the path
+ if (const char* command = this->Makefile->GetDefinition("CMAKE_OBJDUMP")) {
+ /* clang-format off */
+ fout <<
+ "# Set default install directory permissions.\n"
+ "if(NOT DEFINED CMAKE_OBJDUMP)\n"
+ " set(CMAKE_OBJDUMP \""
+ << command << "\")\n"
+ "endif()\n"
+ "\n";
+ /* clang-format on */
+ }
+
// Ask each install generator to write its code.
cmPolicies::PolicyStatus status = this->GetPolicyStatus(cmPolicies::CMP0082);
- std::vector<cmInstallGenerator*> const& installers =
- this->Makefile->GetInstallGenerators();
+ auto const& installers = this->Makefile->GetInstallGenerators();
bool haveSubdirectoryInstall = false;
bool haveInstallAfterSubdirectory = false;
if (status == cmPolicies::WARN) {
- for (cmInstallGenerator* installer : installers) {
+ for (const auto& installer : installers) {
installer->CheckCMP0082(haveSubdirectoryInstall,
haveInstallAfterSubdirectory);
installer->Generate(fout, config, configurationTypes);
}
} else {
- for (cmInstallGenerator* installer : installers) {
+ for (const auto& installer : installers) {
installer->Generate(fout, config, configurationTypes);
}
}
@@ -599,8 +682,7 @@ void cmLocalGenerator::GenerateInstallRules()
if (!c.GetDirectory().GetPropertyAsBool("EXCLUDE_FROM_ALL")) {
std::string odir = c.GetDirectory().GetCurrentBinary();
cmSystemTools::ConvertToUnixSlashes(odir);
- fout << " include(\"" << odir << "/cmake_install.cmake\")"
- << std::endl;
+ fout << " include(\"" << odir << "/cmake_install.cmake\")\n";
}
}
fout << "\n";
@@ -635,11 +717,14 @@ void cmLocalGenerator::GenerateInstallRules()
}
}
-void cmLocalGenerator::AddGeneratorTarget(cmGeneratorTarget* gt)
+void cmLocalGenerator::AddGeneratorTarget(
+ std::unique_ptr<cmGeneratorTarget> gt)
{
- this->GeneratorTargets.push_back(gt);
- this->GeneratorTargetSearchIndex.emplace(gt->GetName(), gt);
- this->GlobalGenerator->IndexGeneratorTarget(gt);
+ cmGeneratorTarget* gt_ptr = gt.get();
+
+ this->GeneratorTargets.push_back(std::move(gt));
+ this->GeneratorTargetSearchIndex.emplace(gt_ptr->GetName(), gt_ptr);
+ this->GlobalGenerator->IndexGeneratorTarget(gt_ptr);
}
void cmLocalGenerator::AddImportedGeneratorTarget(cmGeneratorTarget* gt)
@@ -648,9 +733,10 @@ void cmLocalGenerator::AddImportedGeneratorTarget(cmGeneratorTarget* gt)
this->GlobalGenerator->IndexGeneratorTarget(gt);
}
-void cmLocalGenerator::AddOwnedImportedGeneratorTarget(cmGeneratorTarget* gt)
+void cmLocalGenerator::AddOwnedImportedGeneratorTarget(
+ std::unique_ptr<cmGeneratorTarget> gt)
{
- this->OwnedImportedGeneratorTargets.push_back(gt);
+ this->OwnedImportedGeneratorTargets.push_back(std::move(gt));
}
cmGeneratorTarget* cmLocalGenerator::FindLocalNonAliasGeneratorTarget(
@@ -673,8 +759,8 @@ void cmLocalGenerator::ComputeTargetManifest()
}
// Add our targets to the manifest for each configuration.
- const std::vector<cmGeneratorTarget*>& targets = this->GetGeneratorTargets();
- for (cmGeneratorTarget* target : targets) {
+ const auto& targets = this->GetGeneratorTargets();
+ for (const auto& target : targets) {
if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
@@ -695,17 +781,18 @@ bool cmLocalGenerator::ComputeTargetCompileFeatures()
using LanguagePair = std::pair<std::string, std::string>;
std::vector<LanguagePair> pairedLanguages{ { "OBJC", "C" },
- { "OBJCXX", "CXX" } };
- std::set<LanguagePair> objcEnabledLanguages;
+ { "OBJCXX", "CXX" },
+ { "CUDA", "CXX" } };
+ std::set<LanguagePair> inferredEnabledLanguages;
for (auto const& lang : pairedLanguages) {
if (this->Makefile->GetState()->GetLanguageEnabled(lang.first)) {
- objcEnabledLanguages.insert(lang);
+ inferredEnabledLanguages.insert(lang);
}
}
// Process compile features of all targets.
- const std::vector<cmGeneratorTarget*>& targets = this->GetGeneratorTargets();
- for (cmGeneratorTarget* target : targets) {
+ const auto& targets = this->GetGeneratorTargets();
+ for (const auto& target : targets) {
for (std::string const& c : configNames) {
if (!target->ComputeCompileFeatures(c)) {
return false;
@@ -717,14 +804,14 @@ bool cmLocalGenerator::ComputeTargetCompileFeatures()
if (target->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
auto copyStandardToObjLang = [&](LanguagePair const& lang) -> bool {
if (!target->GetProperty(cmStrCat(lang.first, "_STANDARD"))) {
- auto* standard =
+ cmProp standard =
target->GetProperty(cmStrCat(lang.second, "_STANDARD"));
if (!standard) {
- standard = this->Makefile->GetDefinition(
+ standard = this->Makefile->GetDef(
cmStrCat("CMAKE_", lang.second, "_STANDARD_DEFAULT"));
}
target->Target->SetProperty(cmStrCat(lang.first, "_STANDARD"),
- standard);
+ standard ? standard->c_str() : nullptr);
return true;
}
return false;
@@ -733,17 +820,22 @@ bool cmLocalGenerator::ComputeTargetCompileFeatures()
const char* property) {
if (!target->GetProperty(cmStrCat(lang.first, property)) &&
target->GetProperty(cmStrCat(lang.second, property))) {
- target->Target->SetProperty(
- cmStrCat(lang.first, property),
- target->GetProperty(cmStrCat(lang.second, property)));
+ cmProp p = target->GetProperty(cmStrCat(lang.second, property));
+ target->Target->SetProperty(cmStrCat(lang.first, property),
+ p ? p->c_str() : nullptr);
}
};
- for (auto const& lang : objcEnabledLanguages) {
+ for (auto const& lang : pairedLanguages) {
if (copyStandardToObjLang(lang)) {
copyPropertyToObjLang(lang, "_STANDARD_REQUIRED");
copyPropertyToObjLang(lang, "_EXTENSIONS");
}
}
+ if (cmProp standard = target->GetProperty("CUDA_STANDARD")) {
+ if (*standard == "98") {
+ target->Target->SetProperty("CUDA_STANDARD", "03");
+ }
+ }
}
}
@@ -768,10 +860,13 @@ cmStateSnapshot cmLocalGenerator::GetStateSnapshot() const
const char* cmLocalGenerator::GetRuleLauncher(cmGeneratorTarget* target,
const std::string& prop)
{
+ cmProp p;
if (target) {
- return target->GetProperty(prop);
+ p = target->GetProperty(prop);
+ } else {
+ p = this->Makefile->GetProperty(prop);
}
- return this->Makefile->GetProperty(prop);
+ return p ? p->c_str() : nullptr;
}
std::string cmLocalGenerator::ConvertToIncludeReference(
@@ -875,7 +970,7 @@ std::string cmLocalGenerator::GetIncludeFlags(
if ((sep[0] != ' ') && !flags.empty() && flags.back() == sep[0]) {
flags.back() = ' ';
}
- return flags;
+ return cmTrimWhitespace(flags);
}
void cmLocalGenerator::AddCompileOptions(std::string& flags,
@@ -898,9 +993,9 @@ void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags,
if (const char* langFlagRegexStr =
this->Makefile->GetDefinition(langFlagRegexVar)) {
// Filter flags acceptable to this language.
- if (const char* targetFlags = target->GetProperty("COMPILE_FLAGS")) {
+ if (cmProp targetFlags = target->GetProperty("COMPILE_FLAGS")) {
std::vector<std::string> opts;
- cmSystemTools::ParseWindowsCommandLine(targetFlags, opts);
+ cmSystemTools::ParseWindowsCommandLine(targetFlags->c_str(), opts);
// Re-escape these flags since COMPILE_FLAGS were already parsed
// as a command line above.
std::string compileOpts;
@@ -915,10 +1010,10 @@ void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags,
this->AppendCompileOptions(flags, targetCompileOpts, langFlagRegexStr);
} else {
// Use all flags.
- if (const char* targetFlags = target->GetProperty("COMPILE_FLAGS")) {
+ if (cmProp targetFlags = target->GetProperty("COMPILE_FLAGS")) {
// COMPILE_FLAGS are not escaped for historical reasons.
std::string compileFlags;
- this->AppendFlags(compileFlags, targetFlags);
+ this->AppendFlags(compileFlags, *targetFlags);
if (!compileFlags.empty()) {
flags.emplace_back(std::move(compileFlags));
}
@@ -930,11 +1025,11 @@ void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags,
}
for (auto const& it : target->GetMaxLanguageStandards()) {
- const char* standard = target->GetProperty(it.first + "_STANDARD");
+ cmProp standard = target->GetProperty(it.first + "_STANDARD");
if (!standard) {
continue;
}
- if (this->Makefile->IsLaterStandard(it.first, standard, it.second)) {
+ if (this->Makefile->IsLaterStandard(it.first, *standard, it.second)) {
std::ostringstream e;
e << "The COMPILE_FEATURES property of target \"" << target->GetName()
<< "\" was evaluated when computing the link "
@@ -943,12 +1038,11 @@ void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags,
<< "\" for that computation. Computing the "
"COMPILE_FEATURES based on the link implementation resulted in a "
"higher \""
- << it.first << "_STANDARD\" \"" << standard
+ << it.first << "_STANDARD\" \"" << *standard
<< "\". "
"This is not permitted. The COMPILE_FEATURES may not both depend "
"on "
- "and be depended on by the link implementation."
- << std::endl;
+ "and be depended on by the link implementation.\n";
this->IssueMessage(MessageType::FATAL_ERROR, e.str());
return;
}
@@ -971,10 +1065,10 @@ void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags,
cmGeneratorTarget::ManagedType::Managed) {
// add /JMC flags if target property VS_JUST_MY_CODE_DEBUGGING is set
// to ON
- if (char const* jmcExprGen =
+ if (cmProp jmcExprGen =
target->GetProperty("VS_JUST_MY_CODE_DEBUGGING")) {
std::string isJMCEnabled =
- cmGeneratorExpression::Evaluate(jmcExprGen, this, config);
+ cmGeneratorExpression::Evaluate(*jmcExprGen, this, config);
if (cmIsOn(isJMCEnabled)) {
std::vector<std::string> optVec = cmExpandedList(jmc);
std::string jmcFlags;
@@ -988,6 +1082,92 @@ void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags,
}
}
+cmTarget* cmLocalGenerator::AddCustomCommandToTarget(
+ const std::string& target, const std::vector<std::string>& byproducts,
+ const std::vector<std::string>& depends,
+ const cmCustomCommandLines& commandLines, cmCustomCommandType type,
+ const char* comment, const char* workingDir, bool escapeOldStyle,
+ bool uses_terminal, const std::string& depfile, const std::string& job_pool,
+ bool command_expand_lists, cmObjectLibraryCommands objLibCommands,
+ bool stdPipesUTF8)
+{
+ cmTarget* t = this->Makefile->GetCustomCommandTarget(
+ target, objLibCommands, this->DirectoryBacktrace);
+ if (!t) {
+ return nullptr;
+ }
+
+ detail::AddCustomCommandToTarget(
+ *this, this->DirectoryBacktrace, cmCommandOrigin::Generator, t, byproducts,
+ depends, commandLines, type, comment, workingDir, escapeOldStyle,
+ uses_terminal, depfile, job_pool, command_expand_lists, stdPipesUTF8);
+
+ return t;
+}
+
+cmSourceFile* cmLocalGenerator::AddCustomCommandToOutput(
+ const std::string& output, const std::vector<std::string>& depends,
+ const std::string& main_dependency, const cmCustomCommandLines& commandLines,
+ const char* comment, const char* workingDir, bool replace,
+ bool escapeOldStyle, bool uses_terminal, bool command_expand_lists,
+ const std::string& depfile, const std::string& job_pool, bool stdPipesUTF8)
+{
+ std::vector<std::string> no_byproducts;
+ cmImplicitDependsList no_implicit_depends;
+ return this->AddCustomCommandToOutput(
+ { output }, no_byproducts, depends, main_dependency, no_implicit_depends,
+ commandLines, comment, workingDir, replace, escapeOldStyle, uses_terminal,
+ command_expand_lists, depfile, job_pool, stdPipesUTF8);
+}
+
+cmSourceFile* cmLocalGenerator::AddCustomCommandToOutput(
+ const std::vector<std::string>& outputs,
+ const std::vector<std::string>& byproducts,
+ const std::vector<std::string>& depends, const std::string& main_dependency,
+ const cmImplicitDependsList& implicit_depends,
+ const cmCustomCommandLines& commandLines, const char* comment,
+ const char* workingDir, bool replace, bool escapeOldStyle,
+ bool uses_terminal, bool command_expand_lists, const std::string& depfile,
+ const std::string& job_pool, bool stdPipesUTF8)
+{
+ // Make sure there is at least one output.
+ if (outputs.empty()) {
+ cmSystemTools::Error("Attempt to add a custom rule with no output!");
+ return nullptr;
+ }
+
+ return detail::AddCustomCommandToOutput(
+ *this, this->DirectoryBacktrace, cmCommandOrigin::Generator, outputs,
+ byproducts, depends, main_dependency, implicit_depends, commandLines,
+ comment, workingDir, replace, escapeOldStyle, uses_terminal,
+ command_expand_lists, depfile, job_pool, stdPipesUTF8);
+}
+
+cmTarget* cmLocalGenerator::AddUtilityCommand(
+ const std::string& utilityName, bool excludeFromAll, const char* workingDir,
+ const std::vector<std::string>& byproducts,
+ const std::vector<std::string>& depends,
+ const cmCustomCommandLines& commandLines, bool escapeOldStyle,
+ const char* comment, bool uses_terminal, bool command_expand_lists,
+ const std::string& job_pool, bool stdPipesUTF8)
+{
+ cmTarget* target =
+ this->Makefile->AddNewUtilityTarget(utilityName, excludeFromAll);
+ target->SetIsGeneratorProvided(true);
+
+ if (commandLines.empty() && depends.empty()) {
+ return target;
+ }
+
+ detail::AddUtilityCommand(
+ *this, this->DirectoryBacktrace, cmCommandOrigin::Generator, target,
+ this->Makefile->GetUtilityOutput(target), workingDir, byproducts, depends,
+ commandLines, escapeOldStyle, comment, uses_terminal, command_expand_lists,
+ job_pool, stdPipesUTF8);
+
+ return target;
+}
+
std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit(
cmGeneratorTarget const* target, std::string const& lang,
std::string const& config, bool stripImplicitDirs,
@@ -1074,7 +1254,7 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit(
// directly. In this case adding -I/usr/include can hide SDK headers so we
// must still exclude it.
if ((lang == "C" || lang == "CXX" || lang == "CUDA") &&
- !cmContains(impDirVec, "/usr/include") &&
+ !cm::contains(impDirVec, "/usr/include") &&
std::find_if(impDirVec.begin(), impDirVec.end(),
[](std::string const& d) {
return cmHasLiteralSuffix(d, "/usr/include");
@@ -1084,7 +1264,7 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit(
}
for (std::string const& i : impDirVec) {
- if (implicitSet.insert(cmSystemTools::GetRealPath(i)).second) {
+ if (implicitSet.insert(this->GlobalGenerator->GetRealPath(i)).second) {
implicitDirs.emplace_back(i);
}
}
@@ -1095,13 +1275,14 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit(
&lang](std::string const& dir) {
return (
// Do not exclude directories that are not in an excluded set.
- ((!cmContains(implicitSet, cmSystemTools::GetRealPath(dir))) &&
- (!cmContains(implicitExclude, dir)))
+ ((!cm::contains(implicitSet, this->GlobalGenerator->GetRealPath(dir))) &&
+ (!cm::contains(implicitExclude, dir)))
// Do not exclude entries of the CPATH environment variable even though
// they are implicitly searched by the compiler. They are meant to be
// user-specified directories that can be re-ordered or converted to
// -isystem without breaking real compiler builtin headers.
- || ((lang == "C" || lang == "CXX") && cmContains(this->EnvCPATH, dir)));
+ ||
+ ((lang == "C" || lang == "CXX") && cm::contains(this->EnvCPATH, dir)));
};
// Get the target-specific include directories.
@@ -1148,7 +1329,7 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit(
if (!stripImplicitDirs) {
// Append implicit directories that were requested by the user only
for (BT<std::string> const& udr : userDirs) {
- if (cmContains(implicitSet, cmSystemTools::GetRealPath(udr.Value))) {
+ if (cm::contains(implicitSet, cmSystemTools::GetRealPath(udr.Value))) {
emitBT(udr);
}
}
@@ -1205,14 +1386,15 @@ std::vector<BT<std::string>> cmLocalGenerator::GetStaticLibraryFlags(
std::string const& config, std::string const& linkLanguage,
cmGeneratorTarget* target)
{
+ const std::string configUpper = cmSystemTools::UpperCase(config);
std::vector<BT<std::string>> flags;
if (linkLanguage != "Swift") {
std::string staticLibFlags;
this->AppendFlags(
staticLibFlags,
this->Makefile->GetSafeDefinition("CMAKE_STATIC_LINKER_FLAGS"));
- if (!config.empty()) {
- std::string name = "CMAKE_STATIC_LINKER_FLAGS_" + config;
+ if (!configUpper.empty()) {
+ std::string name = "CMAKE_STATIC_LINKER_FLAGS_" + configUpper;
this->AppendFlags(staticLibFlags,
this->Makefile->GetSafeDefinition(name));
}
@@ -1224,8 +1406,8 @@ std::vector<BT<std::string>> cmLocalGenerator::GetStaticLibraryFlags(
std::string staticLibFlags;
this->AppendFlags(staticLibFlags,
target->GetSafeProperty("STATIC_LIBRARY_FLAGS"));
- if (!config.empty()) {
- std::string name = "STATIC_LIBRARY_FLAGS_" + config;
+ if (!configUpper.empty()) {
+ std::string name = "STATIC_LIBRARY_FLAGS_" + configUpper;
this->AppendFlags(staticLibFlags, target->GetSafeProperty(name));
}
@@ -1241,6 +1423,30 @@ std::vector<BT<std::string>> cmLocalGenerator::GetStaticLibraryFlags(
return flags;
}
+void cmLocalGenerator::GetDeviceLinkFlags(
+ cmLinkLineComputer* linkLineComputer, const std::string& config,
+ std::string& linkLibs, std::string& linkFlags, std::string& frameworkPath,
+ std::string& linkPath, cmGeneratorTarget* target)
+{
+ cmGeneratorTarget::DeviceLinkSetter setter(*target);
+
+ cmComputeLinkInformation* pcli = target->GetLinkInformation(config);
+ const std::string linkLanguage =
+ linkLineComputer->GetLinkerLanguage(target, config);
+
+ if (pcli) {
+ // Compute the required cuda device link libraries when
+ // resolving cuda device symbols
+ this->OutputLinkLibraries(pcli, linkLineComputer, linkLibs, frameworkPath,
+ linkPath);
+ }
+
+ std::vector<std::string> linkOpts;
+ target->GetLinkOptions(linkOpts, config, linkLanguage);
+ // LINK_OPTIONS are escaped.
+ this->AppendCompileOptions(linkFlags, linkOpts);
+}
+
void cmLocalGenerator::GetTargetFlags(
cmLinkLineComputer* linkLineComputer, const std::string& config,
std::string& linkLibs, std::string& flags, std::string& linkFlags,
@@ -1262,23 +1468,17 @@ void cmLocalGenerator::GetTargetFlags(
std::vector<BT<std::string>>& linkFlags, std::string& frameworkPath,
std::vector<BT<std::string>>& linkPath, cmGeneratorTarget* target)
{
- const std::string buildType = cmSystemTools::UpperCase(config);
+ const std::string configUpper = cmSystemTools::UpperCase(config);
cmComputeLinkInformation* pcli = target->GetLinkInformation(config);
const char* libraryLinkVariable =
"CMAKE_SHARED_LINKER_FLAGS"; // default to shared library
const std::string linkLanguage =
- linkLineComputer->GetLinkerLanguage(target, buildType);
+ linkLineComputer->GetLinkerLanguage(target, config);
switch (target->GetType()) {
case cmStateEnums::STATIC_LIBRARY:
- linkFlags = this->GetStaticLibraryFlags(buildType, linkLanguage, target);
- if (pcli && dynamic_cast<cmLinkLineDeviceComputer*>(linkLineComputer)) {
- // Compute the required cuda device link libraries when
- // resolving cuda device symbols
- this->OutputLinkLibraries(pcli, linkLineComputer, linkLibs,
- frameworkPath, linkPath);
- }
+ linkFlags = this->GetStaticLibraryFlags(config, linkLanguage, target);
break;
case cmStateEnums::MODULE_LIBRARY:
libraryLinkVariable = "CMAKE_MODULE_LINKER_FLAGS";
@@ -1288,8 +1488,8 @@ void cmLocalGenerator::GetTargetFlags(
if (linkLanguage != "Swift") {
sharedLibFlags = cmStrCat(
this->Makefile->GetSafeDefinition(libraryLinkVariable), ' ');
- if (!buildType.empty()) {
- std::string build = cmStrCat(libraryLinkVariable, '_', buildType);
+ if (!configUpper.empty()) {
+ std::string build = cmStrCat(libraryLinkVariable, '_', configUpper);
sharedLibFlags += this->Makefile->GetSafeDefinition(build);
sharedLibFlags += " ";
}
@@ -1297,30 +1497,30 @@ void cmLocalGenerator::GetTargetFlags(
!(this->Makefile->IsOn("CYGWIN") ||
this->Makefile->IsOn("MINGW"))) {
std::vector<cmSourceFile*> sources;
- target->GetSourceFiles(sources, buildType);
+ target->GetSourceFiles(sources, config);
std::string defFlag =
this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG");
for (cmSourceFile* sf : sources) {
if (sf->GetExtension() == "def") {
sharedLibFlags += defFlag;
- sharedLibFlags += this->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(sf->ResolveFullPath()), SHELL);
+ sharedLibFlags +=
+ this->ConvertToOutputFormat(sf->ResolveFullPath(), SHELL);
sharedLibFlags += " ";
}
}
}
}
- const char* targetLinkFlags = target->GetProperty("LINK_FLAGS");
+ cmProp targetLinkFlags = target->GetProperty("LINK_FLAGS");
if (targetLinkFlags) {
- sharedLibFlags += targetLinkFlags;
+ sharedLibFlags += *targetLinkFlags;
sharedLibFlags += " ";
}
- if (!buildType.empty()) {
+ if (!configUpper.empty()) {
targetLinkFlags =
- target->GetProperty(cmStrCat("LINK_FLAGS_", buildType));
+ target->GetProperty(cmStrCat("LINK_FLAGS_", configUpper));
if (targetLinkFlags) {
- sharedLibFlags += targetLinkFlags;
+ sharedLibFlags += *targetLinkFlags;
sharedLibFlags += " ";
}
}
@@ -1343,9 +1543,9 @@ void cmLocalGenerator::GetTargetFlags(
if (linkLanguage != "Swift") {
exeFlags = this->Makefile->GetSafeDefinition("CMAKE_EXE_LINKER_FLAGS");
exeFlags += " ";
- if (!buildType.empty()) {
+ if (!configUpper.empty()) {
exeFlags += this->Makefile->GetSafeDefinition(
- cmStrCat("CMAKE_EXE_LINKER_FLAGS_", buildType));
+ cmStrCat("CMAKE_EXE_LINKER_FLAGS_", configUpper));
exeFlags += " ";
}
if (linkLanguage.empty()) {
@@ -1372,7 +1572,7 @@ void cmLocalGenerator::GetTargetFlags(
}
}
- this->AddLanguageFlagsForLinking(flags, target, linkLanguage, buildType);
+ this->AddLanguageFlagsForLinking(flags, target, linkLanguage, config);
if (pcli) {
this->OutputLinkLibraries(pcli, linkLineComputer, linkLibs,
frameworkPath, linkPath);
@@ -1392,16 +1592,16 @@ void cmLocalGenerator::GetTargetFlags(
exeFlags += " ";
}
- const char* targetLinkFlags = target->GetProperty("LINK_FLAGS");
+ cmProp targetLinkFlags = target->GetProperty("LINK_FLAGS");
if (targetLinkFlags) {
- exeFlags += targetLinkFlags;
+ exeFlags += *targetLinkFlags;
exeFlags += " ";
}
- if (!buildType.empty()) {
+ if (!configUpper.empty()) {
targetLinkFlags =
- target->GetProperty(cmStrCat("LINK_FLAGS_", buildType));
+ target->GetProperty(cmStrCat("LINK_FLAGS_", configUpper));
if (targetLinkFlags) {
- exeFlags += targetLinkFlags;
+ exeFlags += *targetLinkFlags;
exeFlags += " ";
}
}
@@ -1432,16 +1632,17 @@ void cmLocalGenerator::GetTargetFlags(
void cmLocalGenerator::GetTargetCompileFlags(cmGeneratorTarget* target,
std::string const& config,
std::string const& lang,
- std::string& flags)
+ std::string& flags,
+ std::string const& arch)
{
std::vector<BT<std::string>> tmpFlags =
- this->GetTargetCompileFlags(target, config, lang);
+ this->GetTargetCompileFlags(target, config, lang, arch);
this->AppendFlags(flags, tmpFlags);
}
std::vector<BT<std::string>> cmLocalGenerator::GetTargetCompileFlags(
cmGeneratorTarget* target, std::string const& config,
- std::string const& lang)
+ std::string const& lang, std::string const& arch)
{
std::vector<BT<std::string>> flags;
std::string compileFlags;
@@ -1455,7 +1656,7 @@ std::vector<BT<std::string>> cmLocalGenerator::GetTargetCompileFlags(
this->AppendFeatureOptions(compileFlags, lang, "IPO");
}
- this->AddArchitectureFlags(compileFlags, target, lang, config);
+ this->AddArchitectureFlags(compileFlags, target, lang, config, arch);
if (lang == "Fortran") {
this->AppendFlags(compileFlags,
@@ -1644,10 +1845,10 @@ std::string cmLocalGenerator::GetLinkLibsCMP0065(
"CMAKE_POLICY_WARNING_CMP0065")) {
std::ostringstream w;
/* clang-format off */
- w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0065) << "\n"
- "For compatibility with older versions of CMake, "
- "additional flags may be added to export symbols on all "
- "executables regardless of their ENABLE_EXPORTS property.";
+ w << cmPolicies::GetPolicyWarning(cmPolicies::CMP0065) << "\n"
+ "For compatibility with older versions of CMake, "
+ "additional flags may be added to export symbols on all "
+ "executables regardless of their ENABLE_EXPORTS property.";
/* clang-format on */
this->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
}
@@ -1680,15 +1881,46 @@ std::string cmLocalGenerator::GetLinkLibsCMP0065(
return linkFlags;
}
+bool cmLocalGenerator::AllAppleArchSysrootsAreTheSame(
+ const std::vector<std::string>& archs, const char* sysroot)
+{
+ if (!sysroot) {
+ return false;
+ }
+
+ for (std::string const& arch : archs) {
+ std::string const& archSysroot = this->AppleArchSysroots[arch];
+ if (cmIsOff(archSysroot)) {
+ continue;
+ }
+ if (archSysroot != sysroot) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
void cmLocalGenerator::AddArchitectureFlags(std::string& flags,
cmGeneratorTarget const* target,
const std::string& lang,
- const std::string& config)
+ const std::string& config,
+ const std::string& filterArch)
{
- // Only add macOS specific flags on Darwin platforms (macOS and iOS):
+ // Only add Apple specific flags on Apple platforms
if (this->Makefile->IsOn("APPLE") && this->EmitUniversalBinaryFlags) {
std::vector<std::string> archs;
target->GetAppleArchs(config, archs);
+ if (!archs.empty() && !lang.empty() &&
+ (lang[0] == 'C' || lang[0] == 'F' || lang[0] == 'O')) {
+ for (std::string const& arch : archs) {
+ if (filterArch.empty() || filterArch == arch) {
+ flags += " -arch ";
+ flags += arch;
+ }
+ }
+ }
+
const char* sysroot = this->Makefile->GetDefinition("CMAKE_OSX_SYSROOT");
if (sysroot && sysroot[0] == '/' && !sysroot[1]) {
sysroot = nullptr;
@@ -1696,27 +1928,35 @@ void cmLocalGenerator::AddArchitectureFlags(std::string& flags,
std::string sysrootFlagVar =
std::string("CMAKE_") + lang + "_SYSROOT_FLAG";
const char* sysrootFlag = this->Makefile->GetDefinition(sysrootFlagVar);
+ if (sysrootFlag && *sysrootFlag) {
+ if (!this->AppleArchSysroots.empty() &&
+ !this->AllAppleArchSysrootsAreTheSame(archs, sysroot)) {
+ for (std::string const& arch : archs) {
+ std::string const& archSysroot = this->AppleArchSysroots[arch];
+ if (cmIsOff(archSysroot)) {
+ continue;
+ }
+ if (filterArch.empty() || filterArch == arch) {
+ flags += " -Xarch_" + arch + " ";
+ // Combine sysroot flag and path to work with -Xarch
+ std::string arch_sysroot = sysrootFlag + archSysroot;
+ flags += this->ConvertToOutputFormat(arch_sysroot, SHELL);
+ }
+ }
+ } else if (sysroot && *sysroot) {
+ flags += " ";
+ flags += sysrootFlag;
+ flags += " ";
+ flags += this->ConvertToOutputFormat(sysroot, SHELL);
+ }
+ }
+
const char* deploymentTarget =
this->Makefile->GetDefinition("CMAKE_OSX_DEPLOYMENT_TARGET");
std::string deploymentTargetFlagVar =
std::string("CMAKE_") + lang + "_OSX_DEPLOYMENT_TARGET_FLAG";
const char* deploymentTargetFlag =
this->Makefile->GetDefinition(deploymentTargetFlagVar);
- if (!archs.empty() && !lang.empty() &&
- (lang[0] == 'C' || lang[0] == 'F' || lang[0] == 'O')) {
- for (std::string const& arch : archs) {
- flags += " -arch ";
- flags += arch;
- }
- }
-
- if (sysrootFlag && *sysrootFlag && sysroot && *sysroot) {
- flags += " ";
- flags += sysrootFlag;
- flags += " ";
- flags += this->ConvertToOutputFormat(sysroot, SHELL);
- }
-
if (deploymentTargetFlag && *deploymentTargetFlag && deploymentTarget &&
*deploymentTarget) {
flags += " ";
@@ -1736,28 +1976,30 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags,
config);
if (lang == "Swift") {
- if (const char* v = target->GetProperty("Swift_LANGUAGE_VERSION")) {
+ if (cmProp v = target->GetProperty("Swift_LANGUAGE_VERSION")) {
if (cmSystemTools::VersionCompare(
cmSystemTools::OP_GREATER_EQUAL,
this->Makefile->GetDefinition("CMAKE_Swift_COMPILER_VERSION"),
"4.2")) {
- this->AppendFlags(flags, "-swift-version " + std::string(v));
+ this->AppendFlags(flags, "-swift-version " + *v);
}
}
+ } else if (lang == "CUDA") {
+ target->AddCUDAArchitectureFlags(flags);
}
// Add MSVC runtime library flags. This is activated by the presence
// of a default selection whether or not it is overridden by a property.
- const char* msvcRuntimeLibraryDefault =
- this->Makefile->GetDefinition("CMAKE_MSVC_RUNTIME_LIBRARY_DEFAULT");
- if (msvcRuntimeLibraryDefault && *msvcRuntimeLibraryDefault) {
- const char* msvcRuntimeLibraryValue =
+ cmProp msvcRuntimeLibraryDefault =
+ this->Makefile->GetDef("CMAKE_MSVC_RUNTIME_LIBRARY_DEFAULT");
+ if (msvcRuntimeLibraryDefault && !msvcRuntimeLibraryDefault->empty()) {
+ cmProp msvcRuntimeLibraryValue =
target->GetProperty("MSVC_RUNTIME_LIBRARY");
if (!msvcRuntimeLibraryValue) {
msvcRuntimeLibraryValue = msvcRuntimeLibraryDefault;
}
std::string const msvcRuntimeLibrary = cmGeneratorExpression::Evaluate(
- msvcRuntimeLibraryValue, this, config, target);
+ *msvcRuntimeLibraryValue, this, config, target);
if (!msvcRuntimeLibrary.empty()) {
if (const char* msvcRuntimeLibraryOptions =
this->Makefile->GetDefinition(
@@ -1830,7 +2072,6 @@ bool cmLocalGenerator::GetRealDependency(const std::string& inName,
if (name.empty()) {
return false;
}
-
if (cmSystemTools::GetFilenameLastExtension(name) == ".exe") {
name = cmSystemTools::GetFilenameWithoutLastExtension(name);
}
@@ -1864,16 +2105,15 @@ bool cmLocalGenerator::GetRealDependency(const std::string& inName,
case cmStateEnums::SHARED_LIBRARY:
case cmStateEnums::MODULE_LIBRARY:
case cmStateEnums::UNKNOWN_LIBRARY:
- dep = target->GetLocation(config);
+ dep = target->GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact,
+ /*realname=*/true);
return true;
case cmStateEnums::OBJECT_LIBRARY:
// An object library has no single file on which to depend.
// This was listed to get the target-level dependency.
- return false;
case cmStateEnums::INTERFACE_LIBRARY:
// An interface library has no file on which to depend.
// This was listed to get the target-level dependency.
- return false;
case cmStateEnums::UTILITY:
case cmStateEnums::GLOBAL_TARGET:
// A utility target has no file on which to depend. This was listed
@@ -1898,8 +2138,16 @@ bool cmLocalGenerator::GetRealDependency(const std::string& inName,
// Treat the name as relative to the source directory in which it
// was given.
- dep = cmStrCat(this->StateSnapshot.GetDirectory().GetCurrentSource(), '/',
- inName);
+ dep = cmStrCat(this->GetCurrentSourceDirectory(), '/', inName);
+
+ // If the in-source path does not exist, assume it instead lives in the
+ // binary directory.
+ if (!cmSystemTools::FileExists(dep)) {
+ dep = cmStrCat(this->GetCurrentBinaryDirectory(), '/', inName);
+ }
+
+ dep = cmSystemTools::CollapseFullPath(dep, this->GetBinaryDirectory());
+
return true;
}
@@ -1930,13 +2178,13 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
}
std::string extProp = lang + "_EXTENSIONS";
bool ext = true;
- if (const char* extPropValue = target->GetProperty(extProp)) {
- if (cmIsOff(extPropValue)) {
+ if (cmProp extPropValue = target->GetProperty(extProp)) {
+ if (cmIsOff(*extPropValue)) {
ext = false;
}
}
std::string stdProp = lang + "_STANDARD";
- const char* standardProp = target->GetProperty(stdProp);
+ cmProp standardProp = target->GetProperty(stdProp);
if (!standardProp) {
if (ext) {
// No language standard is specified and extensions are not disabled.
@@ -1958,7 +2206,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
if (target->GetPropertyAsBool(lang + "_STANDARD_REQUIRED")) {
std::string option_flag =
- "CMAKE_" + lang + standardProp + "_" + type + "_COMPILE_OPTION";
+ "CMAKE_" + lang + *standardProp + "_" + type + "_COMPILE_OPTION";
const char* opt =
target->Target->GetMakefile()->GetDefinition(option_flag);
@@ -1967,7 +2215,7 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
e << "Target \"" << target->GetName()
<< "\" requires the language "
"dialect \""
- << lang << standardProp << "\" "
+ << lang << *standardProp << "\" "
<< (ext ? "(with compiler extensions)" : "")
<< ", but CMake "
"does not know the compile flags to use to enable it.";
@@ -2004,17 +2252,22 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
langStdMap["OBJC"].emplace_back("99");
langStdMap["OBJC"].emplace_back("90");
+ langStdMap["CUDA"].emplace_back("20");
+ langStdMap["CUDA"].emplace_back("17");
langStdMap["CUDA"].emplace_back("14");
langStdMap["CUDA"].emplace_back("11");
- langStdMap["CUDA"].emplace_back("98");
+ langStdMap["CUDA"].emplace_back("03");
}
- std::string standard(standardProp);
-
+ std::string standard(*standardProp);
+ if (lang == "CUDA" && standard == "98") {
+ standard = "03";
+ }
std::vector<std::string>& stds = langStdMap[lang];
auto stdIt = std::find(stds.begin(), stds.end(), standard);
if (stdIt == stds.end()) {
+
std::string e =
lang + "_STANDARD is set to invalid value '" + standard + "'";
this->GetGlobalGenerator()->GetCMakeInstance()->IssueMessage(
@@ -2079,7 +2332,7 @@ static void AddVisibilityCompileOption(std::string& flags,
}
std::string flagDefine = lang + "_VISIBILITY_PRESET";
- const char* prop = target->GetProperty(flagDefine);
+ cmProp prop = target->GetProperty(flagDefine);
if (!prop) {
return;
}
@@ -2087,17 +2340,17 @@ static void AddVisibilityCompileOption(std::string& flags,
*warnCMP0063 += " " + flagDefine + "\n";
return;
}
- if (strcmp(prop, "hidden") != 0 && strcmp(prop, "default") != 0 &&
- strcmp(prop, "protected") != 0 && strcmp(prop, "internal") != 0) {
+ if ((*prop != "hidden") && (*prop != "default") && (*prop != "protected") &&
+ (*prop != "internal")) {
std::ostringstream e;
- e << "Target " << target->GetName() << " uses unsupported value \"" << prop
- << "\" for " << flagDefine << "."
+ e << "Target " << target->GetName() << " uses unsupported value \""
+ << *prop << "\" for " << flagDefine << "."
<< " The supported values are: default, hidden, protected, and "
"internal.";
cmSystemTools::Error(e.str());
return;
}
- std::string option = std::string(opt) + prop;
+ std::string option = opt + *prop;
lg->AppendFlags(flags, option);
}
@@ -2277,7 +2530,9 @@ void cmLocalGenerator::AddConfigVariableFlags(std::string& flags,
void cmLocalGenerator::AppendFlags(std::string& flags,
const std::string& newFlags) const
{
- if (!newFlags.empty()) {
+ bool allSpaces = std::all_of(newFlags.begin(), newFlags.end(), cmIsSpace);
+
+ if (!newFlags.empty() && !allSpaces) {
if (!flags.empty()) {
flags += " ";
}
@@ -2296,176 +2551,325 @@ void cmLocalGenerator::AppendFlags(
void cmLocalGenerator::AppendFlagEscape(std::string& flags,
const std::string& rawFlag) const
{
- this->AppendFlags(flags, this->EscapeForShell(rawFlag));
+ this->AppendFlags(
+ flags,
+ this->EscapeForShell(rawFlag, false, false, false, this->IsNinjaMulti()));
}
void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
{
- // FIXME: Handle all configurations in multi-config generators.
- std::string config;
- if (!this->GetGlobalGenerator()->IsMultiConfig()) {
- config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
- }
+ std::vector<std::string> configsList;
+ std::string configDefault = this->Makefile->GetConfigurations(configsList);
+ if (configsList.empty()) {
+ configsList.push_back(configDefault);
+ }
+
+ for (std::string const& config : configsList) {
+ // FIXME: Refactor collection of sources to not evaluate object libraries.
+ std::vector<cmSourceFile*> sources;
+ target->GetSourceFiles(sources, config);
+
+ for (const std::string& lang : { "C", "CXX", "OBJC", "OBJCXX" }) {
+ auto langSources = std::count_if(
+ sources.begin(), sources.end(), [lang](cmSourceFile* sf) {
+ return lang == sf->GetLanguage() &&
+ !sf->GetProperty("SKIP_PRECOMPILE_HEADERS");
+ });
+ if (langSources == 0) {
+ continue;
+ }
- // FIXME: Refactor collection of sources to not evaluate object libraries.
- std::vector<cmSourceFile*> sources;
- target->GetSourceFiles(sources, config);
+ std::vector<std::string> architectures;
+ if (!this->GetGlobalGenerator()->IsXcode()) {
+ target->GetAppleArchs(config, architectures);
+ }
+ if (architectures.empty()) {
+ architectures.emplace_back();
+ } else {
+ std::string useMultiArchPch;
+ for (const std::string& arch : architectures) {
+ const std::string pchHeader =
+ target->GetPchHeader(config, lang, arch);
+ if (!pchHeader.empty()) {
+ useMultiArchPch = cmStrCat(useMultiArchPch, ";-Xarch_", arch,
+ ";-include", pchHeader);
+ }
+ }
- for (const std::string& lang : { "C", "CXX", "OBJC", "OBJCXX" }) {
- auto langSources =
- std::count_if(sources.begin(), sources.end(), [lang](cmSourceFile* sf) {
- return lang == sf->GetLanguage() &&
- !sf->GetProperty("SKIP_PRECOMPILE_HEADERS");
- });
- if (langSources == 0) {
- continue;
- }
+ if (!useMultiArchPch.empty()) {
+ target->Target->SetProperty(
+ cmStrCat(lang, "_COMPILE_OPTIONS_USE_PCH"), useMultiArchPch);
+ }
+ }
- const std::string pchSource = target->GetPchSource(config, lang);
- const std::string pchHeader = target->GetPchHeader(config, lang);
+ for (const std::string& arch : architectures) {
+ const std::string pchSource = target->GetPchSource(config, lang, arch);
+ const std::string pchHeader = target->GetPchHeader(config, lang, arch);
- if (pchSource.empty() || pchHeader.empty()) {
- continue;
- }
+ if (pchSource.empty() || pchHeader.empty()) {
+ continue;
+ }
- const std::string pchExtension =
- this->Makefile->GetSafeDefinition("CMAKE_PCH_EXTENSION");
+ const std::string pchExtension =
+ this->Makefile->GetSafeDefinition("CMAKE_PCH_EXTENSION");
- if (pchExtension.empty()) {
- continue;
- }
+ if (pchExtension.empty()) {
+ continue;
+ }
- const char* pchReuseFrom =
- target->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
+ cmProp ReuseFrom =
+ target->GetProperty("PRECOMPILE_HEADERS_REUSE_FROM");
- auto pch_sf = this->Makefile->GetOrCreateSource(
- pchSource, false, cmSourceFileLocationKind::Known);
+ auto pch_sf = this->Makefile->GetOrCreateSource(
+ pchSource, false, cmSourceFileLocationKind::Known);
- if (!this->GetGlobalGenerator()->IsXcode()) {
- if (!pchReuseFrom) {
- target->AddSource(pchSource, true);
- }
+ if (!this->GetGlobalGenerator()->IsXcode()) {
+ if (!ReuseFrom) {
+ target->AddSource(pchSource, true);
+ }
- const std::string pchFile = target->GetPchFile(config, lang);
+ const std::string pchFile = target->GetPchFile(config, lang, arch);
- // Exclude the pch files from linking
- if (this->Makefile->IsOn("CMAKE_LINK_PCH")) {
- if (!pchReuseFrom) {
- pch_sf->SetProperty("OBJECT_OUTPUTS", pchFile.c_str());
- } else {
- auto reuseTarget =
- this->GlobalGenerator->FindGeneratorTarget(pchReuseFrom);
+ // Exclude the pch files from linking
+ if (this->Makefile->IsOn("CMAKE_LINK_PCH")) {
+ if (!ReuseFrom) {
+ pch_sf->SetProperty("OBJECT_OUTPUTS", pchFile.c_str());
+ } else {
+ auto reuseTarget =
+ this->GlobalGenerator->FindGeneratorTarget(*ReuseFrom);
+
+ if (this->Makefile->IsOn("CMAKE_PCH_COPY_COMPILE_PDB")) {
+
+ const std::string pdb_prefix =
+ this->GetGlobalGenerator()->IsMultiConfig()
+ ? cmStrCat(this->GlobalGenerator->GetCMakeCFGIntDir(), "/")
+ : "";
+
+ const std::string target_compile_pdb_dir = cmStrCat(
+ target->GetLocalGenerator()->GetCurrentBinaryDirectory(),
+ "/", target->GetName(), ".dir/");
+
+ const std::string copy_script =
+ cmStrCat(target_compile_pdb_dir, "copy_idb_pdb.cmake");
+ cmGeneratedFileStream file(copy_script);
+
+ file << "# CMake generated file\n";
+ for (auto extension : { ".pdb", ".idb" }) {
+ const std::string from_file =
+ cmStrCat(reuseTarget->GetLocalGenerator()
+ ->GetCurrentBinaryDirectory(),
+ "/", *ReuseFrom, ".dir/${PDB_PREFIX}", *ReuseFrom,
+ extension);
+
+ const std::string to_dir = cmStrCat(
+ target->GetLocalGenerator()->GetCurrentBinaryDirectory(),
+ "/", target->GetName(), ".dir/${PDB_PREFIX}");
+
+ const std::string to_file =
+ cmStrCat(to_dir, *ReuseFrom, extension);
+
+ std::string dest_file = to_file;
+
+ std::string const& prefix =
+ target->GetSafeProperty("PREFIX");
+ if (!prefix.empty()) {
+ dest_file =
+ cmStrCat(to_dir, prefix, *ReuseFrom, extension);
+ }
+
+ file << "if (EXISTS \"" << from_file << "\" AND \""
+ << from_file << "\" IS_NEWER_THAN \"" << dest_file
+ << "\")\n";
+ file << " file(COPY \"" << from_file << "\""
+ << " DESTINATION \"" << to_dir << "\")\n";
+ if (!prefix.empty()) {
+ file << " file(REMOVE \"" << dest_file << "\")\n";
+ file << " file(RENAME \"" << to_file << "\" \""
+ << dest_file << "\")\n";
+ }
+ file << "endif()\n";
+ }
+
+ bool stdPipesUTF8 = true;
+ cmCustomCommandLines commandLines = cmMakeSingleCommandLine(
+ { cmSystemTools::GetCMakeCommand(),
+ cmStrCat("-DPDB_PREFIX=", pdb_prefix), "-P",
+ copy_script });
+
+ const std::string no_main_dependency;
+ const std::vector<std::string> no_deps;
+ const char* no_message = "";
+ const char* no_current_dir = nullptr;
+ std::vector<std::string> no_byproducts;
+
+ std::vector<std::string> outputs;
+ outputs.push_back(cmStrCat(target_compile_pdb_dir, pdb_prefix,
+ *ReuseFrom, ".pdb"));
+
+ if (this->GetGlobalGenerator()->IsVisualStudio()) {
+ this->AddCustomCommandToTarget(
+ target->GetName(), outputs, no_deps, commandLines,
+ cmCustomCommandType::PRE_BUILD, no_message, no_current_dir,
+ true, false, "", "", false,
+ cmObjectLibraryCommands::Reject, stdPipesUTF8);
+ } else {
+ cmImplicitDependsList no_implicit_depends;
+ cmSourceFile* copy_rule = this->AddCustomCommandToOutput(
+ outputs, no_byproducts, no_deps, no_main_dependency,
+ no_implicit_depends, commandLines, no_message,
+ no_current_dir, false, true, false, false, "", "",
+ stdPipesUTF8);
+
+ if (copy_rule) {
+ target->AddSource(copy_rule->ResolveFullPath());
+ }
+ }
+
+ target->Target->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY",
+ target_compile_pdb_dir);
+ }
- if (this->Makefile->IsOn("CMAKE_PCH_COPY_COMPILE_PDB")) {
+ std::string pchSourceObj =
+ reuseTarget->GetPchFileObject(config, lang, arch);
- const std::string pdb_prefix =
- this->GetGlobalGenerator()->IsMultiConfig()
- ? cmStrCat(this->GlobalGenerator->GetCMakeCFGIntDir(), "/")
- : "";
+ const std::string configUpper = cmSystemTools::UpperCase(config);
+
+ // Link to the pch object file
+ target->Target->AppendProperty(
+ cmStrCat("LINK_FLAGS_", configUpper),
+ cmStrCat(" ",
+ this->ConvertToOutputFormat(pchSourceObj, SHELL)),
+ true);
+ }
+ } else {
+ pch_sf->SetProperty("PCH_EXTENSION", pchExtension.c_str());
+ }
+
+ // Add pchHeader to source files, which will
+ // be grouped as "Precompile Header File"
+ auto pchHeader_sf = this->Makefile->GetOrCreateSource(
+ pchHeader, false, cmSourceFileLocationKind::Known);
+ std::string err;
+ pchHeader_sf->ResolveFullPath(&err);
+ target->AddSource(pchHeader);
+ }
+ }
+ }
+ }
+}
- const std::string target_compile_pdb_dir = cmStrCat(
- target->GetLocalGenerator()->GetCurrentBinaryDirectory(), "/",
- target->GetName(), ".dir/");
+namespace {
- const std::string copy_script =
- cmStrCat(target_compile_pdb_dir, "copy_idb_pdb.cmake");
- cmGeneratedFileStream file(copy_script);
+inline void RegisterUnitySources(cmGeneratorTarget* target, cmSourceFile* sf,
+ std::string const& filename)
+{
+ target->AddSourceFileToUnityBatch(sf->ResolveFullPath());
+ sf->SetProperty("UNITY_SOURCE_FILE", filename.c_str());
+}
- file << "# CMake generated file\n";
- for (auto extension : { ".pdb", ".idb" }) {
- const std::string from_file = cmStrCat(
- reuseTarget->GetLocalGenerator()->GetCurrentBinaryDirectory(),
- "/", pchReuseFrom, ".dir/${PDB_PREFIX}", pchReuseFrom,
- extension);
+inline void IncludeFileInUnitySources(cmGeneratedFileStream& unity_file,
+ std::string const& sf_full_path,
+ cmProp beforeInclude,
+ cmProp afterInclude)
+{
+ if (beforeInclude) {
+ unity_file << *beforeInclude << "\n";
+ }
- const std::string to_dir = cmStrCat(
- target->GetLocalGenerator()->GetCurrentBinaryDirectory(), "/",
- target->GetName(), ".dir/${PDB_PREFIX}");
+ unity_file << "#include \"" << sf_full_path << "\"\n";
- const std::string to_file =
- cmStrCat(to_dir, pchReuseFrom, extension);
+ if (afterInclude) {
+ unity_file << *afterInclude << "\n";
+ }
+}
- std::string dest_file = to_file;
+std::vector<std::string> AddUnityFilesModeAuto(
+ cmGeneratorTarget* target, std::string const& lang,
+ std::vector<cmSourceFile*> const& filtered_sources, cmProp beforeInclude,
+ cmProp afterInclude, std::string const& filename_base, size_t batchSize)
+{
+ if (batchSize == 0) {
+ batchSize = filtered_sources.size();
+ }
- const std::string prefix = target->GetSafeProperty("PREFIX");
- if (!prefix.empty()) {
- dest_file = cmStrCat(to_dir, prefix, pchReuseFrom, extension);
- }
+ std::vector<std::string> unity_files;
+ for (size_t itemsLeft = filtered_sources.size(), chunk, batch = 0;
+ itemsLeft > 0; itemsLeft -= chunk, ++batch) {
- file << "if (EXISTS \"" << from_file << "\" AND \"" << from_file
- << "\" IS_NEWER_THAN \"" << dest_file << "\")\n";
- file << " file(COPY \"" << from_file << "\""
- << " DESTINATION \"" << to_dir << "\")\n";
- if (!prefix.empty()) {
- file << " file(REMOVE \"" << dest_file << "\")\n";
- file << " file(RENAME \"" << to_file << "\" \"" << dest_file
- << "\")\n";
- }
- file << "endif()\n";
- }
+ chunk = std::min(itemsLeft, batchSize);
- cmCustomCommandLines commandLines;
- cmCustomCommandLine currentLine;
- currentLine.push_back(cmSystemTools::GetCMakeCommand());
- currentLine.push_back(cmStrCat("-DPDB_PREFIX=", pdb_prefix));
- currentLine.push_back("-P");
- currentLine.push_back(copy_script);
- commandLines.push_back(std::move(currentLine));
-
- const std::string no_main_dependency;
- const std::vector<std::string> no_deps;
- const char* no_message = "";
- const char* no_current_dir = nullptr;
- std::vector<std::string> no_byproducts;
-
- std::vector<std::string> outputs;
- outputs.push_back(cmStrCat(target_compile_pdb_dir, pdb_prefix,
- pchReuseFrom, ".pdb"));
-
- if (this->GetGlobalGenerator()->IsMultiConfig()) {
- this->Makefile->AddCustomCommandToTarget(
- target->GetName(), outputs, no_deps, commandLines,
- cmCustomCommandType::PRE_BUILD, no_message, no_current_dir);
- } else {
- cmImplicitDependsList no_implicit_depends;
- cmSourceFile* copy_rule =
- this->Makefile->AddCustomCommandToOutput(
- outputs, no_byproducts, no_deps, no_main_dependency,
- no_implicit_depends, commandLines, no_message,
- no_current_dir);
-
- if (copy_rule) {
- target->AddSource(copy_rule->ResolveFullPath());
- }
- }
+ std::string filename = cmStrCat(filename_base, "unity_", batch,
+ (lang == "C") ? "_c.c" : "_cxx.cxx");
- target->Target->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY",
- target_compile_pdb_dir.c_str());
- }
+ const std::string filename_tmp = cmStrCat(filename, ".tmp");
+ {
+ size_t begin = batch * batchSize;
+ size_t end = begin + chunk;
- std::string pchSourceObj =
- reuseTarget->GetPchFileObject(config, lang);
+ cmGeneratedFileStream file(
+ filename_tmp, false,
+ target->GetGlobalGenerator()->GetMakefileEncoding());
+ file << "/* generated by CMake */\n\n";
- // Link to the pch object file
- target->Target->AppendProperty(
- "LINK_FLAGS",
- cmStrCat(" ", this->ConvertToOutputFormat(pchSourceObj, SHELL))
- .c_str(),
- true);
- }
+ for (; begin != end; ++begin) {
+ cmSourceFile* sf = filtered_sources[begin];
+ RegisterUnitySources(target, sf, filename);
+ IncludeFileInUnitySources(file, sf->ResolveFullPath(), beforeInclude,
+ afterInclude);
+ }
+ }
+ cmSystemTools::MoveFileIfDifferent(filename_tmp, filename);
+ unity_files.emplace_back(std::move(filename));
+ }
+ return unity_files;
+}
+
+std::vector<std::string> AddUnityFilesModeGroup(
+ cmGeneratorTarget* target, std::string const& lang,
+ std::vector<cmSourceFile*> const& filtered_sources, cmProp beforeInclude,
+ cmProp afterInclude, std::string const& filename_base)
+{
+ std::vector<std::string> unity_files;
+
+ // sources organized by group name. Drop any source
+ // without a group
+ std::unordered_map<std::string, std::vector<cmSourceFile*>> explicit_mapping;
+ for (cmSourceFile* sf : filtered_sources) {
+ if (cmProp value = sf->GetProperty("UNITY_GROUP")) {
+ auto i = explicit_mapping.find(*value);
+ if (i == explicit_mapping.end()) {
+ std::vector<cmSourceFile*> sources{ sf };
+ explicit_mapping.emplace(*value, sources);
} else {
- pch_sf->SetProperty("PCH_EXTENSION", pchExtension.c_str());
+ i->second.emplace_back(sf);
}
+ }
+ }
+
+ for (auto const& item : explicit_mapping) {
+ auto const& name = item.first;
+ std::string filename = cmStrCat(filename_base, "unity_", name,
+ (lang == "C") ? "_c.c" : "_cxx.cxx");
+
+ const std::string filename_tmp = cmStrCat(filename, ".tmp");
+ {
+ cmGeneratedFileStream file(
+ filename_tmp, false,
+ target->GetGlobalGenerator()->GetMakefileEncoding());
+ file << "/* generated by CMake */\n\n";
- // Add pchHeader to source files, which will
- // be grouped as "Precompile Header File"
- auto pchHeader_sf = this->Makefile->GetOrCreateSource(
- pchHeader, false, cmSourceFileLocationKind::Known);
- std::string err;
- pchHeader_sf->ResolveFullPath(&err);
- target->AddSource(pchHeader);
+ for (cmSourceFile* sf : item.second) {
+ RegisterUnitySources(target, sf, filename);
+ IncludeFileInUnitySources(file, sf->ResolveFullPath(), beforeInclude,
+ afterInclude);
+ }
}
+ cmSystemTools::MoveFileIfDifferent(filename_tmp, filename);
+ unity_files.emplace_back(std::move(filename));
}
+
+ return unity_files;
+}
}
void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target)
@@ -2488,12 +2892,15 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target)
std::vector<cmSourceFile*> sources;
target->GetSourceFiles(sources, config);
- auto batchSizeString = target->GetProperty("UNITY_BUILD_BATCH_SIZE");
- const size_t unityBatchSize =
- static_cast<size_t>(std::atoi(batchSizeString));
+ cmProp batchSizeString = target->GetProperty("UNITY_BUILD_BATCH_SIZE");
+ const size_t unityBatchSize = batchSizeString
+ ? static_cast<size_t>(std::atoi(batchSizeString->c_str()))
+ : 0;
- auto beforeInclude = target->GetProperty("UNITY_BUILD_CODE_BEFORE_INCLUDE");
- auto afterInclude = target->GetProperty("UNITY_BUILD_CODE_AFTER_INCLUDE");
+ cmProp beforeInclude =
+ target->GetProperty("UNITY_BUILD_CODE_BEFORE_INCLUDE");
+ cmProp afterInclude = target->GetProperty("UNITY_BUILD_CODE_AFTER_INCLUDE");
+ cmProp unityMode = target->GetProperty("UNITY_BUILD_MODE");
for (std::string lang : { "C", "CXX" }) {
std::vector<cmSourceFile*> filtered_sources;
@@ -2508,54 +2915,28 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target)
!sf->GetProperty("INCLUDE_DIRECTORIES");
});
- size_t batchSize = unityBatchSize;
- if (unityBatchSize == 0) {
- batchSize = filtered_sources.size();
+ std::vector<std::string> unity_files;
+ if (!unityMode || *unityMode == "BATCH") {
+ unity_files =
+ AddUnityFilesModeAuto(target, lang, filtered_sources, beforeInclude,
+ afterInclude, filename_base, unityBatchSize);
+ } else if (unityMode && *unityMode == "GROUP") {
+ unity_files =
+ AddUnityFilesModeGroup(target, lang, filtered_sources, beforeInclude,
+ afterInclude, filename_base);
+ } else {
+ // unity mode is set to an unsupported value
+ std::string e("Invalid UNITY_BUILD_MODE value of " + *unityMode +
+ " assigned to target " + target->GetName() +
+ ". Acceptable values are BATCH and GROUP.");
+ this->IssueMessage(MessageType::FATAL_ERROR, e);
}
- for (size_t itemsLeft = filtered_sources.size(), chunk = batchSize,
- batch = 0;
- itemsLeft > 0; itemsLeft -= chunk, ++batch) {
-
- chunk = std::min(itemsLeft, batchSize);
-
- std::string filename = cmStrCat(filename_base, "unity_", batch,
- (lang == "C") ? "_c.c" : "_cxx.cxx");
-
- const std::string filename_tmp = cmStrCat(filename, ".tmp");
- {
- size_t begin = batch * batchSize;
- size_t end = begin + chunk;
-
- cmGeneratedFileStream file(
- filename_tmp, false,
- this->GetGlobalGenerator()->GetMakefileEncoding());
- file << "/* generated by CMake */\n\n";
-
- for (; begin != end; ++begin) {
- cmSourceFile* sf = filtered_sources[begin];
-
- target->AddSourceFileToUnityBatch(sf->ResolveFullPath());
- sf->SetProperty("UNITY_SOURCE_FILE", filename.c_str());
-
- if (beforeInclude) {
- file << beforeInclude << "\n";
- }
-
- file << "#include \"" << sf->ResolveFullPath() << "\"\n";
-
- if (afterInclude) {
- file << afterInclude << "\n";
- }
- }
- }
- cmSystemTools::MoveFileIfDifferent(filename_tmp, filename);
-
- target->AddSource(filename, true);
-
- auto unity = this->Makefile->GetOrCreateSource(filename);
+ for (auto const& file : unity_files) {
+ auto unity = this->GetMakefile()->GetOrCreateSource(file);
+ target->AddSource(file, true);
unity->SetProperty("SKIP_UNITY_BUILD_INCLUSION", "ON");
- unity->SetProperty("UNITY_SOURCE_FILE", filename.c_str());
+ unity->SetProperty("UNITY_SOURCE_FILE", file.c_str());
}
}
}
@@ -2626,11 +3007,11 @@ void cmLocalGenerator::AppendPositionIndependentLinkerFlags(
}
void cmLocalGenerator::AppendCompileOptions(std::string& options,
- const char* options_list,
+ std::string const& options_list,
const char* regex) const
{
// Short-circuit if there are no options.
- if (!options_list) {
+ if (options_list.empty()) {
return;
}
@@ -2684,11 +3065,11 @@ void cmLocalGenerator::AppendCompileOptions(
}
void cmLocalGenerator::AppendIncludeDirectories(
- std::vector<std::string>& includes, const char* includes_list,
+ std::vector<std::string>& includes, const std::string& includes_list,
const cmSourceFile& sourceFile) const
{
// Short-circuit if there are no includes.
- if (!includes_list) {
+ if (includes_list.empty()) {
return;
}
@@ -2791,11 +3172,11 @@ void cmLocalGenerator::JoinDefines(const std::set<std::string>& defines,
// command line without any escapes. However we still have to
// get the '$' and '#' characters through WMake as '$$' and
// '$#'.
- for (const char* c = define.c_str(); *c; ++c) {
- if (*c == '$' || *c == '#') {
+ for (char c : define) {
+ if (c == '$' || c == '#') {
def += '$';
}
- def += *c;
+ def += c;
}
} else {
// Make the definition appear properly on the command line. Use
@@ -2839,8 +3220,8 @@ const char* cmLocalGenerator::GetFeature(const std::string& feature,
}
cmStateSnapshot snp = this->StateSnapshot;
while (snp.IsValid()) {
- if (const char* value = snp.GetDirectory().GetProperty(featureName)) {
- return value;
+ if (cmProp value = snp.GetDirectory().GetProperty(featureName)) {
+ return value->c_str();
}
snp = snp.GetBuildsystemDirectoryParent();
}
@@ -2882,7 +3263,7 @@ class cmInstallTargetGeneratorLocal : public cmInstallTargetGenerator
{
public:
cmInstallTargetGeneratorLocal(cmLocalGenerator* lg, std::string const& t,
- const char* dest, bool implib)
+ std::string const& dest, bool implib)
: cmInstallTargetGenerator(
t, dest, implib, "", std::vector<std::string>(), "Unspecified",
cmInstallGenerator::SelectMessageLevel(lg->GetMakefile()), false,
@@ -2898,15 +3279,15 @@ void cmLocalGenerator::GenerateTargetInstallRules(
{
// Convert the old-style install specification from each target to
// an install generator and run it.
- const std::vector<cmGeneratorTarget*>& tgts = this->GetGeneratorTargets();
- for (cmGeneratorTarget* l : tgts) {
+ const auto& tgts = this->GetGeneratorTargets();
+ for (const auto& l : tgts) {
if (l->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
// Include the user-specified pre-install script for this target.
- if (const char* preinstall = l->GetProperty("PRE_INSTALL_SCRIPT")) {
- cmInstallScriptGenerator g(preinstall, false, nullptr, false);
+ if (cmProp preinstall = l->GetProperty("PRE_INSTALL_SCRIPT")) {
+ cmInstallScriptGenerator g(*preinstall, false, "", false);
g.Generate(os, config, configurationTypes);
}
@@ -2927,8 +3308,8 @@ void cmLocalGenerator::GenerateTargetInstallRules(
case cmStateEnums::STATIC_LIBRARY:
case cmStateEnums::MODULE_LIBRARY: {
// Use a target install generator.
- cmInstallTargetGeneratorLocal g(this, l->GetName(),
- destination.c_str(), false);
+ cmInstallTargetGeneratorLocal g(this, l->GetName(), destination,
+ false);
g.Generate(os, config, configurationTypes);
} break;
case cmStateEnums::SHARED_LIBRARY: {
@@ -2936,19 +3317,19 @@ void cmLocalGenerator::GenerateTargetInstallRules(
// Special code to handle DLL. Install the import library
// to the normal destination and the DLL to the runtime
// destination.
- cmInstallTargetGeneratorLocal g1(this, l->GetName(),
- destination.c_str(), true);
+ cmInstallTargetGeneratorLocal g1(this, l->GetName(), destination,
+ true);
g1.Generate(os, config, configurationTypes);
// We also skip over the leading slash given by the user.
destination = l->Target->GetRuntimeInstallPath().substr(1);
cmSystemTools::ConvertToUnixSlashes(destination);
- cmInstallTargetGeneratorLocal g2(this, l->GetName(),
- destination.c_str(), false);
+ cmInstallTargetGeneratorLocal g2(this, l->GetName(), destination,
+ false);
g2.Generate(os, config, configurationTypes);
#else
// Use a target install generator.
- cmInstallTargetGeneratorLocal g(this, l->GetName(),
- destination.c_str(), false);
+ cmInstallTargetGeneratorLocal g(this, l->GetName(), destination,
+ false);
g.Generate(os, config, configurationTypes);
#endif
} break;
@@ -2958,8 +3339,8 @@ void cmLocalGenerator::GenerateTargetInstallRules(
}
// Include the user-specified post-install script for this target.
- if (const char* postinstall = l->GetProperty("POST_INSTALL_SCRIPT")) {
- cmInstallScriptGenerator g(postinstall, false, nullptr, false);
+ if (cmProp postinstall = l->GetProperty("POST_INSTALL_SCRIPT")) {
+ cmInstallScriptGenerator g(*postinstall, false, "", false);
g.Generate(os, config, configurationTypes);
}
}
@@ -3115,6 +3496,11 @@ bool cmLocalGenerator::IsNMake() const
return this->GetState()->UseNMake();
}
+bool cmLocalGenerator::IsNinjaMulti() const
+{
+ return this->GetState()->UseNinjaMulti();
+}
+
std::string cmLocalGenerator::GetObjectFileNameWithoutTarget(
const cmSourceFile& source, std::string const& dir_max,
bool* hasSourceExtension, char const* customOutputExtension)
@@ -3140,11 +3526,12 @@ std::string cmLocalGenerator::GetObjectFileNameWithoutTarget(
// Select a nice-looking reference to the source file to construct
// the object file name.
std::string objectName;
+ // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
+ // NOLINTNEXTLINE(bugprone-branch-clone)
if ((relSource && !relBinary) || (subSource && !subBinary)) {
objectName = relFromSource;
- } else if ((relBinary && !relSource) || (subBinary && !subSource)) {
- objectName = relFromBinary;
- } else if (relFromBinary.length() < relFromSource.length()) {
+ } else if ((relBinary && !relSource) || (subBinary && !subSource) ||
+ relFromBinary.length() < relFromSource.length()) {
objectName = relFromBinary;
} else {
objectName = relFromSource;
@@ -3162,12 +3549,12 @@ std::string cmLocalGenerator::GetObjectFileNameWithoutTarget(
// Ensure that for the CMakeFiles/<target>.dir/generated_source_file
// we don't end up having:
// CMakeFiles/<target>.dir/CMakeFiles/<target>.dir/generated_source_file.obj
- const char* unitySourceFile = source.GetProperty("UNITY_SOURCE_FILE");
- const char* pchExtension = source.GetProperty("PCH_EXTENSION");
+ cmProp unitySourceFile = source.GetProperty("UNITY_SOURCE_FILE");
+ cmProp psExtension = source.GetProperty("PCH_EXTENSION");
const bool isPchObject = objectName.find("cmake_pch") != std::string::npos;
- if (unitySourceFile || pchExtension || isPchObject) {
- if (pchExtension) {
- customOutputExtension = pchExtension;
+ if (unitySourceFile || psExtension || isPchObject) {
+ if (psExtension) {
+ customOutputExtension = psExtension->c_str();
}
cmsys::RegularExpression var("(CMakeFiles/[^/]+.dir/)");
@@ -3303,7 +3690,6 @@ bool cmLocalGenerator::NeedBackwardsCompatibility_2_4()
break;
case cmPolicies::NEW:
// New behavior is to ignore the variable.
- return false;
case cmPolicies::REQUIRED_IF_USED:
case cmPolicies::REQUIRED_ALWAYS:
// This will never be the case because the only way to require
@@ -3365,8 +3751,8 @@ bool cmLocalGenerator::CheckDefinition(std::string const& define) const
static void cmLGInfoProp(cmMakefile* mf, cmGeneratorTarget* target,
const std::string& prop)
{
- if (const char* val = target->GetProperty(prop)) {
- mf->AddDefinition(prop, val);
+ if (cmProp val = target->GetProperty(prop)) {
+ mf->AddDefinition(prop, *val);
}
}
@@ -3375,8 +3761,9 @@ void cmLocalGenerator::GenerateAppleInfoPList(cmGeneratorTarget* target,
const std::string& fname)
{
// Find the Info.plist template.
- const char* in = target->GetProperty("MACOSX_BUNDLE_INFO_PLIST");
- std::string inFile = (in && *in) ? in : "MacOSXBundleInfo.plist.in";
+ cmProp in = target->GetProperty("MACOSX_BUNDLE_INFO_PLIST");
+ std::string inFile =
+ (in && !in->empty()) ? *in : "MacOSXBundleInfo.plist.in";
if (!cmSystemTools::FileIsFullPath(inFile)) {
std::string inMod = this->Makefile->GetModulesFile(inFile);
if (!inMod.empty()) {
@@ -3414,8 +3801,9 @@ void cmLocalGenerator::GenerateFrameworkInfoPList(
const std::string& fname)
{
// Find the Info.plist template.
- const char* in = target->GetProperty("MACOSX_FRAMEWORK_INFO_PLIST");
- std::string inFile = (in && *in) ? in : "MacOSXFrameworkInfo.plist.in";
+ cmProp in = target->GetProperty("MACOSX_FRAMEWORK_INFO_PLIST");
+ std::string inFile =
+ (in && !in->empty()) ? *in : "MacOSXFrameworkInfo.plist.in";
if (!cmSystemTools::FileIsFullPath(inFile)) {
std::string inMod = this->Makefile->GetModulesFile(inFile);
if (!inMod.empty()) {
@@ -3443,3 +3831,246 @@ void cmLocalGenerator::GenerateFrameworkInfoPList(
cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_BUNDLE_VERSION");
mf->ConfigureFile(inFile, fname, false, false, false);
}
+
+namespace {
+void CreateGeneratedSource(cmLocalGenerator& lg, const std::string& output,
+ cmCommandOrigin origin,
+ const cmListFileBacktrace& lfbt)
+{
+ if (cmGeneratorExpression::Find(output) == std::string::npos) {
+ // Outputs without generator expressions from the project are already
+ // created and marked as generated. Do not mark them again, because
+ // other commands might have overwritten the property.
+ if (origin == cmCommandOrigin::Generator) {
+ lg.GetMakefile()->GetOrCreateGeneratedSource(output);
+ }
+ } else {
+ lg.GetCMakeInstance()->IssueMessage(
+ MessageType::FATAL_ERROR,
+ "Generator expressions in custom command outputs are not implemented!",
+ lfbt);
+ }
+}
+
+void CreateGeneratedSources(cmLocalGenerator& lg,
+ const std::vector<std::string>& outputs,
+ cmCommandOrigin origin,
+ const cmListFileBacktrace& lfbt)
+{
+ for (std::string const& o : outputs) {
+ CreateGeneratedSource(lg, o, origin, lfbt);
+ }
+}
+
+cmSourceFile* AddCustomCommand(
+ cmLocalGenerator& lg, const cmListFileBacktrace& lfbt,
+ const std::vector<std::string>& outputs,
+ const std::vector<std::string>& byproducts,
+ const std::vector<std::string>& depends, const std::string& main_dependency,
+ const cmImplicitDependsList& implicit_depends,
+ const cmCustomCommandLines& commandLines, const char* comment,
+ const char* workingDir, bool replace, bool escapeOldStyle,
+ bool uses_terminal, bool command_expand_lists, const std::string& depfile,
+ const std::string& job_pool, bool stdPipesUTF8)
+{
+ cmMakefile* mf = lg.GetMakefile();
+
+ // Choose a source file on which to store the custom command.
+ cmSourceFile* file = nullptr;
+ if (!commandLines.empty() && !main_dependency.empty()) {
+ // The main dependency was specified. Use it unless a different
+ // custom command already used it.
+ file = mf->GetSource(main_dependency);
+ if (file && file->GetCustomCommand() && !replace) {
+ // The main dependency already has a custom command.
+ if (commandLines == file->GetCustomCommand()->GetCommandLines()) {
+ // The existing custom command is identical. Silently ignore
+ // the duplicate.
+ return file;
+ }
+ // The existing custom command is different. We need to
+ // generate a rule file for this new command.
+ file = nullptr;
+ } else if (!file) {
+ file = mf->CreateSource(main_dependency);
+ }
+ }
+
+ // Generate a rule file if the main dependency is not available.
+ if (!file) {
+ cmGlobalGenerator* gg = lg.GetGlobalGenerator();
+
+ // Construct a rule file associated with the first output produced.
+ std::string outName = gg->GenerateRuleFile(outputs[0]);
+
+ // Check if the rule file already exists.
+ file = mf->GetSource(outName, cmSourceFileLocationKind::Known);
+ if (file && file->GetCustomCommand() && !replace) {
+ // The rule file already exists.
+ if (commandLines != file->GetCustomCommand()->GetCommandLines()) {
+ lg.GetCMakeInstance()->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Attempt to add a custom rule to output\n ", outName,
+ "\nwhich already has a custom rule."),
+ lfbt);
+ }
+ return file;
+ }
+
+ // Create a cmSourceFile for the rule file.
+ if (!file) {
+ file = mf->CreateSource(outName, true, cmSourceFileLocationKind::Known);
+ }
+ file->SetProperty("__CMAKE_RULE", "1");
+ }
+
+ // Attach the custom command to the file.
+ if (file) {
+ // Construct a complete list of dependencies.
+ std::vector<std::string> depends2(depends);
+ if (!main_dependency.empty()) {
+ depends2.push_back(main_dependency);
+ }
+
+ std::unique_ptr<cmCustomCommand> cc = cm::make_unique<cmCustomCommand>(
+ outputs, byproducts, depends2, commandLines, lfbt, comment, workingDir,
+ stdPipesUTF8);
+ cc->SetEscapeOldStyle(escapeOldStyle);
+ cc->SetEscapeAllowMakeVars(true);
+ cc->SetImplicitDepends(implicit_depends);
+ cc->SetUsesTerminal(uses_terminal);
+ cc->SetCommandExpandLists(command_expand_lists);
+ cc->SetDepfile(depfile);
+ cc->SetJobPool(job_pool);
+ file->SetCustomCommand(std::move(cc));
+
+ mf->AddSourceOutputs(file, outputs, byproducts);
+ }
+ return file;
+}
+}
+
+namespace detail {
+void AddCustomCommandToTarget(cmLocalGenerator& lg,
+ const cmListFileBacktrace& lfbt,
+ cmCommandOrigin origin, cmTarget* target,
+ const std::vector<std::string>& byproducts,
+ const std::vector<std::string>& depends,
+ const cmCustomCommandLines& commandLines,
+ cmCustomCommandType type, const char* comment,
+ const char* workingDir, bool escapeOldStyle,
+ bool uses_terminal, const std::string& depfile,
+ const std::string& job_pool,
+ bool command_expand_lists, bool stdPipesUTF8)
+{
+ cmMakefile* mf = lg.GetMakefile();
+
+ // Always create the byproduct sources and mark them generated.
+ CreateGeneratedSources(lg, byproducts, origin, lfbt);
+
+ // Add the command to the appropriate build step for the target.
+ std::vector<std::string> no_output;
+ cmCustomCommand cc(no_output, byproducts, depends, commandLines, lfbt,
+ comment, workingDir, stdPipesUTF8);
+ cc.SetEscapeOldStyle(escapeOldStyle);
+ cc.SetEscapeAllowMakeVars(true);
+ cc.SetUsesTerminal(uses_terminal);
+ cc.SetCommandExpandLists(command_expand_lists);
+ cc.SetDepfile(depfile);
+ cc.SetJobPool(job_pool);
+ switch (type) {
+ case cmCustomCommandType::PRE_BUILD:
+ target->AddPreBuildCommand(std::move(cc));
+ break;
+ case cmCustomCommandType::PRE_LINK:
+ target->AddPreLinkCommand(std::move(cc));
+ break;
+ case cmCustomCommandType::POST_BUILD:
+ target->AddPostBuildCommand(std::move(cc));
+ break;
+ }
+
+ mf->AddTargetByproducts(target, byproducts);
+}
+
+cmSourceFile* AddCustomCommandToOutput(
+ cmLocalGenerator& lg, const cmListFileBacktrace& lfbt,
+ cmCommandOrigin origin, const std::vector<std::string>& outputs,
+ const std::vector<std::string>& byproducts,
+ const std::vector<std::string>& depends, const std::string& main_dependency,
+ const cmImplicitDependsList& implicit_depends,
+ const cmCustomCommandLines& commandLines, const char* comment,
+ const char* workingDir, bool replace, bool escapeOldStyle,
+ bool uses_terminal, bool command_expand_lists, const std::string& depfile,
+ const std::string& job_pool, bool stdPipesUTF8)
+{
+ // Always create the output sources and mark them generated.
+ CreateGeneratedSources(lg, outputs, origin, lfbt);
+ CreateGeneratedSources(lg, byproducts, origin, lfbt);
+
+ return AddCustomCommand(
+ lg, lfbt, outputs, byproducts, depends, main_dependency, implicit_depends,
+ commandLines, comment, workingDir, replace, escapeOldStyle, uses_terminal,
+ command_expand_lists, depfile, job_pool, stdPipesUTF8);
+}
+
+void AppendCustomCommandToOutput(cmLocalGenerator& lg,
+ const cmListFileBacktrace& lfbt,
+ const std::string& output,
+ const std::vector<std::string>& depends,
+ const cmImplicitDependsList& implicit_depends,
+ const cmCustomCommandLines& commandLines)
+{
+ // Lookup an existing command.
+ if (cmSourceFile* sf = lg.GetMakefile()->GetSourceFileWithOutput(output)) {
+ if (cmCustomCommand* cc = sf->GetCustomCommand()) {
+ cc->AppendCommands(commandLines);
+ cc->AppendDepends(depends);
+ cc->AppendImplicitDepends(implicit_depends);
+ return;
+ }
+ }
+
+ // No existing command found.
+ lg.GetCMakeInstance()->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Attempt to append to output\n ", output,
+ "\nwhich is not already a custom command output."),
+ lfbt);
+}
+
+void AddUtilityCommand(cmLocalGenerator& lg, const cmListFileBacktrace& lfbt,
+ cmCommandOrigin origin, cmTarget* target,
+ const cmUtilityOutput& force, const char* workingDir,
+ const std::vector<std::string>& byproducts,
+ const std::vector<std::string>& depends,
+ const cmCustomCommandLines& commandLines,
+ bool escapeOldStyle, const char* comment,
+ bool uses_terminal, bool command_expand_lists,
+ const std::string& job_pool, bool stdPipesUTF8)
+{
+ // Always create the byproduct sources and mark them generated.
+ CreateGeneratedSource(lg, force.Name, origin, lfbt);
+ CreateGeneratedSources(lg, byproducts, origin, lfbt);
+
+ // Use an empty comment to avoid generation of default comment.
+ if (!comment) {
+ comment = "";
+ }
+
+ std::string no_main_dependency;
+ cmImplicitDependsList no_implicit_depends;
+ cmSourceFile* rule = AddCustomCommand(
+ lg, lfbt, { force.Name }, byproducts, depends, no_main_dependency,
+ no_implicit_depends, commandLines, comment, workingDir, /*replace=*/false,
+ escapeOldStyle, uses_terminal, command_expand_lists, /*depfile=*/"",
+ job_pool, stdPipesUTF8);
+ if (rule) {
+ lg.GetMakefile()->AddTargetByproducts(target, byproducts);
+ }
+
+ if (!force.NameCMP0049.empty()) {
+ target->AddSource(force.NameCMP0049);
+ }
+}
+}
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 12359db..9beae61 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -7,13 +7,15 @@
#include <iosfwd>
#include <map>
+#include <memory>
#include <set>
#include <string>
#include <unordered_map>
#include <vector>
-#include "cm_kwiml.h"
+#include <cm3p/kwiml/int.h>
+#include "cmCustomCommandTypes.h"
#include "cmListFileCache.h"
#include "cmMessageType.h"
#include "cmOutputConverter.h"
@@ -22,13 +24,16 @@
class cmComputeLinkInformation;
class cmCustomCommandGenerator;
+class cmCustomCommandLines;
class cmGeneratorTarget;
class cmGlobalGenerator;
+class cmImplicitDependsList;
class cmLinkLineComputer;
class cmMakefile;
class cmRulePlaceholderExpander;
class cmSourceFile;
class cmState;
+class cmTarget;
class cmake;
/** \class cmLocalGenerator
@@ -100,8 +105,8 @@ public:
void AddArchitectureFlags(std::string& flags,
cmGeneratorTarget const* target,
- const std::string& lang,
- const std::string& config);
+ const std::string& lang, const std::string& config,
+ const std::string& filterArch = std::string());
void AddLanguageFlags(std::string& flags, cmGeneratorTarget const* target,
const std::string& lang, const std::string& config);
@@ -143,14 +148,16 @@ public:
bool forResponseFile = false,
const std::string& config = "");
- const std::vector<cmGeneratorTarget*>& GetGeneratorTargets() const
+ using GeneratorTargetVector =
+ std::vector<std::unique_ptr<cmGeneratorTarget>>;
+ const GeneratorTargetVector& GetGeneratorTargets() const
{
return this->GeneratorTargets;
}
- void AddGeneratorTarget(cmGeneratorTarget* gt);
+ void AddGeneratorTarget(std::unique_ptr<cmGeneratorTarget> gt);
void AddImportedGeneratorTarget(cmGeneratorTarget* gt);
- void AddOwnedImportedGeneratorTarget(cmGeneratorTarget* gt);
+ void AddOwnedImportedGeneratorTarget(std::unique_ptr<cmGeneratorTarget> gt);
cmGeneratorTarget* FindLocalNonAliasGeneratorTarget(
const std::string& name) const;
@@ -160,15 +167,8 @@ public:
* Process a list of include directories
*/
void AppendIncludeDirectories(std::vector<std::string>& includes,
- const char* includes_list,
- const cmSourceFile& sourceFile) const;
- void AppendIncludeDirectories(std::vector<std::string>& includes,
std::string const& includes_list,
- const cmSourceFile& sourceFile) const
- {
- this->AppendIncludeDirectories(includes, includes_list.c_str(),
- sourceFile);
- }
+ const cmSourceFile& sourceFile) const;
void AppendIncludeDirectories(std::vector<std::string>& includes,
const std::vector<std::string>& includes_vec,
const cmSourceFile& sourceFile) const;
@@ -188,14 +188,9 @@ public:
* Encode a list of compile options for the compiler
* command line.
*/
- void AppendCompileOptions(std::string& options, const char* options_list,
- const char* regex = nullptr) const;
void AppendCompileOptions(std::string& options,
std::string const& options_list,
- const char* regex = nullptr) const
- {
- this->AppendCompileOptions(options, options_list.c_str(), regex);
- }
+ const char* regex = nullptr) const;
void AppendCompileOptions(std::string& options,
const std::vector<std::string>& options_vec,
const char* regex = nullptr) const;
@@ -292,6 +287,55 @@ public:
cmGeneratorTarget* target, const std::string& lang,
const std::string& config);
+ /**
+ * Add a custom PRE_BUILD, PRE_LINK, or POST_BUILD command to a target.
+ */
+ cmTarget* AddCustomCommandToTarget(
+ const std::string& target, const std::vector<std::string>& byproducts,
+ const std::vector<std::string>& depends,
+ const cmCustomCommandLines& commandLines, cmCustomCommandType type,
+ const char* comment, const char* workingDir, bool escapeOldStyle = true,
+ bool uses_terminal = false, const std::string& depfile = "",
+ const std::string& job_pool = "", bool command_expand_lists = false,
+ cmObjectLibraryCommands objLibCommands = cmObjectLibraryCommands::Reject,
+ bool stdPipesUTF8 = false);
+
+ /**
+ * Add a custom command to a source file.
+ */
+ cmSourceFile* AddCustomCommandToOutput(
+ const std::string& output, const std::vector<std::string>& depends,
+ const std::string& main_dependency,
+ const cmCustomCommandLines& commandLines, const char* comment,
+ const char* workingDir, bool replace = false, bool escapeOldStyle = true,
+ bool uses_terminal = false, bool command_expand_lists = false,
+ const std::string& depfile = "", const std::string& job_pool = "",
+ bool stdPipesUTF8 = false);
+ cmSourceFile* AddCustomCommandToOutput(
+ const std::vector<std::string>& outputs,
+ const std::vector<std::string>& byproducts,
+ const std::vector<std::string>& depends,
+ const std::string& main_dependency,
+ const cmImplicitDependsList& implicit_depends,
+ const cmCustomCommandLines& commandLines, const char* comment,
+ const char* workingDir, bool replace = false, bool escapeOldStyle = true,
+ bool uses_terminal = false, bool command_expand_lists = false,
+ const std::string& depfile = "", const std::string& job_pool = "",
+ bool stdPipesUTF8 = false);
+
+ /**
+ * Add a utility to the build. A utility target is a command that is run
+ * every time the target is built.
+ */
+ cmTarget* AddUtilityCommand(
+ const std::string& utilityName, bool excludeFromAll,
+ const char* workingDir, const std::vector<std::string>& byproducts,
+ const std::vector<std::string>& depends,
+ const cmCustomCommandLines& commandLines, bool escapeOldStyle = true,
+ const char* comment = nullptr, bool uses_terminal = false,
+ bool command_expand_lists = false, const std::string& job_pool = "",
+ bool stdPipesUTF8 = false);
+
std::string GetProjectName() const;
/** Compute the language used to compile the given source file. */
@@ -377,6 +421,11 @@ public:
/** Fill out these strings for the given target. Libraries to link,
* flags, and linkflags. */
+ void GetDeviceLinkFlags(cmLinkLineComputer* linkLineComputer,
+ const std::string& config, std::string& linkLibs,
+ std::string& linkFlags, std::string& frameworkPath,
+ std::string& linkPath, cmGeneratorTarget* target);
+
void GetTargetFlags(cmLinkLineComputer* linkLineComputer,
const std::string& config, std::string& linkLibs,
std::string& flags, std::string& linkFlags,
@@ -395,10 +444,11 @@ public:
std::string const& lang) const;
void GetTargetCompileFlags(cmGeneratorTarget* target,
std::string const& config,
- std::string const& lang, std::string& flags);
- std::vector<BT<std::string>> GetTargetCompileFlags(cmGeneratorTarget* target,
- std::string const& config,
- std::string const& lang);
+ std::string const& lang, std::string& flags,
+ std::string const& arch = std::string());
+ std::vector<BT<std::string>> GetTargetCompileFlags(
+ cmGeneratorTarget* target, std::string const& config,
+ std::string const& lang, std::string const& arch = std::string());
std::string GetFrameworkFlags(std::string const& l,
std::string const& config,
@@ -414,6 +464,7 @@ public:
bool IsWatcomWMake() const;
bool IsMinGWMake() const;
bool IsNMake() const;
+ bool IsNinjaMulti() const;
void IssueMessage(MessageType t, std::string const& text) const;
@@ -461,17 +512,18 @@ protected:
using GeneratorTargetMap =
std::unordered_map<std::string, cmGeneratorTarget*>;
GeneratorTargetMap GeneratorTargetSearchIndex;
- std::vector<cmGeneratorTarget*> GeneratorTargets;
+ GeneratorTargetVector GeneratorTargets;
std::set<cmGeneratorTarget const*> WarnCMP0063;
GeneratorTargetMap ImportedGeneratorTargets;
- std::vector<cmGeneratorTarget*> OwnedImportedGeneratorTargets;
+ GeneratorTargetVector OwnedImportedGeneratorTargets;
std::map<std::string, std::string> AliasTargets;
std::map<std::string, std::string> Compilers;
std::map<std::string, std::string> VariableMappings;
std::string CompilerSysroot;
std::string LinkerSysroot;
+ std::unordered_map<std::string, std::string> AppleArchSysroots;
bool EmitUniversalBinaryFlags;
@@ -486,6 +538,8 @@ private:
int targetType);
void ComputeObjectMaxPath();
+ bool AllAppleArchSysrootsAreTheSame(const std::vector<std::string>& archs,
+ const char* sysroot);
};
#if !defined(CMAKE_BOOTSTRAP)
@@ -494,4 +548,46 @@ bool cmLocalGeneratorCheckObjectName(std::string& objName,
std::string::size_type max_total_len);
#endif
+namespace detail {
+void AddCustomCommandToTarget(cmLocalGenerator& lg,
+ const cmListFileBacktrace& lfbt,
+ cmCommandOrigin origin, cmTarget* target,
+ const std::vector<std::string>& byproducts,
+ const std::vector<std::string>& depends,
+ const cmCustomCommandLines& commandLines,
+ cmCustomCommandType type, const char* comment,
+ const char* workingDir, bool escapeOldStyle,
+ bool uses_terminal, const std::string& depfile,
+ const std::string& job_pool,
+ bool command_expand_lists, bool stdPipesUTF8);
+
+cmSourceFile* AddCustomCommandToOutput(
+ cmLocalGenerator& lg, const cmListFileBacktrace& lfbt,
+ cmCommandOrigin origin, const std::vector<std::string>& outputs,
+ const std::vector<std::string>& byproducts,
+ const std::vector<std::string>& depends, const std::string& main_dependency,
+ const cmImplicitDependsList& implicit_depends,
+ const cmCustomCommandLines& commandLines, const char* comment,
+ const char* workingDir, bool replace, bool escapeOldStyle,
+ bool uses_terminal, bool command_expand_lists, const std::string& depfile,
+ const std::string& job_pool, bool stdPipesUTF8);
+
+void AppendCustomCommandToOutput(cmLocalGenerator& lg,
+ const cmListFileBacktrace& lfbt,
+ const std::string& output,
+ const std::vector<std::string>& depends,
+ const cmImplicitDependsList& implicit_depends,
+ const cmCustomCommandLines& commandLines);
+
+void AddUtilityCommand(cmLocalGenerator& lg, const cmListFileBacktrace& lfbt,
+ cmCommandOrigin origin, cmTarget* target,
+ const cmUtilityOutput& force, const char* workingDir,
+ const std::vector<std::string>& byproducts,
+ const std::vector<std::string>& depends,
+ const cmCustomCommandLines& commandLines,
+ bool escapeOldStyle, const char* comment,
+ bool uses_terminal, bool command_expand_lists,
+ const std::string& job_pool, bool stdPipesUTF8);
+}
+
#endif
diff --git a/Source/cmLocalGhsMultiGenerator.cxx b/Source/cmLocalGhsMultiGenerator.cxx
index 4b10798..098fa5a 100644
--- a/Source/cmLocalGhsMultiGenerator.cxx
+++ b/Source/cmLocalGhsMultiGenerator.cxx
@@ -5,6 +5,8 @@
#include <algorithm>
#include <utility>
+#include <cmext/algorithm>
+
#include "cmGeneratorTarget.h"
#include "cmGhsMultiTargetGenerator.h"
#include "cmGlobalGenerator.h"
@@ -50,10 +52,11 @@ void cmLocalGhsMultiGenerator::GenerateTargetsDepthFirst(
void cmLocalGhsMultiGenerator::Generate()
{
- std::vector<cmGeneratorTarget*> remaining = this->GetGeneratorTargets();
+ std::vector<cmGeneratorTarget*> remaining;
+ cm::append(remaining, this->GetGeneratorTargets());
for (auto& t : remaining) {
if (t) {
- GenerateTargetsDepthFirst(t, remaining);
+ this->GenerateTargetsDepthFirst(t, remaining);
}
}
}
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index 134bbe1..d1944a4 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -29,6 +29,7 @@
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmTarget.h"
#include "cmake.h"
cmLocalNinjaGenerator::cmLocalNinjaGenerator(cmGlobalGenerator* gg,
@@ -61,7 +62,12 @@ void cmLocalNinjaGenerator::Generate()
this->HomeRelativeOutputPath.clear();
}
- this->WriteProcessedMakefile(this->GetBuildFileStream());
+ if (this->GetGlobalGenerator()->IsMultiConfig()) {
+ for (auto const& config : this->GetConfigNames()) {
+ this->WriteProcessedMakefile(this->GetImplFileStream(config));
+ }
+ }
+ this->WriteProcessedMakefile(this->GetCommonFileStream());
#ifdef NINJA_GEN_VERBOSE_FILES
this->WriteProcessedMakefile(this->GetRulesFileStream());
#endif
@@ -82,18 +88,26 @@ void cmLocalNinjaGenerator::Generate()
}
}
- for (cmGeneratorTarget* target : this->GetGeneratorTargets()) {
+ for (const auto& target : this->GetGeneratorTargets()) {
if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
- auto tg = cmNinjaTargetGenerator::New(target);
+ auto tg = cmNinjaTargetGenerator::New(target.get());
if (tg) {
- tg->Generate();
+ if (target->Target->IsPerConfig()) {
+ for (auto const& config : this->GetConfigNames()) {
+ tg->Generate(config);
+ }
+ } else {
+ tg->Generate("");
+ }
}
}
- this->WriteCustomCommandBuildStatements();
- this->AdditionalCleanFiles();
+ for (auto const& config : this->GetConfigNames()) {
+ this->WriteCustomCommandBuildStatements(config);
+ this->AdditionalCleanFiles(config);
+ }
}
// TODO: Picked up from cmLocalUnixMakefileGenerator3. Refactor it.
@@ -130,8 +144,9 @@ std::string cmLocalNinjaGenerator::ConvertToIncludeReference(
bool forceFullPaths)
{
if (forceFullPaths) {
- return this->ConvertToOutputFormat(cmSystemTools::CollapseFullPath(path),
- format);
+ return this->ConvertToOutputFormat(
+ cmSystemTools::CollapseFullPath(path, this->GetCurrentBinaryDirectory()),
+ format);
}
return this->ConvertToOutputFormat(
this->MaybeConvertToRelativePath(this->GetBinaryDirectory(), path),
@@ -140,9 +155,15 @@ std::string cmLocalNinjaGenerator::ConvertToIncludeReference(
// Private methods.
-cmGeneratedFileStream& cmLocalNinjaGenerator::GetBuildFileStream() const
+cmGeneratedFileStream& cmLocalNinjaGenerator::GetImplFileStream(
+ const std::string& config) const
{
- return *this->GetGlobalNinjaGenerator()->GetBuildFileStream();
+ return *this->GetGlobalNinjaGenerator()->GetImplFileStream(config);
+}
+
+cmGeneratedFileStream& cmLocalNinjaGenerator::GetCommonFileStream() const
+{
+ return *this->GetGlobalNinjaGenerator()->GetCommonFileStream();
}
cmGeneratedFileStream& cmLocalNinjaGenerator::GetRulesFileStream() const
@@ -162,10 +183,22 @@ cmake* cmLocalNinjaGenerator::GetCMakeInstance()
void cmLocalNinjaGenerator::WriteBuildFileTop()
{
- // For the build file.
- this->WriteProjectHeader(this->GetBuildFileStream());
- this->WriteNinjaRequiredVersion(this->GetBuildFileStream());
- this->WriteNinjaFilesInclusion(this->GetBuildFileStream());
+ this->WriteProjectHeader(this->GetCommonFileStream());
+
+ if (this->GetGlobalGenerator()->IsMultiConfig()) {
+ for (auto const& config : this->GetConfigNames()) {
+ auto& stream = this->GetImplFileStream(config);
+ this->WriteProjectHeader(stream);
+ this->WriteNinjaRequiredVersion(stream);
+ this->WriteNinjaConfigurationVariable(stream, config);
+ this->WriteNinjaFilesInclusionConfig(stream);
+ }
+ } else {
+ this->WriteNinjaRequiredVersion(this->GetCommonFileStream());
+ this->WriteNinjaConfigurationVariable(this->GetCommonFileStream(),
+ this->GetConfigNames().front());
+ }
+ this->WriteNinjaFilesInclusionCommon(this->GetCommonFileStream());
// For the rule file.
this->WriteProjectHeader(this->GetRulesFileStream());
@@ -174,8 +207,8 @@ void cmLocalNinjaGenerator::WriteBuildFileTop()
void cmLocalNinjaGenerator::WriteProjectHeader(std::ostream& os)
{
cmGlobalNinjaGenerator::WriteDivider(os);
- os << "# Project: " << this->GetProjectName() << std::endl
- << "# Configuration: " << this->ConfigName << std::endl;
+ os << "# Project: " << this->GetProjectName() << '\n'
+ << "# Configurations: " << cmJoin(this->GetConfigNames(), ", ") << '\n';
cmGlobalNinjaGenerator::WriteDivider(os);
}
@@ -202,31 +235,37 @@ void cmLocalNinjaGenerator::WriteNinjaRequiredVersion(std::ostream& os)
cmGlobalNinjaGenerator::WriteComment(
os, "Minimal version of Ninja required by this file");
- os << "ninja_required_version = " << requiredVersion << std::endl
- << std::endl;
+ os << "ninja_required_version = " << requiredVersion << "\n\n";
+}
+
+void cmLocalNinjaGenerator::WriteNinjaConfigurationVariable(
+ std::ostream& os, const std::string& config)
+{
+ cmGlobalNinjaGenerator::WriteVariable(
+ os, "CONFIGURATION", config,
+ "Set configuration variable for custom commands.");
}
void cmLocalNinjaGenerator::WritePools(std::ostream& os)
{
cmGlobalNinjaGenerator::WriteDivider(os);
- const char* jobpools =
+ cmProp jobpools =
this->GetCMakeInstance()->GetState()->GetGlobalProperty("JOB_POOLS");
if (!jobpools) {
- jobpools = this->GetMakefile()->GetDefinition("CMAKE_JOB_POOLS");
+ jobpools = this->GetMakefile()->GetDef("CMAKE_JOB_POOLS");
}
if (jobpools) {
cmGlobalNinjaGenerator::WriteComment(
os, "Pools defined by global property JOB_POOLS");
- std::vector<std::string> pools = cmExpandedList(jobpools);
+ std::vector<std::string> pools = cmExpandedList(*jobpools);
for (std::string const& pool : pools) {
const std::string::size_type eq = pool.find('=');
unsigned int jobs;
if (eq != std::string::npos &&
sscanf(pool.c_str() + eq, "=%u", &jobs) == 1) {
- os << "pool " << pool.substr(0, eq) << std::endl;
- os << " depth = " << jobs << std::endl;
- os << std::endl;
+ os << "pool " << pool.substr(0, eq) << "\n depth = " << jobs
+ << "\n\n";
} else {
cmSystemTools::Error("Invalid pool defined by property 'JOB_POOLS': " +
pool);
@@ -235,11 +274,23 @@ void cmLocalNinjaGenerator::WritePools(std::ostream& os)
}
}
-void cmLocalNinjaGenerator::WriteNinjaFilesInclusion(std::ostream& os)
+void cmLocalNinjaGenerator::WriteNinjaFilesInclusionConfig(std::ostream& os)
{
cmGlobalNinjaGenerator::WriteDivider(os);
- os << "# Include auxiliary files.\n"
- << "\n";
+ os << "# Include auxiliary files.\n\n";
+ cmGlobalNinjaGenerator* ng = this->GetGlobalNinjaGenerator();
+ std::string const ninjaCommonFile =
+ ng->NinjaOutputPath(cmGlobalNinjaMultiGenerator::NINJA_COMMON_FILE);
+ std::string const commonFilePath = ng->EncodePath(ninjaCommonFile);
+ cmGlobalNinjaGenerator::WriteInclude(os, commonFilePath,
+ "Include common file.");
+ os << "\n";
+}
+
+void cmLocalNinjaGenerator::WriteNinjaFilesInclusionCommon(std::ostream& os)
+{
+ cmGlobalNinjaGenerator::WriteDivider(os);
+ os << "# Include auxiliary files.\n\n";
cmGlobalNinjaGenerator* ng = this->GetGlobalNinjaGenerator();
std::string const ninjaRulesFile =
ng->NinjaOutputPath(cmGlobalNinjaGenerator::NINJA_RULES_FILE);
@@ -252,36 +303,41 @@ void cmLocalNinjaGenerator::WriteNinjaFilesInclusion(std::ostream& os)
void cmLocalNinjaGenerator::WriteProcessedMakefile(std::ostream& os)
{
cmGlobalNinjaGenerator::WriteDivider(os);
- os << "# Write statements declared in CMakeLists.txt:" << std::endl
+ os << "# Write statements declared in CMakeLists.txt:\n"
<< "# " << this->Makefile->GetDefinition("CMAKE_CURRENT_LIST_FILE")
- << std::endl;
+ << '\n';
if (this->IsRootMakefile()) {
- os << "# Which is the root file." << std::endl;
+ os << "# Which is the root file.\n";
}
cmGlobalNinjaGenerator::WriteDivider(os);
- os << std::endl;
+ os << '\n';
}
void cmLocalNinjaGenerator::AppendTargetOutputs(cmGeneratorTarget* target,
- cmNinjaDeps& outputs)
+ cmNinjaDeps& outputs,
+ const std::string& config)
{
- this->GetGlobalNinjaGenerator()->AppendTargetOutputs(target, outputs);
+ this->GetGlobalNinjaGenerator()->AppendTargetOutputs(target, outputs,
+ config);
}
void cmLocalNinjaGenerator::AppendTargetDepends(cmGeneratorTarget* target,
cmNinjaDeps& outputs,
+ const std::string& config,
+ const std::string& fileConfig,
cmNinjaTargetDepends depends)
{
- this->GetGlobalNinjaGenerator()->AppendTargetDepends(target, outputs,
- depends);
+ this->GetGlobalNinjaGenerator()->AppendTargetDepends(target, outputs, config,
+ fileConfig, depends);
}
void cmLocalNinjaGenerator::AppendCustomCommandDeps(
- cmCustomCommandGenerator const& ccg, cmNinjaDeps& ninjaDeps)
+ cmCustomCommandGenerator const& ccg, cmNinjaDeps& ninjaDeps,
+ const std::string& config)
{
for (std::string const& i : ccg.GetDepends()) {
std::string dep;
- if (this->GetRealDependency(i, this->GetConfigName(), dep)) {
+ if (this->GetRealDependency(i, config, dep)) {
ninjaDeps.push_back(
this->GetGlobalNinjaGenerator()->ConvertToNinjaPath(dep));
}
@@ -416,6 +472,8 @@ std::string cmLocalNinjaGenerator::BuildCommandLine(
void cmLocalNinjaGenerator::AppendCustomCommandLines(
cmCustomCommandGenerator const& ccg, std::vector<std::string>& cmdLines)
{
+ auto* gg = this->GetGlobalNinjaGenerator();
+
if (ccg.GetNumberOfCommands() > 0) {
std::string wd = ccg.GetWorkingDirectory();
if (wd.empty()) {
@@ -437,8 +495,10 @@ void cmLocalNinjaGenerator::AppendCustomCommandLines(
for (unsigned i = 0; i != ccg.GetNumberOfCommands(); ++i) {
cmdLines.push_back(launcher +
- this->ConvertToOutputFormat(ccg.GetCommand(i),
- cmOutputConverter::SHELL));
+ this->ConvertToOutputFormat(
+ ccg.GetCommand(i),
+ gg->IsMultiConfig() ? cmOutputConverter::NINJAMULTI
+ : cmOutputConverter::SHELL));
std::string& cmd = cmdLines.back();
ccg.AppendArguments(i, cmd);
@@ -446,14 +506,15 @@ void cmLocalNinjaGenerator::AppendCustomCommandLines(
}
void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
- cmCustomCommand const* cc, const cmNinjaDeps& orderOnlyDeps)
+ cmCustomCommand const* cc, const cmNinjaDeps& orderOnlyDeps,
+ const std::string& config)
{
cmGlobalNinjaGenerator* gg = this->GetGlobalNinjaGenerator();
- if (gg->SeenCustomCommand(cc)) {
+ if (gg->SeenCustomCommand(cc, config)) {
return;
}
- cmCustomCommandGenerator ccg(*cc, this->GetConfigName(), this);
+ cmCustomCommandGenerator ccg(*cc, config, this);
const std::vector<std::string>& outputs = ccg.GetOutputs();
const std::vector<std::string>& byproducts = ccg.GetByproducts();
@@ -484,7 +545,7 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
}
cmNinjaDeps ninjaDeps;
- this->AppendCustomCommandDeps(ccg, ninjaDeps);
+ this->AppendCustomCommandDeps(ccg, ninjaDeps, config);
std::vector<std::string> cmdLines;
this->AppendCustomCommandLines(ccg, cmdLines);
@@ -495,7 +556,7 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
build.Outputs = std::move(ninjaOutputs);
build.ExplicitDeps = std::move(ninjaDeps);
build.OrderOnlyDeps = orderOnlyDeps;
- gg->WriteBuild(this->GetBuildFileStream(), build);
+ gg->WriteBuild(this->GetImplFileStream(config), build);
} else {
std::string customStep = cmSystemTools::GetFilenameName(ninjaOutputs[0]);
// Hash full path to make unique.
@@ -507,8 +568,8 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
this->BuildCommandLine(cmdLines, customStep),
this->ConstructComment(ccg), "Custom command for " + ninjaOutputs[0],
cc->GetDepfile(), cc->GetJobPool(), cc->GetUsesTerminal(),
- /*restat*/ !symbolic || !byproducts.empty(), ninjaOutputs, ninjaDeps,
- orderOnlyDeps);
+ /*restat*/ !symbolic || !byproducts.empty(), ninjaOutputs, config,
+ ninjaDeps, orderOnlyDeps);
}
}
@@ -524,7 +585,8 @@ void cmLocalNinjaGenerator::AddCustomCommandTarget(cmCustomCommand const* cc,
ins.first->second.insert(target);
}
-void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements()
+void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements(
+ const std::string& config)
{
for (cmCustomCommand const* customCommand : this->CustomCommands) {
auto i = this->CustomCommandTargets.find(customCommand);
@@ -542,15 +604,16 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements()
auto j = i->second.begin();
assert(j != i->second.end());
std::vector<std::string> ccTargetDeps;
- this->GetGlobalNinjaGenerator()->AppendTargetDependsClosure(*j,
- ccTargetDeps);
+ this->GetGlobalNinjaGenerator()->AppendTargetDependsClosure(
+ *j, ccTargetDeps, config);
std::sort(ccTargetDeps.begin(), ccTargetDeps.end());
++j;
for (; j != i->second.end(); ++j) {
std::vector<std::string> jDeps;
std::vector<std::string> depsIntersection;
- this->GetGlobalNinjaGenerator()->AppendTargetDependsClosure(*j, jDeps);
+ this->GetGlobalNinjaGenerator()->AppendTargetDependsClosure(*j, jDeps,
+ config);
std::sort(jDeps.begin(), jDeps.end());
std::set_intersection(ccTargetDeps.begin(), ccTargetDeps.end(),
jDeps.begin(), jDeps.end(),
@@ -558,17 +621,16 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatements()
ccTargetDeps = depsIntersection;
}
- this->WriteCustomCommandBuildStatement(i->first, ccTargetDeps);
+ this->WriteCustomCommandBuildStatement(i->first, ccTargetDeps, config);
}
}
std::string cmLocalNinjaGenerator::MakeCustomLauncher(
cmCustomCommandGenerator const& ccg)
{
- const char* property_value =
- this->Makefile->GetProperty("RULE_LAUNCH_CUSTOM");
+ cmProp property_value = this->Makefile->GetProperty("RULE_LAUNCH_CUSTOM");
- if (!property_value || !*property_value) {
+ if (!property_value || property_value->empty()) {
return std::string();
}
@@ -590,7 +652,7 @@ std::string cmLocalNinjaGenerator::MakeCustomLauncher(
std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
this->CreateRulePlaceholderExpander());
- std::string launcher = property_value;
+ std::string launcher = *property_value;
rulePlaceholderExpander->ExpandRuleVariables(this, launcher, vars);
if (!launcher.empty()) {
launcher += " ";
@@ -599,15 +661,13 @@ std::string cmLocalNinjaGenerator::MakeCustomLauncher(
return launcher;
}
-void cmLocalNinjaGenerator::AdditionalCleanFiles()
+void cmLocalNinjaGenerator::AdditionalCleanFiles(const std::string& config)
{
- if (const char* prop_value =
+ if (cmProp prop_value =
this->Makefile->GetProperty("ADDITIONAL_CLEAN_FILES")) {
std::vector<std::string> cleanFiles;
{
- cmExpandList(cmGeneratorExpression::Evaluate(
- prop_value, this,
- this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")),
+ cmExpandList(cmGeneratorExpression::Evaluate(*prop_value, this, config),
cleanFiles);
}
std::string const& binaryDir = this->GetCurrentBinaryDirectory();
@@ -615,7 +675,7 @@ void cmLocalNinjaGenerator::AdditionalCleanFiles()
for (std::string const& cleanFile : cleanFiles) {
// Support relative paths
gg->AddAdditionalCleanFile(
- cmSystemTools::CollapseFullPath(cleanFile, binaryDir));
+ cmSystemTools::CollapseFullPath(cleanFile, binaryDir), config);
}
}
}
diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h
index f64534c..ef160e7 100644
--- a/Source/cmLocalNinjaGenerator.h
+++ b/Source/cmLocalNinjaGenerator.h
@@ -64,9 +64,11 @@ public:
std::string const& customStep = std::string(),
cmGeneratorTarget const* target = nullptr) const;
- void AppendTargetOutputs(cmGeneratorTarget* target, cmNinjaDeps& outputs);
+ void AppendTargetOutputs(cmGeneratorTarget* target, cmNinjaDeps& outputs,
+ const std::string& config);
void AppendTargetDepends(
- cmGeneratorTarget* target, cmNinjaDeps& outputs,
+ cmGeneratorTarget* target, cmNinjaDeps& outputs, const std::string& config,
+ const std::string& fileConfig,
cmNinjaTargetDepends depends = DependOnTargetArtifact);
void AddCustomCommandTarget(cmCustomCommand const* cc,
@@ -74,7 +76,8 @@ public:
void AppendCustomCommandLines(cmCustomCommandGenerator const& ccg,
std::vector<std::string>& cmdLines);
void AppendCustomCommandDeps(cmCustomCommandGenerator const& ccg,
- cmNinjaDeps& ninjaDeps);
+ cmNinjaDeps& ninjaDeps,
+ const std::string& config);
protected:
std::string ConvertToIncludeReference(
@@ -83,20 +86,25 @@ protected:
bool forceFullPaths = false) override;
private:
- cmGeneratedFileStream& GetBuildFileStream() const;
+ cmGeneratedFileStream& GetImplFileStream(const std::string& config) const;
+ cmGeneratedFileStream& GetCommonFileStream() const;
cmGeneratedFileStream& GetRulesFileStream() const;
void WriteBuildFileTop();
void WriteProjectHeader(std::ostream& os);
void WriteNinjaRequiredVersion(std::ostream& os);
- void WriteNinjaFilesInclusion(std::ostream& os);
+ void WriteNinjaConfigurationVariable(std::ostream& os,
+ const std::string& config);
+ void WriteNinjaFilesInclusionConfig(std::ostream& os);
+ void WriteNinjaFilesInclusionCommon(std::ostream& os);
void WriteProcessedMakefile(std::ostream& os);
void WritePools(std::ostream& os);
void WriteCustomCommandBuildStatement(cmCustomCommand const* cc,
- const cmNinjaDeps& orderOnlyDeps);
+ const cmNinjaDeps& orderOnlyDeps,
+ const std::string& config);
- void WriteCustomCommandBuildStatements();
+ void WriteCustomCommandBuildStatements(const std::string& config);
std::string MakeCustomLauncher(cmCustomCommandGenerator const& ccg);
@@ -104,7 +112,7 @@ private:
std::string const& customStep,
cmGeneratorTarget const* target) const;
- void AdditionalCleanFiles();
+ void AdditionalCleanFiles(const std::string& config);
std::string HomeRelativeOutputPath;
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 6f2183d..4c7c8c4 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -3,16 +3,18 @@
#include "cmLocalUnixMakefileGenerator3.h"
#include <algorithm>
+#include <cassert>
#include <cstdio>
#include <sstream>
#include <utility>
#include <cm/memory>
+#include <cm/vector>
+#include <cmext/algorithm>
#include "cmsys/FStream.hxx"
#include "cmsys/Terminal.h"
-#include "cmAlgorithms.h"
#include "cmCustomCommand.h" // IWYU pragma: keep
#include "cmCustomCommandGenerator.h"
#include "cmFileTimeCache.h"
@@ -46,37 +48,6 @@
# include "cmDependsJava.h"
#endif
-// Escape special characters in Makefile dependency lines
-class cmMakeSafe
-{
-public:
- cmMakeSafe(const char* s)
- : Data(s)
- {
- }
- cmMakeSafe(std::string const& s)
- : Data(s.c_str())
- {
- }
-
-private:
- const char* Data;
- friend std::ostream& operator<<(std::ostream& os, cmMakeSafe const& self)
- {
- for (const char* c = self.Data; *c; ++c) {
- switch (*c) {
- case '=':
- os << "$(EQUALS)";
- break;
- default:
- os << *c;
- break;
- }
- }
- return os;
- }
-};
-
// Helper function used below.
static std::string cmSplitExtension(std::string const& in, std::string& base)
{
@@ -106,6 +77,13 @@ cmLocalUnixMakefileGenerator3::cmLocalUnixMakefileGenerator3(
cmLocalUnixMakefileGenerator3::~cmLocalUnixMakefileGenerator3() = default;
+std::string cmLocalUnixMakefileGenerator3::GetConfigName() const
+{
+ auto const& configNames = this->GetConfigNames();
+ assert(configNames.size() == 1);
+ return configNames.front();
+}
+
void cmLocalUnixMakefileGenerator3::Generate()
{
// Record whether some options are enabled to avoid checking many
@@ -121,12 +99,12 @@ void cmLocalUnixMakefileGenerator3::Generate()
// Generate the rule files for each target.
cmGlobalUnixMakefileGenerator3* gg =
static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
- for (cmGeneratorTarget* target : this->GetGeneratorTargets()) {
+ for (const auto& target : this->GetGeneratorTargets()) {
if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
std::unique_ptr<cmMakefileTargetGenerator> tg(
- cmMakefileTargetGenerator::New(target));
+ cmMakefileTargetGenerator::New(target.get()));
if (tg) {
tg->WriteRuleFiles();
gg->RecordTargetProgress(tg.get());
@@ -157,15 +135,15 @@ void cmLocalUnixMakefileGenerator3::ComputeHomeRelativeOutputPath()
void cmLocalUnixMakefileGenerator3::GetLocalObjectFiles(
std::map<std::string, LocalObjectInfo>& localObjectFiles)
{
- for (cmGeneratorTarget* gt : this->GetGeneratorTargets()) {
+ for (const auto& gt : this->GetGeneratorTargets()) {
if (gt->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
std::vector<cmSourceFile const*> objectSources;
- gt->GetObjectSources(objectSources, this->ConfigName);
+ gt->GetObjectSources(objectSources, this->GetConfigName());
// Compute full path to object file directory for this target.
std::string dir = cmStrCat(gt->LocalGenerator->GetCurrentBinaryDirectory(),
- '/', this->GetTargetDirectory(gt), '/');
+ '/', this->GetTargetDirectory(gt.get()), '/');
// Compute the name of each object file.
for (cmSourceFile const* sf : objectSources) {
bool hasSourceExtension = true;
@@ -176,7 +154,7 @@ void cmLocalUnixMakefileGenerator3::GetLocalObjectFiles(
}
LocalObjectInfo& info = localObjectFiles[objectName];
info.HasSourceExtension = hasSourceExtension;
- info.emplace_back(gt, sf->GetLanguage());
+ info.emplace_back(gt.get(), sf->GetLanguage());
}
}
}
@@ -352,7 +330,7 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefileTargets(
// for each target we just provide a rule to cd up to the top and do a make
// on the target
std::string localName;
- for (cmGeneratorTarget* target : this->GetGeneratorTargets()) {
+ for (const auto& target : this->GetGeneratorTargets()) {
if ((target->GetType() == cmStateEnums::EXECUTABLE) ||
(target->GetType() == cmStateEnums::STATIC_LIBRARY) ||
(target->GetType() == cmStateEnums::SHARED_LIBRARY) ||
@@ -362,7 +340,8 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefileTargets(
emitted.insert(target->GetName());
// for subdirs add a rule to build this specific target by name.
- localName = cmStrCat(this->GetRelativeTargetDirectory(target), "/rule");
+ localName =
+ cmStrCat(this->GetRelativeTargetDirectory(target.get()), "/rule");
commands.clear();
depends.clear();
@@ -383,11 +362,11 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefileTargets(
}
// Add a fast rule to build the target
- std::string makefileName =
- cmStrCat(this->GetRelativeTargetDirectory(target), "/build.make");
+ std::string makefileName = cmStrCat(
+ this->GetRelativeTargetDirectory(target.get()), "/build.make");
// make sure the makefile name is suitable for a makefile
std::string makeTargetName =
- cmStrCat(this->GetRelativeTargetDirectory(target), "/build");
+ cmStrCat(this->GetRelativeTargetDirectory(target.get()), "/build");
localName = cmStrCat(target->GetName(), "/fast");
depends.clear();
commands.clear();
@@ -400,9 +379,9 @@ void cmLocalUnixMakefileGenerator3::WriteLocalMakefileTargets(
// Add a local name for the rule to relink the target before
// installation.
- if (target->NeedRelinkBeforeInstall(this->ConfigName)) {
- makeTargetName =
- cmStrCat(this->GetRelativeTargetDirectory(target), "/preinstall");
+ if (target->NeedRelinkBeforeInstall(this->GetConfigName())) {
+ makeTargetName = cmStrCat(
+ this->GetRelativeTargetDirectory(target.get()), "/preinstall");
localName = cmStrCat(target->GetName(), "/preinstall");
depends.clear();
commands.clear();
@@ -488,6 +467,14 @@ const std::string& cmLocalUnixMakefileGenerator3::GetHomeRelativeOutputPath()
return this->HomeRelativeOutputPath;
}
+std::string cmLocalUnixMakefileGenerator3::ConvertToMakefilePath(
+ std::string const& path) const
+{
+ cmGlobalUnixMakefileGenerator3* gg =
+ static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
+ return gg->ConvertToMakefilePath(path);
+}
+
void cmLocalUnixMakefileGenerator3::WriteMakeRule(
std::ostream& os, const char* comment, const std::string& target,
const std::vector<std::string>& depends,
@@ -518,7 +505,7 @@ void cmLocalUnixMakefileGenerator3::WriteMakeRule(
}
// Construct the left hand side of the rule.
- std::string tgt = cmSystemTools::ConvertToOutputPath(
+ std::string tgt = this->ConvertToMakefilePath(
this->MaybeConvertToRelativePath(this->GetBinaryDirectory(), target));
const char* space = "";
@@ -532,30 +519,30 @@ void cmLocalUnixMakefileGenerator3::WriteMakeRule(
if (symbolic) {
if (const char* sym =
this->Makefile->GetDefinition("CMAKE_MAKE_SYMBOLIC_RULE")) {
- os << cmMakeSafe(tgt) << space << ": " << sym << "\n";
+ os << tgt << space << ": " << sym << "\n";
}
}
// Write the rule.
if (depends.empty()) {
// No dependencies. The commands will always run.
- os << cmMakeSafe(tgt) << space << ":\n";
+ os << tgt << space << ":\n";
} else {
// Split dependencies into multiple rule lines. This allows for
// very long dependency lists even on older make implementations.
std::string binDir = this->GetBinaryDirectory();
for (std::string const& depend : depends) {
- replace = depend;
- replace = cmSystemTools::ConvertToOutputPath(
- this->MaybeConvertToRelativePath(binDir, replace));
- os << cmMakeSafe(tgt) << space << ": " << cmMakeSafe(replace) << "\n";
+ os << tgt << space << ": "
+ << this->ConvertToMakefilePath(
+ this->MaybeConvertToRelativePath(binDir, depend))
+ << '\n';
}
}
// Write the list of commands.
os << cmWrap("\t", commands, "", "\n") << "\n";
if (symbolic && !this->IsWatcomWMake()) {
- os << ".PHONY : " << cmMakeSafe(tgt) << "\n";
+ os << ".PHONY : " << tgt << "\n";
}
os << "\n";
// Add the output to the local help if requested.
@@ -613,8 +600,7 @@ void cmLocalUnixMakefileGenerator3::WriteMakeVariables(
this->MaybeConvertWatcomShellCommand(cmSystemTools::GetCMakeCommand());
if (cmakeShellCommand.empty()) {
cmakeShellCommand = this->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(cmSystemTools::GetCMakeCommand()),
- cmOutputConverter::SHELL);
+ cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL);
}
/* clang-format off */
@@ -628,7 +614,7 @@ void cmLocalUnixMakefileGenerator3::WriteMakeVariables(
<< "# The command to remove a file.\n"
<< "RM = "
<< cmakeShellCommand
- << " -E remove -f\n"
+ << " -E rm -f\n"
<< "\n";
makefileStream
<< "# Escaping for special characters.\n"
@@ -638,16 +624,14 @@ void cmLocalUnixMakefileGenerator3::WriteMakeVariables(
<< "# The top-level source directory on which CMake was run.\n"
<< "CMAKE_SOURCE_DIR = "
<< this->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(this->GetSourceDirectory()),
- cmOutputConverter::SHELL)
+ this->GetSourceDirectory(), cmOutputConverter::SHELL)
<< "\n"
<< "\n";
makefileStream
<< "# The top-level build directory on which CMake was run.\n"
<< "CMAKE_BINARY_DIR = "
<< this->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(this->GetBinaryDirectory()),
- cmOutputConverter::SHELL)
+ this->GetBinaryDirectory(), cmOutputConverter::SHELL)
<< "\n"
<< "\n";
/* clang-format on */
@@ -673,9 +657,15 @@ void cmLocalUnixMakefileGenerator3::WriteSpecialTargetsTop(
if (!this->IsNMake() && !this->IsWatcomWMake() &&
!this->BorlandMakeCurlyHack) {
// turn off RCS and SCCS automatic stuff from gmake
- makefileStream
- << "# Remove some rules from gmake that .SUFFIXES does not remove.\n"
- << "SUFFIXES =\n\n";
+ constexpr const char* vcs_rules[] = {
+ "%,v", "RCS/%", "RCS/%,v", "SCCS/s.%", "s.%",
+ };
+ for (auto vcs_rule : vcs_rules) {
+ std::vector<std::string> vcs_depend;
+ vcs_depend.emplace_back(vcs_rule);
+ this->WriteMakeRule(makefileStream, "Disable VCS-based implicit rules.",
+ "%", vcs_depend, no_commands, false);
+ }
}
// Add a fake suffix to keep HP happy. Must be max 32 chars for SGI make.
std::vector<std::string> depends;
@@ -853,7 +843,7 @@ void cmLocalUnixMakefileGenerator3::AppendRuleDepends(
// Add a dependency on the rule file itself unless an option to skip
// it is specifically enabled by the user or project.
if (!this->Makefile->IsOn("CMAKE_SKIP_RULE_DEPENDENCY")) {
- cmAppend(depends, ruleFiles);
+ cm::append(depends, ruleFiles);
}
}
@@ -861,7 +851,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomDepends(
std::vector<std::string>& depends, const std::vector<cmCustomCommand>& ccs)
{
for (cmCustomCommand const& cc : ccs) {
- cmCustomCommandGenerator ccg(cc, this->ConfigName, this);
+ cmCustomCommandGenerator ccg(cc, this->GetConfigName(), this);
this->AppendCustomDepend(depends, ccg);
}
}
@@ -872,7 +862,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomDepend(
for (std::string const& d : ccg.GetDepends()) {
// Lookup the real name of the dependency in case it is a CMake target.
std::string dep;
- if (this->GetRealDependency(d, this->ConfigName, dep)) {
+ if (this->GetRealDependency(d, this->GetConfigName(), dep)) {
depends.push_back(std::move(dep));
}
}
@@ -883,7 +873,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommands(
cmGeneratorTarget* target, std::string const& relative)
{
for (cmCustomCommand const& cc : ccs) {
- cmCustomCommandGenerator ccg(cc, this->ConfigName, this);
+ cmCustomCommandGenerator ccg(cc, this->GetConfigName(), this);
this->AppendCustomCommand(commands, ccg, target, relative, true);
}
}
@@ -962,7 +952,8 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand(
// Expand rule variables referenced in the given launcher command.
cmRulePlaceholderExpander::RuleVariables vars;
vars.CMTargetName = target->GetName().c_str();
- vars.CMTargetType = cmState::GetTargetTypeName(target->GetType());
+ vars.CMTargetType =
+ cmState::GetTargetTypeName(target->GetType()).c_str();
std::string output;
const std::vector<std::string>& outputs = ccg.GetOutputs();
if (!outputs.empty()) {
@@ -1026,7 +1017,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand(
this->CreateCDCommand(commands1, dir, relative);
// push back the custom commands
- cmAppend(commands, commands1);
+ cm::append(commands, commands1);
}
void cmLocalUnixMakefileGenerator3::AppendCleanCommand(
@@ -1041,10 +1032,9 @@ void cmLocalUnixMakefileGenerator3::AppendCleanCommand(
cleanfile += filename;
}
cleanfile += ".cmake";
- std::string cleanfilePath = cmSystemTools::CollapseFullPath(cleanfile);
- cmsys::ofstream fout(cleanfilePath.c_str());
+ cmsys::ofstream fout(cleanfile.c_str());
if (!fout) {
- cmSystemTools::Error("Could not create " + cleanfilePath);
+ cmSystemTools::Error("Could not create " + cleanfile);
}
if (!files.empty()) {
fout << "file(REMOVE_RECURSE\n";
@@ -1086,10 +1076,10 @@ void cmLocalUnixMakefileGenerator3::AppendDirectoryCleanCommand(
{
std::vector<std::string> cleanFiles;
// Look for additional files registered for cleaning in this directory.
- if (const char* prop_value =
+ if (cmProp prop_value =
this->Makefile->GetProperty("ADDITIONAL_CLEAN_FILES")) {
cmExpandList(cmGeneratorExpression::Evaluate(
- prop_value, this,
+ *prop_value, this,
this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")),
cleanFiles);
}
@@ -1097,18 +1087,16 @@ void cmLocalUnixMakefileGenerator3::AppendDirectoryCleanCommand(
return;
}
- cmLocalGenerator* rootLG =
- this->GetGlobalGenerator()->GetLocalGenerators().at(0);
+ const auto& rootLG = this->GetGlobalGenerator()->GetLocalGenerators().at(0);
std::string const& binaryDir = rootLG->GetCurrentBinaryDirectory();
std::string const& currentBinaryDir = this->GetCurrentBinaryDirectory();
std::string cleanfile =
cmStrCat(currentBinaryDir, "/CMakeFiles/cmake_directory_clean.cmake");
// Write clean script
{
- std::string cleanfilePath = cmSystemTools::CollapseFullPath(cleanfile);
- cmsys::ofstream fout(cleanfilePath.c_str());
+ cmsys::ofstream fout(cleanfile.c_str());
if (!fout) {
- cmSystemTools::Error("Could not create " + cleanfilePath);
+ cmSystemTools::Error("Could not create " + cleanfile);
return;
}
fout << "file(REMOVE_RECURSE\n";
@@ -1179,9 +1167,8 @@ void cmLocalUnixMakefileGenerator3::AppendEcho(
color_name);
if (progress) {
cmd += "--progress-dir=";
- cmd += this->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(progress->Dir),
- cmOutputConverter::SHELL);
+ cmd += this->ConvertToOutputFormat(progress->Dir,
+ cmOutputConverter::SHELL);
cmd += " ";
cmd += "--progress-num=";
cmd += progress->Arg;
@@ -1316,10 +1303,9 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(
int result;
if (!ftc->Compare(internalDependFile, tgtInfo, &result) || result < 0) {
if (verbose) {
- std::ostringstream msg;
- msg << "Dependee \"" << tgtInfo << "\" is newer than depender \""
- << internalDependFile << "\"." << std::endl;
- cmSystemTools::Stdout(msg.str());
+ cmSystemTools::Stdout(cmStrCat("Dependee \"", tgtInfo,
+ "\" is newer than depender \"",
+ internalDependFile, "\".\n"));
}
needRescanDependInfo = true;
}
@@ -1336,10 +1322,9 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(
if (!ftc->Compare(internalDependFile, dirInfoFile, &result) ||
result < 0) {
if (verbose) {
- std::ostringstream msg;
- msg << "Dependee \"" << dirInfoFile << "\" is newer than depender \""
- << internalDependFile << "\"." << std::endl;
- cmSystemTools::Stdout(msg.str());
+ cmSystemTools::Stdout(cmStrCat("Dependee \"", dirInfoFile,
+ "\" is newer than depender \"",
+ internalDependFile, "\".\n"));
}
needRescanDirInfo = true;
}
@@ -1505,11 +1490,9 @@ void cmLocalUnixMakefileGenerator3::CheckMultipleOutputs(bool verbose)
if (cmSystemTools::FileExists(dependee) &&
!cmSystemTools::FileExists(depender)) {
if (verbose) {
- std::ostringstream msg;
- msg << "Deleting primary custom command output \"" << dependee
- << "\" because another output \"" << depender
- << "\" does not exist." << std::endl;
- cmSystemTools::Stdout(msg.str());
+ cmSystemTools::Stdout(cmStrCat(
+ "Deleting primary custom command output \"", dependee,
+ "\" because another output \"", depender, "\" does not exist.\n"));
}
cmSystemTools::RemoveFile(dependee);
}
@@ -1555,21 +1538,19 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules(
this->WriteDivider(ruleFileStream);
ruleFileStream << "# Targets provided globally by CMake.\n"
<< "\n";
- const std::vector<cmGeneratorTarget*>& targets = this->GetGeneratorTargets();
- for (cmGeneratorTarget* gt : targets) {
+ const auto& targets = this->GetGeneratorTargets();
+ for (const auto& gt : targets) {
if (gt->GetType() == cmStateEnums::GLOBAL_TARGET) {
std::string targetString =
"Special rule for the target " + gt->GetName();
std::vector<std::string> commands;
std::vector<std::string> depends;
- const char* text = gt->GetProperty("EchoString");
- if (!text) {
- text = "Running external command ...";
- }
+ cmProp p = gt->GetProperty("EchoString");
+ const char* text = p ? p->c_str() : "Running external command ...";
depends.reserve(gt->GetUtilities().size());
- for (BT<std::string> const& u : gt->GetUtilities()) {
- depends.push_back(u.Value);
+ for (BT<std::pair<std::string, bool>> const& u : gt->GetUtilities()) {
+ depends.push_back(u.Value.first);
}
this->AppendEcho(commands, text,
cmLocalUnixMakefileGenerator3::EchoGlobal);
@@ -1577,10 +1558,10 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules(
// Global targets store their rules in pre- and post-build commands.
this->AppendCustomDepends(depends, gt->GetPreBuildCommands());
this->AppendCustomDepends(depends, gt->GetPostBuildCommands());
- this->AppendCustomCommands(commands, gt->GetPreBuildCommands(), gt,
- this->GetCurrentBinaryDirectory());
- this->AppendCustomCommands(commands, gt->GetPostBuildCommands(), gt,
+ this->AppendCustomCommands(commands, gt->GetPreBuildCommands(), gt.get(),
this->GetCurrentBinaryDirectory());
+ this->AppendCustomCommands(commands, gt->GetPostBuildCommands(),
+ gt.get(), this->GetCurrentBinaryDirectory());
std::string targetName = gt->GetName();
this->WriteMakeRule(ruleFileStream, targetString.c_str(), targetName,
depends, commands, true);
@@ -1621,15 +1602,14 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules(
{
std::ostringstream progCmd;
progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start ";
- progCmd << this->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(progressDir), cmOutputConverter::SHELL);
+ progCmd << this->ConvertToOutputFormat(progressDir,
+ cmOutputConverter::SHELL);
std::string progressFile = "/CMakeFiles/progress.marks";
std::string progressFileNameFull = this->ConvertToFullPath(progressFile);
progCmd << " "
- << this->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(progressFileNameFull),
- cmOutputConverter::SHELL);
+ << this->ConvertToOutputFormat(progressFileNameFull,
+ cmOutputConverter::SHELL);
commands.push_back(progCmd.str());
}
std::string mf2Dir = "CMakeFiles/Makefile2";
@@ -1639,8 +1619,8 @@ void cmLocalUnixMakefileGenerator3::WriteLocalAllRules(
{
std::ostringstream progCmd;
progCmd << "$(CMAKE_COMMAND) -E cmake_progress_start "; // # 0
- progCmd << this->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(progressDir), cmOutputConverter::SHELL);
+ progCmd << this->ConvertToOutputFormat(progressDir,
+ cmOutputConverter::SHELL);
progCmd << " 0";
commands.push_back(progCmd.str());
}
@@ -1773,7 +1753,7 @@ private:
const std::string& testDir)
{
// First check if the test directory "starts with" the base directory:
- if (testDir.find(baseDir) != 0) {
+ if (!cmHasPrefix(testDir, baseDir)) {
return false;
}
// If it does, then check that it's either the same string, or that the
@@ -1843,7 +1823,7 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo(
// Build a list of preprocessor definitions for the target.
std::set<std::string> defines;
- this->GetTargetDefines(target, this->ConfigName, implicitLang.first,
+ this->GetTargetDefines(target, this->GetConfigName(), implicitLang.first,
defines);
if (!defines.empty()) {
/* clang-format off */
@@ -1867,11 +1847,11 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo(
std::vector<std::string> includes;
this->GetIncludeDirectories(includes, target, implicitLang.first,
- this->ConfigName);
+ this->GetConfigName());
std::string binaryDir = this->GetState()->GetBinaryDirectory();
if (this->Makefile->IsOn("CMAKE_DEPENDS_IN_PROJECT_ONLY")) {
std::string const& sourceDir = this->GetState()->GetSourceDirectory();
- cmEraseIf(includes, ::NotInProjectDir(sourceDir, binaryDir));
+ cm::erase_if(includes, ::NotInProjectDir(sourceDir, binaryDir));
}
for (std::string const& include : includes) {
cmakefileStream << " \""
@@ -1884,13 +1864,13 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo(
// Store include transform rule properties. Write the directory
// rules first because they may be overridden by later target rules.
std::vector<std::string> transformRules;
- if (const char* xform =
+ if (cmProp xform =
this->Makefile->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) {
- cmExpandList(xform, transformRules);
+ cmExpandList(*xform, transformRules);
}
- if (const char* xform =
+ if (cmProp xform =
target->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) {
- cmExpandList(xform, transformRules);
+ cmExpandList(*xform, transformRules);
}
if (!transformRules.empty()) {
cmakefileStream << "set(CMAKE_INCLUDE_TRANSFORMS\n";
@@ -1957,25 +1937,25 @@ std::string cmLocalUnixMakefileGenerator3::GetRecursiveMakeCall(
void cmLocalUnixMakefileGenerator3::WriteDivider(std::ostream& os)
{
os << "#======================================"
- << "=======================================\n";
+ "=======================================\n";
}
void cmLocalUnixMakefileGenerator3::WriteCMakeArgument(std::ostream& os,
- const char* s)
+ const std::string& s)
{
// Write the given string to the stream with escaping to get it back
// into CMake through the lexical scanner.
- os << "\"";
- for (const char* c = s; *c; ++c) {
- if (*c == '\\') {
+ os << '"';
+ for (char c : s) {
+ if (c == '\\') {
os << "\\\\";
- } else if (*c == '"') {
+ } else if (c == '"') {
os << "\\\"";
} else {
- os << *c;
+ os << c;
}
}
- os << "\"";
+ os << '"';
}
std::string cmLocalUnixMakefileGenerator3::ConvertToQuotedOutputPath(
diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h
index f12ae8b..2b07952 100644
--- a/Source/cmLocalUnixMakefileGenerator3.h
+++ b/Source/cmLocalUnixMakefileGenerator3.h
@@ -33,6 +33,8 @@ public:
cmLocalUnixMakefileGenerator3(cmGlobalGenerator* gg, cmMakefile* mf);
~cmLocalUnixMakefileGenerator3() override;
+ std::string GetConfigName() const;
+
void ComputeHomeRelativeOutputPath() override;
/**
@@ -44,6 +46,12 @@ public:
// local generators StartOutputDirectory
const std::string& GetHomeRelativeOutputPath();
+ /**
+ * Convert a file path to a Makefile target or dependency with
+ * escaping and quoting suitable for the generator's make tool.
+ */
+ std::string ConvertToMakefilePath(std::string const& path) const;
+
// Write out a make rule
void WriteMakeRule(std::ostream& os, const char* comment,
const std::string& target,
@@ -75,7 +83,7 @@ public:
void SetBorlandMakeCurlyHack(bool b) { this->BorlandMakeCurlyHack = b; }
// used in writing out Cmake files such as WriteDirectoryInformation
- static void WriteCMakeArgument(std::ostream& os, const char* s);
+ static void WriteCMakeArgument(std::ostream& os, const std::string& s);
/** creates the common disclaimer text at the top of each makefile */
void WriteDisclaimer(std::ostream& os);
diff --git a/Source/cmLocalVisualStudio10Generator.cxx b/Source/cmLocalVisualStudio10Generator.cxx
index f3d828b..9076e26 100644
--- a/Source/cmLocalVisualStudio10Generator.cxx
+++ b/Source/cmLocalVisualStudio10Generator.cxx
@@ -2,8 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmLocalVisualStudio10Generator.h"
-#include "cm_expat.h"
+#include <cmext/algorithm>
+#include <cm3p/expat.h>
+
+#include "cmAlgorithms.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalVisualStudio10Generator.h"
#include "cmMakefile.h"
@@ -101,10 +104,11 @@ void cmLocalVisualStudio10Generator::GenerateTargetsDepthFirst(
void cmLocalVisualStudio10Generator::Generate()
{
- std::vector<cmGeneratorTarget*> remaining = this->GetGeneratorTargets();
+ std::vector<cmGeneratorTarget*> remaining;
+ cm::append(remaining, this->GetGeneratorTargets());
for (auto& t : remaining) {
if (t) {
- GenerateTargetsDepthFirst(t, remaining);
+ this->GenerateTargetsDepthFirst(t, remaining);
}
}
this->WriteStampFiles();
@@ -124,8 +128,7 @@ void cmLocalVisualStudio10Generator::ReadAndStoreExternalGUID(
std::string guidStoreName = cmStrCat(name, "_GUID_CMAKE");
// save the GUID in the cache
this->GlobalGenerator->GetCMakeInstance()->AddCacheEntry(
- guidStoreName.c_str(), parser.GUID.c_str(), "Stored GUID",
- cmStateEnums::INTERNAL);
+ guidStoreName, parser.GUID.c_str(), "Stored GUID", cmStateEnums::INTERNAL);
}
const char* cmLocalVisualStudio10Generator::ReportErrorLabel() const
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index e771a4a..0b02724 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -2,12 +2,14 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmLocalVisualStudio7Generator.h"
+#include <cm/memory>
+#include <cmext/algorithm>
+
#include <windows.h>
+#include <cm3p/expat.h>
#include <ctype.h> // for isspace
-#include "cm_expat.h"
-
#include "cmComputeLinkInformation.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
@@ -18,6 +20,7 @@
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmSourceFile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmXMLParser.h"
#include "cmake.h"
@@ -52,26 +55,23 @@ extern cmVS7FlagTable cmLocalVisualStudio7GeneratorFlagTable[];
cmLocalVisualStudio7Generator::cmLocalVisualStudio7Generator(
cmGlobalGenerator* gg, cmMakefile* mf)
: cmLocalVisualStudioGenerator(gg, mf)
+ , Internal(cm::make_unique<cmLocalVisualStudio7GeneratorInternals>(this))
{
- this->Internal = new cmLocalVisualStudio7GeneratorInternals(this);
}
-cmLocalVisualStudio7Generator::~cmLocalVisualStudio7Generator()
-{
- delete this->Internal;
-}
+cmLocalVisualStudio7Generator::~cmLocalVisualStudio7Generator() = default;
void cmLocalVisualStudio7Generator::AddHelperCommands()
{
// Now create GUIDs for targets
- const std::vector<cmGeneratorTarget*>& tgts = this->GetGeneratorTargets();
- for (cmGeneratorTarget const* l : tgts) {
+ const auto& tgts = this->GetGeneratorTargets();
+ for (const auto& l : tgts) {
if (l->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
- const char* path = l->GetProperty("EXTERNAL_MSPROJECT");
+ cmProp path = l->GetProperty("EXTERNAL_MSPROJECT");
if (path) {
- this->ReadAndStoreExternalGUID(l->GetName(), path);
+ this->ReadAndStoreExternalGUID(l->GetName(), path->c_str());
}
}
@@ -89,8 +89,8 @@ void cmLocalVisualStudio7Generator::FixGlobalTargets()
// Visual Studio .NET 2003 Service Pack 1 will not run post-build
// commands for targets in which no sources are built. Add dummy
// rules to force these targets to build.
- const std::vector<cmGeneratorTarget*>& tgts = this->GetGeneratorTargets();
- for (cmGeneratorTarget* l : tgts) {
+ const auto& tgts = this->GetGeneratorTargets();
+ for (auto& l : tgts) {
if (l->GetType() == cmStateEnums::GLOBAL_TARGET) {
std::vector<std::string> no_depends;
cmCustomCommandLines force_commands =
@@ -102,9 +102,9 @@ void cmLocalVisualStudio7Generator::FixGlobalTargets()
this->Makefile->GetOrCreateGeneratedSource(force)) {
sf->SetProperty("SYMBOLIC", "1");
}
- if (cmSourceFile* file = this->Makefile->AddCustomCommandToOutput(
- force.c_str(), no_depends, no_main_dependency, force_commands, " ",
- 0, true)) {
+ if (cmSourceFile* file = this->AddCustomCommandToOutput(
+ force, no_depends, no_main_dependency, force_commands, " ",
+ nullptr, true)) {
l->AddSource(file->ResolveFullPath());
}
}
@@ -125,17 +125,17 @@ void cmLocalVisualStudio7Generator::WriteProjectFiles()
}
// Get the set of targets in this directory.
- const std::vector<cmGeneratorTarget*>& tgts = this->GetGeneratorTargets();
+ const auto& tgts = this->GetGeneratorTargets();
// Create the project file for each target.
- for (cmGeneratorTarget* l : tgts) {
+ for (const auto& l : tgts) {
if (l->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
// INCLUDE_EXTERNAL_MSPROJECT command only affects the workspace
// so don't build a projectfile for it
if (!l->GetProperty("EXTERNAL_MSPROJECT")) {
- this->CreateSingleVCProj(l->GetName(), l);
+ this->CreateSingleVCProj(l->GetName(), l.get());
}
}
}
@@ -146,7 +146,7 @@ void cmLocalVisualStudio7Generator::WriteStampFiles()
// out of date.
std::string stampName =
cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles");
- cmSystemTools::MakeDirectory(stampName.c_str());
+ cmSystemTools::MakeDirectory(stampName);
stampName += "/generate.stamp";
cmsys::ofstream stamp(stampName.c_str());
stamp << "# CMake generation timestamp file for this directory.\n";
@@ -194,7 +194,7 @@ void cmLocalVisualStudio7Generator::CreateSingleVCProj(
}
// add to the list of projects
- target->Target->SetProperty("GENERATOR_FILE_NAME", lname.c_str());
+ target->Target->SetProperty("GENERATOR_FILE_NAME", lname);
// create the dsp.cmake file
std::string fname;
fname = cmStrCat(this->GetCurrentBinaryDirectory(), '/', lname);
@@ -226,7 +226,6 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule()
std::string makefileIn =
cmStrCat(this->GetCurrentSourceDirectory(), "/CMakeLists.txt");
- makefileIn = cmSystemTools::CollapseFullPath(makefileIn);
if (cmSourceFile* file = this->Makefile->GetSource(makefileIn)) {
if (file->GetCustomCommand()) {
return file;
@@ -252,17 +251,16 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule()
std::string argB = cmStrCat("-B", this->GetBinaryDirectory());
std::string stampName =
cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles/generate.stamp");
+ bool stdPipesUTF8 = true;
cmCustomCommandLines commandLines =
cmMakeSingleCommandLine({ cmSystemTools::GetCMakeCommand(), argS, argB,
"--check-stamp-file", stampName });
std::string comment = cmStrCat("Building Custom Rule ", makefileIn);
const char* no_working_directory = nullptr;
- std::string fullpathStampName =
- cmSystemTools::CollapseFullPath(stampName.c_str());
- this->Makefile->AddCustomCommandToOutput(
- fullpathStampName, listFiles, makefileIn, commandLines, comment.c_str(),
- no_working_directory, true, false);
- if (cmSourceFile* file = this->Makefile->GetSource(makefileIn.c_str())) {
+ this->AddCustomCommandToOutput(
+ stampName, listFiles, makefileIn, commandLines, comment.c_str(),
+ no_working_directory, true, false, false, false, "", "", stdPipesUTF8);
+ if (cmSourceFile* file = this->Makefile->GetSource(makefileIn)) {
// Finalize the source file path now since we're adding this after
// the generator validated all project-named sources.
file->ResolveFullPath();
@@ -279,7 +277,7 @@ void cmLocalVisualStudio7Generator::WriteConfigurations(
{
fout << "\t<Configurations>\n";
for (std::string const& config : configs) {
- this->WriteConfiguration(fout, config.c_str(), libName, target);
+ this->WriteConfiguration(fout, config, libName, target);
}
fout << "\t</Configurations>\n";
}
@@ -580,7 +578,7 @@ public:
this->Stream << this->LG->EscapeForXML("\n");
}
std::string script = this->LG->ConstructScript(ccg);
- this->Stream << this->LG->EscapeForXML(script.c_str());
+ this->Stream << this->LG->EscapeForXML(script);
}
private:
@@ -673,7 +671,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
if (this->FortranProject) {
switch (cmOutputConverter::GetFortranFormat(
- target->GetProperty("Fortran_FORMAT"))) {
+ target->GetSafeProperty("Fortran_FORMAT"))) {
case cmOutputConverter::FortranFormatFixed:
flags += " -fixed";
break;
@@ -733,13 +731,13 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
: target->GetDirectory(configName);
/* clang-format off */
fout << "\t\t\tOutputDirectory=\""
- << this->ConvertToXMLOutputPathSingle(outDir.c_str()) << "\"\n";
+ << this->ConvertToXMLOutputPathSingle(outDir) << "\"\n";
/* clang-format on */
}
/* clang-format off */
fout << "\t\t\tIntermediateDirectory=\""
- << this->ConvertToXMLOutputPath(intermediateDir.c_str())
+ << this->ConvertToXMLOutputPath(intermediateDir)
<< "\"\n"
<< "\t\t\tConfigurationType=\"" << configType << "\"\n"
<< "\t\t\tUseOfMFC=\"" << mfcFlag << "\"\n"
@@ -779,17 +777,15 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
fout << "\t\t\t<Tool\n"
<< "\t\t\t\tName=\"" << tool << "\"\n";
if (this->FortranProject) {
- const char* target_mod_dir =
- target->GetProperty("Fortran_MODULE_DIRECTORY");
+ cmProp target_mod_dir = target->GetProperty("Fortran_MODULE_DIRECTORY");
std::string modDir;
if (target_mod_dir) {
modDir = this->MaybeConvertToRelativePath(
- this->GetCurrentBinaryDirectory(), target_mod_dir);
+ this->GetCurrentBinaryDirectory(), *target_mod_dir);
} else {
modDir = ".";
}
- fout << "\t\t\t\tModulePath=\""
- << this->ConvertToXMLOutputPath(modDir.c_str())
+ fout << "\t\t\t\tModulePath=\"" << this->ConvertToXMLOutputPath(modDir)
<< "\\$(ConfigurationName)\"\n";
}
targetOptions.OutputAdditionalIncludeDirectories(
@@ -802,7 +798,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
std::string pdb = target->GetCompilePDBPath(configName);
if (!pdb.empty()) {
fout << "\t\t\t\tProgramDataBaseFileName=\""
- << this->ConvertToXMLOutputPathSingle(pdb.c_str()) << "\"\n";
+ << this->ConvertToXMLOutputPathSingle(pdb) << "\"\n";
}
}
fout << "/>\n"; // end of <Tool Name=VCCLCompilerTool
@@ -879,7 +875,7 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
fout << "\n\t\t\t\tAdditionalManifestFiles=\"";
for (cmSourceFile const* manifest : manifest_srcs) {
std::string m = manifest->GetFullPath();
- fout << this->ConvertToXMLOutputPath(m.c_str()) << ";";
+ fout << this->ConvertToXMLOutputPath(m) << ";";
}
fout << "\"";
}
@@ -939,17 +935,17 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
" " + GetBuildTypeLinkerFlags("CMAKE_MODULE_LINKER_FLAGS", configName);
}
- const char* targetLinkFlags = target->GetProperty("LINK_FLAGS");
+ cmProp targetLinkFlags = target->GetProperty("LINK_FLAGS");
if (targetLinkFlags) {
extraLinkOptions += " ";
- extraLinkOptions += targetLinkFlags;
+ extraLinkOptions += *targetLinkFlags;
}
std::string configTypeUpper = cmSystemTools::UpperCase(configName);
std::string linkFlagsConfig = cmStrCat("LINK_FLAGS_", configTypeUpper);
- targetLinkFlags = target->GetProperty(linkFlagsConfig.c_str());
+ targetLinkFlags = target->GetProperty(linkFlagsConfig);
if (targetLinkFlags) {
extraLinkOptions += " ";
- extraLinkOptions += targetLinkFlags;
+ extraLinkOptions += *targetLinkFlags;
}
std::vector<std::string> opts;
@@ -985,7 +981,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
fout << "\t\t\t<Tool\n"
<< "\t\t\t\tName=\"" << tool << "\"\n";
fout << "\t\t\t\tOutputFile=\""
- << this->ConvertToXMLOutputPathSingle(libpath.c_str()) << "\"/>\n";
+ << this->ConvertToXMLOutputPathSingle(libpath) << "\"/>\n";
break;
}
case cmStateEnums::STATIC_LIBRARY: {
@@ -1008,14 +1004,13 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
}
}
std::string libflags;
- this->GetStaticLibraryFlags(libflags, configTypeUpper,
- target->GetLinkerLanguage(configName),
- target);
+ this->GetStaticLibraryFlags(
+ libflags, configName, target->GetLinkerLanguage(configName), target);
if (!libflags.empty()) {
fout << "\t\t\t\tAdditionalOptions=\"" << libflags << "\"\n";
}
fout << "\t\t\t\tOutputFile=\""
- << this->ConvertToXMLOutputPathSingle(libpath.c_str()) << "\"/>\n";
+ << this->ConvertToXMLOutputPathSingle(libpath) << "\"/>\n";
break;
}
case cmStateEnums::SHARED_LIBRARY:
@@ -1057,7 +1052,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
temp =
cmStrCat(target->GetDirectory(configName), '/', targetNames.Output);
fout << "\t\t\t\tOutputFile=\""
- << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";
+ << this->ConvertToXMLOutputPathSingle(temp) << "\"\n";
this->WriteTargetVersionAttribute(fout, target);
linkOptions.OutputFlagMap(fout, 4);
fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
@@ -1066,7 +1061,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
temp =
cmStrCat(target->GetPDBDirectory(configName), '/', targetNames.PDB);
fout << "\t\t\t\tProgramDatabaseFile=\""
- << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";
+ << this->ConvertToXMLOutputPathSingle(temp) << "\"\n";
if (targetOptions.IsDebug()) {
fout << "\t\t\t\tGenerateDebugInformation=\"true\"\n";
}
@@ -1078,7 +1073,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
}
}
std::string stackVar = cmStrCat("CMAKE_", linkLanguage, "_STACK_SIZE");
- const char* stackVal = this->Makefile->GetDefinition(stackVar.c_str());
+ const char* stackVal = this->Makefile->GetDefinition(stackVar);
if (stackVal) {
fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\"\n";
}
@@ -1086,7 +1081,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
target->GetDirectory(configName, cmStateEnums::ImportLibraryArtifact),
'/', targetNames.ImportLibrary);
fout << "\t\t\t\tImportLibrary=\""
- << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"";
+ << this->ConvertToXMLOutputPathSingle(temp) << "\"";
if (this->FortranProject) {
fout << "\n\t\t\t\tLinkDLL=\"true\"";
}
@@ -1132,14 +1127,14 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
temp =
cmStrCat(target->GetDirectory(configName), '/', targetNames.Output);
fout << "\t\t\t\tOutputFile=\""
- << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"\n";
+ << this->ConvertToXMLOutputPathSingle(temp) << "\"\n";
this->WriteTargetVersionAttribute(fout, target);
linkOptions.OutputFlagMap(fout, 4);
fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
this->OutputLibraryDirectories(fout, cli.GetDirectories());
fout << "\"\n";
std::string path = this->ConvertToXMLOutputPathSingle(
- target->GetPDBDirectory(configName).c_str());
+ target->GetPDBDirectory(configName));
fout << "\t\t\t\tProgramDatabaseFile=\"" << path << "/"
<< targetNames.PDB << "\"\n";
if (targetOptions.IsDebug()) {
@@ -1167,7 +1162,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
<< "\"\n";
}
std::string stackVar = cmStrCat("CMAKE_", linkLanguage, "_STACK_SIZE");
- const char* stackVal = this->Makefile->GetDefinition(stackVar.c_str());
+ const char* stackVal = this->Makefile->GetDefinition(stackVar);
if (stackVal) {
fout << "\t\t\t\tStackReserveSize=\"" << stackVal << "\"";
}
@@ -1175,7 +1170,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(
target->GetDirectory(configName, cmStateEnums::ImportLibraryArtifact),
'/', targetNames.ImportLibrary);
fout << "\t\t\t\tImportLibrary=\""
- << this->ConvertToXMLOutputPathSingle(temp.c_str()) << "\"/>\n";
+ << this->ConvertToXMLOutputPathSingle(temp) << "\"/>\n";
break;
}
case cmStateEnums::UTILITY:
@@ -1208,8 +1203,8 @@ void cmLocalVisualStudio7Generator::OutputDeploymentDebuggerTool(
std::ostream& fout, std::string const& config, cmGeneratorTarget* target)
{
if (this->WindowsCEProject) {
- const char* dir = target->GetProperty("DEPLOYMENT_REMOTE_DIRECTORY");
- const char* additionalFiles =
+ cmProp dir = target->GetProperty("DEPLOYMENT_REMOTE_DIRECTORY");
+ cmProp additionalFiles =
target->GetProperty("DEPLOYMENT_ADDITIONAL_FILES");
if (dir == nullptr && additionalFiles == nullptr) {
@@ -1219,15 +1214,15 @@ void cmLocalVisualStudio7Generator::OutputDeploymentDebuggerTool(
fout << "\t\t\t<DeploymentTool\n"
"\t\t\t\tForceDirty=\"-1\"\n"
"\t\t\t\tRemoteDirectory=\""
- << GetEscapedPropertyIfValueNotNULL(dir)
+ << GetEscapedPropertyIfValueNotNULL(dir->c_str())
<< "\"\n"
"\t\t\t\tRegisterOutput=\"0\"\n"
"\t\t\t\tAdditionalFiles=\""
- << GetEscapedPropertyIfValueNotNULL(additionalFiles) << "\"/>\n";
+ << GetEscapedPropertyIfValueNotNULL(additionalFiles->c_str())
+ << "\"/>\n";
if (dir != nullptr) {
- std::string const exe =
- dir + std::string("\\") + target->GetFullName(config);
+ std::string const exe = *dir + "\\" + target->GetFullName(config);
fout << "\t\t\t<DebuggerTool\n"
"\t\t\t\tRemoteExecutable=\""
@@ -1256,8 +1251,8 @@ void cmLocalVisualStudio7GeneratorInternals::OutputLibraries(
for (auto const& lib : libs) {
if (lib.IsPath) {
std::string rel =
- lg->MaybeConvertToRelativePath(currentBinDir, lib.Value.Value.c_str());
- fout << lg->ConvertToXMLOutputPath(rel.c_str()) << " ";
+ lg->MaybeConvertToRelativePath(currentBinDir, lib.Value.Value);
+ fout << lg->ConvertToXMLOutputPath(rel) << " ";
} else if (!lib.Target ||
lib.Target->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
fout << lib.Value.Value << " ";
@@ -1282,7 +1277,7 @@ void cmLocalVisualStudio7GeneratorInternals::OutputObjects(
if (!obj->GetObjectLibrary().empty()) {
std::string const& objFile = obj->GetFullPath();
std::string rel = lg->MaybeConvertToRelativePath(currentBinDir, objFile);
- fout << sep << lg->ConvertToXMLOutputPath(rel.c_str());
+ fout << sep << lg->ConvertToXMLOutputPath(rel);
sep = " ";
}
}
@@ -1303,9 +1298,8 @@ void cmLocalVisualStudio7Generator::OutputLibraryDirectories(
}
// Switch to a relative path specification if it is shorter.
- if (cmSystemTools::FileIsFullPath(dir.c_str())) {
- std::string rel =
- this->MaybeConvertToRelativePath(currentBinDir, dir.c_str());
+ if (cmSystemTools::FileIsFullPath(dir)) {
+ std::string rel = this->MaybeConvertToRelativePath(currentBinDir, dir);
if (rel.size() < dir.size()) {
dir = rel;
}
@@ -1314,9 +1308,8 @@ void cmLocalVisualStudio7Generator::OutputLibraryDirectories(
// First search a configuration-specific subdirectory and then the
// original directory.
fout << comma
- << this->ConvertToXMLOutputPath(
- (dir + "/$(ConfigurationName)").c_str())
- << "," << this->ConvertToXMLOutputPath(dir.c_str());
+ << this->ConvertToXMLOutputPath(dir + "/$(ConfigurationName)") << ","
+ << this->ConvertToXMLOutputPath(dir);
comma = ",";
}
}
@@ -1337,7 +1330,7 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
// Add CMakeLists.txt file with rule to re-run CMake for user convenience.
if (target->GetType() != cmStateEnums::GLOBAL_TARGET &&
target->GetName() != CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
- if (cmSourceFile const* sf = this->CreateVCProjBuildRule()) {
+ if (cmSourceFile* sf = this->CreateVCProjBuildRule()) {
cmGeneratorTarget::AllConfigSource acs;
acs.Source = sf;
acs.Kind = cmGeneratorTarget::SourceKindCustomCommand;
@@ -1452,14 +1445,15 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
needfc = true;
}
const std::string COMPILE_FLAGS("COMPILE_FLAGS");
- if (const char* cflags = sf.GetProperty(COMPILE_FLAGS)) {
- fc.CompileFlags = genexInterpreter.Evaluate(cflags, COMPILE_FLAGS);
+ if (cmProp cflags = sf.GetProperty(COMPILE_FLAGS)) {
+ fc.CompileFlags = genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS);
needfc = true;
}
const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
- if (const char* coptions = sf.GetProperty(COMPILE_OPTIONS)) {
+ if (cmProp coptions = sf.GetProperty(COMPILE_OPTIONS)) {
lg->AppendCompileOptions(
- fc.CompileFlags, genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS));
+ fc.CompileFlags,
+ genexInterpreter.Evaluate(*coptions, COMPILE_OPTIONS));
needfc = true;
}
// Add precompile headers compile options.
@@ -1480,7 +1474,7 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
if (lg->FortranProject) {
switch (cmOutputConverter::GetFortranFormat(
- sf.GetProperty("Fortran_FORMAT"))) {
+ sf.GetSafeProperty("Fortran_FORMAT"))) {
case cmOutputConverter::FortranFormatFixed:
fc.CompileFlags = "-fixed " + fc.CompileFlags;
needfc = true;
@@ -1494,41 +1488,40 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
}
}
const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS");
- if (const char* cdefs = sf.GetProperty(COMPILE_DEFINITIONS)) {
- fc.CompileDefs = genexInterpreter.Evaluate(cdefs, COMPILE_DEFINITIONS);
+ if (cmProp cdefs = sf.GetProperty(COMPILE_DEFINITIONS)) {
+ fc.CompileDefs = genexInterpreter.Evaluate(*cdefs, COMPILE_DEFINITIONS);
needfc = true;
}
std::string defPropName = cmStrCat("COMPILE_DEFINITIONS_", configUpper);
- if (const char* ccdefs = sf.GetProperty(defPropName)) {
+ if (cmProp ccdefs = sf.GetProperty(defPropName)) {
fc.CompileDefsConfig =
- genexInterpreter.Evaluate(ccdefs, COMPILE_DEFINITIONS);
+ genexInterpreter.Evaluate(*ccdefs, COMPILE_DEFINITIONS);
needfc = true;
}
const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
- if (const char* cincs = sf.GetProperty(INCLUDE_DIRECTORIES)) {
- fc.IncludeDirs = genexInterpreter.Evaluate(cincs, INCLUDE_DIRECTORIES);
+ if (cmProp cincs = sf.GetProperty(INCLUDE_DIRECTORIES)) {
+ fc.IncludeDirs = genexInterpreter.Evaluate(*cincs, INCLUDE_DIRECTORIES);
needfc = true;
}
// Check for extra object-file dependencies.
- if (const char* deps = sf.GetProperty("OBJECT_DEPENDS")) {
- std::vector<std::string> depends = cmExpandedList(deps);
+ if (cmProp deps = sf.GetProperty("OBJECT_DEPENDS")) {
+ std::vector<std::string> depends = cmExpandedList(*deps);
const char* sep = "";
- for (std::vector<std::string>::iterator j = depends.begin();
- j != depends.end(); ++j) {
+ for (const std::string& d : depends) {
fc.AdditionalDeps += sep;
- fc.AdditionalDeps += lg->ConvertToXMLOutputPath(j->c_str());
+ fc.AdditionalDeps += lg->ConvertToXMLOutputPath(d);
sep = ";";
needfc = true;
}
}
- const std::string& linkLanguage = gt->GetLinkerLanguage(config.c_str());
+ const std::string& linkLanguage = gt->GetLinkerLanguage(config);
// If HEADER_FILE_ONLY is set, we must suppress this generation in
// the project file
fc.ExcludedFromBuild = sf.GetPropertyAsBool("HEADER_FILE_ONLY") ||
- !cmContains(acs.Configs, ci) ||
+ !cm::contains(acs.Configs, ci) ||
(gt->GetPropertyAsBool("UNITY_BUILD") &&
sf.GetProperty("UNITY_SOURCE_FILE") &&
!sf.GetPropertyAsBool("SKIP_UNITY_BUILD_INCLUSION"));
@@ -1629,7 +1622,7 @@ bool cmLocalVisualStudio7Generator::WriteGroup(
FCInfo fcinfo(this, target, acs, configs);
fout << "\t\t\t<File\n";
- std::string d = this->ConvertToXMLOutputPathSingle(source.c_str());
+ std::string d = this->ConvertToXMLOutputPathSingle(source);
// Tell MS-Dev what the source is. If the compiler knows how to
// build it, then it will.
fout << "\t\t\t\tRelativePath=\"" << d << "\">\n";
@@ -1759,21 +1752,21 @@ void cmLocalVisualStudio7Generator::WriteCustomRule(
fout << "\t\t\t\t\t<Tool\n"
<< "\t\t\t\t\tName=\"" << compileTool << "\"\n"
<< "\t\t\t\t\tAdditionalOptions=\""
- << this->EscapeForXML(fc.CompileFlags.c_str()) << "\"/>\n";
+ << this->EscapeForXML(fc.CompileFlags) << "\"/>\n";
}
std::string comment = this->ConstructComment(ccg);
std::string script = this->ConstructScript(ccg);
if (this->FortranProject) {
- cmSystemTools::ReplaceString(script, "$(Configuration)", config.c_str());
+ cmSystemTools::ReplaceString(script, "$(Configuration)", config);
}
/* clang-format off */
fout << "\t\t\t\t\t<Tool\n"
<< "\t\t\t\t\tName=\"" << customTool << "\"\n"
<< "\t\t\t\t\tDescription=\""
- << this->EscapeForXML(comment.c_str()) << "\"\n"
+ << this->EscapeForXML(comment) << "\"\n"
<< "\t\t\t\t\tCommandLine=\""
- << this->EscapeForXML(script.c_str()) << "\"\n"
+ << this->EscapeForXML(script) << "\"\n"
<< "\t\t\t\t\tAdditionalDependencies=\"";
/* clang-format on */
if (ccg.GetDepends().empty()) {
@@ -1789,8 +1782,8 @@ void cmLocalVisualStudio7Generator::WriteCustomRule(
for (std::string const& d : ccg.GetDepends()) {
// Get the real name of the dependency in case it is a CMake target.
std::string dep;
- if (this->GetRealDependency(d.c_str(), config.c_str(), dep)) {
- fout << this->ConvertToXMLOutputPath(dep.c_str()) << ";";
+ if (this->GetRealDependency(d, config, dep)) {
+ fout << this->ConvertToXMLOutputPath(dep) << ";";
}
}
}
@@ -1802,7 +1795,7 @@ void cmLocalVisualStudio7Generator::WriteCustomRule(
// Write a rule for the output generated by this command.
const char* sep = "";
for (std::string const& output : ccg.GetOutputs()) {
- fout << sep << this->ConvertToXMLOutputPathSingle(output.c_str());
+ fout << sep << this->ConvertToXMLOutputPathSingle(output);
sep = ";";
}
}
@@ -1881,20 +1874,20 @@ void cmLocalVisualStudio7Generator::WriteProjectSCC(std::ostream& fout,
{
// if we have all the required Source code control tags
// then add that to the project
- const char* vsProjectname = target->GetProperty("VS_SCC_PROJECTNAME");
- const char* vsLocalpath = target->GetProperty("VS_SCC_LOCALPATH");
- const char* vsProvider = target->GetProperty("VS_SCC_PROVIDER");
+ cmProp vsProjectname = target->GetProperty("VS_SCC_PROJECTNAME");
+ cmProp vsLocalpath = target->GetProperty("VS_SCC_LOCALPATH");
+ cmProp vsProvider = target->GetProperty("VS_SCC_PROVIDER");
if (vsProvider && vsLocalpath && vsProjectname) {
/* clang-format off */
- fout << "\tSccProjectName=\"" << vsProjectname << "\"\n"
- << "\tSccLocalPath=\"" << vsLocalpath << "\"\n"
- << "\tSccProvider=\"" << vsProvider << "\"\n";
+ fout << "\tSccProjectName=\"" << *vsProjectname << "\"\n"
+ << "\tSccLocalPath=\"" << *vsLocalpath << "\"\n"
+ << "\tSccProvider=\"" << *vsProvider << "\"\n";
/* clang-format on */
- const char* vsAuxPath = target->GetProperty("VS_SCC_AUXPATH");
+ cmProp vsAuxPath = target->GetProperty("VS_SCC_AUXPATH");
if (vsAuxPath) {
- fout << "\tSccAuxPath=\"" << vsAuxPath << "\"\n";
+ fout << "\tSccAuxPath=\"" << *vsAuxPath << "\"\n";
}
}
}
@@ -1912,10 +1905,8 @@ void cmLocalVisualStudio7Generator::WriteProjectStartFortran(
<< "\tProjectCreator=\"Intel Fortran\"\n"
<< "\tVersion=\"" << gg->GetIntelProjectVersion() << "\"\n";
/* clang-format on */
- const char* keyword = target->GetProperty("VS_KEYWORD");
- if (!keyword) {
- keyword = "Console Application";
- }
+ cmProp p = target->GetProperty("VS_KEYWORD");
+ const char* keyword = p ? p->c_str() : "Console Application";
const char* projectType = 0;
switch (target->GetType()) {
case cmStateEnums::STATIC_LIBRARY:
@@ -1948,7 +1939,7 @@ void cmLocalVisualStudio7Generator::WriteProjectStartFortran(
this->WriteProjectSCC(fout, target);
/* clang-format off */
fout<< "\tKeyword=\"" << keyword << "\">\n"
- << "\tProjectGUID=\"{" << gg->GetGUID(libName.c_str()) << "}\">\n"
+ << "\tProjectGUID=\"{" << gg->GetGUID(libName) << "}\">\n"
<< "\t<Platforms>\n"
<< "\t\t<Platform\n\t\t\tName=\"" << gg->GetPlatformName() << "\"/>\n"
<< "\t</Platforms>\n";
@@ -1974,20 +1965,16 @@ void cmLocalVisualStudio7Generator::WriteProjectStart(
<< "\tProjectType=\"Visual C++\"\n";
/* clang-format on */
fout << "\tVersion=\"" << (gg->GetVersion() / 10) << ".00\"\n";
- const char* projLabel = target->GetProperty("PROJECT_LABEL");
- if (!projLabel) {
- projLabel = libName.c_str();
- }
- const char* keyword = target->GetProperty("VS_KEYWORD");
- if (!keyword) {
- keyword = "Win32Proj";
- }
+ cmProp p = target->GetProperty("PROJECT_LABEL");
+ const std::string projLabel = p ? *p : libName;
+ p = target->GetProperty("VS_KEYWORD");
+ const std::string keyword = p ? *p : "Win32Proj";
fout << "\tName=\"" << projLabel << "\"\n";
- fout << "\tProjectGUID=\"{" << gg->GetGUID(libName.c_str()) << "}\"\n";
+ fout << "\tProjectGUID=\"{" << gg->GetGUID(libName) << "}\"\n";
this->WriteProjectSCC(fout, target);
- if (const char* targetFrameworkVersion =
+ if (cmProp targetFrameworkVersion =
target->GetProperty("VS_DOTNET_TARGET_FRAMEWORK_VERSION")) {
- fout << "\tTargetFrameworkVersion=\"" << targetFrameworkVersion << "\"\n";
+ fout << "\tTargetFrameworkVersion=\"" << *targetFrameworkVersion << "\"\n";
}
/* clang-format off */
fout << "\tKeyword=\"" << keyword << "\">\n"
@@ -2014,7 +2001,7 @@ void cmLocalVisualStudio7Generator::WriteVCProjFooter(
fout << "\t<Globals>\n";
for (std::string const& key : target->GetPropertyKeys()) {
- if (key.find("VS_GLOBAL_") == 0) {
+ if (cmHasLiteralPrefix(key, "VS_GLOBAL_")) {
std::string name = key.substr(10);
if (!name.empty()) {
/* clang-format off */
@@ -2037,7 +2024,7 @@ std::string cmLocalVisualStudio7Generator::EscapeForXML(const std::string& s)
}
std::string cmLocalVisualStudio7Generator::ConvertToXMLOutputPath(
- const char* path)
+ const std::string& path)
{
std::string ret =
this->ConvertToOutputFormat(path, cmOutputConverter::SHELL);
@@ -2049,7 +2036,7 @@ std::string cmLocalVisualStudio7Generator::ConvertToXMLOutputPath(
}
std::string cmLocalVisualStudio7Generator::ConvertToXMLOutputPathSingle(
- const char* path)
+ const std::string& path)
{
std::string ret =
this->ConvertToOutputFormat(path, cmOutputConverter::SHELL);
@@ -2061,7 +2048,7 @@ std::string cmLocalVisualStudio7Generator::ConvertToXMLOutputPathSingle(
}
void cmVS7GeneratorOptions::OutputFlag(std::ostream& fout, int indent,
- const char* flag,
+ const std::string& flag,
const std::string& content)
{
fout.fill('\t');
@@ -2130,8 +2117,7 @@ void cmLocalVisualStudio7Generator::ReadAndStoreExternalGUID(
std::string guidStoreName = cmStrCat(name, "_GUID_CMAKE");
// save the GUID in the cache
this->GlobalGenerator->GetCMakeInstance()->AddCacheEntry(
- guidStoreName.c_str(), parser.GUID.c_str(), "Stored GUID",
- cmStateEnums::INTERNAL);
+ guidStoreName, parser.GUID.c_str(), "Stored GUID", cmStateEnums::INTERNAL);
}
std::string cmLocalVisualStudio7Generator::GetTargetDirectory(
diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h
index 671783f..8b9b8ad 100644
--- a/Source/cmLocalVisualStudio7Generator.h
+++ b/Source/cmLocalVisualStudio7Generator.h
@@ -6,6 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <iosfwd>
+#include <memory>
#include <string>
#include <vector>
@@ -30,7 +31,7 @@ public:
: cmVisualStudioGeneratorOptions(lg, tool, table, extraTable)
{
}
- void OutputFlag(std::ostream& fout, int indent, const char* tag,
+ void OutputFlag(std::ostream& fout, int indent, const std::string& tag,
const std::string& content) override;
};
@@ -48,6 +49,10 @@ public:
virtual ~cmLocalVisualStudio7Generator();
+ cmLocalVisualStudio7Generator(const cmLocalVisualStudio7Generator&) = delete;
+ const cmLocalVisualStudio7Generator& operator=(
+ const cmLocalVisualStudio7Generator&) = delete;
+
void AddHelperCommands() override;
/**
@@ -101,8 +106,8 @@ private:
void WriteConfiguration(std::ostream& fout, const std::string& configName,
const std::string& libName, cmGeneratorTarget* tgt);
std::string EscapeForXML(const std::string& s);
- std::string ConvertToXMLOutputPath(const char* path);
- std::string ConvertToXMLOutputPathSingle(const char* path);
+ std::string ConvertToXMLOutputPath(const std::string& path);
+ std::string ConvertToXMLOutputPathSingle(const std::string& path);
void OutputTargetRules(std::ostream& fout, const std::string& configName,
cmGeneratorTarget* target,
const std::string& libName);
@@ -144,7 +149,7 @@ private:
bool FortranProject;
bool WindowsCEProject;
- cmLocalVisualStudio7GeneratorInternals* Internal;
+ std::unique_ptr<cmLocalVisualStudio7GeneratorInternals> Internal;
};
#endif
diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx
index 336e3a5..ebd4f96 100644
--- a/Source/cmLocalVisualStudioGenerator.cxx
+++ b/Source/cmLocalVisualStudioGenerator.cxx
@@ -102,10 +102,12 @@ cmLocalVisualStudioGenerator::MaybeCreateImplibDir(cmGeneratorTarget* target,
std::vector<std::string> no_output;
std::vector<std::string> no_byproducts;
std::vector<std::string> no_depends;
+ bool stdPipesUTF8 = true;
cmCustomCommandLines commands = cmMakeSingleCommandLine(
{ cmSystemTools::GetCMakeCommand(), "-E", "make_directory", impDir });
- pcc.reset(new cmCustomCommand(0, no_output, no_byproducts, no_depends,
- commands, 0, 0));
+ pcc.reset(new cmCustomCommand(no_output, no_byproducts, no_depends, commands,
+ cmListFileBacktrace(), nullptr, nullptr,
+ stdPipesUTF8));
pcc->SetEscapeOldStyle(false);
pcc->SetEscapeAllowMakeVars(true);
return pcc;
@@ -154,8 +156,7 @@ std::string cmLocalVisualStudioGenerator::ConstructScript(
script += newline;
newline = newline_text;
script += "cd ";
- script += this->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(workingDirectory), SHELL);
+ script += this->ConvertToOutputFormat(workingDirectory, SHELL);
script += check_error;
// Change the working drive.
diff --git a/Source/cmLocalXCodeGenerator.cxx b/Source/cmLocalXCodeGenerator.cxx
index 5a06d4a..ac0d35e 100644
--- a/Source/cmLocalXCodeGenerator.cxx
+++ b/Source/cmLocalXCodeGenerator.cxx
@@ -40,7 +40,7 @@ void cmLocalXCodeGenerator::Generate()
{
cmLocalGenerator::Generate();
- for (auto target : this->GetGeneratorTargets()) {
+ for (const auto& target : this->GetGeneratorTargets()) {
target->HasMacOSXRpathInstallNameDir("");
}
}
@@ -49,7 +49,7 @@ void cmLocalXCodeGenerator::GenerateInstallRules()
{
cmLocalGenerator::GenerateInstallRules();
- for (auto target : this->GetGeneratorTargets()) {
+ for (const auto& target : this->GetGeneratorTargets()) {
target->HasMacOSXRpathInstallNameDir("");
}
}
diff --git a/Source/cmMachO.cxx b/Source/cmMachO.cxx
index 6cbed36..53112e0 100644
--- a/Source/cmMachO.cxx
+++ b/Source/cmMachO.cxx
@@ -79,14 +79,14 @@ public:
// A load_command and its associated data
struct RawLoadCommand
{
- uint32_t type(const cmMachOHeaderAndLoadCommands* m) const
+ uint32_t type(const cmMachOHeaderAndLoadCommands& m) const
{
if (this->LoadCommand.size() < sizeof(load_command)) {
return 0;
}
const load_command* cmd =
reinterpret_cast<const load_command*>(&this->LoadCommand[0]);
- return m->swap(cmd->cmd);
+ return m.swap(cmd->cmd);
}
std::vector<char> LoadCommand;
};
@@ -186,8 +186,11 @@ class cmMachOInternal
{
public:
cmMachOInternal(const char* fname);
+ cmMachOInternal(const cmMachOInternal&) = delete;
~cmMachOInternal();
+ cmMachOInternal& operator=(const cmMachOInternal&) = delete;
+
// read a Mach-O file
bool read_mach_o(uint32_t file_offset);
@@ -202,7 +205,7 @@ public:
std::string ErrorMessage;
// the list of Mach-O's
- std::vector<cmMachOHeaderAndLoadCommands*> MachOList;
+ std::vector<std::unique_ptr<cmMachOHeaderAndLoadCommands>> MachOList;
};
cmMachOInternal::cmMachOInternal(const char* fname)
@@ -260,12 +263,7 @@ cmMachOInternal::cmMachOInternal(const char* fname)
}
}
-cmMachOInternal::~cmMachOInternal()
-{
- for (auto& i : this->MachOList) {
- delete i;
- }
-}
+cmMachOInternal::~cmMachOInternal() = default;
bool cmMachOInternal::read_mach_o(uint32_t file_offset)
{
@@ -280,25 +278,25 @@ bool cmMachOInternal::read_mach_o(uint32_t file_offset)
return false;
}
- cmMachOHeaderAndLoadCommands* f = nullptr;
+ std::unique_ptr<cmMachOHeaderAndLoadCommands> f;
if (magic == MH_CIGAM || magic == MH_MAGIC) {
bool swap = false;
if (magic == MH_CIGAM) {
swap = true;
}
- f = new cmMachOHeaderAndLoadCommandsImpl<mach_header>(swap);
+ f = cm::make_unique<cmMachOHeaderAndLoadCommandsImpl<mach_header>>(swap);
} else if (magic == MH_CIGAM_64 || magic == MH_MAGIC_64) {
bool swap = false;
if (magic == MH_CIGAM_64) {
swap = true;
}
- f = new cmMachOHeaderAndLoadCommandsImpl<mach_header_64>(swap);
+ f =
+ cm::make_unique<cmMachOHeaderAndLoadCommandsImpl<mach_header_64>>(swap);
}
if (f && f->read_mach_o(this->Fin)) {
- this->MachOList.push_back(f);
+ this->MachOList.push_back(std::move(f));
} else {
- delete f;
this->ErrorMessage = "Failed to read Mach-O header.";
return false;
}
@@ -333,11 +331,12 @@ bool cmMachO::GetInstallName(std::string& install_name)
}
// grab the first Mach-O and get the install name from that one
- cmMachOHeaderAndLoadCommands* macho = this->Internal->MachOList[0];
+ std::unique_ptr<cmMachOHeaderAndLoadCommands>& macho =
+ this->Internal->MachOList[0];
for (size_t i = 0; i < macho->load_commands().size(); i++) {
const cmMachOHeaderAndLoadCommands::RawLoadCommand& cmd =
macho->load_commands()[i];
- uint32_t lc_cmd = cmd.type(macho);
+ uint32_t lc_cmd = cmd.type(*macho);
if (lc_cmd == LC_ID_DYLIB || lc_cmd == LC_LOAD_WEAK_DYLIB ||
lc_cmd == LC_LOAD_DYLIB) {
if (sizeof(dylib_command) < cmd.LoadCommand.size()) {
diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx
index ba9947a..c88b343 100644
--- a/Source/cmMacroCommand.cxx
+++ b/Source/cmMacroCommand.cxx
@@ -7,10 +7,9 @@
#include <cm/memory>
#include <cm/string_view>
+#include <cmext/algorithm>
+#include <cmext/string_view>
-#include "cm_static_string_view.hxx"
-
-#include "cmAlgorithms.h"
#include "cmExecutionStatus.h"
#include "cmFunctionBlocker.h"
#include "cmListFileCache.h"
@@ -167,7 +166,7 @@ bool cmMacroFunctionBlocker::Replay(std::vector<cmListFileFunction> functions,
cmExecutionStatus& status)
{
cmMakefile& mf = status.GetMakefile();
- mf.AppendProperty("MACROS", this->Args[0].c_str());
+ mf.AppendProperty("MACROS", this->Args[0]);
// create a new command and add it to cmake
cmMacroHelperCommand f;
f.Args = this->Args;
@@ -190,7 +189,7 @@ bool cmMacroCommand(std::vector<std::string> const& args,
// create a function blocker
{
auto fb = cm::make_unique<cmMacroFunctionBlocker>();
- cmAppend(fb->Args, args);
+ cm::append(fb->Args, args);
status.GetMakefile().AddFunctionBlocker(std::move(fb));
}
return true;
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index f143ef7..6f05d45 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -15,18 +15,25 @@
#include <cm/iterator>
#include <cm/memory>
+#include <cm/optional>
+#include <cm/vector>
+#include <cmext/algorithm>
+#include <cmext/string_view>
+
+#include <cm3p/json/value.h>
+#include <cm3p/json/writer.h>
#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"
#include "cm_sys_stat.h"
-#include "cmAlgorithms.h"
#include "cmCommandArgumentParserHelper.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandLines.h"
#include "cmExecutionStatus.h"
#include "cmExpandedCommandArgument.h" // IWYU pragma: keep
+#include "cmExportBuildFileGenerator.h"
#include "cmFileLockPool.h"
#include "cmFunctionBlocker.h"
#include "cmGeneratedFileStream.h"
@@ -36,6 +43,7 @@
#include "cmInstallGenerator.h" // IWYU pragma: keep
#include "cmInstallSubdirectoryGenerator.h"
#include "cmListFileCache.h"
+#include "cmLocalGenerator.h"
#include "cmMessageType.h"
#include "cmRange.h"
#include "cmSourceFile.h"
@@ -54,6 +62,7 @@
#include "cmake.h"
#ifndef CMAKE_BOOTSTRAP
+# include "cmMakefileProfilingData.h"
# include "cmVariableWatch.h"
#endif
@@ -117,15 +126,7 @@ cmMakefile::cmMakefile(cmGlobalGenerator* globalGenerator,
#endif
}
-cmMakefile::~cmMakefile()
-{
- cmDeleteAll(this->InstallGenerators);
- cmDeleteAll(this->TestGenerators);
- cmDeleteAll(this->SourceFiles);
- cmDeleteAll(this->Tests);
- cmDeleteAll(this->ImportedTargetsOwned);
- cmDeleteAll(this->EvaluationFiles);
-}
+cmMakefile::~cmMakefile() = default;
cmDirectoryId cmMakefile::GetDirectoryId() const
{
@@ -133,7 +134,7 @@ cmDirectoryId cmMakefile::GetDirectoryId() const
// If we ever need to expose this to CMake language code we should
// add a read-only property in cmMakefile::GetProperty.
char buf[32];
- sprintf(buf, "<%p>",
+ sprintf(buf, "(%p)",
static_cast<void const*>(this)); // cast avoids format warning
return std::string(buf);
}
@@ -146,7 +147,7 @@ void cmMakefile::IssueMessage(MessageType t, std::string const& text) const
this->ExecutionStatusStack.back()->SetNestedError();
}
}
- this->GetCMakeInstance()->IssueMessage(t, text, this->GetBacktrace());
+ this->GetCMakeInstance()->IssueMessage(t, text, this->Backtrace);
}
bool cmMakefile::CheckCMP0037(std::string const& targetName,
@@ -313,21 +314,54 @@ void cmMakefile::PrintCommandTrace(const cmListFileFunction& lff) const
}
std::ostringstream msg;
- msg << full_path << "(" << lff.Line << "): ";
- msg << lff.Name.Original << "(";
- bool expand = this->GetCMakeInstance()->GetTraceExpand();
+ std::vector<std::string> args;
std::string temp;
+ bool expand = this->GetCMakeInstance()->GetTraceExpand();
+
+ args.reserve(lff.Arguments.size());
for (cmListFileArgument const& arg : lff.Arguments) {
if (expand) {
temp = arg.Value;
this->ExpandVariablesInString(temp);
- msg << temp;
+ args.push_back(temp);
} else {
- msg << arg.Value;
+ args.push_back(arg.Value);
+ }
+ }
+
+ switch (this->GetCMakeInstance()->GetTraceFormat()) {
+ case cmake::TraceFormat::TRACE_JSON_V1: {
+#ifndef CMAKE_BOOTSTRAP
+ Json::Value val;
+ Json::StreamWriterBuilder builder;
+ builder["indentation"] = "";
+ val["file"] = full_path;
+ val["line"] = static_cast<Json::Value::Int64>(lff.Line);
+ val["cmd"] = lff.Name.Original;
+ val["args"] = Json::Value(Json::arrayValue);
+ for (std::string const& arg : args) {
+ val["args"].append(arg);
+ }
+ val["time"] = cmSystemTools::GetTime();
+ val["frame"] =
+ static_cast<Json::Value::UInt64>(this->ExecutionStatusStack.size());
+ msg << Json::writeString(builder, val);
+#endif
+ break;
}
- msg << " ";
+ case cmake::TraceFormat::TRACE_HUMAN:
+ msg << full_path << "(" << lff.Line << "): ";
+ msg << lff.Name.Original << "(";
+
+ for (std::string const& arg : args) {
+ msg << arg << " ";
+ }
+ msg << ")";
+ break;
+ case cmake::TraceFormat::TRACE_UNDEFINED:
+ msg << "INTERNAL ERROR: Trace format is TRACE_UNDEFINED";
+ break;
}
- msg << ")";
auto& f = this->GetCMakeInstance()->GetTraceFile();
if (f) {
@@ -341,19 +375,30 @@ void cmMakefile::PrintCommandTrace(const cmListFileFunction& lff) const
class cmMakefileCall
{
public:
- cmMakefileCall(cmMakefile* mf, cmCommandContext const& cc,
+ cmMakefileCall(cmMakefile* mf, cmListFileFunction const& lff,
cmExecutionStatus& status)
: Makefile(mf)
{
cmListFileContext const& lfc = cmListFileContext::FromCommandContext(
- cc, this->Makefile->StateSnapshot.GetExecutionListFile());
+ lff, this->Makefile->StateSnapshot.GetExecutionListFile());
this->Makefile->Backtrace = this->Makefile->Backtrace.Push(lfc);
++this->Makefile->RecursionDepth;
this->Makefile->ExecutionStatusStack.push_back(&status);
+#if !defined(CMAKE_BOOTSTRAP)
+ if (this->Makefile->GetCMakeInstance()->IsProfilingEnabled()) {
+ this->Makefile->GetCMakeInstance()->GetProfilingOutput().StartEntry(lff,
+ lfc);
+ }
+#endif
}
~cmMakefileCall()
{
+#if !defined(CMAKE_BOOTSTRAP)
+ if (this->Makefile->GetCMakeInstance()->IsProfilingEnabled()) {
+ this->Makefile->GetCMakeInstance()->GetProfilingOutput().StopEntry();
+ }
+#endif
this->Makefile->ExecutionStatusStack.pop_back();
--this->Makefile->RecursionDepth;
this->Makefile->Backtrace = this->Makefile->Backtrace.Pop();
@@ -653,6 +698,27 @@ bool cmMakefile::ReadListFile(const std::string& filename)
return true;
}
+bool cmMakefile::ReadListFileAsString(const std::string& content,
+ const std::string& virtualFileName)
+{
+ std::string filenametoread = cmSystemTools::CollapseFullPath(
+ virtualFileName, this->GetCurrentSourceDirectory());
+
+ ListFileScope scope(this, filenametoread);
+
+ cmListFile listFile;
+ if (!listFile.ParseString(content.c_str(), virtualFileName.c_str(),
+ this->GetMessenger(), this->Backtrace)) {
+ return false;
+ }
+
+ this->ReadListFile(listFile, filenametoread);
+ if (cmSystemTools::GetFatalErrorOccured()) {
+ scope.Quiet();
+ }
+ return true;
+}
+
void cmMakefile::ReadListFile(cmListFile const& listFile,
std::string const& filenametoread)
{
@@ -737,18 +803,19 @@ void cmMakefile::AddEvaluationFile(
std::unique_ptr<cmCompiledGeneratorExpression> condition,
bool inputIsContent)
{
- this->EvaluationFiles.push_back(new cmGeneratorExpressionEvaluationFile(
- inputFile, std::move(outputName), std::move(condition), inputIsContent,
- this->GetPolicyStatus(cmPolicies::CMP0070)));
+ this->EvaluationFiles.push_back(
+ cm::make_unique<cmGeneratorExpressionEvaluationFile>(
+ inputFile, std::move(outputName), std::move(condition), inputIsContent,
+ this->GetPolicyStatus(cmPolicies::CMP0070)));
}
-std::vector<cmGeneratorExpressionEvaluationFile*>
+const std::vector<std::unique_ptr<cmGeneratorExpressionEvaluationFile>>&
cmMakefile::GetEvaluationFiles() const
{
return this->EvaluationFiles;
}
-std::vector<cmExportBuildFileGenerator*>
+std::vector<std::unique_ptr<cmExportBuildFileGenerator>> const&
cmMakefile::GetExportBuildFileGenerators() const
{
return this->ExportBuildFileGenerators;
@@ -757,16 +824,21 @@ cmMakefile::GetExportBuildFileGenerators() const
void cmMakefile::RemoveExportBuildFileGeneratorCMP0024(
cmExportBuildFileGenerator* gen)
{
- auto it = std::find(this->ExportBuildFileGenerators.begin(),
- this->ExportBuildFileGenerators.end(), gen);
+ auto it =
+ std::find_if(this->ExportBuildFileGenerators.begin(),
+ this->ExportBuildFileGenerators.end(),
+ [gen](std::unique_ptr<cmExportBuildFileGenerator> const& p) {
+ return p.get() == gen;
+ });
if (it != this->ExportBuildFileGenerators.end()) {
this->ExportBuildFileGenerators.erase(it);
}
}
-void cmMakefile::AddExportBuildFileGenerator(cmExportBuildFileGenerator* gen)
+void cmMakefile::AddExportBuildFileGenerator(
+ std::unique_ptr<cmExportBuildFileGenerator> gen)
{
- this->ExportBuildFileGenerators.push_back(gen);
+ this->ExportBuildFileGenerators.emplace_back(std::move(gen));
}
namespace {
@@ -780,38 +852,42 @@ struct file_not_persistent
};
}
-void cmMakefile::AddFinalAction(FinalAction action)
+void cmMakefile::AddGeneratorAction(GeneratorAction action)
{
- this->FinalActions.push_back(std::move(action));
+ assert(!this->GeneratorActionsInvoked);
+ this->GeneratorActions.emplace_back(std::move(action), this->Backtrace);
}
-void cmMakefile::FinalPass()
+void cmMakefile::DoGenerate(cmLocalGenerator& lg)
{
// do all the variable expansions here
this->ExpandVariablesCMP0019();
// give all the commands a chance to do something
// after the file has been parsed before generation
- for (FinalAction& action : this->FinalActions) {
- action(*this);
+ for (const BT<GeneratorAction>& action : this->GeneratorActions) {
+ action.Value(lg, action.Backtrace);
}
+ this->GeneratorActionsInvoked = true;
+ this->DelayedOutputFiles.clear();
+ this->DelayedOutputFilesHaveGenex = false;
// go through all configured files and see which ones still exist.
// we don't want cmake to re-run if a configured file is created and deleted
// during processing as that would make it a transient file that can't
// influence the build process
- cmEraseIf(this->OutputFiles, file_not_persistent());
+ cm::erase_if(this->OutputFiles, file_not_persistent());
// if a configured file is used as input for another configured file,
// and then deleted it will show up in the input list files so we
// need to scan those too
- cmEraseIf(this->ListFiles, file_not_persistent());
+ cm::erase_if(this->ListFiles, file_not_persistent());
}
// Generate the output file
-void cmMakefile::ConfigureFinalPass()
+void cmMakefile::Generate(cmLocalGenerator& lg)
{
- this->FinalPass();
+ this->DoGenerate(lg);
const char* oldValue = this->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
if (oldValue &&
cmSystemTools::VersionCompare(cmSystemTools::OP_LESS, oldValue, "2.4")) {
@@ -825,6 +901,39 @@ void cmMakefile::ConfigureFinalPass()
}
}
+namespace {
+// There are still too many implicit backtraces through cmMakefile. As a
+// workaround we reset the backtrace temporarily.
+struct BacktraceGuard
+{
+ BacktraceGuard(cmListFileBacktrace& lfbt, cmListFileBacktrace current)
+ : Backtrace(lfbt)
+ , Previous(lfbt)
+ {
+ this->Backtrace = std::move(current);
+ }
+
+ ~BacktraceGuard() { this->Backtrace = std::move(Previous); }
+
+private:
+ cmListFileBacktrace& Backtrace;
+ cmListFileBacktrace Previous;
+};
+
+cm::optional<std::string> MakeOptionalString(const char* str)
+{
+ if (str) {
+ return str;
+ }
+ return cm::nullopt;
+}
+
+const char* GetCStrOrNull(const cm::optional<std::string>& str)
+{
+ return str ? str->c_str() : nullptr;
+}
+}
+
bool cmMakefile::ValidateCustomCommand(
const cmCustomCommandLines& commandLines) const
{
@@ -842,7 +951,8 @@ bool cmMakefile::ValidateCustomCommand(
}
cmTarget* cmMakefile::GetCustomCommandTarget(
- const std::string& target, cmObjectLibraryCommands objLibCommands) const
+ const std::string& target, cmObjectLibraryCommands objLibCommands,
+ const cmListFileBacktrace& lfbt) const
{
// Find the target to which to add the custom command.
auto ti = this->Targets.find(target);
@@ -876,7 +986,7 @@ cmTarget* cmMakefile::GetCustomCommandTarget(
e << "No TARGET '" << target
<< "' has been created in this directory.";
}
- this->IssueMessage(messageType, e.str());
+ this->GetCMakeInstance()->IssueMessage(messageType, e.str(), lfbt);
}
return nullptr;
@@ -889,7 +999,8 @@ cmTarget* cmMakefile::GetCustomCommandTarget(
e << "Target \"" << target
<< "\" is an OBJECT library "
"that may not have PRE_BUILD, PRE_LINK, or POST_BUILD commands.";
- this->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e.str(),
+ lfbt);
return nullptr;
}
if (t->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
@@ -897,7 +1008,8 @@ cmTarget* cmMakefile::GetCustomCommandTarget(
e << "Target \"" << target
<< "\" is an INTERFACE library "
"that may not have PRE_BUILD, PRE_LINK, or POST_BUILD commands.";
- this->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e.str(),
+ lfbt);
return nullptr;
}
@@ -910,9 +1022,10 @@ cmTarget* cmMakefile::AddCustomCommandToTarget(
const cmCustomCommandLines& commandLines, cmCustomCommandType type,
const char* comment, const char* workingDir, bool escapeOldStyle,
bool uses_terminal, const std::string& depfile, const std::string& job_pool,
- bool command_expand_lists, cmObjectLibraryCommands objLibCommands)
+ bool command_expand_lists, bool stdPipesUTF8)
{
- cmTarget* t = this->GetCustomCommandTarget(target, objLibCommands);
+ cmTarget* t = this->GetCustomCommandTarget(
+ target, cmObjectLibraryCommands::Reject, this->Backtrace);
// Validate custom commands.
if (!t || !this->ValidateCustomCommand(commandLines)) {
@@ -920,175 +1033,85 @@ cmTarget* cmMakefile::AddCustomCommandToTarget(
}
// Always create the byproduct sources and mark them generated.
- this->CreateGeneratedSources(byproducts);
-
- this->CommitCustomCommandToTarget(
- t, byproducts, depends, commandLines, type, comment, workingDir,
- escapeOldStyle, uses_terminal, depfile, job_pool, command_expand_lists);
+ this->CreateGeneratedByproducts(byproducts);
+
+ // Strings could be moved into the callback function with C++14.
+ cm::optional<std::string> commentStr = MakeOptionalString(comment);
+ cm::optional<std::string> workingStr = MakeOptionalString(workingDir);
+
+ // Dispatch command creation to allow generator expressions in outputs.
+ this->AddGeneratorAction(
+ [=](cmLocalGenerator& lg, const cmListFileBacktrace& lfbt) {
+ BacktraceGuard guard(this->Backtrace, lfbt);
+ detail::AddCustomCommandToTarget(
+ lg, lfbt, cmCommandOrigin::Project, t, byproducts, depends,
+ commandLines, type, GetCStrOrNull(commentStr),
+ GetCStrOrNull(workingStr), escapeOldStyle, uses_terminal, depfile,
+ job_pool, command_expand_lists, stdPipesUTF8);
+ });
return t;
}
-void cmMakefile::CommitCustomCommandToTarget(
- cmTarget* target, const std::vector<std::string>& byproducts,
- const std::vector<std::string>& depends,
- const cmCustomCommandLines& commandLines, cmCustomCommandType type,
- const char* comment, const char* workingDir, bool escapeOldStyle,
- bool uses_terminal, const std::string& depfile, const std::string& job_pool,
- bool command_expand_lists)
-{
- // Add the command to the appropriate build step for the target.
- std::vector<std::string> no_output;
- cmCustomCommand cc(this, no_output, byproducts, depends, commandLines,
- comment, workingDir);
- cc.SetEscapeOldStyle(escapeOldStyle);
- cc.SetEscapeAllowMakeVars(true);
- cc.SetUsesTerminal(uses_terminal);
- cc.SetCommandExpandLists(command_expand_lists);
- cc.SetDepfile(depfile);
- cc.SetJobPool(job_pool);
- switch (type) {
- case cmCustomCommandType::PRE_BUILD:
- target->AddPreBuildCommand(std::move(cc));
- break;
- case cmCustomCommandType::PRE_LINK:
- target->AddPreLinkCommand(std::move(cc));
- break;
- case cmCustomCommandType::POST_BUILD:
- target->AddPostBuildCommand(std::move(cc));
- break;
- }
-
- this->AddTargetByproducts(target, byproducts);
-}
-
-cmSourceFile* cmMakefile::AddCustomCommandToOutput(
+void cmMakefile::AddCustomCommandToOutput(
const std::string& output, const std::vector<std::string>& depends,
const std::string& main_dependency, const cmCustomCommandLines& commandLines,
- const char* comment, const char* workingDir, bool replace,
- bool escapeOldStyle, bool uses_terminal, bool command_expand_lists,
- const std::string& depfile, const std::string& job_pool)
+ const char* comment, const char* workingDir,
+ const CommandSourceCallback& callback, bool replace, bool escapeOldStyle,
+ bool uses_terminal, bool command_expand_lists, const std::string& depfile,
+ const std::string& job_pool, bool stdPipesUTF8)
{
- std::vector<std::string> outputs;
- outputs.push_back(output);
std::vector<std::string> no_byproducts;
cmImplicitDependsList no_implicit_depends;
- return this->AddCustomCommandToOutput(
- outputs, no_byproducts, depends, main_dependency, no_implicit_depends,
- commandLines, comment, workingDir, replace, escapeOldStyle, uses_terminal,
- command_expand_lists, depfile, job_pool);
+ this->AddCustomCommandToOutput(
+ { output }, no_byproducts, depends, main_dependency, no_implicit_depends,
+ commandLines, comment, workingDir, callback, replace, escapeOldStyle,
+ uses_terminal, command_expand_lists, depfile, job_pool, stdPipesUTF8);
}
-cmSourceFile* cmMakefile::AddCustomCommandToOutput(
+void cmMakefile::AddCustomCommandToOutput(
const std::vector<std::string>& outputs,
const std::vector<std::string>& byproducts,
const std::vector<std::string>& depends, const std::string& main_dependency,
const cmImplicitDependsList& implicit_depends,
const cmCustomCommandLines& commandLines, const char* comment,
- const char* workingDir, bool replace, bool escapeOldStyle,
- bool uses_terminal, bool command_expand_lists, const std::string& depfile,
- const std::string& job_pool)
+ const char* workingDir, const CommandSourceCallback& callback, bool replace,
+ bool escapeOldStyle, bool uses_terminal, bool command_expand_lists,
+ const std::string& depfile, const std::string& job_pool, bool stdPipesUTF8)
{
// Make sure there is at least one output.
if (outputs.empty()) {
cmSystemTools::Error("Attempt to add a custom rule with no output!");
- return nullptr;
+ return;
}
// Validate custom commands.
if (!this->ValidateCustomCommand(commandLines)) {
- return nullptr;
+ return;
}
// Always create the output sources and mark them generated.
- this->CreateGeneratedSources(outputs);
- this->CreateGeneratedSources(byproducts);
-
- return this->CommitCustomCommandToOutput(
- outputs, byproducts, depends, main_dependency, implicit_depends,
- commandLines, comment, workingDir, replace, escapeOldStyle, uses_terminal,
- command_expand_lists, depfile, job_pool);
-}
-
-cmSourceFile* cmMakefile::CommitCustomCommandToOutput(
- const std::vector<std::string>& outputs,
- const std::vector<std::string>& byproducts,
- const std::vector<std::string>& depends, const std::string& main_dependency,
- const cmImplicitDependsList& implicit_depends,
- const cmCustomCommandLines& commandLines, const char* comment,
- const char* workingDir, bool replace, bool escapeOldStyle,
- bool uses_terminal, bool command_expand_lists, const std::string& depfile,
- const std::string& job_pool)
-{
- // Choose a source file on which to store the custom command.
- cmSourceFile* file = nullptr;
- if (!commandLines.empty() && !main_dependency.empty()) {
- // The main dependency was specified. Use it unless a different
- // custom command already used it.
- file = this->GetSource(main_dependency);
- if (file && file->GetCustomCommand() && !replace) {
- // The main dependency already has a custom command.
- if (commandLines == file->GetCustomCommand()->GetCommandLines()) {
- // The existing custom command is identical. Silently ignore
- // the duplicate.
- return file;
+ this->CreateGeneratedOutputs(outputs);
+ this->CreateGeneratedByproducts(byproducts);
+
+ // Strings could be moved into the callback function with C++14.
+ cm::optional<std::string> commentStr = MakeOptionalString(comment);
+ cm::optional<std::string> workingStr = MakeOptionalString(workingDir);
+
+ // Dispatch command creation to allow generator expressions in outputs.
+ this->AddGeneratorAction(
+ [=](cmLocalGenerator& lg, const cmListFileBacktrace& lfbt) {
+ BacktraceGuard guard(this->Backtrace, lfbt);
+ cmSourceFile* sf = detail::AddCustomCommandToOutput(
+ lg, lfbt, cmCommandOrigin::Project, outputs, byproducts, depends,
+ main_dependency, implicit_depends, commandLines,
+ GetCStrOrNull(commentStr), GetCStrOrNull(workingStr), replace,
+ escapeOldStyle, uses_terminal, command_expand_lists, depfile, job_pool,
+ stdPipesUTF8);
+ if (callback && sf) {
+ callback(sf);
}
- // The existing custom command is different. We need to
- // generate a rule file for this new command.
- file = nullptr;
- } else if (!file) {
- file = this->CreateSource(main_dependency);
- }
- }
-
- // Generate a rule file if the main dependency is not available.
- if (!file) {
- cmGlobalGenerator* gg = this->GetGlobalGenerator();
-
- // Construct a rule file associated with the first output produced.
- std::string outName = gg->GenerateRuleFile(outputs[0]);
-
- // Check if the rule file already exists.
- file = this->GetSource(outName, cmSourceFileLocationKind::Known);
- if (file && file->GetCustomCommand() && !replace) {
- // The rule file already exists.
- if (commandLines != file->GetCustomCommand()->GetCommandLines()) {
- cmSystemTools::Error("Attempt to add a custom rule to output \"" +
- outName + "\" which already has a custom rule.");
- }
- return file;
- }
-
- // Create a cmSourceFile for the rule file.
- if (!file) {
- file =
- this->CreateSource(outName, true, cmSourceFileLocationKind::Known);
- }
- file->SetProperty("__CMAKE_RULE", "1");
- }
-
- // Attach the custom command to the file.
- if (file) {
- // Construct a complete list of dependencies.
- std::vector<std::string> depends2(depends);
- if (!main_dependency.empty()) {
- depends2.push_back(main_dependency);
- }
-
- std::unique_ptr<cmCustomCommand> cc = cm::make_unique<cmCustomCommand>(
- this, outputs, byproducts, depends2, commandLines, comment, workingDir);
- cc->SetEscapeOldStyle(escapeOldStyle);
- cc->SetEscapeAllowMakeVars(true);
- cc->SetImplicitDepends(implicit_depends);
- cc->SetUsesTerminal(uses_terminal);
- cc->SetCommandExpandLists(command_expand_lists);
- cc->SetDepfile(depfile);
- cc->SetJobPool(job_pool);
- file->SetCustomCommand(std::move(cc));
-
- this->AddSourceOutputs(file, outputs, byproducts);
- }
- return file;
+ });
}
void cmMakefile::AddCustomCommandOldStyle(
@@ -1136,11 +1159,8 @@ void cmMakefile::AddCustomCommandOldStyle(
if (sourceFiles.find(source)) {
// The source looks like a real file. Use it as the main dependency.
for (std::string const& output : outputs) {
- cmSourceFile* sf = this->AddCustomCommandToOutput(
- output, depends, source, commandLines, comment, nullptr);
- if (sf) {
- addRuleFileToTarget(sf);
- }
+ this->AddCustomCommandToOutput(output, depends, source, commandLines,
+ comment, nullptr, addRuleFileToTarget);
}
} else {
std::string no_main_dependency;
@@ -1149,11 +1169,9 @@ void cmMakefile::AddCustomCommandOldStyle(
// The source may not be a real file. Do not use a main dependency.
for (std::string const& output : outputs) {
- cmSourceFile* sf = this->AddCustomCommandToOutput(
- output, depends2, no_main_dependency, commandLines, comment, nullptr);
- if (sf) {
- addRuleFileToTarget(sf);
- }
+ this->AddCustomCommandToOutput(output, depends2, no_main_dependency,
+ commandLines, comment, nullptr,
+ addRuleFileToTarget);
}
}
}
@@ -1170,29 +1188,18 @@ bool cmMakefile::AppendCustomCommandToOutput(
// Validate custom commands.
if (this->ValidateCustomCommand(commandLines)) {
- // Add command factory to allow generator expressions in output.
- this->CommitAppendCustomCommandToOutput(output, depends, implicit_depends,
- commandLines);
+ // Dispatch command creation to allow generator expressions in outputs.
+ this->AddGeneratorAction(
+ [=](cmLocalGenerator& lg, const cmListFileBacktrace& lfbt) {
+ BacktraceGuard guard(this->Backtrace, lfbt);
+ detail::AppendCustomCommandToOutput(lg, lfbt, output, depends,
+ implicit_depends, commandLines);
+ });
}
return true;
}
-void cmMakefile::CommitAppendCustomCommandToOutput(
- const std::string& output, const std::vector<std::string>& depends,
- const cmImplicitDependsList& implicit_depends,
- const cmCustomCommandLines& commandLines)
-{
- // Lookup an existing command.
- if (cmSourceFile* sf = this->GetSourceFileWithOutput(output)) {
- if (cmCustomCommand* cc = sf->GetCustomCommand()) {
- cc->AppendCommands(commandLines);
- cc->AppendDepends(depends);
- cc->AppendImplicitDepends(implicit_depends);
- }
- }
-}
-
cmUtilityOutput cmMakefile::GetUtilityOutput(cmTarget* target)
{
std::string force = cmStrCat(this->GetCurrentBinaryDirectory(),
@@ -1215,15 +1222,14 @@ cmUtilityOutput cmMakefile::GetUtilityOutput(cmTarget* target)
}
cmTarget* cmMakefile::AddUtilityCommand(
- const std::string& utilityName, cmCommandOrigin origin, bool excludeFromAll,
- const char* workingDirectory, const std::vector<std::string>& byproducts,
+ const std::string& utilityName, bool excludeFromAll, const char* workingDir,
+ const std::vector<std::string>& byproducts,
const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines, bool escapeOldStyle,
const char* comment, bool uses_terminal, bool command_expand_lists,
- const std::string& job_pool)
+ const std::string& job_pool, bool stdPipesUTF8)
{
- cmTarget* target =
- this->AddNewUtilityTarget(utilityName, origin, excludeFromAll);
+ cmTarget* target = this->AddNewUtilityTarget(utilityName, excludeFromAll);
// Validate custom commands.
if ((commandLines.empty() && depends.empty()) ||
@@ -1236,45 +1242,26 @@ cmTarget* cmMakefile::AddUtilityCommand(
this->GetOrCreateGeneratedSource(force.Name);
// Always create the byproduct sources and mark them generated.
- this->CreateGeneratedSources(byproducts);
-
- if (!comment) {
- // Use an empty comment to avoid generation of default comment.
- comment = "";
- }
-
- this->CommitUtilityCommand(target, force, workingDirectory, byproducts,
- depends, commandLines, escapeOldStyle, comment,
- uses_terminal, command_expand_lists, job_pool);
+ this->CreateGeneratedByproducts(byproducts);
+
+ // Strings could be moved into the callback function with C++14.
+ cm::optional<std::string> commentStr = MakeOptionalString(comment);
+ cm::optional<std::string> workingStr = MakeOptionalString(workingDir);
+
+ // Dispatch command creation to allow generator expressions in outputs.
+ this->AddGeneratorAction(
+ [=](cmLocalGenerator& lg, const cmListFileBacktrace& lfbt) {
+ BacktraceGuard guard(this->Backtrace, lfbt);
+ detail::AddUtilityCommand(lg, lfbt, cmCommandOrigin::Project, target,
+ force, GetCStrOrNull(workingStr), byproducts,
+ depends, commandLines, escapeOldStyle,
+ GetCStrOrNull(commentStr), uses_terminal,
+ command_expand_lists, job_pool, stdPipesUTF8);
+ });
return target;
}
-void cmMakefile::CommitUtilityCommand(
- cmTarget* target, const cmUtilityOutput& force, const char* workingDirectory,
- const std::vector<std::string>& byproducts,
- const std::vector<std::string>& depends,
- const cmCustomCommandLines& commandLines, bool escapeOldStyle,
- const char* comment, bool uses_terminal, bool command_expand_lists,
- const std::string& job_pool)
-{
- std::vector<std::string> forced;
- forced.push_back(force.Name);
- std::string no_main_dependency;
- cmImplicitDependsList no_implicit_depends;
- bool no_replace = false;
- cmSourceFile* sf = this->AddCustomCommandToOutput(
- forced, byproducts, depends, no_main_dependency, no_implicit_depends,
- commandLines, comment, workingDirectory, no_replace, escapeOldStyle,
- uses_terminal, command_expand_lists, /*depfile=*/"", job_pool);
- if (!force.NameCMP0049.empty()) {
- target->AddSource(force.NameCMP0049);
- }
- if (sf) {
- this->AddTargetByproducts(target, byproducts);
- }
-}
-
static void s_AddDefineFlag(std::string const& flag, std::string& dflags)
{
// remove any \n\r
@@ -1342,28 +1329,27 @@ void cmMakefile::RemoveDefineFlag(std::string const& flag)
void cmMakefile::AddCompileDefinition(std::string const& option)
{
- this->AppendProperty("COMPILE_DEFINITIONS", option.c_str());
+ this->AppendProperty("COMPILE_DEFINITIONS", option);
}
void cmMakefile::AddCompileOption(std::string const& option)
{
- this->AppendProperty("COMPILE_OPTIONS", option.c_str());
+ this->AppendProperty("COMPILE_OPTIONS", option);
}
void cmMakefile::AddLinkOption(std::string const& option)
{
- this->AppendProperty("LINK_OPTIONS", option.c_str());
+ this->AppendProperty("LINK_OPTIONS", option);
}
void cmMakefile::AddLinkDirectory(std::string const& directory, bool before)
{
- cmListFileBacktrace lfbt = this->GetBacktrace();
if (before) {
- this->StateSnapshot.GetDirectory().PrependLinkDirectoriesEntry(directory,
- lfbt);
+ this->StateSnapshot.GetDirectory().PrependLinkDirectoriesEntry(
+ directory, this->Backtrace);
} else {
- this->StateSnapshot.GetDirectory().AppendLinkDirectoriesEntry(directory,
- lfbt);
+ this->StateSnapshot.GetDirectory().AppendLinkDirectoriesEntry(
+ directory, this->Backtrace);
}
}
@@ -1408,9 +1394,9 @@ bool cmMakefile::ParseDefineFlag(std::string const& def, bool remove)
const char* define = def.c_str() + 2;
if (remove) {
- if (const char* cdefs = this->GetProperty("COMPILE_DEFINITIONS")) {
+ if (cmProp cdefs = this->GetProperty("COMPILE_DEFINITIONS")) {
// Expand the list.
- std::vector<std::string> defs = cmExpandedList(cdefs);
+ std::vector<std::string> defs = cmExpandedList(*cdefs);
// Recompose the list without the definition.
auto defEnd = std::remove(defs.begin(), defs.end(), define);
@@ -1439,29 +1425,32 @@ void cmMakefile::InitializeFromParent(cmMakefile* parent)
// Include transform property. There is no per-config version.
{
const char* prop = "IMPLICIT_DEPENDS_INCLUDE_TRANSFORM";
- this->SetProperty(prop, parent->GetProperty(prop));
+ cmProp p = parent->GetProperty(prop);
+ this->SetProperty(prop, p ? p->c_str() : nullptr);
}
// compile definitions property and per-config versions
cmPolicies::PolicyStatus polSt = this->GetPolicyStatus(cmPolicies::CMP0043);
if (polSt == cmPolicies::WARN || polSt == cmPolicies::OLD) {
- this->SetProperty("COMPILE_DEFINITIONS",
- parent->GetProperty("COMPILE_DEFINITIONS"));
+ cmProp p = parent->GetProperty("COMPILE_DEFINITIONS");
+ this->SetProperty("COMPILE_DEFINITIONS", p ? p->c_str() : nullptr);
std::vector<std::string> configs;
this->GetConfigurations(configs);
for (std::string const& config : configs) {
std::string defPropName =
cmStrCat("COMPILE_DEFINITIONS_", cmSystemTools::UpperCase(config));
- const char* prop = parent->GetProperty(defPropName);
- this->SetProperty(defPropName, prop);
+ cmProp prop = parent->GetProperty(defPropName);
+ this->SetProperty(defPropName, prop ? prop->c_str() : nullptr);
}
}
// labels
- this->SetProperty("LABELS", parent->GetProperty("LABELS"));
+ cmProp p = parent->GetProperty("LABELS");
+ this->SetProperty("LABELS", p ? p->c_str() : nullptr);
// link libraries
- this->SetProperty("LINK_LIBRARIES", parent->GetProperty("LINK_LIBRARIES"));
+ p = parent->GetProperty("LINK_LIBRARIES");
+ this->SetProperty("LINK_LIBRARIES", p ? p->c_str() : nullptr);
// the initial project name
this->StateSnapshot.SetProjectName(parent->StateSnapshot.GetProjectName());
@@ -1476,6 +1465,20 @@ void cmMakefile::InitializeFromParent(cmMakefile* parent)
this->RecursionDepth = parent->RecursionDepth;
}
+void cmMakefile::AddInstallGenerator(std::unique_ptr<cmInstallGenerator> g)
+{
+ if (g) {
+ this->InstallGenerators.push_back(std::move(g));
+ }
+}
+
+void cmMakefile::AddTestGenerator(std::unique_ptr<cmTestGenerator> g)
+{
+ if (g) {
+ this->TestGenerators.push_back(std::move(g));
+ }
+}
+
void cmMakefile::PushFunctionScope(std::string const& fileName,
const cmPolicies::PolicyMap& pm)
{
@@ -1642,7 +1645,7 @@ void cmMakefile::Configure()
allowedCommands.insert("message");
isProblem = false;
for (cmListFileFunction const& func : listFile.Functions) {
- if (!cmContains(allowedCommands, func.Name.Lower)) {
+ if (!cm::contains(allowedCommands, func.Name.Lower)) {
isProblem = true;
break;
}
@@ -1776,8 +1779,10 @@ void cmMakefile::AddSubDirectory(const std::string& srcPath,
cmSystemTools::MakeDirectory(binPath);
- cmMakefile* subMf = new cmMakefile(this->GlobalGenerator, newSnapshot);
- this->GetGlobalGenerator()->AddMakefile(subMf);
+ auto subMfu =
+ cm::make_unique<cmMakefile>(this->GlobalGenerator, newSnapshot);
+ auto subMf = subMfu.get();
+ this->GetGlobalGenerator()->AddMakefile(std::move(subMfu));
if (excludeFromAll) {
subMf->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
@@ -1789,8 +1794,8 @@ void cmMakefile::AddSubDirectory(const std::string& srcPath,
this->UnConfiguredDirectories.push_back(subMf);
}
- this->AddInstallGenerator(new cmInstallSubdirectoryGenerator(
- subMf, binPath.c_str(), excludeFromAll));
+ this->AddInstallGenerator(cm::make_unique<cmInstallSubdirectoryGenerator>(
+ subMf, binPath, excludeFromAll));
}
const std::string& cmMakefile::GetCurrentSourceDirectory() const
@@ -1820,20 +1825,19 @@ void cmMakefile::AddIncludeDirectories(const std::vector<std::string>& incs,
return;
}
- cmListFileBacktrace lfbt = this->GetBacktrace();
std::string entryString = cmJoin(incs, ";");
if (before) {
this->StateSnapshot.GetDirectory().PrependIncludeDirectoriesEntry(
- entryString, lfbt);
+ entryString, this->Backtrace);
} else {
this->StateSnapshot.GetDirectory().AppendIncludeDirectoriesEntry(
- entryString, lfbt);
+ entryString, this->Backtrace);
}
// Property on each target:
for (auto& target : this->Targets) {
cmTarget& t = target.second;
- t.InsertInclude(entryString, lfbt, before);
+ t.InsertInclude(entryString, this->Backtrace, before);
}
}
@@ -1877,8 +1881,7 @@ void cmMakefile::AddCacheDefinition(const std::string& name, const char* value,
cmStateEnums::CacheEntryType type,
bool force)
{
- const std::string* existingValue =
- this->GetState()->GetInitializedCacheValue(name);
+ cmProp existingValue = this->GetState()->GetInitializedCacheValue(name);
// must be outside the following if() to keep it alive long enough
std::string nvalue;
@@ -2008,8 +2011,8 @@ void cmMakefile::AddGlobalLinkInformation(cmTarget& target)
default:;
}
- if (const char* linkLibsProp = this->GetProperty("LINK_LIBRARIES")) {
- std::vector<std::string> linkLibs = cmExpandedList(linkLibsProp);
+ if (cmProp linkLibsProp = this->GetProperty("LINK_LIBRARIES")) {
+ std::vector<std::string> linkLibs = cmExpandedList(*linkLibsProp);
for (auto j = linkLibs.begin(); j != linkLibs.end(); ++j) {
std::string libraryName = *j;
@@ -2027,7 +2030,7 @@ void cmMakefile::AddGlobalLinkInformation(cmTarget& target)
target.AddLinkLibrary(*this, libraryName, libType);
target.AppendProperty(
"INTERFACE_LINK_LIBRARIES",
- target.GetDebugGeneratorExpressions(libraryName, libType).c_str());
+ target.GetDebugGeneratorExpressions(libraryName, libType));
}
}
}
@@ -2080,7 +2083,8 @@ cmTarget* cmMakefile::AddNewTarget(cmStateEnums::TargetType type,
{
auto it =
this->Targets
- .emplace(name, cmTarget(name, type, cmTarget::VisibilityNormal, this))
+ .emplace(name,
+ cmTarget(name, type, cmTarget::VisibilityNormal, this, true))
.first;
this->OrderedTargets.push_back(&it->second);
this->GetGlobalGenerator()->IndexTarget(&it->second);
@@ -2089,11 +2093,9 @@ cmTarget* cmMakefile::AddNewTarget(cmStateEnums::TargetType type,
}
cmTarget* cmMakefile::AddNewUtilityTarget(const std::string& utilityName,
- cmCommandOrigin origin,
bool excludeFromAll)
{
cmTarget* target = this->AddNewTarget(cmStateEnums::UTILITY, utilityName);
- target->SetIsGeneratorProvided(origin == cmCommandOrigin::Generator);
if (excludeFromAll) {
target->SetProperty("EXCLUDE_FROM_ALL", "TRUE");
}
@@ -2155,18 +2157,18 @@ cmSourceFile* cmMakefile::LinearGetSourceFileWithOutput(
// Look through all the source files that have custom commands and see if the
// custom command has the passed source file as an output.
- for (cmSourceFile* src : this->SourceFiles) {
+ for (const auto& src : this->SourceFiles) {
// Does this source file have a custom command?
if (src->GetCustomCommand()) {
// Does the output of the custom command match the source file name?
if (AnyOutputMatches(name, src->GetCustomCommand()->GetOutputs())) {
// Return the first matching output.
- return src;
+ return src.get();
}
if (kind == cmSourceOutputKind::OutputOrByproduct) {
if (AnyOutputMatches(name, src->GetCustomCommand()->GetByproducts())) {
// Do not return the source yet as there might be a matching output.
- fallback = src;
+ fallback = src.get();
}
}
}
@@ -2211,8 +2213,8 @@ cmSourceFile* cmMakefile::GetSourceFileWithOutput(
(!o->second.Sources.SourceIsByproduct ||
kind == cmSourceOutputKind::OutputOrByproduct)) {
// Source file could also be null pointer for example if we found the
- // byproduct of a utility target or a PRE_BUILD, PRE_LINK, or POST_BUILD
- // command of a target.
+ // byproduct of a utility target, a PRE_BUILD, PRE_LINK, or POST_BUILD
+ // command of a target, or a not yet created custom command.
return o->second.Sources.Source;
}
return nullptr;
@@ -2220,12 +2222,20 @@ cmSourceFile* cmMakefile::GetSourceFileWithOutput(
bool cmMakefile::MightHaveCustomCommand(const std::string& name) const
{
- // This will have to be changed for delaying custom command creation, because
- // GetSourceFileWithOutput requires the command to be already created.
- if (cmSourceFile* sf = this->GetSourceFileWithOutput(name)) {
- if (sf->GetCustomCommand()) {
- return true;
- }
+ if (this->DelayedOutputFilesHaveGenex ||
+ cmGeneratorExpression::Find(name) != std::string::npos) {
+ // Could be more restrictive, but for now we assume that there could always
+ // be a match when generator expressions are involved.
+ return true;
+ }
+ // Also see LinearGetSourceFileWithOutput.
+ if (!cmSystemTools::FileIsFullPath(name)) {
+ return AnyOutputMatches(name, this->DelayedOutputFiles);
+ }
+ // Otherwise we use an efficient lookup map.
+ auto o = this->OutputToSource.find(name);
+ if (o != this->OutputToSource.end()) {
+ return o->second.SourceMightBeOutput;
}
return false;
}
@@ -2278,6 +2288,7 @@ void cmMakefile::UpdateOutputToSourceMap(std::string const& output,
SourceEntry entry;
entry.Sources.Source = source;
entry.Sources.SourceIsByproduct = byproduct;
+ entry.SourceMightBeOutput = !byproduct;
auto pr = this->OutputToSource.emplace(output, entry);
if (!pr.second) {
@@ -2287,6 +2298,7 @@ void cmMakefile::UpdateOutputToSourceMap(std::string const& output,
(current.Sources.SourceIsByproduct && !byproduct)) {
current.Sources.Source = source;
current.Sources.SourceIsByproduct = false;
+ current.SourceMightBeOutput = true;
} else {
// Multiple custom commands produce the same output but may
// be attached to a different source file (MAIN_DEPENDENCY).
@@ -2392,11 +2404,11 @@ cmSourceGroup* cmMakefile::GetOrCreateSourceGroup(
cmSourceGroup* cmMakefile::GetOrCreateSourceGroup(const std::string& name)
{
- const char* delimiter = this->GetDefinition("SOURCE_GROUP_DELIMITER");
- if (delimiter == nullptr) {
- delimiter = "\\";
+ const char* delimiters = this->GetDefinition("SOURCE_GROUP_DELIMITER");
+ if (delimiters == nullptr) {
+ delimiters = "/\\";
}
- return this->GetOrCreateSourceGroup(cmTokenize(name, delimiter));
+ return this->GetOrCreateSourceGroup(cmTokenize(name, delimiters));
}
/**
@@ -2444,14 +2456,14 @@ void cmMakefile::ExpandVariablesCMP0019()
}
std::ostringstream w;
- const char* includeDirs = this->GetProperty("INCLUDE_DIRECTORIES");
- if (mightExpandVariablesCMP0019(includeDirs)) {
- std::string dirs = includeDirs;
+ cmProp includeDirs = this->GetProperty("INCLUDE_DIRECTORIES");
+ if (includeDirs && mightExpandVariablesCMP0019(includeDirs->c_str())) {
+ std::string dirs = *includeDirs;
this->ExpandVariablesInString(dirs, true, true);
- if (pol == cmPolicies::WARN && dirs != includeDirs) {
+ if (pol == cmPolicies::WARN && dirs != *includeDirs) {
/* clang-format off */
w << "Evaluated directory INCLUDE_DIRECTORIES\n"
- << " " << includeDirs << "\n"
+ << " " << *includeDirs << "\n"
<< "as\n"
<< " " << dirs << "\n";
/* clang-format on */
@@ -2467,25 +2479,25 @@ void cmMakefile::ExpandVariablesCMP0019()
continue;
}
includeDirs = t.GetProperty("INCLUDE_DIRECTORIES");
- if (mightExpandVariablesCMP0019(includeDirs)) {
- std::string dirs = includeDirs;
+ if (includeDirs && mightExpandVariablesCMP0019(includeDirs->c_str())) {
+ std::string dirs = *includeDirs;
this->ExpandVariablesInString(dirs, true, true);
- if (pol == cmPolicies::WARN && dirs != includeDirs) {
+ if (pol == cmPolicies::WARN && dirs != *includeDirs) {
/* clang-format off */
w << "Evaluated target " << t.GetName() << " INCLUDE_DIRECTORIES\n"
- << " " << includeDirs << "\n"
+ << " " << *includeDirs << "\n"
<< "as\n"
<< " " << dirs << "\n";
/* clang-format on */
}
- t.SetProperty("INCLUDE_DIRECTORIES", dirs.c_str());
+ t.SetProperty("INCLUDE_DIRECTORIES", dirs);
}
}
- if (const char* linkDirsProp = this->GetProperty("LINK_DIRECTORIES")) {
- if (mightExpandVariablesCMP0019(linkDirsProp)) {
- std::string d = linkDirsProp;
- std::string orig = linkDirsProp;
+ if (cmProp linkDirsProp = this->GetProperty("LINK_DIRECTORIES")) {
+ if (mightExpandVariablesCMP0019(linkDirsProp->c_str())) {
+ std::string d = *linkDirsProp;
+ const std::string orig = d;
this->ExpandVariablesInString(d, true, true);
if (pol == cmPolicies::WARN && d != orig) {
/* clang-format off */
@@ -2498,20 +2510,17 @@ void cmMakefile::ExpandVariablesCMP0019()
}
}
- if (const char* linkLibsProp = this->GetProperty("LINK_LIBRARIES")) {
- std::vector<std::string> linkLibs = cmExpandedList(linkLibsProp);
+ if (cmProp linkLibsProp = this->GetProperty("LINK_LIBRARIES")) {
+ std::vector<std::string> linkLibs = cmExpandedList(*linkLibsProp);
for (auto l = linkLibs.begin(); l != linkLibs.end(); ++l) {
std::string libName = *l;
- if (libName == "optimized") {
- ++l;
- libName = *l;
- } else if (libName == "debug") {
+ if (libName == "optimized"_s || libName == "debug"_s) {
++l;
libName = *l;
}
if (mightExpandVariablesCMP0019(libName.c_str())) {
- std::string orig = libName;
+ const std::string orig = libName;
this->ExpandVariablesInString(libName, true, true);
if (pol == cmPolicies::WARN && libName != orig) {
/* clang-format off */
@@ -2615,7 +2624,7 @@ cmMakefile::AppleSDK cmMakefile::GetAppleSDKType() const
};
for (auto const& entry : sdkDatabase) {
- if (sdkRoot.find(entry.name) == 0 ||
+ if (cmHasPrefix(sdkRoot, entry.name) ||
sdkRoot.find(std::string("/") + entry.name) != std::string::npos) {
return entry.sdk;
}
@@ -2673,7 +2682,7 @@ const std::string& cmMakefile::GetRequiredDefinition(
bool cmMakefile::IsDefinitionSet(const std::string& name) const
{
- const std::string* def = this->StateSnapshot.GetDefinition(name);
+ cmProp def = this->StateSnapshot.GetDefinition(name);
if (!def) {
def = this->GetState()->GetInitializedCacheValue(name);
}
@@ -2690,7 +2699,7 @@ bool cmMakefile::IsDefinitionSet(const std::string& name) const
const std::string* cmMakefile::GetDef(const std::string& name) const
{
- const std::string* def = this->StateSnapshot.GetDefinition(name);
+ cmProp def = this->StateSnapshot.GetDefinition(name);
if (!def) {
def = this->GetState()->GetInitializedCacheValue(name);
}
@@ -2739,7 +2748,7 @@ const std::string& cmMakefile::GetSafeDefinition(const std::string& name) const
std::vector<std::string> cmMakefile::GetDefinitions() const
{
std::vector<std::string> res = this->StateSnapshot.ClosureKeys();
- cmAppend(res, this->GetState()->GetCacheEntryKeys());
+ cm::append(res, this->GetState()->GetCacheEntryKeys());
std::sort(res.begin(), res.end());
return res;
}
@@ -3024,7 +3033,7 @@ MessageType cmMakefile::ExpandVariablesInStringNew(
openstack.pop_back();
result.append(last, in - last);
std::string const& lookup = result.substr(var.loc);
- const char* value = nullptr;
+ cmProp value = nullptr;
std::string varresult;
std::string svalue;
switch (var.domain) {
@@ -3032,12 +3041,12 @@ MessageType cmMakefile::ExpandVariablesInStringNew(
if (filename && lookup == lineVar) {
varresult = std::to_string(line);
} else {
- value = this->GetDefinition(lookup);
+ value = this->GetDef(lookup);
}
break;
case ENVIRONMENT:
if (cmSystemTools::GetEnv(lookup, svalue)) {
- value = svalue.c_str();
+ value = &svalue;
}
break;
case CACHE:
@@ -3047,9 +3056,9 @@ MessageType cmMakefile::ExpandVariablesInStringNew(
// Get the string we're meant to append to.
if (value) {
if (escapeQuotes) {
- varresult = cmEscapeQuotes(value);
+ varresult = cmEscapeQuotes(*value);
} else {
- varresult = value;
+ varresult = *value;
}
} else if (!this->SuppressSideEffects) {
this->MaybeWarnUninitialized(lookup, filename);
@@ -3514,24 +3523,25 @@ cmSourceFile* cmMakefile::CreateSource(const std::string& sourceName,
bool generated,
cmSourceFileLocationKind kind)
{
- cmSourceFile* sf = new cmSourceFile(this, sourceName, kind);
+ auto sf = cm::make_unique<cmSourceFile>(this, sourceName, kind);
if (generated) {
sf->SetProperty("GENERATED", "1");
}
- this->SourceFiles.push_back(sf);
auto name =
this->GetCMakeInstance()->StripExtension(sf->GetLocation().GetName());
#if defined(_WIN32) || defined(__APPLE__)
name = cmSystemTools::LowerCase(name);
#endif
- this->SourceFileSearchIndex[name].push_back(sf);
+ this->SourceFileSearchIndex[name].push_back(sf.get());
// for "Known" paths add direct lookup (used for faster lookup in GetSource)
if (kind == cmSourceFileLocationKind::Known) {
- this->KnownFileSearchIndex[sourceName] = sf;
+ this->KnownFileSearchIndex[sourceName] = sf.get();
}
- return sf;
+ this->SourceFiles.push_back(std::move(sf));
+
+ return this->SourceFiles.back().get();
}
cmSourceFile* cmMakefile::GetOrCreateSource(const std::string& sourceName,
@@ -3553,11 +3563,41 @@ cmSourceFile* cmMakefile::GetOrCreateGeneratedSource(
return sf;
}
-void cmMakefile::CreateGeneratedSources(
+void cmMakefile::CreateGeneratedOutputs(
const std::vector<std::string>& outputs)
{
- for (std::string const& output : outputs) {
- this->GetOrCreateGeneratedSource(output);
+ for (std::string const& o : outputs) {
+ if (cmGeneratorExpression::Find(o) == std::string::npos) {
+ this->GetOrCreateGeneratedSource(o);
+ this->AddDelayedOutput(o);
+ } else {
+ this->DelayedOutputFilesHaveGenex = true;
+ }
+ }
+}
+
+void cmMakefile::CreateGeneratedByproducts(
+ const std::vector<std::string>& byproducts)
+{
+ for (std::string const& o : byproducts) {
+ if (cmGeneratorExpression::Find(o) == std::string::npos) {
+ this->GetOrCreateGeneratedSource(o);
+ }
+ }
+}
+
+void cmMakefile::AddDelayedOutput(std::string const& output)
+{
+ // Note that this vector might contain the output names in a different order
+ // than in source file iteration order.
+ this->DelayedOutputFiles.push_back(output);
+
+ SourceEntry entry;
+ entry.SourceMightBeOutput = true;
+
+ auto pr = this->OutputToSource.emplace(output, entry);
+ if (!pr.second) {
+ pr.first->second.SourceMightBeOutput = true;
}
}
@@ -3630,8 +3670,7 @@ int cmMakefile::TryCompile(const std::string& srcdir,
// be run that way but the cmake object requires a vailid path
cmake cm(cmake::RoleProject, cmState::Project);
cm.SetIsInTryCompile(true);
- cmGlobalGenerator* gg =
- cm.CreateGlobalGenerator(this->GetGlobalGenerator()->GetName());
+ auto gg = cm.CreateGlobalGenerator(this->GetGlobalGenerator()->GetName());
if (!gg) {
this->IssueMessage(MessageType::INTERNAL_ERROR,
"Global generator '" +
@@ -3642,7 +3681,7 @@ int cmMakefile::TryCompile(const std::string& srcdir,
return 1;
}
gg->RecursionDepth = this->RecursionDepth;
- cm.SetGlobalGenerator(gg);
+ cm.SetGlobalGenerator(std::move(gg));
// do a configure
cm.SetHomeDirectory(srcdir);
@@ -3651,7 +3690,7 @@ int cmMakefile::TryCompile(const std::string& srcdir,
cm.SetGeneratorPlatform(this->GetSafeDefinition("CMAKE_GENERATOR_PLATFORM"));
cm.SetGeneratorToolset(this->GetSafeDefinition("CMAKE_GENERATOR_TOOLSET"));
cm.LoadCache();
- if (!gg->IsMultiConfig()) {
+ if (!cm.GetGlobalGenerator()->IsMultiConfig()) {
if (const char* config =
this->GetDefinition("CMAKE_TRY_COMPILE_CONFIGURATION")) {
// Tell the single-configuration generator which one to use.
@@ -3697,7 +3736,8 @@ int cmMakefile::TryCompile(const std::string& srcdir,
cm.SetCacheArgs(*cmakeArgs);
}
// to save time we pass the EnableLanguage info directly
- gg->EnableLanguagesFromGenerator(this->GetGlobalGenerator(), this);
+ cm.GetGlobalGenerator()->EnableLanguagesFromGenerator(
+ this->GetGlobalGenerator(), this);
if (this->IsOn("CMAKE_SUPPRESS_DEVELOPER_WARNINGS")) {
cm.AddCacheEntry("CMAKE_SUPPRESS_DEVELOPER_WARNINGS", "TRUE", "",
cmStateEnums::INTERNAL);
@@ -3777,7 +3817,8 @@ void cmMakefile::DisplayStatus(const std::string& message, float s) const
}
std::string cmMakefile::GetModulesFile(const std::string& filename,
- bool& system) const
+ bool& system, bool debug,
+ std::string& debugBuffer) const
{
std::string result;
@@ -3808,6 +3849,9 @@ std::string cmMakefile::GetModulesFile(const std::string& filename,
moduleInCMakeModulePath = itempl;
break;
}
+ if (debug) {
+ debugBuffer = cmStrCat(debugBuffer, " ", itempl, "\n");
+ }
}
}
@@ -3816,6 +3860,9 @@ std::string cmMakefile::GetModulesFile(const std::string& filename,
cmStrCat(cmSystemTools::GetCMakeRoot(), "/Modules/", filename);
cmSystemTools::ConvertToUnixSlashes(moduleInCMakeRoot);
if (!cmSystemTools::FileExists(moduleInCMakeRoot)) {
+ if (debug) {
+ debugBuffer = cmStrCat(debugBuffer, " ", moduleInCMakeRoot, "\n");
+ }
moduleInCMakeRoot.clear();
}
@@ -4029,19 +4076,17 @@ int cmMakefile::ConfigureFile(const std::string& infile,
void cmMakefile::SetProperty(const std::string& prop, const char* value)
{
- cmListFileBacktrace lfbt = this->GetBacktrace();
- this->StateSnapshot.GetDirectory().SetProperty(prop, value, lfbt);
+ this->StateSnapshot.GetDirectory().SetProperty(prop, value, this->Backtrace);
}
-void cmMakefile::AppendProperty(const std::string& prop, const char* value,
- bool asString)
+void cmMakefile::AppendProperty(const std::string& prop,
+ const std::string& value, bool asString)
{
- cmListFileBacktrace lfbt = this->GetBacktrace();
this->StateSnapshot.GetDirectory().AppendProperty(prop, value, asString,
- lfbt);
+ this->Backtrace);
}
-const char* cmMakefile::GetProperty(const std::string& prop) const
+cmProp cmMakefile::GetProperty(const std::string& prop) const
{
// Check for computed properties.
static std::string output;
@@ -4054,20 +4099,21 @@ const char* cmMakefile::GetProperty(const std::string& prop) const
return pair.first;
});
output = cmJoin(keys, ";");
- return output.c_str();
+ return &output;
}
return this->StateSnapshot.GetDirectory().GetProperty(prop);
}
-const char* cmMakefile::GetProperty(const std::string& prop, bool chain) const
+cmProp cmMakefile::GetProperty(const std::string& prop, bool chain) const
{
return this->StateSnapshot.GetDirectory().GetProperty(prop, chain);
}
bool cmMakefile::GetPropertyAsBool(const std::string& prop) const
{
- return cmIsOn(this->GetProperty(prop));
+ cmProp p = this->GetProperty(prop);
+ return p && cmIsOn(*p);
}
std::vector<std::string> cmMakefile::GetPropertyKeys() const
@@ -4090,9 +4136,10 @@ cmTest* cmMakefile::CreateTest(const std::string& testName)
if (test) {
return test;
}
- test = new cmTest(this);
- test->SetName(testName);
- this->Tests[testName] = test;
+ auto newTest = cm::make_unique<cmTest>(this);
+ test = newTest.get();
+ newTest->SetName(testName);
+ this->Tests[testName] = std::move(newTest);
return test;
}
@@ -4100,7 +4147,7 @@ cmTest* cmMakefile::GetTest(const std::string& testName) const
{
auto mi = this->Tests.find(testName);
if (mi != this->Tests.end()) {
- return mi->second;
+ return mi->second.get();
}
return nullptr;
}
@@ -4108,7 +4155,7 @@ cmTest* cmMakefile::GetTest(const std::string& testName) const
void cmMakefile::GetTests(const std::string& config,
std::vector<cmTest*>& tests)
{
- for (auto generator : this->GetTestGenerators()) {
+ for (const auto& generator : this->GetTestGenerators()) {
if (generator->TestsForConfig(config)) {
tests.push_back(generator->GetTest());
}
@@ -4118,8 +4165,8 @@ void cmMakefile::GetTests(const std::string& config,
void cmMakefile::AddCMakeDependFilesFromUser()
{
std::vector<std::string> deps;
- if (const char* deps_str = this->GetProperty("CMAKE_CONFIGURE_DEPENDS")) {
- cmExpandList(deps_str, deps);
+ if (cmProp deps_str = this->GetProperty("CMAKE_CONFIGURE_DEPENDS")) {
+ cmExpandList(*deps_str, deps);
}
for (std::string const& dep : deps) {
if (cmSystemTools::FileIsFullPath(dep)) {
@@ -4214,15 +4261,15 @@ cmTarget* cmMakefile::AddImportedTarget(const std::string& name,
new cmTarget(name, type,
global ? cmTarget::VisibilityImportedGlobally
: cmTarget::VisibilityImported,
- this));
+ this, true));
// Add to the set of available imported targets.
this->ImportedTargets[name] = target.get();
this->GetGlobalGenerator()->IndexTarget(target.get());
// Transfer ownership to this cmMakefile object.
- this->ImportedTargetsOwned.push_back(target.get());
- return target.release();
+ this->ImportedTargetsOwned.push_back(std::move(target));
+ return this->ImportedTargetsOwned.back().get();
}
cmTarget* cmMakefile::FindTargetToUse(const std::string& name,
@@ -4246,7 +4293,7 @@ cmTarget* cmMakefile::FindTargetToUse(const std::string& name,
bool cmMakefile::IsAlias(const std::string& name) const
{
- if (cmContains(this->AliasTargets, name)) {
+ if (cm::contains(this->AliasTargets, name)) {
return true;
}
return this->GetGlobalGenerator()->IsAlias(name);
@@ -4487,7 +4534,7 @@ bool cmMakefile::SetPolicy(cmPolicies::PolicyID id,
// Deprecate old policies, especially those that require a lot
// of code to maintain the old behavior.
- if (status == cmPolicies::OLD && id <= cmPolicies::CMP0067 &&
+ if (status == cmPolicies::OLD && id <= cmPolicies::CMP0071 &&
!(this->GetCMakeInstance()->GetIsInTryCompile() &&
(
// Policies set by cmCoreTryCompile::TryCompileCode.
@@ -4587,17 +4634,21 @@ static const char* const C_FEATURES[] = { nullptr FOR_EACH_C_FEATURE(
static const char* const CXX_FEATURES[] = { nullptr FOR_EACH_CXX_FEATURE(
FEATURE_STRING) };
+
+static const char* const CUDA_FEATURES[] = { nullptr FOR_EACH_CUDA_FEATURE(
+ FEATURE_STRING) };
#undef FEATURE_STRING
static const char* const C_STANDARDS[] = { "90", "99", "11" };
static const char* const CXX_STANDARDS[] = { "98", "11", "14", "17", "20" };
+static const char* const CUDA_STANDARDS[] = { "03", "11", "14", "17", "20" };
bool cmMakefile::AddRequiredTargetFeature(cmTarget* target,
const std::string& feature,
std::string* error) const
{
if (cmGeneratorExpression::Find(feature) != std::string::npos) {
- target->AppendProperty("COMPILE_FEATURES", feature.c_str());
+ target->AppendProperty("COMPILE_FEATURES", feature);
return true;
}
@@ -4612,7 +4663,7 @@ bool cmMakefile::AddRequiredTargetFeature(cmTarget* target,
}
std::vector<std::string> availableFeatures = cmExpandedList(features);
- if (!cmContains(availableFeatures, feature)) {
+ if (!cm::contains(availableFeatures, feature)) {
std::ostringstream e;
e << "The compiler feature \"" << feature << "\" is not known to " << lang
<< " compiler\n\""
@@ -4628,11 +4679,15 @@ bool cmMakefile::AddRequiredTargetFeature(cmTarget* target,
return false;
}
- target->AppendProperty("COMPILE_FEATURES", feature.c_str());
+ target->AppendProperty("COMPILE_FEATURES", feature);
- return lang == "C" || lang == "OBJC"
- ? this->AddRequiredTargetCFeature(target, feature, lang, error)
- : this->AddRequiredTargetCxxFeature(target, feature, lang, error);
+ if (lang == "C" || lang == "OBJC") {
+ return this->AddRequiredTargetCFeature(target, feature, lang, error);
+ }
+ if (lang == "CUDA") {
+ return this->AddRequiredTargetCudaFeature(target, feature, lang, error);
+ }
+ return this->AddRequiredTargetCxxFeature(target, feature, lang, error);
}
bool cmMakefile::CompileFeatureKnown(cmTarget const* target,
@@ -4656,6 +4711,13 @@ bool cmMakefile::CompileFeatureKnown(cmTarget const* target,
lang = "CXX";
return true;
}
+ bool isCudaFeature =
+ std::find_if(cm::cbegin(CUDA_FEATURES) + 1, cm::cend(CUDA_FEATURES),
+ cmStrCmp(feature)) != cm::cend(CUDA_FEATURES);
+ if (isCudaFeature) {
+ lang = "CUDA";
+ return true;
+ }
std::ostringstream e;
if (error) {
e << "specified";
@@ -4724,17 +4786,21 @@ bool cmMakefile::HaveStandardAvailable(cmTarget const* target,
std::string const& lang,
const std::string& feature) const
{
- return lang == "C" || lang == "OBJC"
- ? this->HaveCStandardAvailable(target, feature, lang)
- : this->HaveCxxStandardAvailable(target, feature, lang);
+ if (lang == "C" || lang == "OBJC") {
+ return this->HaveCStandardAvailable(target, feature, lang);
+ }
+ if (lang == "CUDA") {
+ return this->HaveCudaStandardAvailable(target, feature, lang);
+ }
+ return this->HaveCxxStandardAvailable(target, feature, lang);
}
bool cmMakefile::HaveCStandardAvailable(cmTarget const* target,
const std::string& feature,
std::string const& lang) const
{
- const char* defaultCStandard =
- this->GetDefinition(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
+ cmProp defaultCStandard =
+ this->GetDef(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
if (!defaultCStandard) {
this->IssueMessage(
MessageType::INTERNAL_ERROR,
@@ -4745,11 +4811,11 @@ bool cmMakefile::HaveCStandardAvailable(cmTarget const* target,
return true;
}
if (std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
- cmStrCmp(defaultCStandard)) == cm::cend(C_STANDARDS)) {
+ cmStrCmp(*defaultCStandard)) == cm::cend(C_STANDARDS)) {
const std::string e = cmStrCat("The CMAKE_", lang,
"_STANDARD_DEFAULT variable contains an "
"invalid value: \"",
- defaultCStandard, "\".");
+ *defaultCStandard, "\".");
this->IssueMessage(MessageType::INTERNAL_ERROR, e);
return false;
}
@@ -4760,24 +4826,23 @@ bool cmMakefile::HaveCStandardAvailable(cmTarget const* target,
this->CheckNeededCLanguage(feature, lang, needC90, needC99, needC11);
- const char* existingCStandard =
- target->GetProperty(cmStrCat(lang, "_STANDARD"));
+ cmProp existingCStandard = target->GetProperty(cmStrCat(lang, "_STANDARD"));
if (!existingCStandard) {
existingCStandard = defaultCStandard;
}
if (std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
- cmStrCmp(existingCStandard)) == cm::cend(C_STANDARDS)) {
+ cmStrCmp(*existingCStandard)) == cm::cend(C_STANDARDS)) {
const std::string e = cmStrCat(
"The ", lang, "_STANDARD property on target \"", target->GetName(),
- "\" contained an invalid value: \"", existingCStandard, "\".");
+ "\" contained an invalid value: \"", *existingCStandard, "\".");
this->IssueMessage(MessageType::FATAL_ERROR, e);
return false;
}
const char* const* existingCIt = existingCStandard
? std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
- cmStrCmp(existingCStandard))
+ cmStrCmp(*existingCStandard))
: cm::cend(C_STANDARDS);
if (needC11 && existingCStandard &&
@@ -4809,6 +4874,14 @@ bool cmMakefile::IsLaterStandard(std::string const& lang,
return std::find_if(rhsIt, cm::cend(C_STANDARDS), cmStrCmp(lhs)) !=
cm::cend(C_STANDARDS);
}
+ if (lang == "CUDA") {
+ const char* const* rhsIt = std::find_if(
+ cm::cbegin(CUDA_STANDARDS), cm::cend(CUDA_STANDARDS), cmStrCmp(rhs));
+
+ return std::find_if(rhsIt, cm::cend(CUDA_STANDARDS), cmStrCmp(lhs)) !=
+ cm::cend(CUDA_STANDARDS);
+ }
+
const char* const* rhsIt = std::find_if(
cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS), cmStrCmp(rhs));
@@ -4820,8 +4893,8 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
const std::string& feature,
std::string const& lang) const
{
- const char* defaultCxxStandard =
- this->GetDefinition(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
+ cmProp defaultCxxStandard =
+ this->GetDef(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
if (!defaultCxxStandard) {
this->IssueMessage(
MessageType::INTERNAL_ERROR,
@@ -4832,10 +4905,10 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
return true;
}
if (std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
- cmStrCmp(defaultCxxStandard)) == cm::cend(CXX_STANDARDS)) {
+ cmStrCmp(*defaultCxxStandard)) == cm::cend(CXX_STANDARDS)) {
const std::string e =
cmStrCat("The CMAKE_", lang, "_STANDARD_DEFAULT variable contains an ",
- "invalid value: \"", defaultCxxStandard, "\".");
+ "invalid value: \"", *defaultCxxStandard, "\".");
this->IssueMessage(MessageType::INTERNAL_ERROR, e);
return false;
}
@@ -4848,7 +4921,7 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
this->CheckNeededCxxLanguage(feature, lang, needCxx98, needCxx11, needCxx14,
needCxx17, needCxx20);
- const char* existingCxxStandard =
+ cmProp existingCxxStandard =
target->GetProperty(cmStrCat(lang, "_STANDARD"));
if (!existingCxxStandard) {
existingCxxStandard = defaultCxxStandard;
@@ -4856,11 +4929,11 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
const char* const* existingCxxLevel =
std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
- cmStrCmp(existingCxxStandard));
+ cmStrCmp(*existingCxxStandard));
if (existingCxxLevel == cm::cend(CXX_STANDARDS)) {
const std::string e = cmStrCat(
"The ", lang, "_STANDARD property on target \"", target->GetName(),
- "\" contained an invalid value: \"", existingCxxStandard, "\".");
+ "\" contained an invalid value: \"", *existingCxxStandard, "\".");
this->IssueMessage(MessageType::FATAL_ERROR, e);
return false;
}
@@ -4887,27 +4960,27 @@ void cmMakefile::CheckNeededCxxLanguage(const std::string& feature,
if (const char* propCxx98 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "98_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propCxx98);
- needCxx98 = cmContains(props, feature);
+ needCxx98 = cm::contains(props, feature);
}
if (const char* propCxx11 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "11_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propCxx11);
- needCxx11 = cmContains(props, feature);
+ needCxx11 = cm::contains(props, feature);
}
if (const char* propCxx14 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "14_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propCxx14);
- needCxx14 = cmContains(props, feature);
+ needCxx14 = cm::contains(props, feature);
}
if (const char* propCxx17 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "17_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propCxx17);
- needCxx17 = cmContains(props, feature);
+ needCxx17 = cm::contains(props, feature);
}
if (const char* propCxx20 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "20_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propCxx20);
- needCxx20 = cmContains(props, feature);
+ needCxx20 = cm::contains(props, feature);
}
}
@@ -4925,12 +4998,12 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
this->CheckNeededCxxLanguage(feature, lang, needCxx98, needCxx11, needCxx14,
needCxx17, needCxx20);
- const char* existingCxxStandard =
+ cmProp existingCxxStandard =
target->GetProperty(cmStrCat(lang, "_STANDARD"));
if (existingCxxStandard == nullptr) {
- const char* defaultCxxStandard =
- this->GetDefinition(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
- if (defaultCxxStandard && *defaultCxxStandard) {
+ cmProp defaultCxxStandard =
+ this->GetDef(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
+ if (defaultCxxStandard && !defaultCxxStandard->empty()) {
existingCxxStandard = defaultCxxStandard;
}
}
@@ -4938,11 +5011,11 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
if (existingCxxStandard) {
existingCxxLevel =
std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
- cmStrCmp(existingCxxStandard));
+ cmStrCmp(*existingCxxStandard));
if (existingCxxLevel == cm::cend(CXX_STANDARDS)) {
const std::string e = cmStrCat(
"The ", lang, "_STANDARD property on target \"", target->GetName(),
- "\" contained an invalid value: \"", existingCxxStandard, "\".");
+ "\" contained an invalid value: \"", *existingCxxStandard, "\".");
if (error) {
*error = e;
} else {
@@ -4953,27 +5026,6 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
}
}
- const char* existingCudaStandard = target->GetProperty("CUDA_STANDARD");
- const char* const* existingCudaLevel = nullptr;
- if (existingCudaStandard) {
- existingCudaLevel =
- std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
- cmStrCmp(existingCudaStandard));
- if (existingCudaLevel == cm::cend(CXX_STANDARDS)) {
- std::ostringstream e;
- e << "The CUDA_STANDARD property on target \"" << target->GetName()
- << "\" contained an invalid value: \"" << existingCudaStandard
- << "\".";
- if (error) {
- *error = e.str();
- } else {
- this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
- e.str(), this->Backtrace);
- }
- return false;
- }
- }
-
/* clang-format off */
const char* const* needCxxLevel =
needCxx20 ? &CXX_STANDARDS[4]
@@ -4990,11 +5042,164 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
if (!existingCxxLevel || existingCxxLevel < needCxxLevel) {
target->SetProperty(cmStrCat(lang, "_STANDARD"), *needCxxLevel);
}
+ }
+
+ return true;
+}
+bool cmMakefile::HaveCudaStandardAvailable(cmTarget const* target,
+ const std::string& feature,
+ std::string const& lang) const
+{
+ cmProp defaultCudaStandard =
+ this->GetDef(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
+ if (!defaultCudaStandard) {
+ this->IssueMessage(
+ MessageType::INTERNAL_ERROR,
+ cmStrCat("CMAKE_", lang,
+ "_STANDARD_DEFAULT is not set. COMPILE_FEATURES support "
+ "not fully configured for this compiler."));
+ // Return true so the caller does not try to lookup the default standard.
+ return true;
+ }
+ if (std::find_if(cm::cbegin(CUDA_STANDARDS), cm::cend(CUDA_STANDARDS),
+ cmStrCmp(*defaultCudaStandard)) ==
+ cm::cend(CUDA_STANDARDS)) {
+ const std::string e =
+ cmStrCat("The CMAKE_", lang, "_STANDARD_DEFAULT variable contains an ",
+ "invalid value: \"", *defaultCudaStandard, "\".");
+ this->IssueMessage(MessageType::INTERNAL_ERROR, e);
+ return false;
+ }
+
+ bool needCuda03 = false;
+ bool needCuda11 = false;
+ bool needCuda14 = false;
+ bool needCuda17 = false;
+ bool needCuda20 = false;
+ this->CheckNeededCudaLanguage(feature, lang, needCuda03, needCuda11,
+ needCuda14, needCuda17, needCuda20);
+
+ cmProp existingCudaStandard =
+ target->GetProperty(cmStrCat(lang, "_STANDARD"));
+ if (!existingCudaStandard) {
+ existingCudaStandard = defaultCudaStandard;
+ }
+
+ const char* const* existingCudaLevel =
+ std::find_if(cm::cbegin(CUDA_STANDARDS), cm::cend(CUDA_STANDARDS),
+ cmStrCmp(*existingCudaStandard));
+ if (existingCudaLevel == cm::cend(CUDA_STANDARDS)) {
+ const std::string e = cmStrCat(
+ "The ", lang, "_STANDARD property on target \"", target->GetName(),
+ "\" contained an invalid value: \"", *existingCudaStandard, "\".");
+ this->IssueMessage(MessageType::FATAL_ERROR, e);
+ return false;
+ }
+
+ /* clang-format off */
+ const char* const* needCudaLevel =
+ needCuda20 ? &CUDA_STANDARDS[4]
+ : needCuda17 ? &CUDA_STANDARDS[3]
+ : needCuda14 ? &CUDA_STANDARDS[2]
+ : needCuda11 ? &CUDA_STANDARDS[1]
+ : needCuda03 ? &CUDA_STANDARDS[0]
+ : nullptr;
+ /* clang-format on */
+
+ return !needCudaLevel || needCudaLevel <= existingCudaLevel;
+}
+
+void cmMakefile::CheckNeededCudaLanguage(const std::string& feature,
+ std::string const& lang,
+ bool& needCuda03, bool& needCuda11,
+ bool& needCuda14, bool& needCuda17,
+ bool& needCuda20) const
+{
+ if (const char* propCuda03 =
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "03_COMPILE_FEATURES"))) {
+ std::vector<std::string> props = cmExpandedList(propCuda03);
+ needCuda03 = cm::contains(props, feature);
+ }
+ if (const char* propCuda11 =
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "11_COMPILE_FEATURES"))) {
+ std::vector<std::string> props = cmExpandedList(propCuda11);
+ needCuda11 = cm::contains(props, feature);
+ }
+ if (const char* propCuda14 =
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "14_COMPILE_FEATURES"))) {
+ std::vector<std::string> props = cmExpandedList(propCuda14);
+ needCuda14 = cm::contains(props, feature);
+ }
+ if (const char* propCuda17 =
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "17_COMPILE_FEATURES"))) {
+ std::vector<std::string> props = cmExpandedList(propCuda17);
+ needCuda17 = cm::contains(props, feature);
+ }
+ if (const char* propCuda20 =
+ this->GetDefinition(cmStrCat("CMAKE_", lang, "20_COMPILE_FEATURES"))) {
+ std::vector<std::string> props = cmExpandedList(propCuda20);
+ needCuda20 = cm::contains(props, feature);
+ }
+}
+
+bool cmMakefile::AddRequiredTargetCudaFeature(cmTarget* target,
+ const std::string& feature,
+ std::string const& lang,
+ std::string* error) const
+{
+ bool needCuda03 = false;
+ bool needCuda11 = false;
+ bool needCuda14 = false;
+ bool needCuda17 = false;
+ bool needCuda20 = false;
+
+ this->CheckNeededCudaLanguage(feature, lang, needCuda03, needCuda11,
+ needCuda14, needCuda17, needCuda20);
+
+ cmProp existingCudaStandard =
+ target->GetProperty(cmStrCat(lang, "_STANDARD"));
+ if (existingCudaStandard == nullptr) {
+ cmProp defaultCudaStandard =
+ this->GetDef(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
+ if (defaultCudaStandard && !defaultCudaStandard->empty()) {
+ existingCudaStandard = defaultCudaStandard;
+ }
+ }
+ const char* const* existingCudaLevel = nullptr;
+ if (existingCudaStandard) {
+ existingCudaLevel =
+ std::find_if(cm::cbegin(CUDA_STANDARDS), cm::cend(CUDA_STANDARDS),
+ cmStrCmp(*existingCudaStandard));
+ if (existingCudaLevel == cm::cend(CUDA_STANDARDS)) {
+ const std::string e = cmStrCat(
+ "The ", lang, "_STANDARD property on target \"", target->GetName(),
+ "\" contained an invalid value: \"", *existingCudaStandard, "\".");
+ if (error) {
+ *error = e;
+ } else {
+ this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e,
+ this->Backtrace);
+ }
+ return false;
+ }
+ }
+
+ /* clang-format off */
+ const char* const* needCudaLevel =
+ needCuda20 ? &CUDA_STANDARDS[4]
+ : needCuda17 ? &CUDA_STANDARDS[3]
+ : needCuda14 ? &CUDA_STANDARDS[2]
+ : needCuda11 ? &CUDA_STANDARDS[1]
+ : needCuda03 ? &CUDA_STANDARDS[0]
+ : nullptr;
+ /* clang-format on */
+
+ if (needCudaLevel) {
// Ensure the CUDA language level is high enough to support
- // the needed C++ features.
- if (!existingCudaLevel || existingCudaLevel < needCxxLevel) {
- target->SetProperty("CUDA_STANDARD", *needCxxLevel);
+ // the needed CUDA features.
+ if (!existingCudaLevel || existingCudaLevel < needCudaLevel) {
+ target->SetProperty("CUDA_STANDARD", *needCudaLevel);
}
}
@@ -5008,17 +5213,17 @@ void cmMakefile::CheckNeededCLanguage(const std::string& feature,
if (const char* propC90 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "90_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propC90);
- needC90 = cmContains(props, feature);
+ needC90 = cm::contains(props, feature);
}
if (const char* propC99 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "99_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propC99);
- needC99 = cmContains(props, feature);
+ needC99 = cm::contains(props, feature);
}
if (const char* propC11 =
this->GetDefinition(cmStrCat("CMAKE_", lang, "11_COMPILE_FEATURES"))) {
std::vector<std::string> props = cmExpandedList(propC11);
- needC11 = cmContains(props, feature);
+ needC11 = cm::contains(props, feature);
}
}
@@ -5033,21 +5238,20 @@ bool cmMakefile::AddRequiredTargetCFeature(cmTarget* target,
this->CheckNeededCLanguage(feature, lang, needC90, needC99, needC11);
- const char* existingCStandard =
- target->GetProperty(cmStrCat(lang, "_STANDARD"));
+ cmProp existingCStandard = target->GetProperty(cmStrCat(lang, "_STANDARD"));
if (existingCStandard == nullptr) {
- const char* defaultCStandard =
- this->GetDefinition(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
- if (defaultCStandard && *defaultCStandard) {
+ cmProp defaultCStandard =
+ this->GetDef(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
+ if (defaultCStandard && !defaultCStandard->empty()) {
existingCStandard = defaultCStandard;
}
}
if (existingCStandard) {
if (std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
- cmStrCmp(existingCStandard)) == cm::cend(C_STANDARDS)) {
+ cmStrCmp(*existingCStandard)) == cm::cend(C_STANDARDS)) {
const std::string e = cmStrCat(
"The ", lang, "_STANDARD property on target \"", target->GetName(),
- "\" contained an invalid value: \"", existingCStandard, "\".");
+ "\" contained an invalid value: \"", *existingCStandard, "\".");
if (error) {
*error = e;
} else {
@@ -5059,7 +5263,7 @@ bool cmMakefile::AddRequiredTargetCFeature(cmTarget* target,
}
const char* const* existingCIt = existingCStandard
? std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
- cmStrCmp(existingCStandard))
+ cmStrCmp(*existingCStandard))
: cm::cend(C_STANDARDS);
bool setC90 = needC90 && !existingCStandard;
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 6e59494..04a1f2d 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -49,6 +49,7 @@ class cmGeneratorExpressionEvaluationFile;
class cmGlobalGenerator;
class cmImplicitDependsList;
class cmInstallGenerator;
+class cmLocalGenerator;
class cmMessenger;
class cmSourceFile;
class cmState;
@@ -57,6 +58,8 @@ class cmTestGenerator;
class cmVariableWatch;
class cmake;
+using cmProp = const std::string*;
+
/** Flag if byproducts shall also be considered. */
enum class cmSourceOutputKind
{
@@ -116,6 +119,9 @@ public:
bool ReadListFile(const std::string& filename);
+ bool ReadListFileAsString(const std::string& content,
+ const std::string& virtualFileName);
+
bool ReadDependentFile(const std::string& filename,
bool noPolicyScope = true);
@@ -134,7 +140,7 @@ public:
std::unique_ptr<cmFunctionBlocker> RemoveFunctionBlocker();
/**
- * Try running cmake and building a file. This is used for dynalically
+ * Try running cmake and building a file. This is used for dynamically
* loaded commands, not as part of the usual build process.
*/
int TryCompile(const std::string& srcdir, const std::string& bindir,
@@ -151,31 +157,31 @@ public:
bool EnforceUniqueName(std::string const& name, std::string& msg,
bool isCustom = false) const;
- using FinalAction = std::function<void(cmMakefile&)>;
+ using GeneratorAction =
+ std::function<void(cmLocalGenerator&, const cmListFileBacktrace&)>;
/**
- * Register an action that is executed during FinalPass
+ * Register an action that is executed during Generate
*/
- void AddFinalAction(FinalAction action);
+ void AddGeneratorAction(GeneratorAction action);
/**
- * Perform FinalPass, Library dependency analysis etc before output of the
- * makefile.
+ * Perform generate actions, Library dependency analysis etc before output of
+ * the makefile.
*/
- void ConfigureFinalPass();
+ void Generate(cmLocalGenerator& lg);
/**
- * run all FinalActions.
+ * Get the target for PRE_BUILD, PRE_LINK, or POST_BUILD commands.
*/
- void FinalPass();
+ cmTarget* GetCustomCommandTarget(const std::string& target,
+ cmObjectLibraryCommands objLibCommands,
+ const cmListFileBacktrace& lfbt) const;
/**
- * Get the target for PRE_BUILD, PRE_LINK, or POST_BUILD commands.
+ * Dispatch adding a custom PRE_BUILD, PRE_LINK, or POST_BUILD command to a
+ * target.
*/
- cmTarget* GetCustomCommandTarget(
- const std::string& target, cmObjectLibraryCommands objLibCommands) const;
-
- /** Add a custom command to the build. */
cmTarget* AddCustomCommandToTarget(
const std::string& target, const std::vector<std::string>& byproducts,
const std::vector<std::string>& depends,
@@ -183,24 +189,37 @@ public:
const char* comment, const char* workingDir, bool escapeOldStyle = true,
bool uses_terminal = false, const std::string& depfile = "",
const std::string& job_pool = "", bool command_expand_lists = false,
- cmObjectLibraryCommands objLibCommands = cmObjectLibraryCommands::Reject);
- cmSourceFile* AddCustomCommandToOutput(
+ bool stdPipesUTF8 = false);
+
+ /**
+ * Called for each file with custom command.
+ */
+ using CommandSourceCallback = std::function<void(cmSourceFile*)>;
+
+ /**
+ * Dispatch adding a custom command to a source file.
+ */
+ void AddCustomCommandToOutput(
const std::string& output, const std::vector<std::string>& depends,
const std::string& main_dependency,
const cmCustomCommandLines& commandLines, const char* comment,
- const char* workingDir, bool replace = false, bool escapeOldStyle = true,
+ const char* workingDir, const CommandSourceCallback& callback = nullptr,
+ bool replace = false, bool escapeOldStyle = true,
bool uses_terminal = false, bool command_expand_lists = false,
- const std::string& depfile = "", const std::string& job_pool = "");
- cmSourceFile* AddCustomCommandToOutput(
+ const std::string& depfile = "", const std::string& job_pool = "",
+ bool stdPipesUTF8 = false);
+ void AddCustomCommandToOutput(
const std::vector<std::string>& outputs,
const std::vector<std::string>& byproducts,
const std::vector<std::string>& depends,
const std::string& main_dependency,
const cmImplicitDependsList& implicit_depends,
const cmCustomCommandLines& commandLines, const char* comment,
- const char* workingDir, bool replace = false, bool escapeOldStyle = true,
+ const char* workingDir, const CommandSourceCallback& callback = nullptr,
+ bool replace = false, bool escapeOldStyle = true,
bool uses_terminal = false, bool command_expand_lists = false,
- const std::string& depfile = "", const std::string& job_pool = "");
+ const std::string& depfile = "", const std::string& job_pool = "",
+ bool stdPipesUTF8 = false);
void AddCustomCommandOldStyle(const std::string& target,
const std::vector<std::string>& outputs,
const std::vector<std::string>& depends,
@@ -244,7 +263,7 @@ public:
/** Create a target instance for the utility. */
cmTarget* AddNewUtilityTarget(const std::string& utilityName,
- cmCommandOrigin origin, bool excludeFromAll);
+ bool excludeFromAll);
/**
* Add an executable to the build.
@@ -259,17 +278,17 @@ public:
cmUtilityOutput GetUtilityOutput(cmTarget* target);
/**
- * Add a utility to the build. A utility target is a command that
- * is run every time the target is built.
+ * Dispatch adding a utility to the build. A utility target is a command
+ * that is run every time the target is built.
*/
cmTarget* AddUtilityCommand(
- const std::string& utilityName, cmCommandOrigin origin,
- bool excludeFromAll, const char* workingDirectory,
- const std::vector<std::string>& byproducts,
+ const std::string& utilityName, bool excludeFromAll,
+ const char* workingDir, const std::vector<std::string>& byproducts,
const std::vector<std::string>& depends,
const cmCustomCommandLines& commandLines, bool escapeOldStyle = true,
const char* comment = nullptr, bool uses_terminal = false,
- bool command_expand_lists = false, const std::string& job_pool = "");
+ bool command_expand_lists = false, const std::string& job_pool = "",
+ bool stdPipesUTF8 = false);
/**
* Add a subdirectory to the build.
@@ -304,6 +323,12 @@ public:
void AddCacheDefinition(const std::string& name, const char* value,
const char* doc, cmStateEnums::CacheEntryType type,
bool force = false);
+ void AddCacheDefinition(const std::string& name, const std::string& value,
+ const char* doc, cmStateEnums::CacheEntryType type,
+ bool force = false)
+ {
+ AddCacheDefinition(name, value.c_str(), doc, type, force);
+ }
/**
* Remove a variable definition from the build. This is not valid
@@ -398,7 +423,8 @@ public:
}
const char* GetIncludeRegularExpression() const
{
- return this->GetProperty("INCLUDE_REGULAR_EXPRESSION");
+ cmProp p = this->GetProperty("INCLUDE_REGULAR_EXPRESSION");
+ return p ? p->c_str() : nullptr;
}
/**
@@ -409,9 +435,9 @@ public:
{
this->ComplainFileRegularExpression = regex;
}
- const char* GetComplainRegularExpression() const
+ const std::string& GetComplainRegularExpression() const
{
- return this->ComplainFileRegularExpression.c_str();
+ return this->ComplainFileRegularExpression;
}
// -- List of targets
@@ -421,7 +447,7 @@ public:
/** Get the target map - const version */
cmTargetMap const& GetTargets() const { return this->Targets; }
- const std::vector<cmTarget*>& GetOwnedImportedTargets() const
+ const std::vector<std::unique_ptr<cmTarget>>& GetOwnedImportedTargets() const
{
return this->ImportedTargetsOwned;
}
@@ -717,7 +743,7 @@ public:
/**
* Get all the source files this makefile knows about
*/
- const std::vector<cmSourceFile*>& GetSourceFiles() const
+ const std::vector<std::unique_ptr<cmSourceFile>>& GetSourceFiles() const
{
return this->SourceFiles;
}
@@ -756,45 +782,50 @@ public:
std::string GetModulesFile(const std::string& name) const
{
bool system;
- return this->GetModulesFile(name, system);
+ std::string debugBuffer;
+ return this->GetModulesFile(name, system, false, debugBuffer);
+ }
+
+ /**
+ * Return a location of a file in cmake or custom modules directory
+ */
+ std::string GetModulesFile(const std::string& name, bool& system) const
+ {
+ std::string debugBuffer;
+ return this->GetModulesFile(name, system, false, debugBuffer);
}
- std::string GetModulesFile(const std::string& name, bool& system) const;
+ std::string GetModulesFile(const std::string& name, bool& system, bool debug,
+ std::string& debugBuffer) const;
//! Set/Get a property of this directory
void SetProperty(const std::string& prop, const char* value);
- void AppendProperty(const std::string& prop, const char* value,
+ void AppendProperty(const std::string& prop, const std::string& value,
bool asString = false);
- const char* GetProperty(const std::string& prop) const;
- const char* GetProperty(const std::string& prop, bool chain) const;
+ cmProp GetProperty(const std::string& prop) const;
+ cmProp GetProperty(const std::string& prop, bool chain) const;
bool GetPropertyAsBool(const std::string& prop) const;
std::vector<std::string> GetPropertyKeys() const;
//! Initialize a makefile from its parent
void InitializeFromParent(cmMakefile* parent);
- void AddInstallGenerator(cmInstallGenerator* g)
- {
- if (g) {
- this->InstallGenerators.push_back(g);
- }
- }
- std::vector<cmInstallGenerator*>& GetInstallGenerators()
+ void AddInstallGenerator(std::unique_ptr<cmInstallGenerator> g);
+
+ std::vector<std::unique_ptr<cmInstallGenerator>>& GetInstallGenerators()
{
return this->InstallGenerators;
}
- const std::vector<cmInstallGenerator*>& GetInstallGenerators() const
+ const std::vector<std::unique_ptr<cmInstallGenerator>>&
+ GetInstallGenerators() const
{
return this->InstallGenerators;
}
- void AddTestGenerator(cmTestGenerator* g)
- {
- if (g) {
- this->TestGenerators.push_back(g);
- }
- }
- const std::vector<cmTestGenerator*>& GetTestGenerators() const
+ void AddTestGenerator(std::unique_ptr<cmTestGenerator> g);
+
+ const std::vector<std::unique_ptr<cmTestGenerator>>& GetTestGenerators()
+ const
{
return this->TestGenerators;
}
@@ -927,12 +958,14 @@ public:
std::unique_ptr<cmCompiledGeneratorExpression> outputName,
std::unique_ptr<cmCompiledGeneratorExpression> condition,
bool inputIsContent);
- std::vector<cmGeneratorExpressionEvaluationFile*> GetEvaluationFiles() const;
+ const std::vector<std::unique_ptr<cmGeneratorExpressionEvaluationFile>>&
+ GetEvaluationFiles() const;
- std::vector<cmExportBuildFileGenerator*> GetExportBuildFileGenerators()
- const;
+ std::vector<std::unique_ptr<cmExportBuildFileGenerator>> const&
+ GetExportBuildFileGenerators() const;
void RemoveExportBuildFileGeneratorCMP0024(cmExportBuildFileGenerator* gen);
- void AddExportBuildFileGenerator(cmExportBuildFileGenerator* gen);
+ void AddExportBuildFileGenerator(
+ std::unique_ptr<cmExportBuildFileGenerator> gen);
// Maintain a stack of package roots to allow nested PACKAGE_ROOT_PATH
// searches
@@ -962,8 +995,7 @@ protected:
using TargetsVec = std::vector<cmTarget*>;
TargetsVec OrderedTargets;
- using SourceFileVec = std::vector<cmSourceFile*>;
- SourceFileVec SourceFiles;
+ std::vector<std::unique_ptr<cmSourceFile>> SourceFiles;
// Because cmSourceFile names are compared in a fuzzy way (see
// cmSourceFileLocation::Match()) we can't have a straight mapping from
@@ -971,14 +1003,15 @@ protected:
// Name portion of the cmSourceFileLocation and then compare on the list of
// cmSourceFiles that might match that name. Note that on platforms which
// have a case-insensitive filesystem we store the key in all lowercase.
- using SourceFileMap = std::unordered_map<std::string, SourceFileVec>;
+ using SourceFileMap =
+ std::unordered_map<std::string, std::vector<cmSourceFile*>>;
SourceFileMap SourceFileSearchIndex;
// For "Known" paths we can store a direct filename to cmSourceFile map
std::unordered_map<std::string, cmSourceFile*> KnownFileSearchIndex;
// Tests
- std::map<std::string, cmTest*> Tests;
+ std::map<std::string, std::unique_ptr<cmTest>> Tests;
// The set of include directories that are marked as system include
// directories.
@@ -987,8 +1020,8 @@ protected:
std::vector<std::string> ListFiles;
std::vector<std::string> OutputFiles;
- std::vector<cmInstallGenerator*> InstallGenerators;
- std::vector<cmTestGenerator*> TestGenerators;
+ std::vector<std::unique_ptr<cmInstallGenerator>> InstallGenerators;
+ std::vector<std::unique_ptr<cmTestGenerator>> TestGenerators;
std::string ComplainFileRegularExpression;
std::string DefineFlags;
@@ -1001,7 +1034,6 @@ protected:
size_t ObjectLibrariesSourceGroupIndex;
#endif
- std::vector<FinalAction> FinalActions;
cmGlobalGenerator* GlobalGenerator;
bool IsFunctionBlocked(const cmListFileFunction& lff,
cmExecutionStatus& status);
@@ -1011,6 +1043,8 @@ private:
cmListFileBacktrace Backtrace;
int RecursionDepth;
+ void DoGenerate(cmLocalGenerator& lg);
+
void ReadListFile(cmListFile const& listFile,
const std::string& filenametoread);
@@ -1036,15 +1070,17 @@ private:
mutable cmsys::RegularExpression cmNamedCurly;
std::vector<cmMakefile*> UnConfiguredDirectories;
- std::vector<cmExportBuildFileGenerator*> ExportBuildFileGenerators;
+ std::vector<std::unique_ptr<cmExportBuildFileGenerator>>
+ ExportBuildFileGenerators;
- std::vector<cmGeneratorExpressionEvaluationFile*> EvaluationFiles;
+ std::vector<std::unique_ptr<cmGeneratorExpressionEvaluationFile>>
+ EvaluationFiles;
std::vector<cmExecutionStatus*> ExecutionStatusStack;
friend class cmMakefileCall;
friend class cmParseFileScope;
- std::vector<cmTarget*> ImportedTargetsOwned;
+ std::vector<std::unique_ptr<cmTarget>> ImportedTargetsOwned;
using TargetMap = std::unordered_map<std::string, cmTarget*>;
TargetMap ImportedTargets;
@@ -1080,38 +1116,15 @@ private:
bool ValidateCustomCommand(const cmCustomCommandLines& commandLines) const;
- void CreateGeneratedSources(const std::vector<std::string>& outputs);
+ void CreateGeneratedOutputs(const std::vector<std::string>& outputs);
+ void CreateGeneratedByproducts(const std::vector<std::string>& byproducts);
- void CommitCustomCommandToTarget(
- cmTarget* target, const std::vector<std::string>& byproducts,
- const std::vector<std::string>& depends,
- const cmCustomCommandLines& commandLines, cmCustomCommandType type,
- const char* comment, const char* workingDir, bool escapeOldStyle,
- bool uses_terminal, const std::string& depfile,
- const std::string& job_pool, bool command_expand_lists);
- cmSourceFile* CommitCustomCommandToOutput(
- const std::vector<std::string>& outputs,
- const std::vector<std::string>& byproducts,
- const std::vector<std::string>& depends,
- const std::string& main_dependency,
- const cmImplicitDependsList& implicit_depends,
- const cmCustomCommandLines& commandLines, const char* comment,
- const char* workingDir, bool replace, bool escapeOldStyle,
- bool uses_terminal, bool command_expand_lists, const std::string& depfile,
- const std::string& job_pool);
- void CommitAppendCustomCommandToOutput(
- const std::string& output, const std::vector<std::string>& depends,
- const cmImplicitDependsList& implicit_depends,
- const cmCustomCommandLines& commandLines);
+ std::vector<BT<GeneratorAction>> GeneratorActions;
+ bool GeneratorActionsInvoked = false;
+ bool DelayedOutputFilesHaveGenex = false;
+ std::vector<std::string> DelayedOutputFiles;
- void CommitUtilityCommand(cmTarget* target, const cmUtilityOutput& force,
- const char* workingDirectory,
- const std::vector<std::string>& byproducts,
- const std::vector<std::string>& depends,
- const cmCustomCommandLines& commandLines,
- bool escapeOldStyle, const char* comment,
- bool uses_terminal, bool command_expand_lists,
- const std::string& job_pool);
+ void AddDelayedOutput(std::string const& output);
/**
* See LinearGetSourceFileWithOutput for background information
@@ -1131,6 +1144,7 @@ private:
struct SourceEntry
{
cmSourcesWithOutput Sources;
+ bool SourceMightBeOutput = false;
};
// A map for fast output to input look up.
@@ -1149,11 +1163,14 @@ private:
bool AddRequiredTargetCFeature(cmTarget* target, const std::string& feature,
std::string const& lang,
std::string* error = nullptr) const;
-
bool AddRequiredTargetCxxFeature(cmTarget* target,
const std::string& feature,
std::string const& lang,
std::string* error = nullptr) const;
+ bool AddRequiredTargetCudaFeature(cmTarget* target,
+ const std::string& feature,
+ std::string const& lang,
+ std::string* error = nullptr) const;
void CheckNeededCLanguage(const std::string& feature,
std::string const& lang, bool& needC90,
@@ -1162,6 +1179,10 @@ private:
std::string const& lang, bool& needCxx98,
bool& needCxx11, bool& needCxx14,
bool& needCxx17, bool& needCxx20) const;
+ void CheckNeededCudaLanguage(const std::string& feature,
+ std::string const& lang, bool& needCuda03,
+ bool& needCuda11, bool& needCuda14,
+ bool& needCuda17, bool& needCuda20) const;
bool HaveCStandardAvailable(cmTarget const* target,
const std::string& feature,
@@ -1169,6 +1190,9 @@ private:
bool HaveCxxStandardAvailable(cmTarget const* target,
const std::string& feature,
std::string const& lang) const;
+ bool HaveCudaStandardAvailable(cmTarget const* target,
+ const std::string& feature,
+ std::string const& lang) const;
void CheckForUnusedVariables() const;
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 40265ff..e15b016 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -9,8 +9,8 @@
#include <vector>
#include <cm/memory>
+#include <cmext/algorithm>
-#include "cmAlgorithms.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalUnixMakefileGenerator3.h"
@@ -35,10 +35,9 @@ cmMakefileExecutableTargetGenerator::cmMakefileExecutableTargetGenerator(
{
this->CustomCommandDriver = OnDepends;
this->TargetNames =
- this->GeneratorTarget->GetExecutableNames(this->ConfigName);
+ this->GeneratorTarget->GetExecutableNames(this->GetConfigName());
- this->OSXBundleGenerator =
- cm::make_unique<cmOSXBundleGenerator>(target, this->ConfigName);
+ this->OSXBundleGenerator = cm::make_unique<cmOSXBundleGenerator>(target);
this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
}
@@ -64,7 +63,7 @@ void cmMakefileExecutableTargetGenerator::WriteRuleFiles()
// write the link rules
this->WriteExecutableRule(false);
- if (this->GeneratorTarget->NeedRelinkBeforeInstall(this->ConfigName)) {
+ if (this->GeneratorTarget->NeedRelinkBeforeInstall(this->GetConfigName())) {
// Write rules to link an installable version of the target.
this->WriteExecutableRule(true);
}
@@ -85,7 +84,7 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
{
#ifndef CMAKE_BOOTSTRAP
const bool requiresDeviceLinking = requireDeviceLinking(
- *this->GeneratorTarget, *this->LocalGenerator, this->ConfigName);
+ *this->GeneratorTarget, *this->LocalGenerator, this->GetConfigName());
if (!requiresDeviceLinking) {
return;
}
@@ -123,31 +122,15 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
}
// Build a list of compiler flags and linker flags.
- std::string flags;
+ std::string langFlags;
std::string linkFlags;
- // Add flags to create an executable.
- // Add symbol export flags if necessary.
- if (this->GeneratorTarget->IsExecutableWithExports()) {
- std::string export_flag_var =
- cmStrCat("CMAKE_EXE_EXPORTS_", linkLanguage, "_FLAG");
- this->LocalGenerator->AppendFlags(
- linkFlags, this->Makefile->GetSafeDefinition(export_flag_var));
- }
-
- this->LocalGenerator->AppendFlags(linkFlags,
- this->LocalGenerator->GetLinkLibsCMP0065(
- linkLanguage, *this->GeneratorTarget));
-
// Add language feature flags.
this->LocalGenerator->AddLanguageFlagsForLinking(
- flags, this->GeneratorTarget, linkLanguage, this->ConfigName);
-
- this->LocalGenerator->AddArchitectureFlags(flags, this->GeneratorTarget,
- linkLanguage, this->ConfigName);
+ langFlags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
- // Add target-specific linker flags.
- this->GetTargetLinkFlags(linkFlags, linkLanguage);
+ // Add device-specific linker flags.
+ this->GetDeviceLinkFlags(linkFlags, linkLanguage);
// Construct a list of files associated with this executable that
// may need to be cleaned.
@@ -197,6 +180,8 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
this->CreateObjectLists(useLinkScript, false, useResponseFileForObjects,
buildObjs, depends, useWatcomQuote);
+ std::string const& aixExports = this->GetAIXExports(this->GetConfigName());
+
cmRulePlaceholderExpander::RuleVariables vars;
std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
@@ -213,17 +198,19 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutputReal),
output);
- std::string targetFullPathCompilePDB = this->ComputeTargetCompilePDB();
+ std::string targetFullPathCompilePDB =
+ this->ComputeTargetCompilePDB(this->GetConfigName());
std::string targetOutPathCompilePDB =
this->LocalGenerator->ConvertToOutputFormat(targetFullPathCompilePDB,
cmOutputConverter::SHELL);
vars.Language = linkLanguage.c_str();
+ vars.AIXExports = aixExports.c_str();
vars.Objects = buildObjs.c_str();
vars.ObjectDir = objectDir.c_str();
vars.Target = target.c_str();
vars.LinkLibraries = linkLibs.c_str();
- vars.Flags = flags.c_str();
+ vars.LanguageCompileFlags = langFlags.c_str();
vars.LinkFlags = linkFlags.c_str();
vars.TargetCompilePDB = targetOutPathCompilePDB.c_str();
@@ -263,7 +250,7 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule(
this->LocalGenerator->CreateCDCommand(
commands1, this->Makefile->GetCurrentBinaryDirectory(),
this->LocalGenerator->GetBinaryDirectory());
- cmAppend(commands, commands1);
+ cm::append(commands, commands1);
commands1.clear();
// Write the build rule.
@@ -287,12 +274,14 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// Get the name of the executable to generate.
cmGeneratorTarget::Names targetNames =
- this->GeneratorTarget->GetExecutableNames(this->ConfigName);
+ this->GeneratorTarget->GetExecutableNames(this->GetConfigName());
// Construct the full path version of the names.
- std::string outpath = this->GeneratorTarget->GetDirectory(this->ConfigName);
+ std::string outpath =
+ this->GeneratorTarget->GetDirectory(this->GetConfigName());
if (this->GeneratorTarget->IsAppBundleOnApple()) {
- this->OSXBundleGenerator->CreateAppBundle(targetNames.Output, outpath);
+ this->OSXBundleGenerator->CreateAppBundle(targetNames.Output, outpath,
+ this->GetConfigName());
}
outpath += '/';
std::string outpathImp;
@@ -308,18 +297,18 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
cmSystemTools::MakeDirectory(outpath);
if (!targetNames.ImportLibrary.empty()) {
outpathImp = this->GeneratorTarget->GetDirectory(
- this->ConfigName, cmStateEnums::ImportLibraryArtifact);
+ this->GetConfigName(), cmStateEnums::ImportLibraryArtifact);
cmSystemTools::MakeDirectory(outpathImp);
outpathImp += '/';
}
}
std::string compilePdbOutputPath =
- this->GeneratorTarget->GetCompilePDBDirectory(this->ConfigName);
+ this->GeneratorTarget->GetCompilePDBDirectory(this->GetConfigName());
cmSystemTools::MakeDirectory(compilePdbOutputPath);
std::string pdbOutputPath =
- this->GeneratorTarget->GetPDBDirectory(this->ConfigName);
+ this->GeneratorTarget->GetPDBDirectory(this->GetConfigName());
cmSystemTools::MakeDirectory(pdbOutputPath);
pdbOutputPath += '/';
@@ -347,7 +336,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// Get the language to use for linking this executable.
std::string linkLanguage =
- this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
+ this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());
// Make sure we have a link language.
if (linkLanguage.empty()) {
@@ -380,7 +369,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// Add flags to create an executable.
this->LocalGenerator->AddConfigVariableFlags(
- linkFlags, "CMAKE_EXE_LINKER_FLAGS", this->ConfigName);
+ linkFlags, "CMAKE_EXE_LINKER_FLAGS", this->GetConfigName());
if (this->GeneratorTarget->GetPropertyAsBool("WIN32_EXECUTABLE")) {
this->LocalGenerator->AppendFlags(
@@ -409,25 +398,26 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// Add language feature flags.
this->LocalGenerator->AddLanguageFlagsForLinking(
- flags, this->GeneratorTarget, linkLanguage, this->ConfigName);
+ flags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
- this->LocalGenerator->AddArchitectureFlags(flags, this->GeneratorTarget,
- linkLanguage, this->ConfigName);
+ this->LocalGenerator->AddArchitectureFlags(
+ flags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
// Add target-specific linker flags.
this->GetTargetLinkFlags(linkFlags, linkLanguage);
{
- std::unique_ptr<cmLinkLineComputer> linkLineComputer(
+ std::unique_ptr<cmLinkLineComputer> linkLineComputer =
this->CreateLinkLineComputer(
this->LocalGenerator,
- this->LocalGenerator->GetStateSnapshot().GetDirectory()));
+ this->LocalGenerator->GetStateSnapshot().GetDirectory());
- this->AddModuleDefinitionFlag(linkLineComputer.get(), linkFlags);
+ this->AddModuleDefinitionFlag(linkLineComputer.get(), linkFlags,
+ this->GetConfigName());
}
- this->LocalGenerator->AppendIPOLinkerFlags(linkFlags, this->GeneratorTarget,
- this->ConfigName, linkLanguage);
+ this->LocalGenerator->AppendIPOLinkerFlags(
+ linkFlags, this->GeneratorTarget, this->GetConfigName(), linkLanguage);
// Construct a list of files associated with this executable that
// may need to be cleaned.
@@ -451,7 +441,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
targetFullPathImport));
std::string implib;
if (this->GeneratorTarget->GetImplibGNUtoMS(
- this->ConfigName, targetFullPathImport, implib)) {
+ this->GetConfigName(), targetFullPathImport, implib)) {
exeCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), implib));
}
@@ -479,7 +469,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// Construct the main link rule.
std::vector<std::string> real_link_commands;
std::string linkRuleVar = this->GeneratorTarget->GetCreateRuleVariable(
- linkLanguage, this->ConfigName);
+ linkLanguage, this->GetConfigName());
std::string linkRule = this->GetLinkRule(linkRuleVar);
std::vector<std::string> commands1;
cmExpandList(linkRule, real_link_commands);
@@ -506,10 +496,10 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// Set path conversion for link script shells.
this->LocalGenerator->SetLinkScriptShell(useLinkScript);
- std::unique_ptr<cmLinkLineComputer> linkLineComputer(
+ std::unique_ptr<cmLinkLineComputer> linkLineComputer =
this->CreateLinkLineComputer(
this->LocalGenerator,
- this->LocalGenerator->GetStateSnapshot().GetDirectory()));
+ this->LocalGenerator->GetStateSnapshot().GetDirectory());
linkLineComputer->SetForResponse(useResponseFileForLibs);
linkLineComputer->SetUseWatcomQuote(useWatcomQuote);
linkLineComputer->SetRelink(relink);
@@ -536,12 +526,12 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
// maybe create .def file from list of objects
this->GenDefFile(real_link_commands);
- std::string manifests = this->GetManifests();
+ std::string manifests = this->GetManifests(this->GetConfigName());
cmRulePlaceholderExpander::RuleVariables vars;
vars.CMTargetName = this->GeneratorTarget->GetName().c_str();
vars.CMTargetType =
- cmState::GetTargetTypeName(this->GeneratorTarget->GetType());
+ cmState::GetTargetTypeName(this->GeneratorTarget->GetType()).c_str();
vars.Language = linkLanguage.c_str();
vars.Objects = buildObjs.c_str();
std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
@@ -627,7 +617,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
this->LocalGenerator->CreateCDCommand(
commands1, this->Makefile->GetCurrentBinaryDirectory(),
this->LocalGenerator->GetBinaryDirectory());
- cmAppend(commands, commands1);
+ cm::append(commands, commands1);
commands1.clear();
// Add a rule to create necessary symlinks for the library.
@@ -639,7 +629,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
this->LocalGenerator->CreateCDCommand(
commands1, this->Makefile->GetCurrentBinaryDirectory(),
this->LocalGenerator->GetBinaryDirectory());
- cmAppend(commands, commands1);
+ cm::append(commands, commands1);
commands1.clear();
}
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index 54a6606..2d360e6 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -9,8 +9,8 @@
#include <vector>
#include <cm/memory>
+#include <cmext/algorithm>
-#include "cmAlgorithms.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalUnixMakefileGenerator3.h"
@@ -36,11 +36,10 @@ cmMakefileLibraryTargetGenerator::cmMakefileLibraryTargetGenerator(
this->CustomCommandDriver = OnDepends;
if (this->GeneratorTarget->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
this->TargetNames =
- this->GeneratorTarget->GetLibraryNames(this->ConfigName);
+ this->GeneratorTarget->GetLibraryNames(this->GetConfigName());
}
- this->OSXBundleGenerator =
- cm::make_unique<cmOSXBundleGenerator>(target, this->ConfigName);
+ this->OSXBundleGenerator = cm::make_unique<cmOSXBundleGenerator>(target);
this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
}
@@ -69,14 +68,16 @@ void cmMakefileLibraryTargetGenerator::WriteRuleFiles()
break;
case cmStateEnums::SHARED_LIBRARY:
this->WriteSharedLibraryRules(false);
- if (this->GeneratorTarget->NeedRelinkBeforeInstall(this->ConfigName)) {
+ if (this->GeneratorTarget->NeedRelinkBeforeInstall(
+ this->GetConfigName())) {
// Write rules to link an installable version of the target.
this->WriteSharedLibraryRules(true);
}
break;
case cmStateEnums::MODULE_LIBRARY:
this->WriteModuleLibraryRules(false);
- if (this->GeneratorTarget->NeedRelinkBeforeInstall(this->ConfigName)) {
+ if (this->GeneratorTarget->NeedRelinkBeforeInstall(
+ this->GetConfigName())) {
// Write rules to link an installable version of the target.
this->WriteModuleLibraryRules(true);
}
@@ -126,22 +127,21 @@ void cmMakefileLibraryTargetGenerator::WriteObjectLibraryRules()
void cmMakefileLibraryTargetGenerator::WriteStaticLibraryRules()
{
const bool requiresDeviceLinking = requireDeviceLinking(
- *this->GeneratorTarget, *this->LocalGenerator, this->ConfigName);
+ *this->GeneratorTarget, *this->LocalGenerator, this->GetConfigName());
if (requiresDeviceLinking) {
std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY";
this->WriteDeviceLibraryRules(linkRuleVar, false);
}
std::string linkLanguage =
- this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
+ this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());
std::string linkRuleVar = this->GeneratorTarget->GetCreateRuleVariable(
- linkLanguage, this->ConfigName);
+ linkLanguage, this->GetConfigName());
std::string extraFlags;
this->LocalGenerator->GetStaticLibraryFlags(
- extraFlags, cmSystemTools::UpperCase(this->ConfigName), linkLanguage,
- this->GeneratorTarget);
+ extraFlags, this->GetConfigName(), linkLanguage, this->GeneratorTarget);
this->WriteLibraryRules(linkRuleVar, extraFlags, false);
}
@@ -154,7 +154,7 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
if (!relink) {
const bool requiresDeviceLinking = requireDeviceLinking(
- *this->GeneratorTarget, *this->LocalGenerator, this->ConfigName);
+ *this->GeneratorTarget, *this->LocalGenerator, this->GetConfigName());
if (requiresDeviceLinking) {
std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY";
this->WriteDeviceLibraryRules(linkRuleVar, relink);
@@ -162,21 +162,22 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
}
std::string linkLanguage =
- this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
+ this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());
std::string linkRuleVar =
cmStrCat("CMAKE_", linkLanguage, "_CREATE_SHARED_LIBRARY");
std::string extraFlags;
this->GetTargetLinkFlags(extraFlags, linkLanguage);
this->LocalGenerator->AddConfigVariableFlags(
- extraFlags, "CMAKE_SHARED_LINKER_FLAGS", this->ConfigName);
+ extraFlags, "CMAKE_SHARED_LINKER_FLAGS", this->GetConfigName());
- std::unique_ptr<cmLinkLineComputer> linkLineComputer(
+ std::unique_ptr<cmLinkLineComputer> linkLineComputer =
this->CreateLinkLineComputer(
this->LocalGenerator,
- this->LocalGenerator->GetStateSnapshot().GetDirectory()));
+ this->LocalGenerator->GetStateSnapshot().GetDirectory());
- this->AddModuleDefinitionFlag(linkLineComputer.get(), extraFlags);
+ this->AddModuleDefinitionFlag(linkLineComputer.get(), extraFlags,
+ this->GetConfigName());
if (this->GeneratorTarget->GetPropertyAsBool("LINK_WHAT_YOU_USE")) {
this->LocalGenerator->AppendFlags(extraFlags, " -Wl,--no-as-needed");
@@ -188,7 +189,7 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink)
{
if (!relink) {
const bool requiresDeviceLinking = requireDeviceLinking(
- *this->GeneratorTarget, *this->LocalGenerator, this->ConfigName);
+ *this->GeneratorTarget, *this->LocalGenerator, this->GetConfigName());
if (requiresDeviceLinking) {
std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_LIBRARY";
this->WriteDeviceLibraryRules(linkRuleVar, relink);
@@ -196,21 +197,22 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink)
}
std::string linkLanguage =
- this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
+ this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());
std::string linkRuleVar =
cmStrCat("CMAKE_", linkLanguage, "_CREATE_SHARED_MODULE");
std::string extraFlags;
this->GetTargetLinkFlags(extraFlags, linkLanguage);
this->LocalGenerator->AddConfigVariableFlags(
- extraFlags, "CMAKE_MODULE_LINKER_FLAGS", this->ConfigName);
+ extraFlags, "CMAKE_MODULE_LINKER_FLAGS", this->GetConfigName());
- std::unique_ptr<cmLinkLineComputer> linkLineComputer(
+ std::unique_ptr<cmLinkLineComputer> linkLineComputer =
this->CreateLinkLineComputer(
this->LocalGenerator,
- this->LocalGenerator->GetStateSnapshot().GetDirectory()));
+ this->LocalGenerator->GetStateSnapshot().GetDirectory());
- this->AddModuleDefinitionFlag(linkLineComputer.get(), extraFlags);
+ this->AddModuleDefinitionFlag(linkLineComputer.get(), extraFlags,
+ this->GetConfigName());
this->WriteLibraryRules(linkRuleVar, extraFlags, relink);
}
@@ -218,14 +220,14 @@ void cmMakefileLibraryTargetGenerator::WriteModuleLibraryRules(bool relink)
void cmMakefileLibraryTargetGenerator::WriteFrameworkRules(bool relink)
{
std::string linkLanguage =
- this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
+ this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());
std::string linkRuleVar =
cmStrCat("CMAKE_", linkLanguage, "_CREATE_MACOSX_FRAMEWORK");
std::string extraFlags;
this->GetTargetLinkFlags(extraFlags, linkLanguage);
this->LocalGenerator->AddConfigVariableFlags(
- extraFlags, "CMAKE_MACOSX_FRAMEWORK_LINKER_FLAGS", this->ConfigName);
+ extraFlags, "CMAKE_MACOSX_FRAMEWORK_LINKER_FLAGS", this->GetConfigName());
this->WriteLibraryRules(linkRuleVar, extraFlags, relink);
}
@@ -247,9 +249,14 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules(
std::vector<std::string> depends;
this->AppendLinkDepends(depends, linkLanguage);
+ // Add language-specific flags.
+ std::string langFlags;
+ this->LocalGenerator->AddLanguageFlagsForLinking(
+ langFlags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
+
// Create set of linking flags.
std::string linkFlags;
- this->GetTargetLinkFlags(linkFlags, linkLanguage);
+ this->GetDeviceLinkFlags(linkFlags, linkLanguage);
// Get the name of the device object to generate.
std::string const targetOutputReal =
@@ -331,7 +338,8 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules(
this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutputReal),
output);
- std::string targetFullPathCompilePDB = this->ComputeTargetCompilePDB();
+ std::string targetFullPathCompilePDB =
+ this->ComputeTargetCompilePDB(this->GetConfigName());
std::string targetOutPathCompilePDB =
this->LocalGenerator->ConvertToOutputFormat(targetFullPathCompilePDB,
cmOutputConverter::SHELL);
@@ -341,16 +349,10 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules(
vars.Target = target.c_str();
vars.LinkLibraries = linkLibs.c_str();
vars.ObjectsQuoted = buildObjs.c_str();
+ vars.LanguageCompileFlags = langFlags.c_str();
vars.LinkFlags = linkFlags.c_str();
vars.TargetCompilePDB = targetOutPathCompilePDB.c_str();
- // Add language-specific flags.
- std::string langFlags;
- this->LocalGenerator->AddLanguageFlagsForLinking(
- langFlags, this->GeneratorTarget, linkLanguage, this->ConfigName);
-
- vars.LanguageCompileFlags = langFlags.c_str();
-
std::string launcher;
const char* val = this->LocalGenerator->GetRuleLauncher(
this->GeneratorTarget, "RULE_LAUNCH_LINK");
@@ -393,7 +395,7 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules(
this->LocalGenerator->CreateCDCommand(
commands1, this->Makefile->GetCurrentBinaryDirectory(),
this->LocalGenerator->GetBinaryDirectory());
- cmAppend(commands, commands1);
+ cm::append(commands, commands1);
commands1.clear();
// Compute the list of outputs.
@@ -420,7 +422,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
// Get the language to use for linking this library.
std::string linkLanguage =
- this->GeneratorTarget->GetLinkerLanguage(this->ConfigName);
+ this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());
// Make sure we have a link language.
if (linkLanguage.empty()) {
@@ -439,8 +441,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
// Create set of linking flags.
std::string linkFlags;
this->LocalGenerator->AppendFlags(linkFlags, extraFlags);
- this->LocalGenerator->AppendIPOLinkerFlags(linkFlags, this->GeneratorTarget,
- this->ConfigName, linkLanguage);
+ this->LocalGenerator->AppendIPOLinkerFlags(
+ linkFlags, this->GeneratorTarget, this->GetConfigName(), linkLanguage);
// Add OSX version flags, if any.
if (this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY ||
@@ -450,20 +452,20 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
}
// Construct the name of the library.
- this->GeneratorTarget->GetLibraryNames(this->ConfigName);
+ this->GeneratorTarget->GetLibraryNames(this->GetConfigName());
// Construct the full path version of the names.
std::string outpath;
std::string outpathImp;
if (this->GeneratorTarget->IsFrameworkOnApple()) {
- outpath = this->GeneratorTarget->GetDirectory(this->ConfigName);
+ outpath = this->GeneratorTarget->GetDirectory(this->GetConfigName());
this->OSXBundleGenerator->CreateFramework(this->TargetNames.Output,
- outpath);
+ outpath, this->GetConfigName());
outpath += '/';
} else if (this->GeneratorTarget->IsCFBundleOnApple()) {
- outpath = this->GeneratorTarget->GetDirectory(this->ConfigName);
- this->OSXBundleGenerator->CreateCFBundle(this->TargetNames.Output,
- outpath);
+ outpath = this->GeneratorTarget->GetDirectory(this->GetConfigName());
+ this->OSXBundleGenerator->CreateCFBundle(this->TargetNames.Output, outpath,
+ this->GetConfigName());
outpath += '/';
} else if (relink) {
outpath = cmStrCat(this->Makefile->GetCurrentBinaryDirectory(),
@@ -474,23 +476,23 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
outpathImp = outpath;
}
} else {
- outpath = this->GeneratorTarget->GetDirectory(this->ConfigName);
+ outpath = this->GeneratorTarget->GetDirectory(this->GetConfigName());
cmSystemTools::MakeDirectory(outpath);
outpath += '/';
if (!this->TargetNames.ImportLibrary.empty()) {
outpathImp = this->GeneratorTarget->GetDirectory(
- this->ConfigName, cmStateEnums::ImportLibraryArtifact);
+ this->GetConfigName(), cmStateEnums::ImportLibraryArtifact);
cmSystemTools::MakeDirectory(outpathImp);
outpathImp += '/';
}
}
std::string compilePdbOutputPath =
- this->GeneratorTarget->GetCompilePDBDirectory(this->ConfigName);
+ this->GeneratorTarget->GetCompilePDBDirectory(this->GetConfigName());
cmSystemTools::MakeDirectory(compilePdbOutputPath);
std::string pdbOutputPath =
- this->GeneratorTarget->GetPDBDirectory(this->ConfigName);
+ this->GeneratorTarget->GetPDBDirectory(this->GetConfigName());
cmSystemTools::MakeDirectory(pdbOutputPath);
pdbOutputPath += "/";
@@ -567,7 +569,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
this->LocalGenerator->CreateCDCommand(
commands1, this->Makefile->GetCurrentBinaryDirectory(),
this->LocalGenerator->GetBinaryDirectory());
- cmAppend(commands, commands1);
+ cm::append(commands, commands1);
commands1.clear();
}
@@ -586,7 +588,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
targetFullPathImport));
std::string implib;
if (this->GeneratorTarget->GetImplibGNUtoMS(
- this->ConfigName, targetFullPathImport, implib)) {
+ this->GetConfigName(), targetFullPathImport, implib)) {
libCleanFiles.insert(this->LocalGenerator->MaybeConvertToRelativePath(
this->LocalGenerator->GetCurrentBinaryDirectory(), implib));
}
@@ -638,7 +640,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
cmStrCat("CMAKE_", linkLanguage, "_ARCHIVE_CREATE");
arCreateVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
- arCreateVar, linkLanguage, this->ConfigName);
+ arCreateVar, linkLanguage, this->GetConfigName());
if (const char* rule = this->Makefile->GetDefinition(arCreateVar)) {
cmExpandList(rule, archiveCreateCommands);
@@ -647,7 +649,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
cmStrCat("CMAKE_", linkLanguage, "_ARCHIVE_APPEND");
arAppendVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
- arAppendVar, linkLanguage, this->ConfigName);
+ arAppendVar, linkLanguage, this->GetConfigName());
if (const char* rule = this->Makefile->GetDefinition(arAppendVar)) {
cmExpandList(rule, archiveAppendCommands);
@@ -656,7 +658,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
cmStrCat("CMAKE_", linkLanguage, "_ARCHIVE_FINISH");
arFinishVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
- arFinishVar, linkLanguage, this->ConfigName);
+ arFinishVar, linkLanguage, this->GetConfigName());
if (const char* rule = this->Makefile->GetDefinition(arFinishVar)) {
cmExpandList(rule, archiveFinishCommands);
@@ -696,10 +698,10 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
std::string linkLibs;
if (this->GeneratorTarget->GetType() != cmStateEnums::STATIC_LIBRARY) {
- std::unique_ptr<cmLinkLineComputer> linkLineComputer(
+ std::unique_ptr<cmLinkLineComputer> linkLineComputer =
this->CreateLinkLineComputer(
this->LocalGenerator,
- this->LocalGenerator->GetStateSnapshot().GetDirectory()));
+ this->LocalGenerator->GetStateSnapshot().GetDirectory());
linkLineComputer->SetForResponse(useResponseFileForLibs);
linkLineComputer->SetUseWatcomQuote(useWatcomQuote);
linkLineComputer->SetRelink(relink);
@@ -723,10 +725,12 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
cmOutputConverter::SHELL);
}
+ std::string const& aixExports = this->GetAIXExports(this->GetConfigName());
+
// maybe create .def file from list of objects
this->GenDefFile(real_link_commands);
- std::string manifests = this->GetManifests();
+ std::string manifests = this->GetManifests(this->GetConfigName());
cmRulePlaceholderExpander::RuleVariables vars;
vars.TargetPDB = targetOutPathPDB.c_str();
@@ -750,8 +754,9 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
vars.CMTargetName = this->GeneratorTarget->GetName().c_str();
vars.CMTargetType =
- cmState::GetTargetTypeName(this->GeneratorTarget->GetType());
+ cmState::GetTargetTypeName(this->GeneratorTarget->GetType()).c_str();
vars.Language = linkLanguage.c_str();
+ vars.AIXExports = aixExports.c_str();
vars.Objects = buildObjs.c_str();
std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
@@ -771,7 +776,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
vars.Target = target.c_str();
vars.LinkLibraries = linkLibs.c_str();
vars.ObjectsQuoted = buildObjs.c_str();
- if (this->GeneratorTarget->HasSOName(this->ConfigName)) {
+ if (this->GeneratorTarget->HasSOName(this->GetConfigName())) {
vars.SONameFlag = this->Makefile->GetSONameFlag(linkLanguage);
vars.TargetSOName = this->TargetNames.SharedObject.c_str();
}
@@ -783,8 +788,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
std::string install_name_dir;
if (this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY) {
// Get the install_name directory for the build tree.
- install_name_dir =
- this->GeneratorTarget->GetInstallNameDirForBuildTree(this->ConfigName);
+ install_name_dir = this->GeneratorTarget->GetInstallNameDirForBuildTree(
+ this->GetConfigName());
// Set the rule variable replacement value.
if (install_name_dir.empty()) {
@@ -800,10 +805,10 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
// Add language-specific flags.
std::string langFlags;
this->LocalGenerator->AddLanguageFlagsForLinking(
- langFlags, this->GeneratorTarget, linkLanguage, this->ConfigName);
+ langFlags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
this->LocalGenerator->AddArchitectureFlags(
- langFlags, this->GeneratorTarget, linkLanguage, this->ConfigName);
+ langFlags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
vars.LanguageCompileFlags = langFlags.c_str();
@@ -903,7 +908,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
this->LocalGenerator->CreateCDCommand(
commands1, this->Makefile->GetCurrentBinaryDirectory(),
this->LocalGenerator->GetBinaryDirectory());
- cmAppend(commands, commands1);
+ cm::append(commands, commands1);
commands1.clear();
// Add a rule to create necessary symlinks for the library.
@@ -917,7 +922,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
this->LocalGenerator->CreateCDCommand(
commands1, this->Makefile->GetCurrentBinaryDirectory(),
this->LocalGenerator->GetBinaryDirectory());
- cmAppend(commands, commands1);
+ cm::append(commands, commands1);
commands1.clear();
}
diff --git a/Source/cmMakefileProfilingData.cxx b/Source/cmMakefileProfilingData.cxx
new file mode 100644
index 0000000..e0150dc
--- /dev/null
+++ b/Source/cmMakefileProfilingData.cxx
@@ -0,0 +1,114 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmMakefileProfilingData.h"
+
+#include <chrono>
+#include <stdexcept>
+#include <vector>
+
+#include <cm3p/json/value.h>
+#include <cm3p/json/writer.h>
+
+#include "cmsys/FStream.hxx"
+#include "cmsys/SystemInformation.hxx"
+
+#include "cmListFileCache.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+
+cmMakefileProfilingData::cmMakefileProfilingData(
+ const std::string& profileStream)
+{
+ std::ios::openmode omode = std::ios::out | std::ios::trunc;
+ this->ProfileStream.open(profileStream.c_str(), omode);
+ Json::StreamWriterBuilder wbuilder;
+ this->JsonWriter =
+ std::unique_ptr<Json::StreamWriter>(wbuilder.newStreamWriter());
+ if (!this->ProfileStream.good()) {
+ throw std::runtime_error(std::string("Unable to open: ") + profileStream);
+ }
+
+ this->ProfileStream << "[";
+};
+
+cmMakefileProfilingData::~cmMakefileProfilingData() noexcept
+{
+ if (this->ProfileStream.good()) {
+ try {
+ this->ProfileStream << "]";
+ this->ProfileStream.close();
+ } catch (...) {
+ cmSystemTools::Error("Error writing profiling output!");
+ }
+ }
+}
+
+void cmMakefileProfilingData::StartEntry(const cmListFileFunction& lff,
+ cmListFileContext const& lfc)
+{
+ /* Do not try again if we previously failed to write to output. */
+ if (!this->ProfileStream.good()) {
+ return;
+ }
+
+ try {
+ if (this->ProfileStream.tellp() > 1) {
+ this->ProfileStream << ",";
+ }
+ cmsys::SystemInformation info;
+ Json::Value v;
+ v["ph"] = "B";
+ v["name"] = lff.Name.Original;
+ v["cat"] = "cmake";
+ v["ts"] = Json::Value::UInt64(
+ std::chrono::duration_cast<std::chrono::microseconds>(
+ std::chrono::steady_clock::now().time_since_epoch())
+ .count());
+ v["pid"] = static_cast<int>(info.GetProcessId());
+ v["tid"] = 0;
+ Json::Value argsValue;
+ if (!lff.Arguments.empty()) {
+ std::string args;
+ for (const auto& a : lff.Arguments) {
+ args += (args.empty() ? "" : " ") + a.Value;
+ }
+ argsValue["functionArgs"] = args;
+ }
+ argsValue["location"] = lfc.FilePath + ":" + std::to_string(lfc.Line);
+ v["args"] = argsValue;
+
+ this->JsonWriter->write(v, &this->ProfileStream);
+ } catch (std::ios_base::failure& fail) {
+ cmSystemTools::Error(
+ cmStrCat("Failed to write to profiling output: ", fail.what()));
+ } catch (...) {
+ cmSystemTools::Error("Error writing profiling output!");
+ }
+}
+
+void cmMakefileProfilingData::StopEntry()
+{
+ /* Do not try again if we previously failed to write to output. */
+ if (!this->ProfileStream.good()) {
+ return;
+ }
+
+ try {
+ this->ProfileStream << ",";
+ cmsys::SystemInformation info;
+ Json::Value v;
+ v["ph"] = "E";
+ v["ts"] = Json::Value::UInt64(
+ std::chrono::duration_cast<std::chrono::microseconds>(
+ std::chrono::steady_clock::now().time_since_epoch())
+ .count());
+ v["pid"] = static_cast<int>(info.GetProcessId());
+ v["tid"] = 0;
+ this->JsonWriter->write(v, &this->ProfileStream);
+ } catch (std::ios_base::failure& fail) {
+ cmSystemTools::Error(
+ cmStrCat("Failed to write to profiling output:", fail.what()));
+ } catch (...) {
+ cmSystemTools::Error("Error writing profiling output!");
+ }
+}
diff --git a/Source/cmMakefileProfilingData.h b/Source/cmMakefileProfilingData.h
new file mode 100644
index 0000000..1babd97
--- /dev/null
+++ b/Source/cmMakefileProfilingData.h
@@ -0,0 +1,29 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmMakefileProfilingData_h
+#define cmMakefileProfilingData_h
+#include <memory>
+#include <string>
+
+#include "cmsys/FStream.hxx"
+
+namespace Json {
+class StreamWriter;
+}
+
+class cmListFileContext;
+struct cmListFileFunction;
+
+class cmMakefileProfilingData
+{
+public:
+ cmMakefileProfilingData(const std::string&);
+ ~cmMakefileProfilingData() noexcept;
+ void StartEntry(const cmListFileFunction& lff, cmListFileContext const& lfc);
+ void StopEntry();
+
+private:
+ cmsys::ofstream ProfileStream;
+ std::unique_ptr<Json::StreamWriter> JsonWriter;
+};
+#endif
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 9d08e07..5f0cfcf 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -2,12 +2,15 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmMakefileTargetGenerator.h"
+#include <cassert>
#include <cstdio>
-#include <memory>
#include <sstream>
+#include <unordered_map>
#include <utility>
-#include "cmAlgorithms.h"
+#include <cm/memory>
+#include <cmext/algorithm>
+
#include "cmComputeLinkInformation.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
@@ -15,6 +18,7 @@
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalUnixMakefileGenerator3.h"
+#include "cmLinkLineComputer.h" // IWYU pragma: keep
#include "cmLocalCommonGenerator.h"
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
@@ -35,12 +39,7 @@
cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmGeneratorTarget* target)
: cmCommonTargetGenerator(target)
- , OSXBundleGenerator(nullptr)
- , MacOSXContentGenerator(nullptr)
{
- this->BuildFileStream = nullptr;
- this->InfoFileStream = nullptr;
- this->FlagFileStream = nullptr;
this->CustomCommandDriver = OnBuild;
this->LocalGenerator =
static_cast<cmLocalUnixMakefileGenerator3*>(target->GetLocalGenerator());
@@ -48,35 +47,31 @@ cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmGeneratorTarget* target)
this->LocalGenerator->GetGlobalGenerator());
cmake* cm = this->GlobalGenerator->GetCMakeInstance();
this->NoRuleMessages = false;
- if (const char* ruleStatus =
- cm->GetState()->GetGlobalProperty("RULE_MESSAGES")) {
- this->NoRuleMessages = cmIsOff(ruleStatus);
+ if (cmProp ruleStatus = cm->GetState()->GetGlobalProperty("RULE_MESSAGES")) {
+ this->NoRuleMessages = cmIsOff(*ruleStatus);
}
- MacOSXContentGenerator = new MacOSXContentGeneratorType(this);
+ MacOSXContentGenerator = cm::make_unique<MacOSXContentGeneratorType>(this);
}
-cmMakefileTargetGenerator::~cmMakefileTargetGenerator()
-{
- delete MacOSXContentGenerator;
-}
+cmMakefileTargetGenerator::~cmMakefileTargetGenerator() = default;
-cmMakefileTargetGenerator* cmMakefileTargetGenerator::New(
+std::unique_ptr<cmMakefileTargetGenerator> cmMakefileTargetGenerator::New(
cmGeneratorTarget* tgt)
{
- cmMakefileTargetGenerator* result = nullptr;
+ std::unique_ptr<cmMakefileTargetGenerator> result;
switch (tgt->GetType()) {
case cmStateEnums::EXECUTABLE:
- result = new cmMakefileExecutableTargetGenerator(tgt);
+ result = cm::make_unique<cmMakefileExecutableTargetGenerator>(tgt);
break;
case cmStateEnums::STATIC_LIBRARY:
case cmStateEnums::SHARED_LIBRARY:
case cmStateEnums::MODULE_LIBRARY:
case cmStateEnums::OBJECT_LIBRARY:
- result = new cmMakefileLibraryTargetGenerator(tgt);
+ result = cm::make_unique<cmMakefileLibraryTargetGenerator>(tgt);
break;
case cmStateEnums::UTILITY:
- result = new cmMakefileUtilityTargetGenerator(tgt);
+ result = cm::make_unique<cmMakefileUtilityTargetGenerator>(tgt);
break;
default:
return result;
@@ -85,6 +80,25 @@ cmMakefileTargetGenerator* cmMakefileTargetGenerator::New(
return result;
}
+std::string cmMakefileTargetGenerator::GetConfigName()
+{
+ auto const& configNames = this->LocalGenerator->GetConfigNames();
+ assert(configNames.size() == 1);
+ return configNames.front();
+}
+
+void cmMakefileTargetGenerator::GetDeviceLinkFlags(
+ std::string& linkFlags, const std::string& linkLanguage)
+{
+ cmGeneratorTarget::DeviceLinkSetter setter(*this->GetGeneratorTarget());
+
+ std::vector<std::string> linkOpts;
+ this->GeneratorTarget->GetLinkOptions(linkOpts, this->GetConfigName(),
+ linkLanguage);
+ // LINK_OPTIONS are escaped.
+ this->LocalGenerator->AppendCompileOptions(linkFlags, linkOpts);
+}
+
void cmMakefileTargetGenerator::GetTargetLinkFlags(
std::string& flags, const std::string& linkLanguage)
{
@@ -92,17 +106,18 @@ void cmMakefileTargetGenerator::GetTargetLinkFlags(
flags, this->GeneratorTarget->GetSafeProperty("LINK_FLAGS"));
std::string linkFlagsConfig =
- cmStrCat("LINK_FLAGS_", cmSystemTools::UpperCase(this->ConfigName));
+ cmStrCat("LINK_FLAGS_", cmSystemTools::UpperCase(this->GetConfigName()));
this->LocalGenerator->AppendFlags(
flags, this->GeneratorTarget->GetSafeProperty(linkFlagsConfig));
std::vector<std::string> opts;
- this->GeneratorTarget->GetLinkOptions(opts, this->ConfigName, linkLanguage);
+ this->GeneratorTarget->GetLinkOptions(opts, this->GetConfigName(),
+ linkLanguage);
// LINK_OPTIONS are escaped.
this->LocalGenerator->AppendCompileOptions(flags, opts);
this->LocalGenerator->AppendPositionIndependentLinkerFlags(
- flags, this->GeneratorTarget, this->ConfigName, linkLanguage);
+ flags, this->GeneratorTarget, this->GetConfigName(), linkLanguage);
}
void cmMakefileTargetGenerator::CreateRuleFile()
@@ -128,9 +143,9 @@ void cmMakefileTargetGenerator::CreateRuleFile()
// Open the rule file. This should be copy-if-different because the
// rules may depend on this file itself.
- this->BuildFileStream =
- new cmGeneratedFileStream(this->BuildFileNameFull, false,
- this->GlobalGenerator->GetMakefileEncoding());
+ this->BuildFileStream = cm::make_unique<cmGeneratedFileStream>(
+ this->BuildFileNameFull, false,
+ this->GlobalGenerator->GetMakefileEncoding());
if (!this->BuildFileStream) {
return;
}
@@ -152,26 +167,26 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
// Evaluates generator expressions and expands prop_value
auto evaluatedFiles =
- [this](const char* prop_value) -> std::vector<std::string> {
+ [this](const std::string& prop_value) -> std::vector<std::string> {
std::vector<std::string> files;
- cmExpandList(
- cmGeneratorExpression::Evaluate(prop_value, this->LocalGenerator,
- this->ConfigName, this->GeneratorTarget),
- files);
+ cmExpandList(cmGeneratorExpression::Evaluate(
+ prop_value, this->LocalGenerator, this->GetConfigName(),
+ this->GeneratorTarget),
+ files);
return files;
};
// Look for additional files registered for cleaning in this directory.
- if (const char* prop_value =
+ if (cmProp prop_value =
this->Makefile->GetProperty("ADDITIONAL_MAKE_CLEAN_FILES")) {
- std::vector<std::string> const files = evaluatedFiles(prop_value);
+ std::vector<std::string> const files = evaluatedFiles(*prop_value);
this->CleanFiles.insert(files.begin(), files.end());
}
// Look for additional files registered for cleaning in this target.
- if (const char* prop_value =
+ if (cmProp prop_value =
this->GeneratorTarget->GetProperty("ADDITIONAL_CLEAN_FILES")) {
- std::vector<std::string> const files = evaluatedFiles(prop_value);
+ std::vector<std::string> const files = evaluatedFiles(*prop_value);
// For relative path support
std::string const& binaryDir =
this->LocalGenerator->GetCurrentBinaryDirectory();
@@ -181,18 +196,19 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
}
// add custom commands to the clean rules?
- const char* clean_no_custom = this->Makefile->GetProperty("CLEAN_NO_CUSTOM");
- bool clean = cmIsOff(clean_no_custom);
+ cmProp clean_no_custom = this->Makefile->GetProperty("CLEAN_NO_CUSTOM");
+ bool clean = clean_no_custom ? cmIsOff(*clean_no_custom) : true;
// First generate the object rule files. Save a list of all object
// files for this target.
std::vector<cmSourceFile const*> customCommands;
- this->GeneratorTarget->GetCustomCommands(customCommands, this->ConfigName);
+ this->GeneratorTarget->GetCustomCommands(customCommands,
+ this->GetConfigName());
std::string currentBinDir =
this->LocalGenerator->GetCurrentBinaryDirectory();
for (cmSourceFile const* sf : customCommands) {
- cmCustomCommandGenerator ccg(*sf->GetCustomCommand(), this->ConfigName,
- this->LocalGenerator);
+ cmCustomCommandGenerator ccg(*sf->GetCustomCommand(),
+ this->GetConfigName(), this->LocalGenerator);
this->GenerateCustomRuleFile(ccg);
if (clean) {
const std::vector<std::string>& outputs = ccg.GetOutputs();
@@ -215,12 +231,14 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
std::vector<cmCustomCommand> buildEventCommands =
this->GeneratorTarget->GetPreBuildCommands();
- cmAppend(buildEventCommands, this->GeneratorTarget->GetPreLinkCommands());
- cmAppend(buildEventCommands,
- this->GeneratorTarget->GetPostBuildCommands());
+ cm::append(buildEventCommands,
+ this->GeneratorTarget->GetPreLinkCommands());
+ cm::append(buildEventCommands,
+ this->GeneratorTarget->GetPostBuildCommands());
for (const auto& be : buildEventCommands) {
- cmCustomCommandGenerator beg(be, this->ConfigName, this->LocalGenerator);
+ cmCustomCommandGenerator beg(be, this->GetConfigName(),
+ this->LocalGenerator);
const std::vector<std::string>& byproducts = beg.GetByproducts();
for (std::string const& byproduct : byproducts) {
this->CleanFiles.insert(
@@ -230,17 +248,19 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
}
}
std::vector<cmSourceFile const*> headerSources;
- this->GeneratorTarget->GetHeaderSources(headerSources, this->ConfigName);
+ this->GeneratorTarget->GetHeaderSources(headerSources,
+ this->GetConfigName());
this->OSXBundleGenerator->GenerateMacOSXContentStatements(
- headerSources, this->MacOSXContentGenerator);
+ headerSources, this->MacOSXContentGenerator.get(), this->GetConfigName());
std::vector<cmSourceFile const*> extraSources;
- this->GeneratorTarget->GetExtraSources(extraSources, this->ConfigName);
+ this->GeneratorTarget->GetExtraSources(extraSources, this->GetConfigName());
this->OSXBundleGenerator->GenerateMacOSXContentStatements(
- extraSources, this->MacOSXContentGenerator);
+ extraSources, this->MacOSXContentGenerator.get(), this->GetConfigName());
const char* pchExtension =
this->Makefile->GetDefinition("CMAKE_PCH_EXTENSION");
std::vector<cmSourceFile const*> externalObjects;
- this->GeneratorTarget->GetExternalObjects(externalObjects, this->ConfigName);
+ this->GeneratorTarget->GetExternalObjects(externalObjects,
+ this->GetConfigName());
for (cmSourceFile const* sf : externalObjects) {
auto const& objectFileName = sf->GetFullPath();
if (!cmSystemTools::StringEndsWith(objectFileName, pchExtension)) {
@@ -248,7 +268,8 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
}
}
std::vector<cmSourceFile const*> objectSources;
- this->GeneratorTarget->GetObjectSources(objectSources, this->ConfigName);
+ this->GeneratorTarget->GetObjectSources(objectSources,
+ this->GetConfigName());
for (cmSourceFile const* sf : objectSources) {
// Generate this object file's rule file.
this->WriteObjectRuleFiles(*sf);
@@ -291,17 +312,16 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
dependFileNameFull, false, this->GlobalGenerator->GetMakefileEncoding());
depFileStream << "# Empty dependencies file for "
<< this->GeneratorTarget->GetName() << ".\n"
- << "# This may be replaced when dependencies are built."
- << std::endl;
+ << "# This may be replaced when dependencies are built.\n";
}
// Open the flags file. This should be copy-if-different because the
// rules may depend on this file itself.
this->FlagFileNameFull =
cmStrCat(this->TargetBuildDirectoryFull, "/flags.make");
- this->FlagFileStream =
- new cmGeneratedFileStream(this->FlagFileNameFull, false,
- this->GlobalGenerator->GetMakefileEncoding());
+ this->FlagFileStream = cm::make_unique<cmGeneratedFileStream>(
+ this->FlagFileNameFull, false,
+ this->GlobalGenerator->GetMakefileEncoding());
if (!this->FlagFileStream) {
return;
}
@@ -333,22 +353,37 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
<< "\n";
}
+ bool const escapeOctothorpe = this->GlobalGenerator->CanEscapeOctothorpe();
+
for (std::string const& language : languages) {
- std::string flags = this->GetFlags(language);
- std::string defines = this->GetDefines(language);
- std::string includes = this->GetIncludes(language);
- // Escape comment characters so they do not terminate assignment.
- cmSystemTools::ReplaceString(flags, "#", "\\#");
- cmSystemTools::ReplaceString(defines, "#", "\\#");
- cmSystemTools::ReplaceString(includes, "#", "\\#");
- *this->FlagFileStream << language << "_FLAGS = " << flags << "\n\n";
+ std::string defines = this->GetDefines(language, this->GetConfigName());
+ std::string includes = this->GetIncludes(language, this->GetConfigName());
+ if (escapeOctothorpe) {
+ // Escape comment characters so they do not terminate assignment.
+ cmSystemTools::ReplaceString(defines, "#", "\\#");
+ cmSystemTools::ReplaceString(includes, "#", "\\#");
+ }
*this->FlagFileStream << language << "_DEFINES = " << defines << "\n\n";
*this->FlagFileStream << language << "_INCLUDES = " << includes << "\n\n";
+
+ std::vector<std::string> architectures;
+ this->GeneratorTarget->GetAppleArchs(this->GetConfigName(), architectures);
+ architectures.emplace_back();
+
+ for (const std::string& arch : architectures) {
+ std::string flags =
+ this->GetFlags(language, this->GetConfigName(), arch);
+ if (escapeOctothorpe) {
+ cmSystemTools::ReplaceString(flags, "#", "\\#");
+ }
+ *this->FlagFileStream << language << "_FLAGS" << arch << " = " << flags
+ << "\n\n";
+ }
}
}
void cmMakefileTargetGenerator::MacOSXContentGeneratorType::operator()(
- cmSourceFile const& source, const char* pkgloc)
+ cmSourceFile const& source, const char* pkgloc, const std::string& config)
{
// Skip OS X content when not building a Framework or Bundle.
if (!this->Generator->GetGeneratorTarget()->IsBundleOnApple()) {
@@ -356,7 +391,8 @@ void cmMakefileTargetGenerator::MacOSXContentGeneratorType::operator()(
}
std::string macdir =
- this->Generator->OSXBundleGenerator->InitMacOSXContentDirectory(pkgloc);
+ this->Generator->OSXBundleGenerator->InitMacOSXContentDirectory(pkgloc,
+ config);
// Get the input file location.
std::string const& input = source.GetFullPath();
@@ -451,21 +487,41 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
// generate the depend scanning rule
this->WriteObjectDependRules(source, depends);
- std::string config = this->LocalGenerator->GetConfigName();
+ std::string config = this->GetConfigName();
std::string configUpper = cmSystemTools::UpperCase(config);
// Add precompile headers dependencies
- const std::string pchSource =
- this->GeneratorTarget->GetPchSource(config, lang);
- if (!pchSource.empty() && !source.GetProperty("SKIP_PRECOMPILE_HEADERS")) {
- std::string const& pchHeader =
- this->GeneratorTarget->GetPchHeader(config, lang);
- depends.push_back(pchHeader);
- if (source.GetFullPath() != pchSource) {
- depends.push_back(this->GeneratorTarget->GetPchFile(config, lang));
+ std::vector<std::string> architectures;
+ this->GeneratorTarget->GetAppleArchs(config, architectures);
+ if (architectures.empty()) {
+ architectures.emplace_back();
+ }
+
+ std::string filterArch;
+ std::unordered_map<std::string, std::string> pchSources;
+ for (const std::string& arch : architectures) {
+ const std::string pchSource =
+ this->GeneratorTarget->GetPchSource(config, lang, arch);
+ if (pchSource == source.GetFullPath()) {
+ filterArch = arch;
+ }
+ if (!pchSource.empty()) {
+ pchSources.insert(std::make_pair(pchSource, arch));
+ }
+ }
+
+ if (!pchSources.empty() && !source.GetProperty("SKIP_PRECOMPILE_HEADERS")) {
+ for (const std::string& arch : architectures) {
+ std::string const& pchHeader =
+ this->GeneratorTarget->GetPchHeader(config, lang, arch);
+ depends.push_back(pchHeader);
+ if (pchSources.find(source.GetFullPath()) == pchSources.end()) {
+ depends.push_back(
+ this->GeneratorTarget->GetPchFile(config, lang, arch));
+ }
+ this->LocalGenerator->AddImplicitDepends(this->GeneratorTarget, lang,
+ objFullPath, pchHeader);
}
- this->LocalGenerator->AddImplicitDepends(this->GeneratorTarget, lang,
- objFullPath, pchHeader);
}
std::string relativeObj =
@@ -476,7 +532,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
std::string flags;
// Add language-specific flags.
- std::string langFlags = cmStrCat("$(", lang, "_FLAGS)");
+ std::string langFlags = cmStrCat("$(", lang, "_FLAGS", filterArch, ")");
this->LocalGenerator->AppendFlags(flags, langFlags);
cmGeneratorExpressionInterpreter genexInterpreter(
@@ -489,9 +545,9 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
// Add flags from source file properties.
const std::string COMPILE_FLAGS("COMPILE_FLAGS");
- if (const char* cflags = source.GetProperty(COMPILE_FLAGS)) {
+ if (cmProp cflags = source.GetProperty(COMPILE_FLAGS)) {
const std::string& evaluatedFlags =
- genexInterpreter.Evaluate(cflags, COMPILE_FLAGS);
+ genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS);
this->LocalGenerator->AppendFlags(flags, evaluatedFlags);
*this->FlagFileStream << "# Custom flags: " << relativeObj
<< "_FLAGS = " << evaluatedFlags << "\n"
@@ -499,9 +555,9 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
}
const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
- if (const char* coptions = source.GetProperty(COMPILE_OPTIONS)) {
+ if (cmProp coptions = source.GetProperty(COMPILE_OPTIONS)) {
const std::string& evaluatedOptions =
- genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS);
+ genexInterpreter.Evaluate(*coptions, COMPILE_OPTIONS);
this->LocalGenerator->AppendCompileOptions(flags, evaluatedOptions);
*this->FlagFileStream << "# Custom options: " << relativeObj
<< "_OPTIONS = " << evaluatedOptions << "\n"
@@ -509,11 +565,12 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
}
// Add precompile headers compile options.
- if (!pchSource.empty() && !source.GetProperty("SKIP_PRECOMPILE_HEADERS")) {
+ if (!pchSources.empty() && !source.GetProperty("SKIP_PRECOMPILE_HEADERS")) {
std::string pchOptions;
- if (source.GetFullPath() == pchSource) {
- pchOptions =
- this->GeneratorTarget->GetPchCreateCompileOptions(config, lang);
+ auto pchIt = pchSources.find(source.GetFullPath());
+ if (pchIt != pchSources.end()) {
+ pchOptions = this->GeneratorTarget->GetPchCreateCompileOptions(
+ config, lang, pchIt->second);
} else {
pchOptions =
this->GeneratorTarget->GetPchUseCompileOptions(config, lang);
@@ -532,9 +589,9 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
std::vector<std::string> includes;
const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
- if (const char* cincludes = source.GetProperty(INCLUDE_DIRECTORIES)) {
+ if (cmProp cincludes = source.GetProperty(INCLUDE_DIRECTORIES)) {
const std::string& evaluatedIncludes =
- genexInterpreter.Evaluate(cincludes, INCLUDE_DIRECTORIES);
+ genexInterpreter.Evaluate(*cincludes, INCLUDE_DIRECTORIES);
this->LocalGenerator->AppendIncludeDirectories(includes, evaluatedIncludes,
source);
*this->FlagFileStream << "# Custom include directories: " << relativeObj
@@ -548,18 +605,18 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
// Add source-specific preprocessor definitions.
const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS");
- if (const char* compile_defs = source.GetProperty(COMPILE_DEFINITIONS)) {
+ if (cmProp compile_defs = source.GetProperty(COMPILE_DEFINITIONS)) {
const std::string& evaluatedDefs =
- genexInterpreter.Evaluate(compile_defs, COMPILE_DEFINITIONS);
+ genexInterpreter.Evaluate(*compile_defs, COMPILE_DEFINITIONS);
this->LocalGenerator->AppendDefines(defines, evaluatedDefs);
*this->FlagFileStream << "# Custom defines: " << relativeObj
<< "_DEFINES = " << evaluatedDefs << "\n"
<< "\n";
}
std::string defPropName = cmStrCat("COMPILE_DEFINITIONS_", configUpper);
- if (const char* config_compile_defs = source.GetProperty(defPropName)) {
+ if (cmProp config_compile_defs = source.GetProperty(defPropName)) {
const std::string& evaluatedDefs =
- genexInterpreter.Evaluate(config_compile_defs, COMPILE_DEFINITIONS);
+ genexInterpreter.Evaluate(*config_compile_defs, COMPILE_DEFINITIONS);
this->LocalGenerator->AppendDefines(defines, evaluatedDefs);
*this->FlagFileStream << "# Custom defines: " << relativeObj << "_DEFINES_"
<< configUpper << " = " << evaluatedDefs << "\n"
@@ -593,16 +650,17 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
{
std::string targetFullPathReal;
std::string targetFullPathPDB;
- std::string targetFullPathCompilePDB = this->ComputeTargetCompilePDB();
+ std::string targetFullPathCompilePDB =
+ this->ComputeTargetCompilePDB(this->GetConfigName());
if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE ||
this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY ||
this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->GeneratorTarget->GetType() == cmStateEnums::MODULE_LIBRARY) {
targetFullPathReal = this->GeneratorTarget->GetFullPath(
- this->ConfigName, cmStateEnums::RuntimeBinaryArtifact, true);
- targetFullPathPDB =
- cmStrCat(this->GeneratorTarget->GetPDBDirectory(this->ConfigName), '/',
- this->GeneratorTarget->GetPDBName(this->ConfigName));
+ this->GetConfigName(), cmStateEnums::RuntimeBinaryArtifact, true);
+ targetFullPathPDB = cmStrCat(
+ this->GeneratorTarget->GetPDBDirectory(this->GetConfigName()), '/',
+ this->GeneratorTarget->GetPDBName(this->GetConfigName()));
}
targetOutPathReal = this->LocalGenerator->ConvertToOutputFormat(
@@ -628,7 +686,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
cmRulePlaceholderExpander::RuleVariables vars;
vars.CMTargetName = this->GeneratorTarget->GetName().c_str();
vars.CMTargetType =
- cmState::GetTargetTypeName(this->GeneratorTarget->GetType());
+ cmState::GetTargetTypeName(this->GeneratorTarget->GetType()).c_str();
vars.Language = lang.c_str();
vars.Target = targetOutPathReal.c_str();
vars.TargetPDB = targetOutPathPDB.c_str();
@@ -706,16 +764,18 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
// no launcher for CMAKE_EXPORT_COMPILE_COMMANDS
rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
compileCommand, vars);
- std::string workingDirectory = cmSystemTools::CollapseFullPath(
- this->LocalGenerator->GetCurrentBinaryDirectory());
+ std::string workingDirectory =
+ this->LocalGenerator->GetCurrentBinaryDirectory();
compileCommand.replace(compileCommand.find(langFlags), langFlags.size(),
- this->GetFlags(lang));
+ this->GetFlags(lang, this->GetConfigName()));
std::string langDefines = std::string("$(") + lang + "_DEFINES)";
compileCommand.replace(compileCommand.find(langDefines),
- langDefines.size(), this->GetDefines(lang));
+ langDefines.size(),
+ this->GetDefines(lang, this->GetConfigName()));
std::string langIncludes = std::string("$(") + lang + "_INCLUDES)";
compileCommand.replace(compileCommand.find(langIncludes),
- langIncludes.size(), this->GetIncludes(lang));
+ langIncludes.size(),
+ this->GetIncludes(lang, this->GetConfigName()));
const char* eliminate[] = {
this->Makefile->GetDefinition("CMAKE_START_TEMP_FILE"),
@@ -737,25 +797,24 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
(lang == "C" || lang == "CXX" || lang == "Fortran" || lang == "CUDA" ||
lang == "OBJC" || lang == "OBJCXX")) {
std::string const clauncher_prop = lang + "_COMPILER_LAUNCHER";
- const char* clauncher =
- this->GeneratorTarget->GetProperty(clauncher_prop);
- if (clauncher && *clauncher) {
- compilerLauncher = clauncher;
+ cmProp clauncher = this->GeneratorTarget->GetProperty(clauncher_prop);
+ if (clauncher && !clauncher->empty()) {
+ compilerLauncher = *clauncher;
}
}
// Maybe insert an include-what-you-use runner.
if (!compileCommands.empty() && (lang == "C" || lang == "CXX")) {
std::string const iwyu_prop = lang + "_INCLUDE_WHAT_YOU_USE";
- const char* iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
+ cmProp iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
std::string const tidy_prop = lang + "_CLANG_TIDY";
- const char* tidy = this->GeneratorTarget->GetProperty(tidy_prop);
+ cmProp tidy = this->GeneratorTarget->GetProperty(tidy_prop);
std::string const cpplint_prop = lang + "_CPPLINT";
- const char* cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
+ cmProp cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
std::string const cppcheck_prop = lang + "_CPPCHECK";
- const char* cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
- if ((iwyu && *iwyu) || (tidy && *tidy) || (cpplint && *cpplint) ||
- (cppcheck && *cppcheck)) {
+ cmProp cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
+ if ((iwyu && !iwyu->empty()) || (tidy && !tidy->empty()) ||
+ (cpplint && !cpplint->empty()) || (cppcheck && !cppcheck->empty())) {
std::string run_iwyu = "$(CMAKE_COMMAND) -E __run_co_compile";
if (!compilerLauncher.empty()) {
// In __run_co_compile case the launcher command is supplied
@@ -764,24 +823,30 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
run_iwyu += this->LocalGenerator->EscapeForShell(compilerLauncher);
compilerLauncher.clear();
}
- if (iwyu && *iwyu) {
+ if (iwyu && !iwyu->empty()) {
run_iwyu += " --iwyu=";
- run_iwyu += this->LocalGenerator->EscapeForShell(iwyu);
+ run_iwyu += this->LocalGenerator->EscapeForShell(*iwyu);
}
- if (tidy && *tidy) {
+ if (tidy && !tidy->empty()) {
run_iwyu += " --tidy=";
- run_iwyu += this->LocalGenerator->EscapeForShell(tidy);
+ const char* driverMode = this->Makefile->GetDefinition(
+ "CMAKE_" + lang + "_CLANG_TIDY_DRIVER_MODE");
+ if (!(driverMode && *driverMode)) {
+ driverMode = lang == "C" ? "gcc" : "g++";
+ }
+ run_iwyu += this->LocalGenerator->EscapeForShell(
+ cmStrCat(*tidy, ";--extra-arg-before=--driver-mode=", driverMode));
}
- if (cpplint && *cpplint) {
+ if (cpplint && !cpplint->empty()) {
run_iwyu += " --cpplint=";
- run_iwyu += this->LocalGenerator->EscapeForShell(cpplint);
+ run_iwyu += this->LocalGenerator->EscapeForShell(*cpplint);
}
- if (cppcheck && *cppcheck) {
+ if (cppcheck && !cppcheck->empty()) {
run_iwyu += " --cppcheck=";
- run_iwyu += this->LocalGenerator->EscapeForShell(cppcheck);
+ run_iwyu += this->LocalGenerator->EscapeForShell(*cppcheck);
}
- if ((tidy && *tidy) || (cpplint && *cpplint) ||
- (cppcheck && *cppcheck)) {
+ if ((tidy && !tidy->empty()) || (cpplint && !cpplint->empty()) ||
+ (cppcheck && !cppcheck->empty())) {
run_iwyu += " --source=";
run_iwyu += sourceFile;
}
@@ -824,14 +889,14 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
this->LocalGenerator->CreateCDCommand(
compileCommands, this->LocalGenerator->GetCurrentBinaryDirectory(),
this->LocalGenerator->GetBinaryDirectory());
- cmAppend(commands, compileCommands);
+ cm::append(commands, compileCommands);
}
// Check for extra outputs created by the compilation.
std::vector<std::string> outputs(1, relativeObj);
- if (const char* extra_outputs_str = source.GetProperty("OBJECT_OUTPUTS")) {
+ if (cmProp extra_outputs_str = source.GetProperty("OBJECT_OUTPUTS")) {
// Register these as extra files to clean.
- cmExpandList(extra_outputs_str, outputs);
+ cmExpandList(*extra_outputs_str, outputs);
this->CleanFiles.insert(outputs.begin() + 1, outputs.end());
}
@@ -883,7 +948,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
preprocessCommands,
this->LocalGenerator->GetCurrentBinaryDirectory(),
this->LocalGenerator->GetBinaryDirectory());
- cmAppend(commands, preprocessCommands);
+ cm::append(commands, preprocessCommands);
} else {
std::string cmd =
cmStrCat("$(CMAKE_COMMAND) -E cmake_unimplemented_variable ",
@@ -927,7 +992,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
this->LocalGenerator->CreateCDCommand(
assemblyCommands, this->LocalGenerator->GetCurrentBinaryDirectory(),
this->LocalGenerator->GetBinaryDirectory());
- cmAppend(commands, assemblyCommands);
+ cm::append(commands, assemblyCommands);
} else {
std::string cmd =
cmStrCat("$(CMAKE_COMMAND) -E cmake_unimplemented_variable ",
@@ -1037,7 +1102,8 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
this->InfoFileNameFull = cmStrCat(dir, "/DependInfo.cmake");
this->InfoFileNameFull =
this->LocalGenerator->ConvertToFullPath(this->InfoFileNameFull);
- this->InfoFileStream = new cmGeneratedFileStream(this->InfoFileNameFull);
+ this->InfoFileStream =
+ cm::make_unique<cmGeneratedFileStream>(this->InfoFileNameFull);
if (!this->InfoFileStream) {
return;
}
@@ -1069,7 +1135,8 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
<< "# Targets to which this target links.\n"
<< "set(CMAKE_TARGET_LINKED_INFO_FILES\n";
/* clang-format on */
- std::vector<std::string> dirs = this->GetLinkedTargetDirectories();
+ std::vector<std::string> dirs =
+ this->GetLinkedTargetDirectories(this->GetConfigName());
for (std::string const& d : dirs) {
*this->InfoFileStream << " \"" << d << "/DependInfo.cmake\"\n";
}
@@ -1109,8 +1176,7 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
// translation table for the dependency scanning process.
depCmd << "cd "
<< (this->LocalGenerator->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(
- this->LocalGenerator->GetBinaryDirectory()),
+ this->LocalGenerator->GetBinaryDirectory(),
cmOutputConverter::SHELL))
<< " && ";
#endif
@@ -1126,23 +1192,19 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
depCmd << "$(CMAKE_COMMAND) -E cmake_depends \""
<< this->GlobalGenerator->GetName() << "\" "
<< this->LocalGenerator->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(
- this->LocalGenerator->GetSourceDirectory()),
+ this->LocalGenerator->GetSourceDirectory(),
cmOutputConverter::SHELL)
<< " "
<< this->LocalGenerator->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(
- this->LocalGenerator->GetCurrentSourceDirectory()),
+ this->LocalGenerator->GetCurrentSourceDirectory(),
cmOutputConverter::SHELL)
<< " "
<< this->LocalGenerator->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(
- this->LocalGenerator->GetBinaryDirectory()),
+ this->LocalGenerator->GetBinaryDirectory(),
cmOutputConverter::SHELL)
<< " "
<< this->LocalGenerator->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(
- this->LocalGenerator->GetCurrentBinaryDirectory()),
+ this->LocalGenerator->GetCurrentBinaryDirectory(),
cmOutputConverter::SHELL)
<< " "
<< this->LocalGenerator->ConvertToOutputFormat(
@@ -1172,9 +1234,9 @@ void cmMakefileTargetGenerator::DriveCustomCommands(
sources, this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
for (cmSourceFile* source : sources) {
if (cmCustomCommand* cc = source->GetCustomCommand()) {
- cmCustomCommandGenerator ccg(*cc, this->ConfigName,
+ cmCustomCommandGenerator ccg(*cc, this->GetConfigName(),
this->LocalGenerator);
- cmAppend(depends, ccg.GetOutputs());
+ cm::append(depends, ccg.GetOutputs());
}
}
}
@@ -1185,8 +1247,8 @@ void cmMakefileTargetGenerator::WriteObjectDependRules(
// Create the list of dependencies known at cmake time. These are
// shared between the object file and dependency scanning rule.
depends.push_back(source.GetFullPath());
- if (const char* objectDeps = source.GetProperty("OBJECT_DEPENDS")) {
- cmExpandList(objectDeps, depends);
+ if (cmProp objectDeps = source.GetProperty("OBJECT_DEPENDS")) {
+ cmExpandList(*objectDeps, depends);
}
}
@@ -1230,8 +1292,10 @@ void cmMakefileTargetGenerator::GenerateCustomRuleFile(
// Setup implicit dependency scanning.
for (auto const& idi : ccg.GetCC().GetImplicitDepends()) {
- std::string objFullPath = cmSystemTools::CollapseFullPath(outputs[0]);
- std::string srcFullPath = cmSystemTools::CollapseFullPath(idi.second);
+ std::string objFullPath = cmSystemTools::CollapseFullPath(
+ outputs[0], this->LocalGenerator->GetCurrentBinaryDirectory());
+ std::string srcFullPath = cmSystemTools::CollapseFullPath(
+ idi.second, this->LocalGenerator->GetCurrentBinaryDirectory());
this->LocalGenerator->AddImplicitDepends(this->GeneratorTarget, idi.first,
objFullPath, srcFullPath);
}
@@ -1411,7 +1475,7 @@ void cmMakefileTargetGenerator::WriteTargetDriverRule(
}
// Make sure the extra files are built.
- cmAppend(depends, this->ExtraFiles);
+ cm::append(depends, this->ExtraFiles);
}
// Write the driver rule.
@@ -1430,10 +1494,10 @@ void cmMakefileTargetGenerator::AppendTargetDepends(
}
// Loop over all library dependencies.
- const std::string& cfg = this->LocalGenerator->GetConfigName();
+ const std::string& cfg = this->GetConfigName();
if (cmComputeLinkInformation* cli =
this->GeneratorTarget->GetLinkInformation(cfg)) {
- cmAppend(depends, cli->GetDepends());
+ cm::append(depends, cli->GetDepends());
}
}
@@ -1449,7 +1513,7 @@ void cmMakefileTargetGenerator::AppendObjectDepends(
}
// Add dependencies on the external object files.
- cmAppend(depends, this->ExternalObjects);
+ cm::append(depends, this->ExternalObjects);
// Add a dependency on the rule file itself.
this->LocalGenerator->AppendRuleDepend(depends,
@@ -1475,13 +1539,13 @@ void cmMakefileTargetGenerator::AppendLinkDepends(
// Add a dependency on user-specified manifest files, if any.
std::vector<cmSourceFile const*> manifest_srcs;
- this->GeneratorTarget->GetManifests(manifest_srcs, this->ConfigName);
+ this->GeneratorTarget->GetManifests(manifest_srcs, this->GetConfigName());
for (cmSourceFile const* manifest_src : manifest_srcs) {
depends.push_back(manifest_src->GetFullPath());
}
// Add user-specified dependencies.
- this->GeneratorTarget->GetLinkDepends(depends, this->ConfigName,
+ this->GeneratorTarget->GetLinkDepends(depends, this->GetConfigName(),
linkLanguage);
}
@@ -1489,10 +1553,11 @@ std::string cmMakefileTargetGenerator::GetLinkRule(
const std::string& linkRuleVar)
{
std::string linkRule = this->Makefile->GetRequiredDefinition(linkRuleVar);
- if (this->GeneratorTarget->HasImplibGNUtoMS(this->ConfigName)) {
- std::string ruleVar = cmStrCat(
- "CMAKE_", this->GeneratorTarget->GetLinkerLanguage(this->ConfigName),
- "_GNUtoMS_RULE");
+ if (this->GeneratorTarget->HasImplibGNUtoMS(this->GetConfigName())) {
+ std::string ruleVar =
+ cmStrCat("CMAKE_",
+ this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName()),
+ "_GNUtoMS_RULE");
if (const char* rule = this->Makefile->GetDefinition(ruleVar)) {
linkRule += rule;
}
@@ -1502,9 +1567,9 @@ std::string cmMakefileTargetGenerator::GetLinkRule(
void cmMakefileTargetGenerator::CloseFileStreams()
{
- delete this->BuildFileStream;
- delete this->InfoFileStream;
- delete this->FlagFileStream;
+ this->BuildFileStream.reset();
+ this->InfoFileStream.reset();
+ this->FlagFileStream.reset();
}
void cmMakefileTargetGenerator::CreateLinkScript(
@@ -1613,7 +1678,8 @@ std::string cmMakefileTargetGenerator::CreateResponseFile(
return responseFileName;
}
-cmLinkLineComputer* cmMakefileTargetGenerator::CreateLinkLineComputer(
+std::unique_ptr<cmLinkLineComputer>
+cmMakefileTargetGenerator::CreateLinkLineComputer(
cmOutputConverter* outputConverter, cmStateDirectory const& stateDir)
{
if (this->Makefile->IsOn("MSVC60")) {
@@ -1631,7 +1697,7 @@ void cmMakefileTargetGenerator::CreateLinkLibs(
std::string frameworkPath;
std::string linkPath;
cmComputeLinkInformation* pcli =
- this->GeneratorTarget->GetLinkInformation(this->ConfigName);
+ this->GeneratorTarget->GetLinkInformation(this->GetConfigName());
this->LocalGenerator->OutputLinkLibraries(pcli, linkLineComputer, linkLibs,
frameworkPath, linkPath);
linkLibs = frameworkPath + linkPath + linkLibs;
@@ -1639,9 +1705,10 @@ 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->ConfigName),
- "_RESPONSE_FILE_LINK_FLAG");
+ std::string responseFlagVar =
+ cmStrCat("CMAKE_",
+ this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName()),
+ "_RESPONSE_FILE_LINK_FLAG");
const char* responseFlag = this->Makefile->GetDefinition(responseFlagVar);
if (!responseFlag) {
responseFlag = "@";
@@ -1676,9 +1743,10 @@ void cmMakefileTargetGenerator::CreateObjectLists(
this->WriteObjectsStrings(object_strings, responseFileLimit);
// Lookup the response file reference flag.
- std::string responseFlagVar = cmStrCat(
- "CMAKE_", this->GeneratorTarget->GetLinkerLanguage(this->ConfigName),
- "_RESPONSE_FILE_LINK_FLAG");
+ std::string responseFlagVar =
+ cmStrCat("CMAKE_",
+ this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName()),
+ "_RESPONSE_FILE_LINK_FLAG");
const char* responseFlag = this->Makefile->GetDefinition(responseFlagVar);
if (!responseFlag) {
responseFlag = "@";
@@ -1717,7 +1785,8 @@ void cmMakefileTargetGenerator::CreateObjectLists(
}
void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags,
- const std::string& lang)
+ const std::string& lang,
+ const std::string& /*config*/)
{
std::string responseVar =
cmStrCat("CMAKE_", lang, "_USE_RESPONSE_FILE_FOR_INCLUDES");
@@ -1725,11 +1794,11 @@ void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags,
std::vector<std::string> includes;
this->LocalGenerator->GetIncludeDirectories(includes, this->GeneratorTarget,
- lang, this->ConfigName);
+ lang, this->GetConfigName());
std::string includeFlags = this->LocalGenerator->GetIncludeFlags(
includes, this->GeneratorTarget, lang, false, useResponseFile,
- this->ConfigName);
+ this->GetConfigName());
if (includeFlags.empty()) {
return;
}
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index 7b9c7a5..f38f862 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -34,10 +34,15 @@ class cmMakefileTargetGenerator : public cmCommonTargetGenerator
public:
// constructor to set the ivars
cmMakefileTargetGenerator(cmGeneratorTarget* target);
+ cmMakefileTargetGenerator(const cmMakefileTargetGenerator&) = delete;
~cmMakefileTargetGenerator() override;
+ cmMakefileTargetGenerator& operator=(const cmMakefileTargetGenerator&) =
+ delete;
+
// construct using this factory call
- static cmMakefileTargetGenerator* New(cmGeneratorTarget* tgt);
+ static std::unique_ptr<cmMakefileTargetGenerator> New(
+ cmGeneratorTarget* tgt);
/* the main entry point for this class. Writes the Makefiles associated
with this target */
@@ -52,7 +57,11 @@ public:
cmGeneratorTarget* GetGeneratorTarget() { return this->GeneratorTarget; }
+ std::string GetConfigName();
+
protected:
+ void GetDeviceLinkFlags(std::string& linkFlags,
+ const std::string& linkLanguage);
void GetTargetLinkFlags(std::string& flags, const std::string& linkLanguage);
// create the file and directory etc
@@ -81,7 +90,8 @@ protected:
{
}
- void operator()(cmSourceFile const& source, const char* pkgloc) override;
+ void operator()(cmSourceFile const& source, const char* pkgloc,
+ const std::string& config) override;
private:
cmMakefileTargetGenerator* Generator;
@@ -137,7 +147,7 @@ protected:
std::vector<std::string>& makefile_commands,
std::vector<std::string>& makefile_depends);
- cmLinkLineComputer* CreateLinkLineComputer(
+ std::unique_ptr<cmLinkLineComputer> CreateLinkLineComputer(
cmOutputConverter* outputConverter, cmStateDirectory const& stateDir);
/** Create a response file with the given set of options. Returns
@@ -163,7 +173,8 @@ protected:
/** Add commands for generate def files */
void GenDefFile(std::vector<std::string>& real_link_commands);
- void AddIncludeFlags(std::string& flags, const std::string& lang) override;
+ void AddIncludeFlags(std::string& flags, const std::string& lang,
+ const std::string& config) override;
virtual void CloseFileStreams();
cmLocalUnixMakefileGenerator3* LocalGenerator;
@@ -191,11 +202,11 @@ protected:
std::string TargetBuildDirectoryFull;
// the stream for the build file
- cmGeneratedFileStream* BuildFileStream;
+ std::unique_ptr<cmGeneratedFileStream> BuildFileStream;
// the stream for the flag file
std::string FlagFileNameFull;
- cmGeneratedFileStream* FlagFileStream;
+ std::unique_ptr<cmGeneratedFileStream> FlagFileStream;
class StringList : public std::vector<std::string>
{
};
@@ -203,7 +214,7 @@ protected:
// the stream for the info file
std::string InfoFileNameFull;
- cmGeneratedFileStream* InfoFileStream;
+ std::unique_ptr<cmGeneratedFileStream> InfoFileStream;
// files to clean
std::set<std::string> CleanFiles;
@@ -232,7 +243,7 @@ protected:
// macOS content info.
std::set<std::string> MacContentFolders;
std::unique_ptr<cmOSXBundleGenerator> OSXBundleGenerator;
- MacOSXContentGeneratorType* MacOSXContentGenerator;
+ std::unique_ptr<MacOSXContentGeneratorType> MacOSXContentGenerator;
};
#endif
diff --git a/Source/cmMakefileUtilityTargetGenerator.cxx b/Source/cmMakefileUtilityTargetGenerator.cxx
index 1625e4f..6c18e48 100644
--- a/Source/cmMakefileUtilityTargetGenerator.cxx
+++ b/Source/cmMakefileUtilityTargetGenerator.cxx
@@ -22,8 +22,7 @@ cmMakefileUtilityTargetGenerator::cmMakefileUtilityTargetGenerator(
: cmMakefileTargetGenerator(target)
{
this->CustomCommandDriver = OnUtility;
- this->OSXBundleGenerator =
- cm::make_unique<cmOSXBundleGenerator>(target, this->ConfigName);
+ this->OSXBundleGenerator = cm::make_unique<cmOSXBundleGenerator>(target);
this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
}
diff --git a/Source/cmMarkAsAdvancedCommand.cxx b/Source/cmMarkAsAdvancedCommand.cxx
index ca46e14..45043fa 100644
--- a/Source/cmMarkAsAdvancedCommand.cxx
+++ b/Source/cmMarkAsAdvancedCommand.cxx
@@ -4,8 +4,11 @@
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
+#include "cmMessageType.h"
+#include "cmPolicies.h"
#include "cmState.h"
#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"
@@ -28,14 +31,63 @@ bool cmMarkAsAdvancedCommand(std::vector<std::string> const& args,
}
i = 1;
}
+
+ cmMakefile& mf = status.GetMakefile();
+ cmState* state = mf.GetState();
+
for (; i < args.size(); ++i) {
std::string const& variable = args[i];
- cmState* state = status.GetMakefile().GetState();
- if (!state->GetCacheEntryValue(variable)) {
- status.GetMakefile().GetCMakeInstance()->AddCacheEntry(
- variable, nullptr, nullptr, cmStateEnums::UNINITIALIZED);
- overwrite = true;
+
+ bool issueMessage = false;
+ bool oldBehavior = false;
+ bool ignoreVariable = false;
+ switch (mf.GetPolicyStatus(cmPolicies::CMP0102)) {
+ case cmPolicies::WARN:
+ if (mf.PolicyOptionalWarningEnabled("CMAKE_POLICY_WARNING_CMP0102")) {
+ if (!state->GetCacheEntryValue(variable)) {
+ issueMessage = true;
+ }
+ }
+ CM_FALLTHROUGH;
+ case cmPolicies::OLD:
+ oldBehavior = true;
+ break;
+ case cmPolicies::NEW:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ if (!state->GetCacheEntryValue(variable)) {
+ ignoreVariable = true;
+ }
+ break;
+ }
+
+ // First see if we should issue a message about CMP0102
+ if (issueMessage) {
+ std::string err = cmStrCat(
+ "Policy CMP0102 is not set: The variable named \"", variable,
+ "\" is not in the cache. This results in an empty cache entry which "
+ "is no longer created when policy CMP0102 is set to NEW. Run \"cmake "
+ "--help-policy CMP0102\" for policy details. Use the cmake_policy "
+ "command to set the policy and suppress this warning.");
+ mf.IssueMessage(MessageType::AUTHOR_WARNING, err);
}
+
+ // If it's not in the cache and we're using the new behavior, nothing to
+ // see here.
+ if (ignoreVariable) {
+ continue;
+ }
+
+ // Check if we want the old behavior of making a dummy cache entry.
+ if (oldBehavior) {
+ if (!state->GetCacheEntryValue(variable)) {
+ status.GetMakefile().GetCMakeInstance()->AddCacheEntry(
+ variable, nullptr, nullptr, cmStateEnums::UNINITIALIZED);
+ overwrite = true;
+ }
+ }
+
+ // We need a cache entry to do this.
if (!state->GetCacheEntryValue(variable)) {
cmSystemTools::Error("This should never happen...");
return false;
diff --git a/Source/cmMathCommand.cxx b/Source/cmMathCommand.cxx
index f11b906..56221bf 100644
--- a/Source/cmMathCommand.cxx
+++ b/Source/cmMathCommand.cxx
@@ -4,7 +4,7 @@
#include <cstdio>
-#include "cm_kwiml.h"
+#include <cm3p/kwiml/int.h>
#include "cmExecutionStatus.h"
#include "cmExprParserHelper.h"
diff --git a/Source/cmMessageCommand.cxx b/Source/cmMessageCommand.cxx
index 96a6386..c7bb9a7 100644
--- a/Source/cmMessageCommand.cxx
+++ b/Source/cmMessageCommand.cxx
@@ -3,6 +3,10 @@
#include "cmMessageCommand.h"
#include <cassert>
+#include <utility>
+
+#include <cm/string_view>
+#include <cmext/string_view>
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
@@ -13,6 +17,55 @@
#include "cmSystemTools.h"
#include "cmake.h"
+namespace {
+
+enum class CheckingType
+{
+ UNDEFINED,
+ CHECK_START,
+ CHECK_PASS,
+ CHECK_FAIL
+};
+
+std::string IndentText(std::string text, cmMakefile& mf)
+{
+ auto indent =
+ cmJoin(cmExpandedList(mf.GetSafeDefinition("CMAKE_MESSAGE_INDENT")), "");
+
+ const auto showContext = mf.GetCMakeInstance()->GetShowLogContext() ||
+ mf.IsOn("CMAKE_MESSAGE_CONTEXT_SHOW");
+ if (showContext) {
+ auto context = cmJoin(
+ cmExpandedList(mf.GetSafeDefinition("CMAKE_MESSAGE_CONTEXT")), ".");
+ if (!context.empty()) {
+ indent.insert(0u, cmStrCat("["_s, context, "] "_s));
+ }
+ }
+
+ if (!indent.empty()) {
+ cmSystemTools::ReplaceString(text, "\n", "\n" + indent);
+ text.insert(0u, indent);
+ }
+ return text;
+}
+
+void ReportCheckResult(cm::string_view what, std::string result,
+ cmMakefile& mf)
+{
+ if (mf.GetCMakeInstance()->HasCheckInProgress()) {
+ auto text = mf.GetCMakeInstance()->GetTopCheckInProgressMessage() + " - " +
+ std::move(result);
+ mf.DisplayStatus(IndentText(std::move(text), mf), -1);
+ } else {
+ mf.GetMessenger()->DisplayMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat("Ignored "_s, what, " without CHECK_START"_s),
+ mf.GetBacktrace());
+ }
+}
+
+} // anonymous namespace
+
// cmLibraryCommand
bool cmMessageCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
@@ -21,11 +74,15 @@ bool cmMessageCommand(std::vector<std::string> const& args,
status.SetError("called with incorrect number of arguments");
return false;
}
+
+ auto& mf = status.GetMakefile();
+
auto i = args.cbegin();
auto type = MessageType::MESSAGE;
auto fatal = false;
auto level = cmake::LogLevel::LOG_UNDEFINED;
+ auto checkingType = CheckingType::UNDEFINED;
if (*i == "SEND_ERROR") {
type = MessageType::FATAL_ERROR;
level = cmake::LogLevel::LOG_ERROR;
@@ -40,19 +97,30 @@ bool cmMessageCommand(std::vector<std::string> const& args,
level = cmake::LogLevel::LOG_WARNING;
++i;
} else if (*i == "AUTHOR_WARNING") {
- if (status.GetMakefile().IsSet("CMAKE_SUPPRESS_DEVELOPER_ERRORS") &&
- !status.GetMakefile().IsOn("CMAKE_SUPPRESS_DEVELOPER_ERRORS")) {
+ if (mf.IsSet("CMAKE_SUPPRESS_DEVELOPER_ERRORS") &&
+ !mf.IsOn("CMAKE_SUPPRESS_DEVELOPER_ERRORS")) {
fatal = true;
type = MessageType::AUTHOR_ERROR;
level = cmake::LogLevel::LOG_ERROR;
- } else if (!status.GetMakefile().IsOn(
- "CMAKE_SUPPRESS_DEVELOPER_WARNINGS")) {
+ } else if (!mf.IsOn("CMAKE_SUPPRESS_DEVELOPER_WARNINGS")) {
type = MessageType::AUTHOR_WARNING;
level = cmake::LogLevel::LOG_WARNING;
} else {
return true;
}
++i;
+ } else if (*i == "CHECK_START") {
+ level = cmake::LogLevel::LOG_STATUS;
+ checkingType = CheckingType::CHECK_START;
+ ++i;
+ } else if (*i == "CHECK_PASS") {
+ level = cmake::LogLevel::LOG_STATUS;
+ checkingType = CheckingType::CHECK_PASS;
+ ++i;
+ } else if (*i == "CHECK_FAIL") {
+ level = cmake::LogLevel::LOG_STATUS;
+ checkingType = CheckingType::CHECK_FAIL;
+ ++i;
} else if (*i == "STATUS") {
level = cmake::LogLevel::LOG_STATUS;
++i;
@@ -66,12 +134,12 @@ bool cmMessageCommand(std::vector<std::string> const& args,
level = cmake::LogLevel::LOG_TRACE;
++i;
} else if (*i == "DEPRECATION") {
- if (status.GetMakefile().IsOn("CMAKE_ERROR_DEPRECATED")) {
+ if (mf.IsOn("CMAKE_ERROR_DEPRECATED")) {
fatal = true;
type = MessageType::DEPRECATION_ERROR;
level = cmake::LogLevel::LOG_ERROR;
- } else if (!status.GetMakefile().IsSet("CMAKE_WARN_DEPRECATED") ||
- status.GetMakefile().IsOn("CMAKE_WARN_DEPRECATED")) {
+ } else if (!mf.IsSet("CMAKE_WARN_DEPRECATED") ||
+ mf.IsOn("CMAKE_WARN_DEPRECATED")) {
type = MessageType::DEPRECATION_WARNING;
level = cmake::LogLevel::LOG_WARNING;
} else {
@@ -89,10 +157,19 @@ bool cmMessageCommand(std::vector<std::string> const& args,
assert("Message log level expected to be set" &&
level != cmake::LogLevel::LOG_UNDEFINED);
- auto desiredLevel = status.GetMakefile().GetCMakeInstance()->GetLogLevel();
+ 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;
+ }
+ }
+
if (desiredLevel < level) {
// Suppress the message
return true;
@@ -100,37 +177,42 @@ bool cmMessageCommand(std::vector<std::string> const& args,
auto message = cmJoin(cmMakeRange(i, args.cend()), "");
- if (cmake::LogLevel::LOG_NOTICE <= level) {
- // Check if any indentation has requested:
- // `CMAKE_MESSAGE_INDENT` is a list of "padding" pieces
- // to be joined and prepended to the message lines.
- auto indent = cmJoin(cmExpandedList(status.GetMakefile().GetSafeDefinition(
- "CMAKE_MESSAGE_INDENT")),
- "");
- // Make every line of the `message` indented
- // NOTE Can't reuse `cmDocumentationFormatter::PrintPreformatted`
- // here cuz it appends `\n` to the EOM ;-(
- cmSystemTools::ReplaceString(message, "\n", "\n" + indent);
- message = indent + message;
- }
-
switch (level) {
case cmake::LogLevel::LOG_ERROR:
case cmake::LogLevel::LOG_WARNING:
// we've overridden the message type, above, so display it directly
- status.GetMakefile().GetMessenger()->DisplayMessage(
- type, message, status.GetMakefile().GetBacktrace());
+ mf.GetMessenger()->DisplayMessage(type, message, mf.GetBacktrace());
break;
case cmake::LogLevel::LOG_NOTICE:
- cmSystemTools::Message(message);
+ cmSystemTools::Message(IndentText(message, mf));
break;
case cmake::LogLevel::LOG_STATUS:
+ switch (checkingType) {
+ case CheckingType::CHECK_START:
+ mf.DisplayStatus(IndentText(message, mf), -1);
+ mf.GetCMakeInstance()->PushCheckInProgressMessage(message);
+ break;
+
+ case CheckingType::CHECK_PASS:
+ ReportCheckResult("CHECK_PASS"_s, message, mf);
+ break;
+
+ case CheckingType::CHECK_FAIL:
+ ReportCheckResult("CHECK_FAIL"_s, message, mf);
+ break;
+
+ default:
+ mf.DisplayStatus(IndentText(message, mf), -1);
+ break;
+ }
+ break;
+
case cmake::LogLevel::LOG_VERBOSE:
case cmake::LogLevel::LOG_DEBUG:
case cmake::LogLevel::LOG_TRACE:
- status.GetMakefile().DisplayStatus(message, -1);
+ mf.DisplayStatus(IndentText(message, mf), -1);
break;
default:
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index a458cac..db069ed 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -11,8 +11,8 @@
#include <utility>
#include <cm/memory>
+#include <cm/vector>
-#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
#include "cmCustomCommand.h" // IWYU pragma: keep
#include "cmCustomCommandGenerator.h"
@@ -41,33 +41,25 @@
cmNinjaNormalTargetGenerator::cmNinjaNormalTargetGenerator(
cmGeneratorTarget* target)
: cmNinjaTargetGenerator(target)
- , TargetLinkLanguage("")
{
- this->TargetLinkLanguage = target->GetLinkerLanguage(this->GetConfigName());
- if (target->GetType() == cmStateEnums::EXECUTABLE) {
- this->TargetNames = this->GetGeneratorTarget()->GetExecutableNames(
- GetLocalGenerator()->GetConfigName());
- } else {
- this->TargetNames = this->GetGeneratorTarget()->GetLibraryNames(
- GetLocalGenerator()->GetConfigName());
- }
-
if (target->GetType() != cmStateEnums::OBJECT_LIBRARY) {
// on Windows the output dir is already needed at compile time
// ensure the directory exists (OutDir test)
- EnsureDirectoryExists(target->GetDirectory(this->GetConfigName()));
+ for (auto const& config : this->GetConfigNames()) {
+ EnsureDirectoryExists(target->GetDirectory(config));
+ }
}
- this->OSXBundleGenerator =
- cm::make_unique<cmOSXBundleGenerator>(target, this->GetConfigName());
+ this->OSXBundleGenerator = cm::make_unique<cmOSXBundleGenerator>(target);
this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
}
cmNinjaNormalTargetGenerator::~cmNinjaNormalTargetGenerator() = default;
-void cmNinjaNormalTargetGenerator::Generate()
+void cmNinjaNormalTargetGenerator::Generate(const std::string& config)
{
- if (this->TargetLinkLanguage.empty()) {
+ std::string lang = this->GeneratorTarget->GetLinkerLanguage(config);
+ if (this->TargetLinkLanguage(config).empty()) {
cmSystemTools::Error("CMake can not determine linker language for "
"target: " +
this->GetGeneratorTarget()->GetName());
@@ -75,25 +67,48 @@ void cmNinjaNormalTargetGenerator::Generate()
}
// Write the rules for each language.
- this->WriteLanguagesRules();
+ this->WriteLanguagesRules(config);
// Write the build statements
- this->WriteObjectBuildStatements();
+ bool firstForConfig = true;
+ for (auto const& fileConfig : this->GetConfigNames()) {
+ if (!this->GetGlobalGenerator()
+ ->GetCrossConfigs(fileConfig)
+ .count(config)) {
+ continue;
+ }
+ this->WriteObjectBuildStatements(config, fileConfig, firstForConfig);
+ firstForConfig = false;
+ }
if (this->GetGeneratorTarget()->GetType() == cmStateEnums::OBJECT_LIBRARY) {
- this->WriteObjectLibStatement();
+ this->WriteObjectLibStatement(config);
} else {
- // If this target has cuda language link inputs, and we need to do
- // device linking
- this->WriteDeviceLinkStatement();
- this->WriteLinkStatement();
+ firstForConfig = true;
+ for (auto const& fileConfig : this->GetConfigNames()) {
+ if (!this->GetGlobalGenerator()
+ ->GetCrossConfigs(fileConfig)
+ .count(config)) {
+ continue;
+ }
+ // If this target has cuda language link inputs, and we need to do
+ // device linking
+ this->WriteDeviceLinkStatement(config, fileConfig, firstForConfig);
+ this->WriteLinkStatement(config, fileConfig, firstForConfig);
+ firstForConfig = false;
+ }
+ }
+ if (this->GetGlobalGenerator()->EnableCrossConfigBuild()) {
+ this->GetGlobalGenerator()->AddTargetAlias(
+ this->GetTargetName(), this->GetGeneratorTarget(), "all");
}
// Find ADDITIONAL_CLEAN_FILES
- this->AdditionalCleanFiles();
+ this->AdditionalCleanFiles(config);
}
-void cmNinjaNormalTargetGenerator::WriteLanguagesRules()
+void cmNinjaNormalTargetGenerator::WriteLanguagesRules(
+ const std::string& config)
{
#ifdef NINJA_GEN_VERBOSE_FILES
cmGlobalNinjaGenerator::WriteDivider(this->GetRulesFileStream());
@@ -106,8 +121,7 @@ void cmNinjaNormalTargetGenerator::WriteLanguagesRules()
// Write rules for languages compiled in this target.
std::set<std::string> languages;
std::vector<cmSourceFile const*> sourceFiles;
- this->GetGeneratorTarget()->GetObjectSources(
- sourceFiles, this->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE"));
+ this->GetGeneratorTarget()->GetObjectSources(sourceFiles, config);
for (cmSourceFile const* sf : sourceFiles) {
std::string const lang = sf->GetLanguage();
if (!lang.empty()) {
@@ -115,7 +129,7 @@ void cmNinjaNormalTargetGenerator::WriteLanguagesRules()
}
}
for (std::string const& language : languages) {
- this->WriteLanguageRules(language);
+ this->WriteLanguageRules(language, config);
}
}
@@ -139,22 +153,28 @@ const char* cmNinjaNormalTargetGenerator::GetVisibleTypeName() const
}
}
-std::string cmNinjaNormalTargetGenerator::LanguageLinkerRule() const
+std::string cmNinjaNormalTargetGenerator::LanguageLinkerRule(
+ const std::string& config) const
{
- return this->TargetLinkLanguage + "_" +
- cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType()) +
- "_LINKER__" +
+ return cmStrCat(
+ this->TargetLinkLanguage(config), "_",
+ cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType()),
+ "_LINKER__",
cmGlobalNinjaGenerator::EncodeRuleName(
- this->GetGeneratorTarget()->GetName());
+ this->GetGeneratorTarget()->GetName()),
+ "_", config);
}
-std::string cmNinjaNormalTargetGenerator::LanguageLinkerDeviceRule() const
+std::string cmNinjaNormalTargetGenerator::LanguageLinkerDeviceRule(
+ const std::string& config) const
{
- return this->TargetLinkLanguage + "_" +
- cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType()) +
- "_DEVICE_LINKER__" +
+ return cmStrCat(
+ this->TargetLinkLanguage(config), "_",
+ cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType()),
+ "_DEVICE_LINKER__",
cmGlobalNinjaGenerator::EncodeRuleName(
- this->GetGeneratorTarget()->GetName());
+ this->GetGeneratorTarget()->GetName()),
+ "_", config);
}
struct cmNinjaRemoveNoOpCommands
@@ -165,14 +185,16 @@ struct cmNinjaRemoveNoOpCommands
}
};
-void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(bool useResponseFile)
+void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(
+ bool useResponseFile, const std::string& config)
{
- cmNinjaRule rule(this->LanguageLinkerDeviceRule());
+ cmNinjaRule rule(this->LanguageLinkerDeviceRule(config));
if (!this->GetGlobalGenerator()->HasRule(rule.Name)) {
cmRulePlaceholderExpander::RuleVariables vars;
vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
vars.CMTargetType =
- cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType());
+ cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType())
+ .c_str();
vars.Language = "CUDA";
@@ -211,11 +233,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(bool useResponseFile)
vars.LinkFlags = "$LINK_FLAGS";
vars.Manifests = "$MANIFESTS";
- std::string langFlags;
- if (this->GetGeneratorTarget()->GetType() != cmStateEnums::EXECUTABLE) {
- langFlags += "$LANGUAGE_COMPILE_FLAGS $ARCH_FLAGS";
- vars.LanguageCompileFlags = langFlags.c_str();
- }
+ vars.LanguageCompileFlags = "$LANGUAGE_COMPILE_FLAGS";
std::string launcher;
const char* val = this->GetLocalGenerator()->GetRuleLauncher(
@@ -236,35 +254,40 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(bool useResponseFile)
}
// If there is no ranlib the command will be ":". Skip it.
- cmEraseIf(linkCmds, cmNinjaRemoveNoOpCommands());
+ cm::erase_if(linkCmds, cmNinjaRemoveNoOpCommands());
rule.Command = this->GetLocalGenerator()->BuildCommandLine(linkCmds);
// Write the linker rule with response file if needed.
- rule.Comment = cmStrCat("Rule for linking ", this->TargetLinkLanguage, ' ',
- this->GetVisibleTypeName(), '.');
- rule.Description = cmStrCat("Linking ", this->TargetLinkLanguage, ' ',
- this->GetVisibleTypeName(), " $TARGET_FILE");
+ rule.Comment =
+ cmStrCat("Rule for linking ", this->TargetLinkLanguage(config), ' ',
+ this->GetVisibleTypeName(), '.');
+ rule.Description =
+ cmStrCat("Linking ", this->TargetLinkLanguage(config), ' ',
+ this->GetVisibleTypeName(), " $TARGET_FILE");
rule.Restat = "$RESTAT";
this->GetGlobalGenerator()->AddRule(rule);
}
}
-void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
+void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile,
+ const std::string& config)
{
cmStateEnums::TargetType targetType = this->GetGeneratorTarget()->GetType();
- std::string linkRuleName = this->LanguageLinkerRule();
+ std::string linkRuleName = this->LanguageLinkerRule(config);
if (!this->GetGlobalGenerator()->HasRule(linkRuleName)) {
cmNinjaRule rule(std::move(linkRuleName));
cmRulePlaceholderExpander::RuleVariables vars;
vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
- vars.CMTargetType = cmState::GetTargetTypeName(targetType);
+ vars.CMTargetType = cmState::GetTargetTypeName(targetType).c_str();
- vars.Language = this->TargetLinkLanguage.c_str();
+ std::string lang = this->TargetLinkLanguage(config);
+ vars.Language = config.c_str();
+ vars.AIXExports = "$AIX_EXPORTS";
- if (this->TargetLinkLanguage == "Swift") {
+ if (this->TargetLinkLanguage(config) == "Swift") {
vars.SwiftLibraryName = "$SWIFT_LIBRARY_NAME";
vars.SwiftModule = "$SWIFT_MODULE";
vars.SwiftModuleName = "$SWIFT_MODULE_NAME";
@@ -278,7 +301,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
std::string responseFlag;
- std::string cmakeVarLang = cmStrCat("CMAKE_", this->TargetLinkLanguage);
+ std::string cmakeVarLang =
+ cmStrCat("CMAKE_", this->TargetLinkLanguage(config));
// build response file name
std::string cmakeLinkVar = cmakeVarLang + "_RESPONSE_FILE_LINK_FLAG";
@@ -304,7 +328,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
rule.RspContent = "$in_newline";
}
rule.RspContent += " $LINK_PATH $LINK_LIBRARIES";
- if (this->TargetLinkLanguage == "Swift") {
+ if (this->TargetLinkLanguage(config) == "Swift") {
vars.SwiftSources = responseFlag.c_str();
} else {
vars.Objects = responseFlag.c_str();
@@ -359,7 +383,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
this->GetLocalGenerator()->CreateRulePlaceholderExpander());
// Rule for linking library/executable.
- std::vector<std::string> linkCmds = this->ComputeLinkCmd();
+ std::vector<std::string> linkCmds = this->ComputeLinkCmd(config);
for (std::string& linkCmd : linkCmds) {
linkCmd = cmStrCat(launcher, linkCmd);
rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(),
@@ -367,22 +391,25 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
}
// If there is no ranlib the command will be ":". Skip it.
- cmEraseIf(linkCmds, cmNinjaRemoveNoOpCommands());
+ cm::erase_if(linkCmds, cmNinjaRemoveNoOpCommands());
linkCmds.insert(linkCmds.begin(), "$PRE_LINK");
linkCmds.emplace_back("$POST_BUILD");
rule.Command = this->GetLocalGenerator()->BuildCommandLine(linkCmds);
// Write the linker rule with response file if needed.
- rule.Comment = cmStrCat("Rule for linking ", this->TargetLinkLanguage, ' ',
- this->GetVisibleTypeName(), '.');
- rule.Description = cmStrCat("Linking ", this->TargetLinkLanguage, ' ',
- this->GetVisibleTypeName(), " $TARGET_FILE");
+ rule.Comment =
+ cmStrCat("Rule for linking ", this->TargetLinkLanguage(config), ' ',
+ this->GetVisibleTypeName(), '.');
+ rule.Description =
+ cmStrCat("Linking ", this->TargetLinkLanguage(config), ' ',
+ this->GetVisibleTypeName(), " $TARGET_FILE");
rule.Restat = "$RESTAT";
this->GetGlobalGenerator()->AddRule(rule);
}
- if (this->TargetNames.Output != this->TargetNames.Real &&
+ auto const tgtNames = this->TargetNames(config);
+ if (tgtNames.Output != tgtNames.Real &&
!this->GetGeneratorTarget()->IsFrameworkOnApple()) {
std::string cmakeCommand =
this->GetLocalGenerator()->ConvertToOutputFormat(
@@ -441,7 +468,8 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeDeviceLinkCmd()
return linkCmds;
}
-std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd()
+std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd(
+ const std::string& config)
{
std::vector<std::string> linkCmds;
cmMakefile* mf = this->GetMakefile();
@@ -450,14 +478,14 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd()
// this occurs when things like IPO is enabled, and we need to use the
// CMAKE_<lang>_CREATE_STATIC_LIBRARY_IPO define instead.
std::string linkCmdVar = this->GetGeneratorTarget()->GetCreateRuleVariable(
- this->TargetLinkLanguage, this->GetConfigName());
+ this->TargetLinkLanguage(config), config);
const char* linkCmd = mf->GetDefinition(linkCmdVar);
if (linkCmd) {
std::string linkCmdStr = linkCmd;
- if (this->GetGeneratorTarget()->HasImplibGNUtoMS(this->ConfigName)) {
- std::string ruleVar = cmStrCat(
- "CMAKE_", this->GeneratorTarget->GetLinkerLanguage(this->ConfigName),
- "_GNUtoMS_RULE");
+ if (this->GetGeneratorTarget()->HasImplibGNUtoMS(config)) {
+ std::string ruleVar =
+ cmStrCat("CMAKE_", this->GeneratorTarget->GetLinkerLanguage(config),
+ "_GNUtoMS_RULE");
if (const char* rule = this->Makefile->GetDefinition(ruleVar)) {
linkCmdStr += rule;
}
@@ -469,9 +497,8 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd()
cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL),
" -E __run_co_compile --lwyu=");
cmGeneratorTarget& gt = *this->GetGeneratorTarget();
- const std::string cfgName = this->GetConfigName();
std::string targetOutputReal = this->ConvertToNinjaPath(
- gt.GetFullPath(cfgName, cmStateEnums::RuntimeBinaryArtifact,
+ gt.GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact,
/*realname=*/true));
cmakeCommand += targetOutputReal;
linkCmds.push_back(std::move(cmakeCommand));
@@ -486,25 +513,25 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd()
std::string cmakeCommand =
this->GetLocalGenerator()->ConvertToOutputFormat(
cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL);
- linkCmds.push_back(cmakeCommand + " -E remove $TARGET_FILE");
+ linkCmds.push_back(cmakeCommand + " -E rm -f $TARGET_FILE");
}
// TODO: Use ARCHIVE_APPEND for archives over a certain size.
{
- std::string linkCmdVar =
- cmStrCat("CMAKE_", this->TargetLinkLanguage, "_ARCHIVE_CREATE");
+ std::string linkCmdVar = cmStrCat(
+ "CMAKE_", this->TargetLinkLanguage(config), "_ARCHIVE_CREATE");
linkCmdVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
- linkCmdVar, this->TargetLinkLanguage, this->GetConfigName());
+ linkCmdVar, this->TargetLinkLanguage(config), config);
std::string const& linkCmd = mf->GetRequiredDefinition(linkCmdVar);
cmExpandList(linkCmd, linkCmds);
}
{
- std::string linkCmdVar =
- cmStrCat("CMAKE_", this->TargetLinkLanguage, "_ARCHIVE_FINISH");
+ std::string linkCmdVar = cmStrCat(
+ "CMAKE_", this->TargetLinkLanguage(config), "_ARCHIVE_FINISH");
linkCmdVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
- linkCmdVar, this->TargetLinkLanguage, this->GetConfigName());
+ linkCmdVar, this->TargetLinkLanguage(config), config);
std::string const& linkCmd = mf->GetRequiredDefinition(linkCmdVar);
cmExpandList(linkCmd, linkCmds);
@@ -523,19 +550,28 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd()
linkCmds.push_back(cmakeCommand + " -E touch $TARGET_FILE");
}
#endif
- return linkCmds;
- }
+ } break;
case cmStateEnums::SHARED_LIBRARY:
case cmStateEnums::MODULE_LIBRARY:
+ break;
case cmStateEnums::EXECUTABLE:
+ if (this->TargetLinkLanguage(config) == "Swift") {
+ if (this->GeneratorTarget->IsExecutableWithExports()) {
+ const std::string flags =
+ this->Makefile->GetSafeDefinition("CMAKE_EXE_EXPORTS_Swift_FLAG");
+ cmExpandList(flags, linkCmds);
+ }
+ }
break;
default:
assert(false && "Unexpected target type");
}
- return std::vector<std::string>();
+ return linkCmds;
}
-void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
+void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement(
+ const std::string& config, const std::string& fileConfig,
+ bool firstForConfig)
{
cmGlobalNinjaGenerator* globalGen = this->GetGlobalGenerator();
if (!globalGen->GetLanguageEnabled("CUDA")) {
@@ -545,37 +581,64 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
cmGeneratorTarget* genTarget = this->GetGeneratorTarget();
bool requiresDeviceLinking = requireDeviceLinking(
- *this->GeneratorTarget, *this->GetLocalGenerator(), this->ConfigName);
+ *this->GeneratorTarget, *this->GetLocalGenerator(), config);
if (!requiresDeviceLinking) {
return;
}
- // Now we can do device linking
-
// First and very important step is to make sure while inside this
// step our link language is set to CUDA
std::string cudaLinkLanguage = "CUDA";
std::string const& objExt =
this->Makefile->GetSafeDefinition("CMAKE_CUDA_OUTPUT_EXTENSION");
- std::string const cfgName = this->GetConfigName();
- std::string const targetOutputReal = ConvertToNinjaPath(
- genTarget->ObjectDirectory + "cmake_device_link" + objExt);
+ std::string targetOutputDir =
+ cmStrCat(this->GetLocalGenerator()->GetTargetDirectory(genTarget),
+ globalGen->ConfigDirectory(config), "/");
+ targetOutputDir = globalGen->ExpandCFGIntDir(targetOutputDir, config);
- std::string const targetOutputImplib = ConvertToNinjaPath(
- genTarget->GetFullPath(cfgName, cmStateEnums::ImportLibraryArtifact));
+ std::string targetOutputReal =
+ ConvertToNinjaPath(targetOutputDir + "cmake_device_link" + objExt);
+ std::string targetOutputImplib = ConvertToNinjaPath(
+ genTarget->GetFullPath(config, cmStateEnums::ImportLibraryArtifact));
+
+ if (config != fileConfig) {
+ std::string targetOutputFileConfigDir =
+ cmStrCat(this->GetLocalGenerator()->GetTargetDirectory(genTarget),
+ globalGen->ConfigDirectory(fileConfig), "/");
+ targetOutputFileConfigDir =
+ globalGen->ExpandCFGIntDir(targetOutputDir, fileConfig);
+ if (targetOutputDir == targetOutputFileConfigDir) {
+ return;
+ }
+
+ if (!genTarget->GetFullName(config, cmStateEnums::ImportLibraryArtifact)
+ .empty() &&
+ !genTarget
+ ->GetFullName(fileConfig, cmStateEnums::ImportLibraryArtifact)
+ .empty() &&
+ targetOutputImplib ==
+ ConvertToNinjaPath(genTarget->GetFullPath(
+ fileConfig, cmStateEnums::ImportLibraryArtifact))) {
+ return;
+ }
+ }
+
+ if (firstForConfig) {
+ globalGen->GetByproductsForCleanTarget(config).push_back(targetOutputReal);
+ }
this->DeviceLinkObject = targetOutputReal;
// Write comments.
- cmGlobalNinjaGenerator::WriteDivider(this->GetBuildFileStream());
+ cmGlobalNinjaGenerator::WriteDivider(this->GetCommonFileStream());
const cmStateEnums::TargetType targetType = genTarget->GetType();
- this->GetBuildFileStream() << "# Device Link build statements for "
- << cmState::GetTargetTypeName(targetType)
- << " target " << this->GetTargetName() << "\n\n";
+ this->GetCommonFileStream() << "# Device Link build statements for "
+ << cmState::GetTargetTypeName(targetType)
+ << " target " << this->GetTargetName() << "\n\n";
// Compute the comment.
- cmNinjaBuild build(this->LanguageLinkerDeviceRule());
+ cmNinjaBuild build(this->LanguageLinkerDeviceRule(config));
build.Comment =
cmStrCat("Link the ", this->GetVisibleTypeName(), ' ', targetOutputReal);
@@ -584,14 +647,15 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
// Compute outputs.
build.Outputs.push_back(targetOutputReal);
// Compute specific libraries to link with.
- build.ExplicitDeps = this->GetObjects();
- build.ImplicitDeps = this->ComputeLinkDeps(this->TargetLinkLanguage);
+ build.ExplicitDeps = this->GetObjects(config);
+ build.ImplicitDeps =
+ this->ComputeLinkDeps(this->TargetLinkLanguage(config), config);
std::string frameworkPath;
std::string linkPath;
- std::string createRule = genTarget->GetCreateRuleVariable(
- this->TargetLinkLanguage, this->GetConfigName());
+ std::string createRule =
+ genTarget->GetCreateRuleVariable(this->TargetLinkLanguage(config), config);
const bool useWatcomQuote =
this->GetMakefile()->IsOn(createRule + "_USE_WATCOM_QUOTE");
cmLocalNinjaGenerator& localGen = *this->GetLocalGenerator();
@@ -605,43 +669,34 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
this->GetLocalGenerator()->GetStateSnapshot().GetDirectory(),
globalGen));
linkLineComputer->SetUseWatcomQuote(useWatcomQuote);
+ linkLineComputer->SetUseNinjaMulti(globalGen->IsMultiConfig());
- localGen.GetTargetFlags(
- linkLineComputer.get(), this->GetConfigName(), vars["LINK_LIBRARIES"],
- vars["FLAGS"], vars["LINK_FLAGS"], frameworkPath, linkPath, genTarget);
+ localGen.GetDeviceLinkFlags(linkLineComputer.get(), config,
+ vars["LINK_LIBRARIES"], vars["LINK_FLAGS"],
+ frameworkPath, linkPath, genTarget);
this->addPoolNinjaVariable("JOB_POOL_LINK", genTarget, vars);
- vars["LINK_FLAGS"] =
- cmGlobalNinjaGenerator::EncodeLiteral(vars["LINK_FLAGS"]);
+ vars["LINK_FLAGS"] = globalGen->EncodeLiteral(vars["LINK_FLAGS"]);
- vars["MANIFESTS"] = this->GetManifests();
+ vars["MANIFESTS"] = this->GetManifests(config);
vars["LINK_PATH"] = frameworkPath + linkPath;
- // Compute architecture specific link flags. Yes, these go into a different
- // variable for executables, probably due to a mistake made when duplicating
- // code between the Makefile executable and library generators.
- if (targetType == cmStateEnums::EXECUTABLE) {
- std::string t = vars["FLAGS"];
- localGen.AddArchitectureFlags(t, genTarget, cudaLinkLanguage, cfgName);
- vars["FLAGS"] = t;
- } else {
- std::string t = vars["ARCH_FLAGS"];
- localGen.AddArchitectureFlags(t, genTarget, cudaLinkLanguage, cfgName);
- vars["ARCH_FLAGS"] = t;
- t.clear();
- localGen.AddLanguageFlagsForLinking(t, genTarget, cudaLinkLanguage,
- cfgName);
- vars["LANGUAGE_COMPILE_FLAGS"] = t;
- }
- if (genTarget->HasSOName(cfgName)) {
+ // Compute language specific link flags.
+ std::string langFlags;
+ localGen.AddLanguageFlagsForLinking(langFlags, genTarget, cudaLinkLanguage,
+ config);
+ vars["LANGUAGE_COMPILE_FLAGS"] = langFlags;
+
+ auto const tgtNames = this->TargetNames(config);
+ if (genTarget->HasSOName(config)) {
vars["SONAME_FLAG"] =
- this->GetMakefile()->GetSONameFlag(this->TargetLinkLanguage);
- vars["SONAME"] = this->TargetNames.SharedObject;
+ this->GetMakefile()->GetSONameFlag(this->TargetLinkLanguage(config));
+ vars["SONAME"] = tgtNames.SharedObject;
if (targetType == cmStateEnums::SHARED_LIBRARY) {
std::string install_dir =
- this->GetGeneratorTarget()->GetInstallNameDirForBuildTree(cfgName);
+ this->GetGeneratorTarget()->GetInstallNameDirForBuildTree(config);
if (!install_dir.empty()) {
vars["INSTALLNAME_DIR"] = localGen.ConvertToOutputFormat(
install_dir, cmOutputConverter::SHELL);
@@ -649,25 +704,28 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
}
}
- if (!this->TargetNames.ImportLibrary.empty()) {
+ if (!tgtNames.ImportLibrary.empty()) {
const std::string impLibPath = localGen.ConvertToOutputFormat(
targetOutputImplib, cmOutputConverter::SHELL);
vars["TARGET_IMPLIB"] = impLibPath;
EnsureParentDirectoryExists(impLibPath);
}
- const std::string objPath = GetGeneratorTarget()->GetSupportDirectory();
+ const std::string objPath =
+ cmStrCat(GetGeneratorTarget()->GetSupportDirectory(),
+ globalGen->ConfigDirectory(config));
+
vars["OBJECT_DIR"] = this->GetLocalGenerator()->ConvertToOutputFormat(
this->ConvertToNinjaPath(objPath), cmOutputConverter::SHELL);
EnsureDirectoryExists(objPath);
- this->SetMsvcTargetPdbVariable(vars);
+ this->SetMsvcTargetPdbVariable(vars, config);
+ std::string& linkLibraries = vars["LINK_LIBRARIES"];
+ std::string& link_path = vars["LINK_PATH"];
if (globalGen->IsGCCOnWindows()) {
// ar.exe can't handle backslashes in rsp files (implicitly used by gcc)
- std::string& linkLibraries = vars["LINK_LIBRARIES"];
std::replace(linkLibraries.begin(), linkLibraries.end(), '\\', '/');
- std::string& link_path = vars["LINK_PATH"];
std::replace(link_path.begin(), link_path.end(), '\\', '/');
}
@@ -675,65 +733,100 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement()
// do not check if the user has explicitly forced a response file.
int const commandLineLengthLimit =
static_cast<int>(cmSystemTools::CalculateCommandLineLengthLimit()) -
- globalGen->GetRuleCmdLength(this->LanguageLinkerDeviceRule());
+ globalGen->GetRuleCmdLength(this->LanguageLinkerDeviceRule(config));
build.RspFile = this->ConvertToNinjaPath(std::string("CMakeFiles/") +
genTarget->GetName() + ".rsp");
// Gather order-only dependencies.
- this->GetLocalGenerator()->AppendTargetDepends(this->GetGeneratorTarget(),
- build.OrderOnlyDeps);
+ this->GetLocalGenerator()->AppendTargetDepends(
+ this->GetGeneratorTarget(), build.OrderOnlyDeps, config, config);
// Write the build statement for this target.
bool usedResponseFile = false;
- globalGen->WriteBuild(this->GetBuildFileStream(), build,
+ globalGen->WriteBuild(this->GetCommonFileStream(), build,
commandLineLengthLimit, &usedResponseFile);
- this->WriteDeviceLinkRule(usedResponseFile);
+ this->WriteDeviceLinkRule(usedResponseFile, config);
}
-void cmNinjaNormalTargetGenerator::WriteLinkStatement()
+void cmNinjaNormalTargetGenerator::WriteLinkStatement(
+ const std::string& config, const std::string& fileConfig,
+ bool firstForConfig)
{
cmMakefile* mf = this->GetMakefile();
cmGlobalNinjaGenerator* globalGen = this->GetGlobalGenerator();
cmGeneratorTarget* gt = this->GetGeneratorTarget();
- const std::string cfgName = this->GetConfigName();
- std::string targetOutput = ConvertToNinjaPath(gt->GetFullPath(cfgName));
+ std::string targetOutput = ConvertToNinjaPath(gt->GetFullPath(config));
std::string targetOutputReal = ConvertToNinjaPath(
- gt->GetFullPath(cfgName, cmStateEnums::RuntimeBinaryArtifact,
+ gt->GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact,
/*realname=*/true));
std::string targetOutputImplib = ConvertToNinjaPath(
- gt->GetFullPath(cfgName, cmStateEnums::ImportLibraryArtifact));
+ gt->GetFullPath(config, cmStateEnums::ImportLibraryArtifact));
+ if (config != fileConfig) {
+ if (targetOutput == ConvertToNinjaPath(gt->GetFullPath(fileConfig))) {
+ return;
+ }
+ if (targetOutputReal ==
+ ConvertToNinjaPath(gt->GetFullPath(fileConfig,
+ cmStateEnums::RuntimeBinaryArtifact,
+ /*realname=*/true))) {
+ return;
+ }
+ if (!gt->GetFullName(config, cmStateEnums::ImportLibraryArtifact)
+ .empty() &&
+ !gt->GetFullName(fileConfig, cmStateEnums::ImportLibraryArtifact)
+ .empty() &&
+ targetOutputImplib ==
+ ConvertToNinjaPath(gt->GetFullPath(
+ fileConfig, cmStateEnums::ImportLibraryArtifact))) {
+ return;
+ }
+ }
+
+ auto const tgtNames = this->TargetNames(config);
if (gt->IsAppBundleOnApple()) {
// Create the app bundle
- std::string outpath = gt->GetDirectory(cfgName);
- this->OSXBundleGenerator->CreateAppBundle(this->TargetNames.Output,
- outpath);
+ std::string outpath = gt->GetDirectory(config);
+ this->OSXBundleGenerator->CreateAppBundle(tgtNames.Output, outpath,
+ config);
// Calculate the output path
- targetOutput = cmStrCat(outpath, '/', this->TargetNames.Output);
+ targetOutput = cmStrCat(outpath, '/', tgtNames.Output);
targetOutput = this->ConvertToNinjaPath(targetOutput);
- targetOutputReal = cmStrCat(outpath, '/', this->TargetNames.Real);
+ targetOutputReal = cmStrCat(outpath, '/', tgtNames.Real);
targetOutputReal = this->ConvertToNinjaPath(targetOutputReal);
} else if (gt->IsFrameworkOnApple()) {
// Create the library framework.
- this->OSXBundleGenerator->CreateFramework(this->TargetNames.Output,
- gt->GetDirectory(cfgName));
+
+ cmOSXBundleGenerator::SkipParts bundleSkipParts;
+ if (globalGen->GetName() == "Ninja Multi-Config") {
+ const auto postFix = this->GeneratorTarget->GetFilePostfix(config);
+ // Skip creating Info.plist when there are multiple configurations, and
+ // the current configuration has a postfix. The non-postfix configuration
+ // Info.plist can be used by all the other configurations.
+ if (!postFix.empty()) {
+ bundleSkipParts.infoPlist = true;
+ }
+ }
+
+ this->OSXBundleGenerator->CreateFramework(
+ tgtNames.Output, gt->GetDirectory(config), config, bundleSkipParts);
} else if (gt->IsCFBundleOnApple()) {
// Create the core foundation bundle.
- this->OSXBundleGenerator->CreateCFBundle(this->TargetNames.Output,
- gt->GetDirectory(cfgName));
+ this->OSXBundleGenerator->CreateCFBundle(tgtNames.Output,
+ gt->GetDirectory(config), config);
}
// Write comments.
- cmGlobalNinjaGenerator::WriteDivider(this->GetBuildFileStream());
+ cmGlobalNinjaGenerator::WriteDivider(this->GetImplFileStream(fileConfig));
const cmStateEnums::TargetType targetType = gt->GetType();
- this->GetBuildFileStream()
+ this->GetImplFileStream(fileConfig)
<< "# Link build statements for " << cmState::GetTargetTypeName(targetType)
<< " target " << this->GetTargetName() << "\n\n";
- cmNinjaBuild linkBuild(this->LanguageLinkerRule());
+ cmNinjaBuild linkBuild(this->LanguageLinkerRule(config));
cmNinjaVars& vars = linkBuild.Variables;
// Compute the comment.
@@ -742,17 +835,20 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
// Compute outputs.
linkBuild.Outputs.push_back(targetOutputReal);
+ if (firstForConfig) {
+ globalGen->GetByproductsForCleanTarget(config).push_back(targetOutputReal);
+ }
- if (this->TargetLinkLanguage == "Swift") {
- vars["SWIFT_LIBRARY_NAME"] = [this]() -> std::string {
+ if (this->TargetLinkLanguage(config) == "Swift") {
+ vars["SWIFT_LIBRARY_NAME"] = [this, config]() -> std::string {
cmGeneratorTarget::Names targetNames =
- this->GetGeneratorTarget()->GetLibraryNames(this->GetConfigName());
+ this->GetGeneratorTarget()->GetLibraryNames(config);
return targetNames.Base;
}();
vars["SWIFT_MODULE_NAME"] = [gt]() -> std::string {
- if (const char* name = gt->GetProperty("Swift_MODULE_NAME")) {
- return name;
+ if (cmProp name = gt->GetProperty("Swift_MODULE_NAME")) {
+ return *name;
}
return gt->GetName();
}();
@@ -760,15 +856,15 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
vars["SWIFT_MODULE"] = [this](const std::string& module) -> std::string {
std::string directory =
this->GetLocalGenerator()->GetCurrentBinaryDirectory();
- if (const char* prop = this->GetGeneratorTarget()->GetProperty(
+ if (cmProp prop = this->GetGeneratorTarget()->GetProperty(
"Swift_MODULE_DIRECTORY")) {
- directory = prop;
+ directory = *prop;
}
std::string name = module + ".swiftmodule";
- if (const char* prop =
+ if (cmProp prop =
this->GetGeneratorTarget()->GetProperty("Swift_MODULE")) {
- name = prop;
+ name = *prop;
}
return this->GetLocalGenerator()->ConvertToOutputFormat(
@@ -776,18 +872,17 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
cmOutputConverter::SHELL);
}(vars["SWIFT_MODULE_NAME"]);
+ const std::string map = cmStrCat(gt->GetSupportDirectory(), '/', config,
+ '/', "output-file-map.json");
vars["SWIFT_OUTPUT_FILE_MAP"] =
this->GetLocalGenerator()->ConvertToOutputFormat(
- this->ConvertToNinjaPath(gt->GetSupportDirectory() +
- "/output-file-map.json"),
- cmOutputConverter::SHELL);
+ this->ConvertToNinjaPath(map), cmOutputConverter::SHELL);
- vars["SWIFT_SOURCES"] = [this]() -> std::string {
+ vars["SWIFT_SOURCES"] = [this, config]() -> std::string {
std::vector<cmSourceFile const*> sources;
std::stringstream oss;
- this->GetGeneratorTarget()->GetObjectSources(sources,
- this->GetConfigName());
+ this->GetGeneratorTarget()->GetObjectSources(sources, config);
cmLocalGenerator const* LocalGen = this->GetLocalGenerator();
for (const auto& source : sources) {
oss << " "
@@ -801,27 +896,28 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
// Since we do not perform object builds, compute the
// defines/flags/includes here so that they can be passed along
// appropriately.
- vars["DEFINES"] = this->GetDefines("Swift");
- vars["FLAGS"] = this->GetFlags("Swift");
- vars["INCLUDES"] = this->GetIncludes("Swift");
+ vars["DEFINES"] = this->GetDefines("Swift", config);
+ vars["FLAGS"] = this->GetFlags("Swift", config);
+ vars["INCLUDES"] = this->GetIncludes("Swift", config);
}
// Compute specific libraries to link with.
- if (this->TargetLinkLanguage == "Swift") {
+ if (this->TargetLinkLanguage(config) == "Swift") {
std::vector<cmSourceFile const*> sources;
- gt->GetObjectSources(sources, this->GetConfigName());
+ gt->GetObjectSources(sources, config);
for (const auto& source : sources) {
linkBuild.Outputs.push_back(
- this->ConvertToNinjaPath(this->GetObjectFilePath(source)));
+ this->ConvertToNinjaPath(this->GetObjectFilePath(source, config)));
linkBuild.ExplicitDeps.push_back(
this->ConvertToNinjaPath(this->GetSourceFilePath(source)));
}
linkBuild.Outputs.push_back(vars["SWIFT_MODULE"]);
} else {
- linkBuild.ExplicitDeps = this->GetObjects();
+ linkBuild.ExplicitDeps = this->GetObjects(config);
}
- linkBuild.ImplicitDeps = this->ComputeLinkDeps(this->TargetLinkLanguage);
+ linkBuild.ImplicitDeps =
+ this->ComputeLinkDeps(this->TargetLinkLanguage(config), config);
if (!this->DeviceLinkObject.empty()) {
linkBuild.ExplicitDeps.push_back(this->DeviceLinkObject);
@@ -831,39 +927,42 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
std::string linkPath;
std::string createRule =
- gt->GetCreateRuleVariable(this->TargetLinkLanguage, this->GetConfigName());
+ gt->GetCreateRuleVariable(this->TargetLinkLanguage(config), config);
bool useWatcomQuote = mf->IsOn(createRule + "_USE_WATCOM_QUOTE");
cmLocalNinjaGenerator& localGen = *this->GetLocalGenerator();
vars["TARGET_FILE"] =
localGen.ConvertToOutputFormat(targetOutputReal, cmOutputConverter::SHELL);
- std::unique_ptr<cmLinkLineComputer> linkLineComputer(
+ std::unique_ptr<cmLinkLineComputer> linkLineComputer =
globalGen->CreateLinkLineComputer(
this->GetLocalGenerator(),
- this->GetLocalGenerator()->GetStateSnapshot().GetDirectory()));
+ this->GetLocalGenerator()->GetStateSnapshot().GetDirectory());
linkLineComputer->SetUseWatcomQuote(useWatcomQuote);
+ linkLineComputer->SetUseNinjaMulti(globalGen->IsMultiConfig());
- localGen.GetTargetFlags(linkLineComputer.get(), this->GetConfigName(),
+ localGen.GetTargetFlags(linkLineComputer.get(), config,
vars["LINK_LIBRARIES"], vars["FLAGS"],
vars["LINK_FLAGS"], frameworkPath, linkPath, gt);
// Add OS X version flags, if any.
if (this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->GeneratorTarget->GetType() == cmStateEnums::MODULE_LIBRARY) {
- this->AppendOSXVerFlag(vars["LINK_FLAGS"], this->TargetLinkLanguage,
- "COMPATIBILITY", true);
- this->AppendOSXVerFlag(vars["LINK_FLAGS"], this->TargetLinkLanguage,
- "CURRENT", false);
+ this->AppendOSXVerFlag(vars["LINK_FLAGS"],
+ this->TargetLinkLanguage(config), "COMPATIBILITY",
+ true);
+ this->AppendOSXVerFlag(vars["LINK_FLAGS"],
+ this->TargetLinkLanguage(config), "CURRENT", false);
}
this->addPoolNinjaVariable("JOB_POOL_LINK", gt, vars);
- this->AddModuleDefinitionFlag(linkLineComputer.get(), vars["LINK_FLAGS"]);
- vars["LINK_FLAGS"] =
- cmGlobalNinjaGenerator::EncodeLiteral(vars["LINK_FLAGS"]);
+ this->AddModuleDefinitionFlag(linkLineComputer.get(), vars["LINK_FLAGS"],
+ config);
+ vars["LINK_FLAGS"] = globalGen->EncodeLiteral(vars["LINK_FLAGS"]);
- vars["MANIFESTS"] = this->GetManifests();
+ vars["MANIFESTS"] = this->GetManifests(config);
+ vars["AIX_EXPORTS"] = this->GetAIXExports(config);
vars["LINK_PATH"] = frameworkPath + linkPath;
std::string lwyuFlags;
@@ -876,23 +975,26 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
// code between the Makefile executable and library generators.
if (targetType == cmStateEnums::EXECUTABLE) {
std::string t = vars["FLAGS"];
- localGen.AddArchitectureFlags(t, gt, TargetLinkLanguage, cfgName);
+ localGen.AddArchitectureFlags(t, gt, this->TargetLinkLanguage(config),
+ config);
t += lwyuFlags;
vars["FLAGS"] = t;
} else {
std::string t = vars["ARCH_FLAGS"];
- localGen.AddArchitectureFlags(t, gt, TargetLinkLanguage, cfgName);
+ localGen.AddArchitectureFlags(t, gt, this->TargetLinkLanguage(config),
+ config);
vars["ARCH_FLAGS"] = t;
t.clear();
t += lwyuFlags;
- localGen.AddLanguageFlagsForLinking(t, gt, TargetLinkLanguage, cfgName);
+ localGen.AddLanguageFlagsForLinking(
+ t, gt, this->TargetLinkLanguage(config), config);
vars["LANGUAGE_COMPILE_FLAGS"] = t;
}
- if (gt->HasSOName(cfgName)) {
- vars["SONAME_FLAG"] = mf->GetSONameFlag(this->TargetLinkLanguage);
- vars["SONAME"] = this->TargetNames.SharedObject;
+ if (gt->HasSOName(config)) {
+ vars["SONAME_FLAG"] = mf->GetSONameFlag(this->TargetLinkLanguage(config));
+ vars["SONAME"] = tgtNames.SharedObject;
if (targetType == cmStateEnums::SHARED_LIBRARY) {
- std::string install_dir = gt->GetInstallNameDirForBuildTree(cfgName);
+ std::string install_dir = gt->GetInstallNameDirForBuildTree(config);
if (!install_dir.empty()) {
vars["INSTALLNAME_DIR"] = localGen.ConvertToOutputFormat(
install_dir, cmOutputConverter::SHELL);
@@ -902,17 +1004,21 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
cmNinjaDeps byproducts;
- if (!this->TargetNames.ImportLibrary.empty()) {
+ if (!tgtNames.ImportLibrary.empty()) {
const std::string impLibPath = localGen.ConvertToOutputFormat(
targetOutputImplib, cmOutputConverter::SHELL);
vars["TARGET_IMPLIB"] = impLibPath;
EnsureParentDirectoryExists(impLibPath);
- if (gt->HasImportLibrary(cfgName)) {
+ if (gt->HasImportLibrary(config)) {
byproducts.push_back(targetOutputImplib);
+ if (firstForConfig) {
+ globalGen->GetByproductsForCleanTarget(config).push_back(
+ targetOutputImplib);
+ }
}
}
- if (!this->SetMsvcTargetPdbVariable(vars)) {
+ if (!this->SetMsvcTargetPdbVariable(vars, config)) {
// It is common to place debug symbols at a specific place,
// so we need a plain target name in the rule available.
std::string prefix;
@@ -927,16 +1033,17 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
vars["TARGET_PDB"] = base + suffix + dbg_suffix;
}
- const std::string objPath = gt->GetSupportDirectory();
+ const std::string objPath =
+ cmStrCat(gt->GetSupportDirectory(), globalGen->ConfigDirectory(config));
vars["OBJECT_DIR"] = this->GetLocalGenerator()->ConvertToOutputFormat(
this->ConvertToNinjaPath(objPath), cmOutputConverter::SHELL);
EnsureDirectoryExists(objPath);
+ std::string& linkLibraries = vars["LINK_LIBRARIES"];
+ std::string& link_path = vars["LINK_PATH"];
if (globalGen->IsGCCOnWindows()) {
// ar.exe can't handle backslashes in rsp files (implicitly used by gcc)
- std::string& linkLibraries = vars["LINK_LIBRARIES"];
std::replace(linkLibraries.begin(), linkLibraries.end(), '\\', '/');
- std::string& link_path = vars["LINK_PATH"];
std::replace(link_path.begin(), link_path.end(), '\\', '/');
}
@@ -947,23 +1054,30 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
std::vector<std::string> preLinkCmdLines;
std::vector<std::string> postBuildCmdLines;
- std::vector<std::string>* cmdLineLists[3] = { &preLinkCmdLines,
- &preLinkCmdLines,
- &postBuildCmdLines };
-
- for (unsigned i = 0; i != 3; ++i) {
- for (cmCustomCommand const& cc : *cmdLists[i]) {
- cmCustomCommandGenerator ccg(cc, cfgName, this->GetLocalGenerator());
- localGen.AppendCustomCommandLines(ccg, *cmdLineLists[i]);
- std::vector<std::string> const& ccByproducts = ccg.GetByproducts();
- std::transform(ccByproducts.begin(), ccByproducts.end(),
- std::back_inserter(byproducts), MapToNinjaPath());
+
+ if (config == fileConfig) {
+ std::vector<std::string>* cmdLineLists[3] = { &preLinkCmdLines,
+ &preLinkCmdLines,
+ &postBuildCmdLines };
+
+ for (unsigned i = 0; i != 3; ++i) {
+ for (cmCustomCommand const& cc : *cmdLists[i]) {
+ cmCustomCommandGenerator ccg(cc, config, this->GetLocalGenerator());
+ localGen.AppendCustomCommandLines(ccg, *cmdLineLists[i]);
+ std::vector<std::string> const& ccByproducts = ccg.GetByproducts();
+ std::transform(ccByproducts.begin(), ccByproducts.end(),
+ std::back_inserter(byproducts), MapToNinjaPath());
+ std::transform(
+ ccByproducts.begin(), ccByproducts.end(),
+ std::back_inserter(globalGen->GetByproductsForCleanTarget()),
+ MapToNinjaPath());
+ }
}
}
// maybe create .def file from list of objects
cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
- gt->GetModuleDefinitionInfo(this->GetConfigName());
+ gt->GetModuleDefinitionInfo(config);
if (mdi && mdi->DefFileGenerated) {
std::string cmakeCommand =
this->GetLocalGenerator()->ConvertToOutputFormat(
@@ -989,7 +1103,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
cmGeneratedFileStream fout(obj_list_file);
if (mdi->WindowsExportAllSymbols) {
- cmNinjaDeps objs = this->GetObjects();
+ cmNinjaDeps objs = this->GetObjects(config);
for (std::string const& obj : objs) {
if (cmHasLiteralSuffix(obj, ".obj")) {
fout << obj << "\n";
@@ -1024,7 +1138,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
symlinkVars["POST_BUILD"] = postBuildCmdLine;
}
- std::string cmakeVarLang = cmStrCat("CMAKE_", this->TargetLinkLanguage);
+ std::string cmakeVarLang =
+ cmStrCat("CMAKE_", this->TargetLinkLanguage(config));
// build response file name
std::string cmakeLinkVar = cmakeVarLang + "_RESPONSE_FILE_LINK_FLAG";
@@ -1032,8 +1147,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
const char* flag = GetMakefile()->GetDefinition(cmakeLinkVar);
bool const lang_supports_response =
- !(this->TargetLinkLanguage == "RC" ||
- (this->TargetLinkLanguage == "CUDA" && !flag));
+ !(this->TargetLinkLanguage(config) == "RC" ||
+ (this->TargetLinkLanguage(config) == "CUDA" && !flag));
int commandLineLengthLimit = -1;
if (!lang_supports_response || !this->ForceResponseFile()) {
commandLineLengthLimit =
@@ -1045,18 +1160,19 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
gt->GetName() + ".rsp");
// Gather order-only dependencies.
- this->GetLocalGenerator()->AppendTargetDepends(gt, linkBuild.OrderOnlyDeps);
+ this->GetLocalGenerator()->AppendTargetDepends(gt, linkBuild.OrderOnlyDeps,
+ config, fileConfig);
// Add order-only dependencies on versioning symlinks of shared libs we link.
if (!this->GeneratorTarget->IsDLLPlatform()) {
if (cmComputeLinkInformation* cli =
- this->GeneratorTarget->GetLinkInformation(this->GetConfigName())) {
+ this->GeneratorTarget->GetLinkInformation(config)) {
for (auto const& item : cli->GetItems()) {
if (item.Target &&
item.Target->GetType() == cmStateEnums::SHARED_LIBRARY &&
!item.Target->IsFrameworkOnApple()) {
- std::string const& lib = this->ConvertToNinjaPath(
- item.Target->GetFullPath(this->GetConfigName()));
+ std::string const& lib =
+ this->ConvertToNinjaPath(item.Target->GetFullPath(config));
if (std::find(linkBuild.ImplicitDeps.begin(),
linkBuild.ImplicitDeps.end(),
lib) == linkBuild.ImplicitDeps.end()) {
@@ -1077,24 +1193,27 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
// Write the build statement for this target.
bool usedResponseFile = false;
- globalGen->WriteBuild(this->GetBuildFileStream(), linkBuild,
+ globalGen->WriteBuild(this->GetImplFileStream(fileConfig), linkBuild,
commandLineLengthLimit, &usedResponseFile);
- this->WriteLinkRule(usedResponseFile);
+ this->WriteLinkRule(usedResponseFile, config);
if (symlinkNeeded) {
if (targetType == cmStateEnums::EXECUTABLE) {
cmNinjaBuild build("CMAKE_SYMLINK_EXECUTABLE");
build.Comment = "Create executable symlink " + targetOutput;
build.Outputs.push_back(targetOutput);
+ if (firstForConfig) {
+ globalGen->GetByproductsForCleanTarget(config).push_back(targetOutput);
+ }
build.ExplicitDeps.push_back(targetOutputReal);
build.Variables = std::move(symlinkVars);
- globalGen->WriteBuild(this->GetBuildFileStream(), build);
+ globalGen->WriteBuild(this->GetImplFileStream(fileConfig), build);
} else {
cmNinjaBuild build("CMAKE_SYMLINK_LIBRARY");
build.Comment = "Create library symlink " + targetOutput;
std::string const soName = this->ConvertToNinjaPath(
- this->GetTargetFilePath(this->TargetNames.SharedObject));
+ this->GetTargetFilePath(tgtNames.SharedObject, config));
// If one link has to be created.
if (targetOutputReal == soName || targetOutput == soName) {
symlinkVars["SONAME"] =
@@ -1103,33 +1222,58 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement()
} else {
symlinkVars["SONAME"].clear();
build.Outputs.push_back(soName);
+ if (firstForConfig) {
+ globalGen->GetByproductsForCleanTarget(config).push_back(soName);
+ }
}
build.Outputs.push_back(targetOutput);
+ if (firstForConfig) {
+ globalGen->GetByproductsForCleanTarget(config).push_back(targetOutput);
+ }
build.ExplicitDeps.push_back(targetOutputReal);
build.Variables = std::move(symlinkVars);
- globalGen->WriteBuild(this->GetBuildFileStream(), build);
+ globalGen->WriteBuild(this->GetImplFileStream(fileConfig), build);
}
}
// Add aliases for the file name and the target name.
- globalGen->AddTargetAlias(this->TargetNames.Output, gt);
- globalGen->AddTargetAlias(this->GetTargetName(), gt);
+ globalGen->AddTargetAlias(tgtNames.Output, gt, config);
+ globalGen->AddTargetAlias(this->GetTargetName(), gt, config);
}
-void cmNinjaNormalTargetGenerator::WriteObjectLibStatement()
+void cmNinjaNormalTargetGenerator::WriteObjectLibStatement(
+ const std::string& config)
{
// Write a phony output that depends on all object files.
{
cmNinjaBuild build("phony");
build.Comment = "Object library " + this->GetTargetName();
this->GetLocalGenerator()->AppendTargetOutputs(this->GetGeneratorTarget(),
- build.Outputs);
- build.ExplicitDeps = this->GetObjects();
- this->GetGlobalGenerator()->WriteBuild(this->GetBuildFileStream(), build);
+ build.Outputs, config);
+ this->GetLocalGenerator()->AppendTargetOutputs(
+ this->GetGeneratorTarget(),
+ this->GetGlobalGenerator()->GetByproductsForCleanTarget(config), config);
+ build.ExplicitDeps = this->GetObjects(config);
+ this->GetGlobalGenerator()->WriteBuild(this->GetCommonFileStream(), build);
}
// Add aliases for the target name.
- this->GetGlobalGenerator()->AddTargetAlias(this->GetTargetName(),
- this->GetGeneratorTarget());
+ this->GetGlobalGenerator()->AddTargetAlias(
+ this->GetTargetName(), this->GetGeneratorTarget(), config);
+}
+
+cmGeneratorTarget::Names cmNinjaNormalTargetGenerator::TargetNames(
+ const std::string& config) const
+{
+ if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) {
+ return this->GeneratorTarget->GetExecutableNames(config);
+ }
+ return this->GeneratorTarget->GetLibraryNames(config);
+}
+
+std::string cmNinjaNormalTargetGenerator::TargetLinkLanguage(
+ const std::string& config) const
+{
+ return this->GeneratorTarget->GetLinkerLanguage(config);
}
diff --git a/Source/cmNinjaNormalTargetGenerator.h b/Source/cmNinjaNormalTargetGenerator.h
index ebc1268..9de99b9 100644
--- a/Source/cmNinjaNormalTargetGenerator.h
+++ b/Source/cmNinjaNormalTargetGenerator.h
@@ -17,30 +17,33 @@ public:
cmNinjaNormalTargetGenerator(cmGeneratorTarget* target);
~cmNinjaNormalTargetGenerator() override;
- void Generate() override;
+ void Generate(const std::string& config) override;
private:
- std::string LanguageLinkerRule() const;
- std::string LanguageLinkerDeviceRule() const;
+ std::string LanguageLinkerRule(const std::string& config) const;
+ std::string LanguageLinkerDeviceRule(const std::string& config) const;
const char* GetVisibleTypeName() const;
- void WriteLanguagesRules();
+ void WriteLanguagesRules(const std::string& config);
- void WriteLinkRule(bool useResponseFile);
- void WriteDeviceLinkRule(bool useResponseFile);
+ void WriteLinkRule(bool useResponseFile, const std::string& config);
+ void WriteDeviceLinkRule(bool useResponseFile, const std::string& config);
- void WriteLinkStatement();
- void WriteDeviceLinkStatement();
+ void WriteLinkStatement(const std::string& config,
+ const std::string& fileConfig, bool firstForConfig);
+ void WriteDeviceLinkStatement(const std::string& config,
+ const std::string& fileConfig,
+ bool firstForConfig);
- void WriteObjectLibStatement();
+ void WriteObjectLibStatement(const std::string& config);
- std::vector<std::string> ComputeLinkCmd();
+ std::vector<std::string> ComputeLinkCmd(const std::string& config);
std::vector<std::string> ComputeDeviceLinkCmd();
private:
// Target name info.
- cmGeneratorTarget::Names TargetNames;
- std::string TargetLinkLanguage;
+ cmGeneratorTarget::Names TargetNames(const std::string& config) const;
+ std::string TargetLinkLanguage(const std::string& config) const;
std::string DeviceLinkObject;
};
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 0aab912..efd2fd5 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -7,14 +7,16 @@
#include <iterator>
#include <map>
#include <ostream>
+#include <unordered_map>
+#include <unordered_set>
#include <utility>
#include <cm/memory>
+#include <cmext/algorithm>
-#include "cm_jsoncpp_value.h"
-#include "cm_jsoncpp_writer.h"
+#include <cm3p/json/value.h>
+#include <cm3p/json/writer.h>
-#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
#include "cmCustomCommandGenerator.h"
#include "cmGeneratedFileStream.h"
@@ -58,19 +60,27 @@ std::unique_ptr<cmNinjaTargetGenerator> cmNinjaTargetGenerator::New(
cmNinjaTargetGenerator::cmNinjaTargetGenerator(cmGeneratorTarget* target)
: cmCommonTargetGenerator(target)
- , MacOSXContentGenerator(nullptr)
, OSXBundleGenerator(nullptr)
, LocalGenerator(
static_cast<cmLocalNinjaGenerator*>(target->GetLocalGenerator()))
{
- MacOSXContentGenerator = cm::make_unique<MacOSXContentGeneratorType>(this);
+ for (auto const& fileConfig : target->Makefile->GetGeneratorConfigs()) {
+ this->Configs[fileConfig].MacOSXContentGenerator =
+ cm::make_unique<MacOSXContentGeneratorType>(this, fileConfig);
+ }
}
cmNinjaTargetGenerator::~cmNinjaTargetGenerator() = default;
-cmGeneratedFileStream& cmNinjaTargetGenerator::GetBuildFileStream() const
+cmGeneratedFileStream& cmNinjaTargetGenerator::GetImplFileStream(
+ const std::string& config) const
{
- return *this->GetGlobalGenerator()->GetBuildFileStream();
+ return *this->GetGlobalGenerator()->GetImplFileStream(config);
+}
+
+cmGeneratedFileStream& cmNinjaTargetGenerator::GetCommonFileStream() const
+{
+ return *this->GetGlobalGenerator()->GetCommonFileStream();
}
cmGeneratedFileStream& cmNinjaTargetGenerator::GetRulesFileStream() const
@@ -84,17 +94,21 @@ cmGlobalNinjaGenerator* cmNinjaTargetGenerator::GetGlobalGenerator() const
}
std::string cmNinjaTargetGenerator::LanguageCompilerRule(
- const std::string& lang) const
+ const std::string& lang, const std::string& config) const
{
- return lang + "_COMPILER__" +
- cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName());
+ return cmStrCat(
+ lang, "_COMPILER__",
+ cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()),
+ '_', config);
}
std::string cmNinjaTargetGenerator::LanguagePreprocessRule(
- std::string const& lang) const
+ std::string const& lang, const std::string& config) const
{
- return lang + "_PREPROCESS__" +
- cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName());
+ return cmStrCat(
+ lang, "_PREPROCESS__",
+ cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()),
+ '_', config);
}
bool cmNinjaTargetGenerator::NeedExplicitPreprocessing(
@@ -117,10 +131,12 @@ bool cmNinjaTargetGenerator::CompilePreprocessedSourceWithDefines(
}
std::string cmNinjaTargetGenerator::LanguageDyndepRule(
- const std::string& lang) const
+ const std::string& lang, const std::string& config) const
{
- return lang + "_DYNDEP__" +
- cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName());
+ return cmStrCat(
+ lang, "_DYNDEP__",
+ cmGlobalNinjaGenerator::EncodeRuleName(this->GeneratorTarget->GetName()),
+ '_', config);
}
bool cmNinjaTargetGenerator::NeedDyndep(std::string const& lang) const
@@ -128,9 +144,11 @@ bool cmNinjaTargetGenerator::NeedDyndep(std::string const& lang) const
return lang == "Fortran";
}
-std::string cmNinjaTargetGenerator::OrderDependsTargetForTarget()
+std::string cmNinjaTargetGenerator::OrderDependsTargetForTarget(
+ const std::string& config)
{
- return "cmake_object_order_depends_target_" + this->GetTargetName();
+ return this->GetGlobalGenerator()->OrderDependsTargetForTarget(
+ this->GeneratorTarget, config);
}
// TODO: Most of the code is picked up from
@@ -138,10 +156,29 @@ std::string cmNinjaTargetGenerator::OrderDependsTargetForTarget()
// void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
// Refactor it.
std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
- cmSourceFile const* source, const std::string& language)
+ cmSourceFile const* source, const std::string& language,
+ const std::string& config)
{
- std::string flags = this->GetFlags(language);
- const std::string configName = this->LocalGenerator->GetConfigName();
+ std::vector<std::string> architectures;
+ std::unordered_map<std::string, std::string> pchSources;
+ this->GeneratorTarget->GetAppleArchs(config, architectures);
+ if (architectures.empty()) {
+ architectures.emplace_back();
+ }
+
+ std::string filterArch;
+ for (const std::string& arch : architectures) {
+ const std::string pchSource =
+ this->GeneratorTarget->GetPchSource(config, language, arch);
+ if (pchSource == source->GetFullPath()) {
+ filterArch = arch;
+ }
+ if (!pchSource.empty()) {
+ pchSources.insert(std::make_pair(pchSource, arch));
+ }
+ }
+
+ std::string flags = this->GetFlags(language, config, filterArch);
// Add Fortran format flags.
if (language == "Fortran") {
@@ -150,32 +187,30 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
// Add source file specific flags.
cmGeneratorExpressionInterpreter genexInterpreter(
- this->LocalGenerator, configName, this->GeneratorTarget, language);
+ this->LocalGenerator, config, this->GeneratorTarget, language);
const std::string COMPILE_FLAGS("COMPILE_FLAGS");
- if (const char* cflags = source->GetProperty(COMPILE_FLAGS)) {
+ if (cmProp cflags = source->GetProperty(COMPILE_FLAGS)) {
this->LocalGenerator->AppendFlags(
- flags, genexInterpreter.Evaluate(cflags, COMPILE_FLAGS));
+ flags, genexInterpreter.Evaluate(*cflags, COMPILE_FLAGS));
}
const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
- if (const char* coptions = source->GetProperty(COMPILE_OPTIONS)) {
+ if (cmProp coptions = source->GetProperty(COMPILE_OPTIONS)) {
this->LocalGenerator->AppendCompileOptions(
- flags, genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS));
+ flags, genexInterpreter.Evaluate(*coptions, COMPILE_OPTIONS));
}
// Add precompile headers compile options.
- const std::string pchSource =
- this->GeneratorTarget->GetPchSource(configName, language);
-
- if (!pchSource.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
+ if (!pchSources.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
std::string pchOptions;
- if (source->GetFullPath() == pchSource) {
+ auto pchIt = pchSources.find(source->GetFullPath());
+ if (pchIt != pchSources.end()) {
pchOptions = this->GeneratorTarget->GetPchCreateCompileOptions(
- configName, language);
+ config, language, pchIt->second);
} else {
pchOptions =
- this->GeneratorTarget->GetPchUseCompileOptions(configName, language);
+ this->GeneratorTarget->GetPchUseCompileOptions(config, language);
}
this->LocalGenerator->AppendCompileOptions(
@@ -186,16 +221,17 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
}
void cmNinjaTargetGenerator::AddIncludeFlags(std::string& languageFlags,
- std::string const& language)
+ std::string const& language,
+ const std::string& config)
{
std::vector<std::string> includes;
this->LocalGenerator->GetIncludeDirectories(includes, this->GeneratorTarget,
- language, this->GetConfigName());
+ language, config);
// Add include directory flags.
std::string includeFlags = this->LocalGenerator->GetIncludeFlags(
includes, this->GeneratorTarget, language,
language == "RC", // full include paths for RC needed by cmcldeps
- false, this->GetConfigName());
+ false, config);
if (this->GetGlobalGenerator()->IsGCCOnWindows()) {
std::replace(includeFlags.begin(), includeFlags.end(), '\\', '/');
}
@@ -205,8 +241,8 @@ void cmNinjaTargetGenerator::AddIncludeFlags(std::string& languageFlags,
bool cmNinjaTargetGenerator::NeedDepTypeMSVC(const std::string& lang) const
{
- std::string const& deptype =
- this->GetMakefile()->GetSafeDefinition("CMAKE_NINJA_DEPTYPE_" + lang);
+ std::string const& deptype = this->GetMakefile()->GetSafeDefinition(
+ cmStrCat("CMAKE_NINJA_DEPTYPE_", lang));
if (deptype == "msvc") {
return true;
}
@@ -232,58 +268,63 @@ bool cmNinjaTargetGenerator::NeedDepTypeMSVC(const std::string& lang) const
// TODO: Refactor with
// void cmMakefileTargetGenerator::WriteTargetLanguageFlags().
std::string cmNinjaTargetGenerator::ComputeDefines(cmSourceFile const* source,
- const std::string& language)
+ const std::string& language,
+ const std::string& config)
{
std::set<std::string> defines;
- const std::string config = this->LocalGenerator->GetConfigName();
cmGeneratorExpressionInterpreter genexInterpreter(
this->LocalGenerator, config, this->GeneratorTarget, language);
+ // Seriously??
+ if (this->GetGlobalGenerator()->IsMultiConfig()) {
+ defines.insert(cmStrCat("CMAKE_INTDIR=\"", config, '"'));
+ }
+
const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS");
- if (const char* compile_defs = source->GetProperty(COMPILE_DEFINITIONS)) {
+ if (cmProp compile_defs = source->GetProperty(COMPILE_DEFINITIONS)) {
this->LocalGenerator->AppendDefines(
- defines, genexInterpreter.Evaluate(compile_defs, COMPILE_DEFINITIONS));
+ defines, genexInterpreter.Evaluate(*compile_defs, COMPILE_DEFINITIONS));
}
std::string defPropName =
cmStrCat("COMPILE_DEFINITIONS_", cmSystemTools::UpperCase(config));
- if (const char* config_compile_defs = source->GetProperty(defPropName)) {
+ if (cmProp config_compile_defs = source->GetProperty(defPropName)) {
this->LocalGenerator->AppendDefines(
defines,
- genexInterpreter.Evaluate(config_compile_defs, COMPILE_DEFINITIONS));
+ genexInterpreter.Evaluate(*config_compile_defs, COMPILE_DEFINITIONS));
}
- std::string definesString = this->GetDefines(language);
+ std::string definesString = this->GetDefines(language, config);
this->LocalGenerator->JoinDefines(defines, definesString, language);
return definesString;
}
std::string cmNinjaTargetGenerator::ComputeIncludes(
- cmSourceFile const* source, const std::string& language)
+ cmSourceFile const* source, const std::string& language,
+ const std::string& config)
{
std::vector<std::string> includes;
- const std::string config = this->LocalGenerator->GetConfigName();
cmGeneratorExpressionInterpreter genexInterpreter(
this->LocalGenerator, config, this->GeneratorTarget, language);
const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
- if (const char* cincludes = source->GetProperty(INCLUDE_DIRECTORIES)) {
+ if (cmProp cincludes = source->GetProperty(INCLUDE_DIRECTORIES)) {
this->LocalGenerator->AppendIncludeDirectories(
- includes, genexInterpreter.Evaluate(cincludes, INCLUDE_DIRECTORIES),
+ includes, genexInterpreter.Evaluate(*cincludes, INCLUDE_DIRECTORIES),
*source);
}
std::string includesString = this->LocalGenerator->GetIncludeFlags(
includes, this->GeneratorTarget, language, true, false, config);
this->LocalGenerator->AppendFlags(includesString,
- this->GetIncludes(language));
+ this->GetIncludes(language, config));
return includesString;
}
cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps(
- const std::string& linkLanguage) const
+ const std::string& linkLanguage, const std::string& config) const
{
// Static libraries never depend on other targets for linking.
if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY ||
@@ -292,7 +333,7 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps(
}
cmComputeLinkInformation* cli =
- this->GeneratorTarget->GetLinkInformation(this->GetConfigName());
+ this->GeneratorTarget->GetLinkInformation(config);
if (!cli) {
return cmNinjaDeps();
}
@@ -303,8 +344,7 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps(
// Add a dependency on the link definitions file, if any.
if (cmGeneratorTarget::ModuleDefinitionInfo const* mdi =
- this->GeneratorTarget->GetModuleDefinitionInfo(
- this->GetConfigName())) {
+ this->GeneratorTarget->GetModuleDefinitionInfo(config)) {
for (cmSourceFile const* src : mdi->Sources) {
result.push_back(this->ConvertToNinjaPath(src->GetFullPath()));
}
@@ -312,15 +352,14 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps(
// Add a dependency on user-specified manifest files, if any.
std::vector<cmSourceFile const*> manifest_srcs;
- this->GeneratorTarget->GetManifests(manifest_srcs, this->ConfigName);
+ this->GeneratorTarget->GetManifests(manifest_srcs, config);
for (cmSourceFile const* manifest_src : manifest_srcs) {
result.push_back(this->ConvertToNinjaPath(manifest_src->GetFullPath()));
}
// Add user-specified dependencies.
std::vector<std::string> linkDeps;
- this->GeneratorTarget->GetLinkDepends(linkDeps, this->ConfigName,
- linkLanguage);
+ this->GeneratorTarget->GetLinkDepends(linkDeps, config, linkLanguage);
std::transform(linkDeps.begin(), linkDeps.end(), std::back_inserter(result),
MapToNinjaPath());
@@ -334,21 +373,21 @@ std::string cmNinjaTargetGenerator::GetSourceFilePath(
}
std::string cmNinjaTargetGenerator::GetObjectFilePath(
- cmSourceFile const* source) const
+ cmSourceFile const* source, const std::string& config) const
{
std::string path = this->LocalGenerator->GetHomeRelativeOutputPath();
if (!path.empty()) {
- path += "/";
+ path += '/';
}
std::string const& objectName = this->GeneratorTarget->GetObjectName(source);
- path += this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
- path += "/";
- path += objectName;
+ path += cmStrCat(
+ this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
+ this->GetGlobalGenerator()->ConfigDirectory(config), '/', objectName);
return path;
}
std::string cmNinjaTargetGenerator::GetPreprocessedFilePath(
- cmSourceFile const* source) const
+ cmSourceFile const* source, const std::string& config) const
{
// Choose an extension to compile already-preprocessed source.
std::string ppExt = source->GetExtension();
@@ -371,57 +410,57 @@ std::string cmNinjaTargetGenerator::GetPreprocessedFilePath(
this->GetGlobalGenerator()->GetLanguageOutputExtension(*source);
assert(objName.size() >= objExt.size());
std::string const ppName =
- objName.substr(0, objName.size() - objExt.size()) + "-pp." + ppExt;
+ cmStrCat(objName.substr(0, objName.size() - objExt.size()), "-pp.", ppExt);
std::string path = this->LocalGenerator->GetHomeRelativeOutputPath();
if (!path.empty()) {
- path += "/";
+ path += '/';
}
- path += this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
- path += "/";
- path += ppName;
+ path +=
+ cmStrCat(this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
+ this->GetGlobalGenerator()->ConfigDirectory(config), '/', ppName);
return path;
}
std::string cmNinjaTargetGenerator::GetDyndepFilePath(
- std::string const& lang) const
+ std::string const& lang, const std::string& config) const
{
std::string path = this->LocalGenerator->GetHomeRelativeOutputPath();
if (!path.empty()) {
- path += "/";
+ path += '/';
}
- path += this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
- path += "/";
- path += lang;
- path += ".dd";
+ path += cmStrCat(
+ this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
+ this->GetGlobalGenerator()->ConfigDirectory(config), '/', lang, ".dd");
return path;
}
std::string cmNinjaTargetGenerator::GetTargetDependInfoPath(
- std::string const& lang) const
+ std::string const& lang, const std::string& config) const
{
std::string path =
cmStrCat(this->Makefile->GetCurrentBinaryDirectory(), '/',
this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget),
- '/', lang, "DependInfo.json");
+ this->GetGlobalGenerator()->ConfigDirectory(config), '/', lang,
+ "DependInfo.json");
return path;
}
-std::string cmNinjaTargetGenerator::GetTargetOutputDir() const
+std::string cmNinjaTargetGenerator::GetTargetOutputDir(
+ const std::string& config) const
{
- std::string dir = this->GeneratorTarget->GetDirectory(this->GetConfigName());
+ std::string dir = this->GeneratorTarget->GetDirectory(config);
return ConvertToNinjaPath(dir);
}
std::string cmNinjaTargetGenerator::GetTargetFilePath(
- const std::string& name) const
+ const std::string& name, const std::string& config) const
{
- std::string path = this->GetTargetOutputDir();
+ std::string path = this->GetTargetOutputDir(config);
if (path.empty() || path == ".") {
return name;
}
- path += "/";
- path += name;
+ path += cmStrCat('/', name);
return path;
}
@@ -430,21 +469,21 @@ std::string cmNinjaTargetGenerator::GetTargetName() const
return this->GeneratorTarget->GetName();
}
-bool cmNinjaTargetGenerator::SetMsvcTargetPdbVariable(cmNinjaVars& vars) const
+bool cmNinjaTargetGenerator::SetMsvcTargetPdbVariable(
+ cmNinjaVars& vars, const std::string& config) const
{
cmMakefile* mf = this->GetMakefile();
if (mf->GetDefinition("MSVC_C_ARCHITECTURE_ID") ||
mf->GetDefinition("MSVC_CXX_ARCHITECTURE_ID") ||
mf->GetDefinition("MSVC_CUDA_ARCHITECTURE_ID")) {
std::string pdbPath;
- std::string compilePdbPath = this->ComputeTargetCompilePDB();
+ std::string compilePdbPath = this->ComputeTargetCompilePDB(config);
if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE ||
this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY ||
this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->GeneratorTarget->GetType() == cmStateEnums::MODULE_LIBRARY) {
- pdbPath = cmStrCat(
- this->GeneratorTarget->GetPDBDirectory(this->GetConfigName()), '/',
- this->GeneratorTarget->GetPDBName(this->GetConfigName()));
+ pdbPath = cmStrCat(this->GeneratorTarget->GetPDBDirectory(config), '/',
+ this->GeneratorTarget->GetPDBName(config));
}
vars["TARGET_PDB"] = this->GetLocalGenerator()->ConvertToOutputFormat(
@@ -460,20 +499,22 @@ bool cmNinjaTargetGenerator::SetMsvcTargetPdbVariable(cmNinjaVars& vars) const
return false;
}
-void cmNinjaTargetGenerator::WriteLanguageRules(const std::string& language)
+void cmNinjaTargetGenerator::WriteLanguageRules(const std::string& language,
+ const std::string& config)
{
#ifdef NINJA_GEN_VERBOSE_FILES
this->GetRulesFileStream() << "# Rules for language " << language << "\n\n";
#endif
- this->WriteCompileRule(language);
+ this->WriteCompileRule(language, config);
}
-void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
+void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
+ const std::string& config)
{
cmRulePlaceholderExpander::RuleVariables vars;
vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
vars.CMTargetType =
- cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType());
+ cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType()).c_str();
vars.Language = lang.c_str();
vars.Source = "$in";
vars.Object = "$out";
@@ -498,7 +539,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
bool const lang_supports_response = lang != "RC";
if (lang_supports_response && this->ForceResponseFile()) {
std::string const responseFlagVar =
- "CMAKE_" + lang + "_RESPONSE_FILE_FLAG";
+ cmStrCat("CMAKE_", lang, "_RESPONSE_FILE_FLAG");
responseFlag = this->Makefile->GetSafeDefinition(responseFlagVar);
if (responseFlag.empty() && lang != "CUDA") {
responseFlag = "@";
@@ -509,7 +550,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
this->GetLocalGenerator()->CreateRulePlaceholderExpander());
std::string const tdi = this->GetLocalGenerator()->ConvertToOutputFormat(
- ConvertToNinjaPath(this->GetTargetDependInfoPath(lang)),
+ ConvertToNinjaPath(this->GetTargetDependInfoPath(lang, config)),
cmLocalGenerator::SHELL);
std::string launcher;
@@ -524,7 +565,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
if (explicitPP) {
- cmNinjaRule rule(this->LanguagePreprocessRule(lang));
+ cmNinjaRule rule(this->LanguagePreprocessRule(lang, config));
// Explicit preprocessing always uses a depfile.
rule.DepType = ""; // no deps= for multiple outputs
rule.DepFile = "$DEP_FILE";
@@ -563,7 +604,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
rule.RspFile = "$RSP_FILE";
rule.RspContent =
cmStrCat(' ', ppVars.Defines, ' ', ppVars.Includes, ' ', ppFlags);
- ppFlags = responseFlag + rule.RspFile;
+ ppFlags = cmStrCat(responseFlag, rule.RspFile);
ppVars.Defines = "";
ppVars.Includes = "";
}
@@ -604,7 +645,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
if (needDyndep) {
// Write the rule for ninja dyndep file generation.
- cmNinjaRule rule(this->LanguageDyndepRule(lang));
+ cmNinjaRule rule(this->LanguageDyndepRule(lang, config));
// Command line length is almost always limited -> use response file for
// dyndep rules
rule.RspFile = "$out.rsp";
@@ -628,13 +669,13 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
this->GetGlobalGenerator()->AddRule(rule);
}
- cmNinjaRule rule(this->LanguageCompilerRule(lang));
+ cmNinjaRule rule(this->LanguageCompilerRule(lang, config));
// If using a response file, move defines, includes, and flags into it.
if (!responseFlag.empty()) {
rule.RspFile = "$RSP_FILE";
rule.RspContent =
cmStrCat(' ', vars.Defines, ' ', vars.Includes, ' ', flags);
- flags = responseFlag + rule.RspFile;
+ flags = cmStrCat(responseFlag, rule.RspFile);
vars.Defines = "";
vars.Includes = "";
}
@@ -647,7 +688,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
rule.DepType = "msvc";
rule.DepFile.clear();
flags += " /showIncludes";
- } else if (mf->IsOn("CMAKE_NINJA_CMCLDEPS_" + lang)) {
+ } else if (mf->IsOn(cmStrCat("CMAKE_NINJA_CMCLDEPS_", lang))) {
// For the MS resource compiler we need cmcldeps, but skip dependencies
// for source-file try_compile cases because they are always fresh.
if (!mf->GetIsSourceFileTryCompile()) {
@@ -664,14 +705,14 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
} else {
rule.DepType = "gcc";
rule.DepFile = "$DEP_FILE";
- const std::string flagsName = "CMAKE_DEPFILE_FLAGS_" + lang;
+ const std::string flagsName = cmStrCat("CMAKE_DEPFILE_FLAGS_", lang);
std::string depfileFlags = mf->GetSafeDefinition(flagsName);
if (!depfileFlags.empty()) {
cmSystemTools::ReplaceString(depfileFlags, "<DEPFILE>", "$DEP_FILE");
cmSystemTools::ReplaceString(depfileFlags, "<OBJECT>", "$out");
cmSystemTools::ReplaceString(depfileFlags, "<CMAKE_C_COMPILER>",
mf->GetDefinition("CMAKE_C_COMPILER"));
- flags += " " + depfileFlags;
+ flags += cmStrCat(' ', depfileFlags);
}
}
@@ -694,7 +735,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
const std::string& compileCmd = mf->GetRequiredDefinition(cmdVar);
cmExpandList(compileCmd, compileCmds);
} else {
- const std::string cmdVar = "CMAKE_" + lang + "_COMPILE_OBJECT";
+ const std::string cmdVar = cmStrCat("CMAKE_", lang, "_COMPILE_OBJECT");
const std::string& compileCmd = mf->GetRequiredDefinition(cmdVar);
cmExpandList(compileCmd, compileCmds);
}
@@ -704,51 +745,59 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
if (!compileCmds.empty() &&
(lang == "C" || lang == "CXX" || lang == "Fortran" || lang == "CUDA" ||
lang == "OBJC" || lang == "OBJCXX")) {
- std::string const clauncher_prop = lang + "_COMPILER_LAUNCHER";
- const char* clauncher = this->GeneratorTarget->GetProperty(clauncher_prop);
- if (clauncher && *clauncher) {
- compilerLauncher = clauncher;
+ std::string const clauncher_prop = cmStrCat(lang, "_COMPILER_LAUNCHER");
+ cmProp clauncher = this->GeneratorTarget->GetProperty(clauncher_prop);
+ if (clauncher && !clauncher->empty()) {
+ compilerLauncher = *clauncher;
}
}
// Maybe insert an include-what-you-use runner.
if (!compileCmds.empty() && (lang == "C" || lang == "CXX")) {
- std::string const iwyu_prop = lang + "_INCLUDE_WHAT_YOU_USE";
- const char* iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
- std::string const tidy_prop = lang + "_CLANG_TIDY";
- const char* tidy = this->GeneratorTarget->GetProperty(tidy_prop);
- std::string const cpplint_prop = lang + "_CPPLINT";
- const char* cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
- std::string const cppcheck_prop = lang + "_CPPCHECK";
- const char* cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
- if ((iwyu && *iwyu) || (tidy && *tidy) || (cpplint && *cpplint) ||
- (cppcheck && *cppcheck)) {
+ std::string const iwyu_prop = cmStrCat(lang, "_INCLUDE_WHAT_YOU_USE");
+ cmProp iwyu = this->GeneratorTarget->GetProperty(iwyu_prop);
+ std::string const tidy_prop = cmStrCat(lang, "_CLANG_TIDY");
+ cmProp tidy = this->GeneratorTarget->GetProperty(tidy_prop);
+ std::string const cpplint_prop = cmStrCat(lang, "_CPPLINT");
+ cmProp cpplint = this->GeneratorTarget->GetProperty(cpplint_prop);
+ std::string const cppcheck_prop = cmStrCat(lang, "_CPPCHECK");
+ cmProp cppcheck = this->GeneratorTarget->GetProperty(cppcheck_prop);
+ if ((iwyu && !iwyu->empty()) || (tidy && !tidy->empty()) ||
+ (cpplint && !cpplint->empty()) || (cppcheck && !cppcheck->empty())) {
std::string run_iwyu = cmStrCat(cmakeCmd, " -E __run_co_compile");
if (!compilerLauncher.empty()) {
// In __run_co_compile case the launcher command is supplied
// via --launcher=<maybe-list> and consumed
- run_iwyu += " --launcher=";
- run_iwyu += this->LocalGenerator->EscapeForShell(compilerLauncher);
+ run_iwyu +=
+ cmStrCat(" --launcher=",
+ this->LocalGenerator->EscapeForShell(compilerLauncher));
compilerLauncher.clear();
}
- if (iwyu && *iwyu) {
- run_iwyu += " --iwyu=";
- run_iwyu += this->GetLocalGenerator()->EscapeForShell(iwyu);
+ if (iwyu && !iwyu->empty()) {
+ run_iwyu += cmStrCat(" --iwyu=",
+ this->GetLocalGenerator()->EscapeForShell(*iwyu));
}
- if (tidy && *tidy) {
+ if (tidy && !tidy->empty()) {
run_iwyu += " --tidy=";
- run_iwyu += this->GetLocalGenerator()->EscapeForShell(tidy);
+ const char* driverMode = this->Makefile->GetDefinition(
+ cmStrCat("CMAKE_", lang, "_CLANG_TIDY_DRIVER_MODE"));
+ if (!(driverMode && *driverMode)) {
+ driverMode = lang == "C" ? "gcc" : "g++";
+ }
+ run_iwyu += this->GetLocalGenerator()->EscapeForShell(
+ cmStrCat(*tidy, ";--extra-arg-before=--driver-mode=", driverMode));
}
- if (cpplint && *cpplint) {
- run_iwyu += " --cpplint=";
- run_iwyu += this->GetLocalGenerator()->EscapeForShell(cpplint);
+ if (cpplint && !cpplint->empty()) {
+ run_iwyu += cmStrCat(
+ " --cpplint=", this->GetLocalGenerator()->EscapeForShell(*cpplint));
}
- if (cppcheck && *cppcheck) {
- run_iwyu += " --cppcheck=";
- run_iwyu += this->GetLocalGenerator()->EscapeForShell(cppcheck);
+ if (cppcheck && !cppcheck->empty()) {
+ run_iwyu +=
+ cmStrCat(" --cppcheck=",
+ this->GetLocalGenerator()->EscapeForShell(*cppcheck));
}
- if ((tidy && *tidy) || (cpplint && *cpplint) ||
- (cppcheck && *cppcheck)) {
+ if ((tidy && !tidy->empty()) || (cpplint && !cpplint->empty()) ||
+ (cppcheck && !cppcheck->empty())) {
run_iwyu += " --source=$in";
}
run_iwyu += " -- ";
@@ -767,7 +816,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
i = this->LocalGenerator->EscapeForShell(i);
}
}
- compileCmds.front().insert(0, cmJoin(args, " ") + " ");
+ compileCmds.front().insert(0, cmStrCat(cmJoin(args, " "), ' '));
}
if (!compileCmds.empty()) {
@@ -788,70 +837,75 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
this->GetGlobalGenerator()->AddRule(rule);
}
-void cmNinjaTargetGenerator::WriteObjectBuildStatements()
+void cmNinjaTargetGenerator::WriteObjectBuildStatements(
+ const std::string& config, const std::string& fileConfig,
+ bool firstForConfig)
{
// Write comments.
- cmGlobalNinjaGenerator::WriteDivider(this->GetBuildFileStream());
- this->GetBuildFileStream()
+ cmGlobalNinjaGenerator::WriteDivider(this->GetImplFileStream(fileConfig));
+ this->GetImplFileStream(fileConfig)
<< "# Object build statements for "
<< cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType())
<< " target " << this->GetTargetName() << "\n\n";
{
std::vector<cmSourceFile const*> customCommands;
- this->GeneratorTarget->GetCustomCommands(customCommands, this->ConfigName);
+ this->GeneratorTarget->GetCustomCommands(customCommands, config);
for (cmSourceFile const* sf : customCommands) {
cmCustomCommand const* cc = sf->GetCustomCommand();
this->GetLocalGenerator()->AddCustomCommandTarget(
cc, this->GetGeneratorTarget());
// Record the custom commands for this target. The container is used
// in WriteObjectBuildStatement when called in a loop below.
- this->CustomCommands.push_back(cc);
+ this->Configs[config].CustomCommands.push_back(cc);
}
}
{
std::vector<cmSourceFile const*> headerSources;
- this->GeneratorTarget->GetHeaderSources(headerSources, this->ConfigName);
+ this->GeneratorTarget->GetHeaderSources(headerSources, config);
this->OSXBundleGenerator->GenerateMacOSXContentStatements(
- headerSources, this->MacOSXContentGenerator.get());
+ headerSources, this->Configs[fileConfig].MacOSXContentGenerator.get(),
+ config);
}
{
std::vector<cmSourceFile const*> extraSources;
- this->GeneratorTarget->GetExtraSources(extraSources, this->ConfigName);
+ this->GeneratorTarget->GetExtraSources(extraSources, config);
this->OSXBundleGenerator->GenerateMacOSXContentStatements(
- extraSources, this->MacOSXContentGenerator.get());
+ extraSources, this->Configs[fileConfig].MacOSXContentGenerator.get(),
+ config);
}
- {
+ if (firstForConfig) {
const char* pchExtension =
GetMakefile()->GetDefinition("CMAKE_PCH_EXTENSION");
std::vector<cmSourceFile const*> externalObjects;
- this->GeneratorTarget->GetExternalObjects(externalObjects,
- this->ConfigName);
+ this->GeneratorTarget->GetExternalObjects(externalObjects, config);
for (cmSourceFile const* sf : externalObjects) {
- const auto objectFileName = this->GetSourceFilePath(sf);
+ auto objectFileName = this->GetGlobalGenerator()->ExpandCFGIntDir(
+ this->GetSourceFilePath(sf), config);
if (!cmSystemTools::StringEndsWith(objectFileName, pchExtension)) {
- this->Objects.push_back(objectFileName);
+ this->Configs[config].Objects.push_back(objectFileName);
}
}
}
{
cmNinjaBuild build("phony");
- build.Comment = "Order-only phony target for " + this->GetTargetName();
- build.Outputs.push_back(this->OrderDependsTargetForTarget());
+ build.Comment =
+ cmStrCat("Order-only phony target for ", this->GetTargetName());
+ build.Outputs.push_back(this->OrderDependsTargetForTarget(config));
cmNinjaDeps& orderOnlyDeps = build.OrderOnlyDeps;
this->GetLocalGenerator()->AppendTargetDepends(
- this->GeneratorTarget, orderOnlyDeps, DependOnTargetOrdering);
+ this->GeneratorTarget, orderOnlyDeps, config, fileConfig,
+ DependOnTargetOrdering);
// Add order-only dependencies on other files associated with the target.
- cmAppend(orderOnlyDeps, this->ExtraFiles);
+ cm::append(orderOnlyDeps, this->Configs[config].ExtraFiles);
// Add order-only dependencies on custom command outputs.
- for (cmCustomCommand const* cc : this->CustomCommands) {
- cmCustomCommandGenerator ccg(*cc, this->GetConfigName(),
- this->GetLocalGenerator());
+ for (cmCustomCommand const* cc : this->Configs[config].CustomCommands) {
+ cmCustomCommandGenerator ccg(*cc, config, this->GetLocalGenerator());
const std::vector<std::string>& ccoutputs = ccg.GetOutputs();
const std::vector<std::string>& ccbyproducts = ccg.GetByproducts();
std::transform(ccoutputs.begin(), ccoutputs.end(),
@@ -877,26 +931,27 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements()
orderOnlyDeps.push_back(this->ConvertToNinjaPath(tgtDir));
}
- this->GetGlobalGenerator()->WriteBuild(this->GetBuildFileStream(), build);
+ this->GetGlobalGenerator()->WriteBuild(this->GetImplFileStream(fileConfig),
+ build);
}
{
std::vector<cmSourceFile const*> objectSources;
- this->GeneratorTarget->GetObjectSources(objectSources, this->ConfigName);
+ this->GeneratorTarget->GetObjectSources(objectSources, config);
for (cmSourceFile const* sf : objectSources) {
- this->WriteObjectBuildStatement(sf);
+ this->WriteObjectBuildStatement(sf, config, fileConfig, firstForConfig);
}
}
- for (auto const& langDDIFiles : this->DDIFiles) {
+ for (auto const& langDDIFiles : this->Configs[config].DDIFiles) {
std::string const& language = langDDIFiles.first;
cmNinjaDeps const& ddiFiles = langDDIFiles.second;
- cmNinjaBuild build(this->LanguageDyndepRule(language));
- build.Outputs.push_back(this->GetDyndepFilePath(language));
+ cmNinjaBuild build(this->LanguageDyndepRule(language, config));
+ build.Outputs.push_back(this->GetDyndepFilePath(language, config));
build.ExplicitDeps = ddiFiles;
- this->WriteTargetDependInfo(language);
+ this->WriteTargetDependInfo(language, config);
// Make sure dyndep files for all our dependencies have already
// been generated so that the '<LANG>Modules.json' files they
@@ -907,53 +962,59 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements()
// refactoring the Ninja generator to generate targets in
// dependency order so that we can collect the needed information.
this->GetLocalGenerator()->AppendTargetDepends(
- this->GeneratorTarget, build.OrderOnlyDeps, DependOnTargetArtifact);
+ this->GeneratorTarget, build.OrderOnlyDeps, config, fileConfig,
+ DependOnTargetArtifact);
- this->GetGlobalGenerator()->WriteBuild(this->GetBuildFileStream(), build);
+ this->GetGlobalGenerator()->WriteBuild(this->GetImplFileStream(fileConfig),
+ build);
}
- this->GetBuildFileStream() << "\n";
+ this->GetImplFileStream(fileConfig) << "\n";
- if (!this->SwiftOutputMap.empty()) {
+ if (!this->Configs[config].SwiftOutputMap.empty()) {
std::string const mapFilePath =
- this->GeneratorTarget->GetSupportDirectory() + "/output-file-map.json";
- std::string const targetSwiftDepsPath = [this]() -> std::string {
+ cmStrCat(this->GeneratorTarget->GetSupportDirectory(), '/', config, '/',
+ "output-file-map.json");
+ std::string const targetSwiftDepsPath = [this, config]() -> std::string {
cmGeneratorTarget const* target = this->GeneratorTarget;
- if (const char* name = target->GetProperty("Swift_DEPENDENCIES_FILE")) {
- return name;
+ if (cmProp name = target->GetProperty("Swift_DEPENDENCIES_FILE")) {
+ return *name;
}
- return this->ConvertToNinjaPath(target->GetSupportDirectory() + "/" +
- target->GetName() + ".swiftdeps");
+ return this->ConvertToNinjaPath(
+ cmStrCat(target->GetSupportDirectory(), '/', config, '/',
+ target->GetName(), ".swiftdeps"));
}();
// build the global target dependencies
// https://github.com/apple/swift/blob/master/docs/Driver.md#output-file-maps
Json::Value deps(Json::objectValue);
deps["swift-dependencies"] = targetSwiftDepsPath;
- this->SwiftOutputMap[""] = deps;
+ this->Configs[config].SwiftOutputMap[""] = deps;
cmGeneratedFileStream output(mapFilePath);
- output << this->SwiftOutputMap;
+ output << this->Configs[config].SwiftOutputMap;
}
}
void cmNinjaTargetGenerator::WriteObjectBuildStatement(
- cmSourceFile const* source)
+ cmSourceFile const* source, const std::string& config,
+ const std::string& fileConfig, bool firstForConfig)
{
std::string const language = source->GetLanguage();
std::string const sourceFileName =
language == "RC" ? source->GetFullPath() : this->GetSourceFilePath(source);
- std::string const objectDir =
- this->ConvertToNinjaPath(this->GeneratorTarget->GetSupportDirectory());
+ std::string const objectDir = this->ConvertToNinjaPath(
+ cmStrCat(this->GeneratorTarget->GetSupportDirectory(),
+ this->GetGlobalGenerator()->ConfigDirectory(config)));
std::string const objectFileName =
- this->ConvertToNinjaPath(this->GetObjectFilePath(source));
+ this->ConvertToNinjaPath(this->GetObjectFilePath(source, config));
std::string const objectFileDir =
cmSystemTools::GetFilenamePath(objectFileName);
std::string cmakeVarLang = cmStrCat("CMAKE_", language);
// build response file name
- std::string cmakeLinkVar = cmakeVarLang + "_RESPONSE_FILE_FLAG";
+ std::string cmakeLinkVar = cmStrCat(cmakeVarLang, "_RESPONSE_FILE_FLAG");
const char* flag = GetMakefile()->GetDefinition(cmakeLinkVar);
@@ -962,11 +1023,11 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
int const commandLineLengthLimit =
((lang_supports_response && this->ForceResponseFile())) ? -1 : 0;
- cmNinjaBuild objBuild(this->LanguageCompilerRule(language));
+ cmNinjaBuild objBuild(this->LanguageCompilerRule(language, config));
cmNinjaVars& vars = objBuild.Variables;
- vars["FLAGS"] = this->ComputeFlagsForObject(source, language);
- vars["DEFINES"] = this->ComputeDefines(source, language);
- vars["INCLUDES"] = this->ComputeIncludes(source, language);
+ vars["FLAGS"] = this->ComputeFlagsForObject(source, language, config);
+ vars["DEFINES"] = this->ComputeDefines(source, language, config);
+ vars["INCLUDES"] = this->ComputeIncludes(source, language, config);
if (!this->NeedDepTypeMSVC(language)) {
bool replaceExt(false);
@@ -978,14 +1039,15 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
if (!replaceExt) {
// use original code
vars["DEP_FILE"] = this->GetLocalGenerator()->ConvertToOutputFormat(
- objectFileName + ".d", cmOutputConverter::SHELL);
+ cmStrCat(objectFileName, ".d"), cmOutputConverter::SHELL);
} else {
// Replace the original source file extension with the
// depend file extension.
- std::string dependFileName =
- cmSystemTools::GetFilenameWithoutLastExtension(objectFileName) + ".d";
+ std::string dependFileName = cmStrCat(
+ cmSystemTools::GetFilenameWithoutLastExtension(objectFileName), ".d");
vars["DEP_FILE"] = this->GetLocalGenerator()->ConvertToOutputFormat(
- objectFileDir + "/" + dependFileName, cmOutputConverter::SHELL);
+ cmStrCat(objectFileDir, '/', dependFileName),
+ cmOutputConverter::SHELL);
}
}
@@ -994,11 +1056,13 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
vars["FLAGS"], vars["DEFINES"], vars["INCLUDES"]);
objBuild.Outputs.push_back(objectFileName);
- const char* pchExtension =
- this->GetMakefile()->GetDefinition("CMAKE_PCH_EXTENSION");
- if (!cmSystemTools::StringEndsWith(objectFileName, pchExtension)) {
- // Add this object to the list of object files.
- this->Objects.push_back(objectFileName);
+ if (firstForConfig) {
+ const char* pchExtension =
+ this->GetMakefile()->GetDefinition("CMAKE_PCH_EXTENSION");
+ if (!cmSystemTools::StringEndsWith(objectFileName, pchExtension)) {
+ // Add this object to the list of object files.
+ this->Configs[config].Objects.push_back(objectFileName);
+ }
}
objBuild.ExplicitDeps.push_back(sourceFileName);
@@ -1006,19 +1070,35 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
// Add precompile headers dependencies
std::vector<std::string> depList;
- const std::string pchSource =
- this->GeneratorTarget->GetPchSource(this->GetConfigName(), language);
- if (!pchSource.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
- depList.push_back(
- this->GeneratorTarget->GetPchHeader(this->GetConfigName(), language));
- if (source->GetFullPath() != pchSource) {
+ std::vector<std::string> architectures;
+ this->GeneratorTarget->GetAppleArchs(config, architectures);
+ if (architectures.empty()) {
+ architectures.emplace_back();
+ }
+
+ std::unordered_set<std::string> pchSources;
+ for (const std::string& arch : architectures) {
+ const std::string pchSource =
+ this->GeneratorTarget->GetPchSource(config, language, arch);
+
+ if (!pchSource.empty()) {
+ pchSources.insert(pchSource);
+ }
+ }
+
+ if (!pchSources.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
+ for (const std::string& arch : architectures) {
depList.push_back(
- this->GeneratorTarget->GetPchFile(this->GetConfigName(), language));
+ this->GeneratorTarget->GetPchHeader(config, language, arch));
+ if (pchSources.find(source->GetFullPath()) == pchSources.end()) {
+ depList.push_back(
+ this->GeneratorTarget->GetPchFile(config, language, arch));
+ }
}
}
- if (const char* objectDeps = source->GetProperty("OBJECT_DEPENDS")) {
- std::vector<std::string> objDepList = cmExpandedList(objectDeps);
+ if (cmProp objectDeps = source->GetProperty("OBJECT_DEPENDS")) {
+ std::vector<std::string> objDepList = cmExpandedList(*objectDeps);
std::copy(objDepList.begin(), objDepList.end(),
std::back_inserter(depList));
}
@@ -1034,7 +1114,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
MapToNinjaPath());
}
- objBuild.OrderOnlyDeps.push_back(this->OrderDependsTargetForTarget());
+ objBuild.OrderOnlyDeps.push_back(this->OrderDependsTargetForTarget(config));
// If the source file is GENERATED and does not have a custom command
// (either attached to this source file or another one), assume that one of
@@ -1054,13 +1134,13 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
// For some cases we do an explicit preprocessor invocation.
bool const explicitPP = this->NeedExplicitPreprocessing(language);
if (explicitPP) {
- cmNinjaBuild ppBuild(this->LanguagePreprocessRule(language));
+ cmNinjaBuild ppBuild(this->LanguagePreprocessRule(language, config));
std::string const ppFileName =
- this->ConvertToNinjaPath(this->GetPreprocessedFilePath(source));
+ this->ConvertToNinjaPath(this->GetPreprocessedFilePath(source, config));
ppBuild.Outputs.push_back(ppFileName);
- ppBuild.RspFile = ppFileName + ".rsp";
+ ppBuild.RspFile = cmStrCat(ppFileName, ".rsp");
bool const compilePP = this->UsePreprocessedSource(language);
bool const compilePPWithDefines =
@@ -1089,7 +1169,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
// In case compilation requires flags that are incompatible with
// preprocessing, include them here.
std::string const& postFlag = this->Makefile->GetSafeDefinition(
- "CMAKE_" + language + "_POSTPROCESS_FLAG");
+ cmStrCat("CMAKE_", language, "_POSTPROCESS_FLAG"));
this->LocalGenerator->AppendFlags(vars["FLAGS"], postFlag);
}
@@ -1115,15 +1195,15 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
std::string sourceDirectoryFlag = this->LocalGenerator->GetIncludeFlags(
sourceDirectory, this->GeneratorTarget, language, false, false,
- this->GetConfigName());
+ config);
- vars["INCLUDES"] = sourceDirectoryFlag + " " + vars["INCLUDES"];
+ vars["INCLUDES"] = cmStrCat(sourceDirectoryFlag, ' ', vars["INCLUDES"]);
}
// Explicit preprocessing always uses a depfile.
ppBuild.Variables["DEP_FILE"] =
this->GetLocalGenerator()->ConvertToOutputFormat(
- objectFileName + ".pp.d", cmOutputConverter::SHELL);
+ cmStrCat(objectFileName, ".pp.d"), cmOutputConverter::SHELL);
if (compilePP) {
// The actual compilation does not need a depfile because it
// depends on the already-preprocessed source.
@@ -1136,20 +1216,22 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
ppBuild.Variables["OBJ_FILE"] = objectFileName;
// Tell dependency scanner where to store dyndep intermediate results.
- std::string const ddiFile = objectFileName + ".ddi";
+ std::string const ddiFile = cmStrCat(objectFileName, ".ddi");
ppBuild.Variables["DYNDEP_INTERMEDIATE_FILE"] = ddiFile;
ppBuild.ImplicitOuts.push_back(ddiFile);
- this->DDIFiles[language].push_back(ddiFile);
+ if (firstForConfig) {
+ this->Configs[config].DDIFiles[language].push_back(ddiFile);
+ }
}
this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetGeneratorTarget(),
ppBuild.Variables);
- this->GetGlobalGenerator()->WriteBuild(this->GetBuildFileStream(), ppBuild,
- commandLineLengthLimit);
+ this->GetGlobalGenerator()->WriteBuild(this->GetImplFileStream(fileConfig),
+ ppBuild, commandLineLengthLimit);
}
if (needDyndep) {
- std::string const dyndep = this->GetDyndepFilePath(language);
+ std::string const dyndep = this->GetDyndepFilePath(language, config);
objBuild.OrderOnlyDeps.push_back(dyndep);
vars["dyndep"] = dyndep;
}
@@ -1164,34 +1246,44 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetGeneratorTarget(),
vars);
- this->SetMsvcTargetPdbVariable(vars);
+ if (!pchSources.empty() && !source->GetProperty("SKIP_PRECOMPILE_HEADERS")) {
+ auto pchIt = pchSources.find(source->GetFullPath());
+ if (pchIt != pchSources.end()) {
+ this->addPoolNinjaVariable("JOB_POOL_PRECOMPILE_HEADER",
+ this->GetGeneratorTarget(), vars);
+ }
+ }
+
+ this->SetMsvcTargetPdbVariable(vars, config);
- objBuild.RspFile = objectFileName + ".rsp";
+ objBuild.RspFile = cmStrCat(objectFileName, ".rsp");
if (language == "Swift") {
- this->EmitSwiftDependencyInfo(source);
+ this->EmitSwiftDependencyInfo(source, config);
} else {
- this->GetGlobalGenerator()->WriteBuild(this->GetBuildFileStream(),
+ this->GetGlobalGenerator()->WriteBuild(this->GetImplFileStream(fileConfig),
objBuild, commandLineLengthLimit);
}
- if (const char* objectOutputs = source->GetProperty("OBJECT_OUTPUTS")) {
+ if (cmProp objectOutputs = source->GetProperty("OBJECT_OUTPUTS")) {
cmNinjaBuild build("phony");
build.Comment = "Additional output files.";
- build.Outputs = cmExpandedList(objectOutputs);
+ build.Outputs = cmExpandedList(*objectOutputs);
std::transform(build.Outputs.begin(), build.Outputs.end(),
build.Outputs.begin(), MapToNinjaPath());
build.ExplicitDeps = objBuild.Outputs;
- this->GetGlobalGenerator()->WriteBuild(this->GetBuildFileStream(), build);
+ this->GetGlobalGenerator()->WriteBuild(this->GetImplFileStream(fileConfig),
+ build);
}
}
-void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang)
+void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang,
+ const std::string& config)
{
Json::Value tdi(Json::objectValue);
tdi["language"] = lang;
- tdi["compiler-id"] =
- this->Makefile->GetSafeDefinition("CMAKE_" + lang + "_COMPILER_ID");
+ tdi["compiler-id"] = this->Makefile->GetSafeDefinition(
+ cmStrCat("CMAKE_", lang, "_COMPILER_ID"));
if (lang == "Fortran") {
std::string mod_dir = this->GeneratorTarget->GetFortranModuleDirectory(
@@ -1214,7 +1306,7 @@ void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang)
Json::Value& tdi_include_dirs = tdi["include-dirs"] = Json::arrayValue;
std::vector<std::string> includes;
this->LocalGenerator->GetIncludeDirectories(includes, this->GeneratorTarget,
- lang, this->GetConfigName());
+ lang, config);
for (std::string const& i : includes) {
// Convert the include directories the same way we do for -I flags.
// See upstream ninja issue 1251.
@@ -1223,48 +1315,49 @@ void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang)
Json::Value& tdi_linked_target_dirs = tdi["linked-target-dirs"] =
Json::arrayValue;
- for (std::string const& l : this->GetLinkedTargetDirectories()) {
+ for (std::string const& l : this->GetLinkedTargetDirectories(config)) {
tdi_linked_target_dirs.append(l);
}
- std::string const tdin = this->GetTargetDependInfoPath(lang);
+ std::string const tdin = this->GetTargetDependInfoPath(lang, config);
cmGeneratedFileStream tdif(tdin);
tdif << tdi;
}
void cmNinjaTargetGenerator::EmitSwiftDependencyInfo(
- cmSourceFile const* source)
+ cmSourceFile const* source, const std::string& config)
{
std::string const sourceFilePath =
this->ConvertToNinjaPath(this->GetSourceFilePath(source));
std::string const objectFilePath =
- this->ConvertToNinjaPath(this->GetObjectFilePath(source));
+ this->ConvertToNinjaPath(this->GetObjectFilePath(source, config));
std::string const swiftDepsPath = [source, objectFilePath]() -> std::string {
- if (const char* name = source->GetProperty("Swift_DEPENDENCIES_FILE")) {
- return name;
+ if (cmProp name = source->GetProperty("Swift_DEPENDENCIES_FILE")) {
+ return *name;
}
- return objectFilePath + ".swiftdeps";
+ return cmStrCat(objectFilePath, ".swiftdeps");
}();
std::string const swiftDiaPath = [source, objectFilePath]() -> std::string {
- if (const char* name = source->GetProperty("Swift_DIAGNOSTICS_FILE")) {
- return name;
+ if (cmProp name = source->GetProperty("Swift_DIAGNOSTICS_FILE")) {
+ return *name;
}
- return objectFilePath + ".dia";
+ return cmStrCat(objectFilePath, ".dia");
}();
- std::string const makeDepsPath = [this, source]() -> std::string {
+ std::string const makeDepsPath = [this, source, config]() -> std::string {
cmLocalNinjaGenerator const* local = this->GetLocalGenerator();
std::string const objectFileName =
- this->ConvertToNinjaPath(this->GetObjectFilePath(source));
+ this->ConvertToNinjaPath(this->GetObjectFilePath(source, config));
std::string const objectFileDir =
cmSystemTools::GetFilenamePath(objectFileName);
if (this->Makefile->IsOn("CMAKE_Swift_DEPFLE_EXTNSION_REPLACE")) {
- std::string dependFileName =
- cmSystemTools::GetFilenameWithoutLastExtension(objectFileName) + ".d";
- return local->ConvertToOutputFormat(objectFileDir + "/" + dependFileName,
- cmOutputConverter::SHELL);
+ std::string dependFileName = cmStrCat(
+ cmSystemTools::GetFilenameWithoutLastExtension(objectFileName), ".d");
+ return local->ConvertToOutputFormat(
+ cmStrCat(objectFileDir, '/', dependFileName),
+ cmOutputConverter::SHELL);
}
- return local->ConvertToOutputFormat(objectFileName + ".d",
+ return local->ConvertToOutputFormat(cmStrCat(objectFileName, ".d"),
cmOutputConverter::SHELL);
}();
@@ -1275,7 +1368,7 @@ void cmNinjaTargetGenerator::EmitSwiftDependencyInfo(
entry["dependencies"] = makeDepsPath;
entry["swift-dependencies"] = swiftDepsPath;
entry["diagnostics"] = swiftDiaPath;
- SwiftOutputMap[sourceFilePath] = entry;
+ this->Configs[config].SwiftOutputMap[sourceFilePath] = entry;
}
void cmNinjaTargetGenerator::ExportObjectCompileCommand(
@@ -1329,7 +1422,7 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand(
this->GetMakefile()->GetRequiredDefinition(cmdVar);
cmExpandList(compileCmd, compileCmds);
} else {
- const std::string cmdVar = "CMAKE_" + language + "_COMPILE_OBJECT";
+ const std::string cmdVar = cmStrCat("CMAKE_", language, "_COMPILE_OBJECT");
const std::string& compileCmd =
this->GetMakefile()->GetRequiredDefinition(cmdVar);
cmExpandList(compileCmd, compileCmds);
@@ -1350,27 +1443,34 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand(
this->GetGlobalGenerator()->AddCXXCompileCommand(cmdLine, sourceFileName);
}
-void cmNinjaTargetGenerator::AdditionalCleanFiles()
+void cmNinjaTargetGenerator::AdditionalCleanFiles(const std::string& config)
{
- if (const char* prop_value =
+ if (cmProp prop_value =
this->GeneratorTarget->GetProperty("ADDITIONAL_CLEAN_FILES")) {
cmLocalNinjaGenerator* lg = this->LocalGenerator;
std::vector<std::string> cleanFiles;
- cmExpandList(cmGeneratorExpression::Evaluate(
- prop_value, lg,
- this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"),
- this->GeneratorTarget),
+ cmExpandList(cmGeneratorExpression::Evaluate(*prop_value, lg, config,
+ this->GeneratorTarget),
cleanFiles);
std::string const& binaryDir = lg->GetCurrentBinaryDirectory();
cmGlobalNinjaGenerator* gg = lg->GetGlobalNinjaGenerator();
for (std::string const& cleanFile : cleanFiles) {
// Support relative paths
gg->AddAdditionalCleanFile(
- cmSystemTools::CollapseFullPath(cleanFile, binaryDir));
+ cmSystemTools::CollapseFullPath(cleanFile, binaryDir), config);
}
}
}
+cmNinjaDeps cmNinjaTargetGenerator::GetObjects(const std::string& config) const
+{
+ auto const it = this->Configs.find(config);
+ if (it != this->Configs.end()) {
+ return it->second.Objects;
+ }
+ return {};
+}
+
void cmNinjaTargetGenerator::EnsureDirectoryExists(
const std::string& path) const
{
@@ -1393,7 +1493,7 @@ void cmNinjaTargetGenerator::EnsureParentDirectoryExists(
}
void cmNinjaTargetGenerator::MacOSXContentGeneratorType::operator()(
- cmSourceFile const& source, const char* pkgloc)
+ cmSourceFile const& source, const char* pkgloc, const std::string& config)
{
// Skip OS X content when not building a Framework or Bundle.
if (!this->Generator->GetGeneratorTarget()->IsBundleOnApple()) {
@@ -1401,7 +1501,18 @@ void cmNinjaTargetGenerator::MacOSXContentGeneratorType::operator()(
}
std::string macdir =
- this->Generator->OSXBundleGenerator->InitMacOSXContentDirectory(pkgloc);
+ this->Generator->OSXBundleGenerator->InitMacOSXContentDirectory(pkgloc,
+ config);
+
+ // Reject files that collide with files from the Ninja file's native config.
+ if (config != this->FileConfig) {
+ std::string nativeMacdir =
+ this->Generator->OSXBundleGenerator->InitMacOSXContentDirectory(
+ pkgloc, this->FileConfig);
+ if (macdir == nativeMacdir) {
+ return;
+ }
+ }
// Get the input file location.
std::string input = source.GetFullPath();
@@ -1413,20 +1524,20 @@ void cmNinjaTargetGenerator::MacOSXContentGeneratorType::operator()(
output = this->Generator->GetGlobalGenerator()->ConvertToNinjaPath(output);
// Write a build statement to copy the content into the bundle.
- this->Generator->GetGlobalGenerator()->WriteMacOSXContentBuild(input,
- output);
+ this->Generator->GetGlobalGenerator()->WriteMacOSXContentBuild(
+ input, output, this->FileConfig);
// Add as a dependency to the target so that it gets called.
- this->Generator->ExtraFiles.push_back(std::move(output));
+ this->Generator->Configs[config].ExtraFiles.push_back(std::move(output));
}
void cmNinjaTargetGenerator::addPoolNinjaVariable(
const std::string& pool_property, cmGeneratorTarget* target,
cmNinjaVars& vars)
{
- const char* pool = target->GetProperty(pool_property);
+ cmProp pool = target->GetProperty(pool_property);
if (pool) {
- vars["pool"] = pool;
+ vars["pool"] = *pool;
}
}
diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h
index 4627bcd..1ac5683 100644
--- a/Source/cmNinjaTargetGenerator.h
+++ b/Source/cmNinjaTargetGenerator.h
@@ -9,9 +9,10 @@
#include <memory>
#include <set>
#include <string>
+#include <utility>
#include <vector>
-#include "cm_jsoncpp_value.h"
+#include <cm3p/json/value.h>
#include "cmCommonTargetGenerator.h"
#include "cmGlobalNinjaGenerator.h"
@@ -38,16 +39,17 @@ public:
/// Destructor.
~cmNinjaTargetGenerator() override;
- virtual void Generate() = 0;
+ virtual void Generate(const std::string& config) = 0;
std::string GetTargetName() const;
bool NeedDepTypeMSVC(const std::string& lang) const;
protected:
- bool SetMsvcTargetPdbVariable(cmNinjaVars&) const;
+ bool SetMsvcTargetPdbVariable(cmNinjaVars&, const std::string& config) const;
- cmGeneratedFileStream& GetBuildFileStream() const;
+ cmGeneratedFileStream& GetImplFileStream(const std::string& config) const;
+ cmGeneratedFileStream& GetCommonFileStream() const;
cmGeneratedFileStream& GetRulesFileStream() const;
cmGeneratorTarget* GetGeneratorTarget() const
@@ -64,15 +66,18 @@ protected:
cmMakefile* GetMakefile() const { return this->Makefile; }
- std::string LanguageCompilerRule(const std::string& lang) const;
- std::string LanguagePreprocessRule(std::string const& lang) const;
+ std::string LanguageCompilerRule(const std::string& lang,
+ const std::string& config) const;
+ std::string LanguagePreprocessRule(std::string const& lang,
+ const std::string& config) const;
bool NeedExplicitPreprocessing(std::string const& lang) const;
- std::string LanguageDyndepRule(std::string const& lang) const;
+ std::string LanguageDyndepRule(std::string const& lang,
+ const std::string& config) const;
bool NeedDyndep(std::string const& lang) const;
bool UsePreprocessedSource(std::string const& lang) const;
bool CompilePreprocessedSourceWithDefines(std::string const& lang) const;
- std::string OrderDependsTargetForTarget();
+ std::string OrderDependsTargetForTarget(const std::string& config);
std::string ComputeOrderDependsForTarget();
@@ -82,15 +87,19 @@ protected:
* by LanguageFlagsVarName().
*/
std::string ComputeFlagsForObject(cmSourceFile const* source,
- const std::string& language);
+ const std::string& language,
+ const std::string& config);
- void AddIncludeFlags(std::string& flags, std::string const& lang) override;
+ void AddIncludeFlags(std::string& flags, std::string const& lang,
+ const std::string& config) override;
std::string ComputeDefines(cmSourceFile const* source,
- const std::string& language);
+ const std::string& language,
+ const std::string& config);
std::string ComputeIncludes(cmSourceFile const* source,
- const std::string& language);
+ const std::string& language,
+ const std::string& config);
std::string ConvertToNinjaPath(const std::string& path) const
{
@@ -102,36 +111,51 @@ protected:
}
/// @return the list of link dependency for the given target @a target.
- cmNinjaDeps ComputeLinkDeps(const std::string& linkLanguage) const;
+ cmNinjaDeps ComputeLinkDeps(const std::string& linkLanguage,
+ const std::string& config) const;
/// @return the source file path for the given @a source.
std::string GetSourceFilePath(cmSourceFile const* source) const;
/// @return the object file path for the given @a source.
- std::string GetObjectFilePath(cmSourceFile const* source) const;
+ std::string GetObjectFilePath(cmSourceFile const* source,
+ const std::string& config) const;
/// @return the preprocessed source file path for the given @a source.
- std::string GetPreprocessedFilePath(cmSourceFile const* source) const;
+ std::string GetPreprocessedFilePath(cmSourceFile const* source,
+ const std::string& config) const;
/// @return the dyndep file path for this target.
- std::string GetDyndepFilePath(std::string const& lang) const;
+ std::string GetDyndepFilePath(std::string const& lang,
+ const std::string& config) const;
/// @return the target dependency scanner info file path
- std::string GetTargetDependInfoPath(std::string const& lang) const;
+ std::string GetTargetDependInfoPath(std::string const& lang,
+ const std::string& config) const;
/// @return the file path where the target named @a name is generated.
- std::string GetTargetFilePath(const std::string& name) const;
+ std::string GetTargetFilePath(const std::string& name,
+ const std::string& config) const;
/// @return the output path for the target.
- virtual std::string GetTargetOutputDir() const;
-
- void WriteLanguageRules(const std::string& language);
- void WriteCompileRule(const std::string& language);
- void WriteObjectBuildStatements();
- void WriteObjectBuildStatement(cmSourceFile const* source);
- void WriteTargetDependInfo(std::string const& lang);
-
- void EmitSwiftDependencyInfo(cmSourceFile const* source);
+ virtual std::string GetTargetOutputDir(const std::string& config) const;
+
+ void WriteLanguageRules(const std::string& language,
+ const std::string& config);
+ void WriteCompileRule(const std::string& language,
+ const std::string& config);
+ void WriteObjectBuildStatements(const std::string& config,
+ const std::string& fileConfig,
+ bool firstForConfig);
+ void WriteObjectBuildStatement(cmSourceFile const* source,
+ const std::string& config,
+ const std::string& fileConfig,
+ bool firstForConfig);
+ void WriteTargetDependInfo(std::string const& lang,
+ const std::string& config);
+
+ void EmitSwiftDependencyInfo(cmSourceFile const* source,
+ const std::string& config);
void ExportObjectCompileCommand(
std::string const& language, std::string const& sourceFileName,
@@ -139,9 +163,9 @@ protected:
std::string const& objectFileDir, std::string const& flags,
std::string const& defines, std::string const& includes);
- void AdditionalCleanFiles();
+ void AdditionalCleanFiles(const std::string& config);
- cmNinjaDeps GetObjects() const { return this->Objects; }
+ cmNinjaDeps GetObjects(const std::string& config) const;
void EnsureDirectoryExists(const std::string& dir) const;
void EnsureParentDirectoryExists(const std::string& path) const;
@@ -150,19 +174,22 @@ protected:
struct MacOSXContentGeneratorType
: cmOSXBundleGenerator::MacOSXContentGeneratorType
{
- MacOSXContentGeneratorType(cmNinjaTargetGenerator* g)
+ MacOSXContentGeneratorType(cmNinjaTargetGenerator* g,
+ std::string fileConfig)
: Generator(g)
+ , FileConfig(std::move(fileConfig))
{
}
- void operator()(cmSourceFile const& source, const char* pkgloc) override;
+ void operator()(cmSourceFile const& source, const char* pkgloc,
+ const std::string& config) override;
private:
cmNinjaTargetGenerator* Generator;
+ std::string FileConfig;
};
friend struct MacOSXContentGeneratorType;
- std::unique_ptr<MacOSXContentGeneratorType> MacOSXContentGenerator;
// Properly initialized by sub-classes.
std::unique_ptr<cmOSXBundleGenerator> OSXBundleGenerator;
std::set<std::string> MacContentFolders;
@@ -174,14 +201,21 @@ protected:
private:
cmLocalNinjaGenerator* LocalGenerator;
- /// List of object files for this target.
- cmNinjaDeps Objects;
- // Fortran Support
- std::map<std::string, cmNinjaDeps> DDIFiles;
- // Swift Support
- Json::Value SwiftOutputMap;
- std::vector<cmCustomCommand const*> CustomCommands;
- cmNinjaDeps ExtraFiles;
+
+ struct ByConfig
+ {
+ /// List of object files for this target.
+ cmNinjaDeps Objects;
+ // Fortran Support
+ std::map<std::string, cmNinjaDeps> DDIFiles;
+ // Swift Support
+ Json::Value SwiftOutputMap;
+ std::vector<cmCustomCommand const*> CustomCommands;
+ cmNinjaDeps ExtraFiles;
+ std::unique_ptr<MacOSXContentGeneratorType> MacOSXContentGenerator;
+ };
+
+ std::map<std::string, ByConfig> Configs;
};
#endif // ! cmNinjaTargetGenerator_h
diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx
index 5259037..134924e 100644
--- a/Source/cmNinjaUtilityTargetGenerator.cxx
+++ b/Source/cmNinjaUtilityTargetGenerator.cxx
@@ -15,13 +15,13 @@
#include "cmGeneratorTarget.h"
#include "cmGlobalNinjaGenerator.h"
#include "cmLocalNinjaGenerator.h"
-#include "cmMakefile.h"
#include "cmNinjaTypes.h"
#include "cmOutputConverter.h"
#include "cmSourceFile.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmTarget.h"
cmNinjaUtilityTargetGenerator::cmNinjaUtilityTargetGenerator(
cmGeneratorTarget* target)
@@ -31,14 +31,18 @@ cmNinjaUtilityTargetGenerator::cmNinjaUtilityTargetGenerator(
cmNinjaUtilityTargetGenerator::~cmNinjaUtilityTargetGenerator() = default;
-void cmNinjaUtilityTargetGenerator::Generate()
+void cmNinjaUtilityTargetGenerator::Generate(const std::string& config)
{
cmGlobalNinjaGenerator* gg = this->GetGlobalGenerator();
cmLocalNinjaGenerator* lg = this->GetLocalGenerator();
cmGeneratorTarget* genTarget = this->GetGeneratorTarget();
+ std::string configDir;
+ if (genTarget->Target->IsPerConfig()) {
+ configDir = gg->ConfigDirectory(config);
+ }
std::string utilCommandName =
- cmStrCat(lg->GetCurrentBinaryDirectory(), "/CMakeFiles/",
+ cmStrCat(lg->GetCurrentBinaryDirectory(), "/CMakeFiles", configDir, "/",
this->GetTargetName(), ".util");
utilCommandName = this->ConvertToNinjaPath(utilCommandName);
@@ -55,8 +59,8 @@ void cmNinjaUtilityTargetGenerator::Generate()
for (std::vector<cmCustomCommand> const* cmdList : cmdLists) {
for (cmCustomCommand const& ci : *cmdList) {
- cmCustomCommandGenerator ccg(ci, this->GetConfigName(), lg);
- lg->AppendCustomCommandDeps(ccg, deps);
+ cmCustomCommandGenerator ccg(ci, config, lg);
+ lg->AppendCustomCommandDeps(ccg, deps, config);
lg->AppendCustomCommandLines(ccg, commands);
std::vector<std::string> const& ccByproducts = ccg.GetByproducts();
std::transform(ccByproducts.begin(), ccByproducts.end(),
@@ -69,13 +73,11 @@ void cmNinjaUtilityTargetGenerator::Generate()
}
{
- std::string const& config =
- this->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE");
std::vector<cmSourceFile*> sources;
genTarget->GetSourceFiles(sources, config);
for (cmSourceFile const* source : sources) {
if (cmCustomCommand const* cc = source->GetCustomCommand()) {
- cmCustomCommandGenerator ccg(*cc, this->GetConfigName(), lg);
+ cmCustomCommandGenerator ccg(*cc, config, lg);
lg->AddCustomCommandTarget(cc, genTarget);
// Depend on all custom command outputs.
@@ -89,20 +91,28 @@ void cmNinjaUtilityTargetGenerator::Generate()
}
}
- lg->AppendTargetOutputs(genTarget, phonyBuild.Outputs);
- lg->AppendTargetDepends(genTarget, deps);
+ std::string outputConfig;
+ if (genTarget->Target->IsPerConfig()) {
+ outputConfig = config;
+ }
+ lg->AppendTargetOutputs(genTarget, phonyBuild.Outputs, outputConfig);
+ if (genTarget->Target->GetType() != cmStateEnums::GLOBAL_TARGET) {
+ lg->AppendTargetOutputs(genTarget, gg->GetByproductsForCleanTarget(),
+ config);
+ }
+ lg->AppendTargetDepends(genTarget, deps, config, config);
if (commands.empty()) {
phonyBuild.Comment = "Utility command for " + this->GetTargetName();
phonyBuild.ExplicitDeps = std::move(deps);
- gg->WriteBuild(this->GetBuildFileStream(), phonyBuild);
+ gg->WriteBuild(this->GetCommonFileStream(), phonyBuild);
} else {
std::string command =
lg->BuildCommandLine(commands, "utility", this->GeneratorTarget);
std::string desc;
- const char* echoStr = genTarget->GetProperty("EchoString");
+ cmProp echoStr = genTarget->GetProperty("EchoString");
if (echoStr) {
- desc = echoStr;
+ desc = *echoStr;
} else {
desc = "Running utility command for " + this->GetTargetName();
}
@@ -118,6 +128,7 @@ void cmNinjaUtilityTargetGenerator::Generate()
lg->ConvertToOutputFormat(lg->GetBinaryDirectory(),
cmOutputConverter::SHELL));
cmSystemTools::ReplaceString(command, "$(ARGS)", "");
+ command = gg->ExpandCFGIntDir(command, config);
if (command.find('$') != std::string::npos) {
return;
@@ -127,22 +138,32 @@ void cmNinjaUtilityTargetGenerator::Generate()
gg->SeenCustomCommandOutput(util_output);
}
+ std::string ccConfig;
+ if (genTarget->Target->IsPerConfig() &&
+ genTarget->GetType() != cmStateEnums::GLOBAL_TARGET) {
+ ccConfig = config;
+ }
gg->WriteCustomCommandBuild(command, desc,
"Utility command for " + this->GetTargetName(),
/*depfile*/ "", /*job_pool*/ "", uses_terminal,
- /*restat*/ true, util_outputs, deps);
+ /*restat*/ true, util_outputs, ccConfig, deps);
phonyBuild.ExplicitDeps.push_back(utilCommandName);
- gg->WriteBuild(this->GetBuildFileStream(), phonyBuild);
+ gg->WriteBuild(this->GetCommonFileStream(), phonyBuild);
}
// Find ADDITIONAL_CLEAN_FILES
- this->AdditionalCleanFiles();
+ this->AdditionalCleanFiles(config);
// Add an alias for the logical target name regardless of what directory
// contains it. Skip this for GLOBAL_TARGET because they are meant to
// be per-directory and have one at the top-level anyway.
if (genTarget->GetType() != cmStateEnums::GLOBAL_TARGET) {
- gg->AddTargetAlias(this->GetTargetName(), genTarget);
+ gg->AddTargetAlias(this->GetTargetName(), genTarget, config);
+ } else if (gg->IsMultiConfig() && genTarget->Target->IsPerConfig()) {
+ cmNinjaBuild phonyAlias("phony");
+ gg->AppendTargetOutputs(genTarget, phonyAlias.Outputs, "");
+ phonyAlias.ExplicitDeps = phonyBuild.Outputs;
+ gg->WriteBuild(this->GetImplFileStream(config), phonyAlias);
}
}
diff --git a/Source/cmNinjaUtilityTargetGenerator.h b/Source/cmNinjaUtilityTargetGenerator.h
index 01cc459..ca3f0a4 100644
--- a/Source/cmNinjaUtilityTargetGenerator.h
+++ b/Source/cmNinjaUtilityTargetGenerator.h
@@ -5,6 +5,8 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <string>
+
#include "cmNinjaTargetGenerator.h"
class cmGeneratorTarget;
@@ -15,7 +17,7 @@ public:
cmNinjaUtilityTargetGenerator(cmGeneratorTarget* target);
~cmNinjaUtilityTargetGenerator() override;
- void Generate() override;
+ void Generate(const std::string& config) override;
};
#endif // ! cmNinjaUtilityTargetGenerator_h
diff --git a/Source/cmOSXBundleGenerator.cxx b/Source/cmOSXBundleGenerator.cxx
index a6f4e51..7eea4b2 100644
--- a/Source/cmOSXBundleGenerator.cxx
+++ b/Source/cmOSXBundleGenerator.cxx
@@ -3,7 +3,6 @@
#include "cmOSXBundleGenerator.h"
#include <cassert>
-#include <utility>
#include "cmGeneratorTarget.h"
#include "cmLocalGenerator.h"
@@ -15,12 +14,10 @@
class cmSourceFile;
-cmOSXBundleGenerator::cmOSXBundleGenerator(cmGeneratorTarget* target,
- std::string configName)
+cmOSXBundleGenerator::cmOSXBundleGenerator(cmGeneratorTarget* target)
: GT(target)
, Makefile(target->Target->GetMakefile())
, LocalGenerator(target->GetLocalGenerator())
- , ConfigName(std::move(configName))
, MacContentFolders(nullptr)
{
if (this->MustSkip()) {
@@ -34,34 +31,34 @@ bool cmOSXBundleGenerator::MustSkip()
}
void cmOSXBundleGenerator::CreateAppBundle(const std::string& targetName,
- std::string& outpath)
+ std::string& outpath,
+ const std::string& config)
{
if (this->MustSkip()) {
return;
}
// Compute bundle directory names.
- std::string out =
- cmStrCat(outpath, '/',
- this->GT->GetAppBundleDirectory(this->ConfigName,
- cmGeneratorTarget::FullLevel));
+ std::string out = cmStrCat(
+ outpath, '/',
+ this->GT->GetAppBundleDirectory(config, cmGeneratorTarget::FullLevel));
cmSystemTools::MakeDirectory(out);
this->Makefile->AddCMakeOutputFile(out);
// Configure the Info.plist file. Note that it needs the executable name
// to be set.
- std::string plist =
- cmStrCat(outpath, '/',
- this->GT->GetAppBundleDirectory(this->ConfigName,
- cmGeneratorTarget::ContentLevel),
- "/Info.plist");
+ std::string plist = cmStrCat(
+ outpath, '/',
+ this->GT->GetAppBundleDirectory(config, cmGeneratorTarget::ContentLevel),
+ "/Info.plist");
this->LocalGenerator->GenerateAppleInfoPList(this->GT, targetName, plist);
this->Makefile->AddCMakeOutputFile(plist);
outpath = out;
}
-void cmOSXBundleGenerator::CreateFramework(const std::string& targetName,
- const std::string& outpath)
+void cmOSXBundleGenerator::CreateFramework(
+ const std::string& targetName, const std::string& outpath,
+ const std::string& config, const cmOSXBundleGenerator::SkipParts& skipParts)
{
if (this->MustSkip()) {
return;
@@ -70,28 +67,28 @@ void cmOSXBundleGenerator::CreateFramework(const std::string& targetName,
assert(this->MacContentFolders);
// Compute the location of the top-level foo.framework directory.
- std::string contentdir =
- cmStrCat(outpath, '/',
- this->GT->GetFrameworkDirectory(this->ConfigName,
- cmGeneratorTarget::ContentLevel),
- '/');
+ std::string contentdir = cmStrCat(
+ outpath, '/',
+ this->GT->GetFrameworkDirectory(config, cmGeneratorTarget::ContentLevel),
+ '/');
std::string newoutpath = outpath + "/" +
- this->GT->GetFrameworkDirectory(this->ConfigName,
- cmGeneratorTarget::FullLevel);
+ this->GT->GetFrameworkDirectory(config, cmGeneratorTarget::FullLevel);
std::string frameworkVersion = this->GT->GetFrameworkVersion();
- // Configure the Info.plist file
- std::string plist = newoutpath;
- if (!this->Makefile->PlatformIsAppleEmbedded()) {
- // Put the Info.plist file into the Resources directory.
- this->MacContentFolders->insert("Resources");
- plist += "/Resources";
- }
- plist += "/Info.plist";
std::string name = cmSystemTools::GetFilenameName(targetName);
- this->LocalGenerator->GenerateFrameworkInfoPList(this->GT, name, plist);
+ if (!skipParts.infoPlist) {
+ // Configure the Info.plist file
+ std::string plist = newoutpath;
+ if (!this->Makefile->PlatformIsAppleEmbedded()) {
+ // Put the Info.plist file into the Resources directory.
+ this->MacContentFolders->insert("Resources");
+ plist += "/Resources";
+ }
+ plist += "/Info.plist";
+ this->LocalGenerator->GenerateFrameworkInfoPList(this->GT, name, plist);
+ }
// Generate Versions directory only for MacOSX frameworks
if (this->Makefile->PlatformIsAppleEmbedded()) {
@@ -156,27 +153,26 @@ void cmOSXBundleGenerator::CreateFramework(const std::string& targetName,
}
void cmOSXBundleGenerator::CreateCFBundle(const std::string& targetName,
- const std::string& root)
+ const std::string& root,
+ const std::string& config)
{
if (this->MustSkip()) {
return;
}
// Compute bundle directory names.
- std::string out =
- cmStrCat(root, '/',
- this->GT->GetCFBundleDirectory(this->ConfigName,
- cmGeneratorTarget::FullLevel));
+ std::string out = cmStrCat(
+ root, '/',
+ this->GT->GetCFBundleDirectory(config, cmGeneratorTarget::FullLevel));
cmSystemTools::MakeDirectory(out);
this->Makefile->AddCMakeOutputFile(out);
// Configure the Info.plist file. Note that it needs the executable name
// to be set.
- std::string plist =
- cmStrCat(root, '/',
- this->GT->GetCFBundleDirectory(this->ConfigName,
- cmGeneratorTarget::ContentLevel),
- "/Info.plist");
+ std::string plist = cmStrCat(
+ root, '/',
+ this->GT->GetCFBundleDirectory(config, cmGeneratorTarget::ContentLevel),
+ "/Info.plist");
std::string name = cmSystemTools::GetFilenameName(targetName);
this->LocalGenerator->GenerateAppleInfoPList(this->GT, name, plist);
this->Makefile->AddCMakeOutputFile(plist);
@@ -184,7 +180,7 @@ void cmOSXBundleGenerator::CreateCFBundle(const std::string& targetName,
void cmOSXBundleGenerator::GenerateMacOSXContentStatements(
std::vector<cmSourceFile const*> const& sources,
- MacOSXContentGeneratorType* generator)
+ MacOSXContentGeneratorType* generator, const std::string& config)
{
if (this->MustSkip()) {
return;
@@ -194,20 +190,19 @@ void cmOSXBundleGenerator::GenerateMacOSXContentStatements(
cmGeneratorTarget::SourceFileFlags tsFlags =
this->GT->GetTargetSourceFileFlags(source);
if (tsFlags.Type != cmGeneratorTarget::SourceFileTypeNormal) {
- (*generator)(*source, tsFlags.MacFolder);
+ (*generator)(*source, tsFlags.MacFolder, config);
}
}
}
std::string cmOSXBundleGenerator::InitMacOSXContentDirectory(
- const char* pkgloc)
+ const char* pkgloc, const std::string& config)
{
// Construct the full path to the content subdirectory.
- std::string macdir =
- cmStrCat(this->GT->GetMacContentDirectory(
- this->ConfigName, cmStateEnums::RuntimeBinaryArtifact),
- '/', pkgloc);
+ std::string macdir = cmStrCat(this->GT->GetMacContentDirectory(
+ config, cmStateEnums::RuntimeBinaryArtifact),
+ '/', pkgloc);
cmSystemTools::MakeDirectory(macdir);
// Record use of this content location. Only the first level
diff --git a/Source/cmOSXBundleGenerator.h b/Source/cmOSXBundleGenerator.h
index 3dea6cc..5bf1d98 100644
--- a/Source/cmOSXBundleGenerator.h
+++ b/Source/cmOSXBundleGenerator.h
@@ -17,29 +17,43 @@ class cmSourceFile;
class cmOSXBundleGenerator
{
public:
- cmOSXBundleGenerator(cmGeneratorTarget* target, std::string configName);
+ cmOSXBundleGenerator(cmGeneratorTarget* target);
+
+ struct SkipParts
+ {
+ SkipParts()
+ : infoPlist(false)
+ {
+ }
+ bool infoPlist; // NOLINT(modernize-use-default-member-init)
+ };
// create an app bundle at a given root, and return
// the directory within the bundle that contains the executable
- void CreateAppBundle(const std::string& targetName, std::string& root);
+ void CreateAppBundle(const std::string& targetName, std::string& root,
+ const std::string& config);
// create a framework at a given root
- void CreateFramework(const std::string& targetName, const std::string& root);
+ void CreateFramework(const std::string& targetName, const std::string& root,
+ const std::string& config,
+ const SkipParts& skipParts = SkipParts());
// create a cf bundle at a given root
- void CreateCFBundle(const std::string& targetName, const std::string& root);
+ void CreateCFBundle(const std::string& targetName, const std::string& root,
+ const std::string& config);
struct MacOSXContentGeneratorType
{
virtual ~MacOSXContentGeneratorType() = default;
- virtual void operator()(cmSourceFile const& source,
- const char* pkgloc) = 0;
+ virtual void operator()(cmSourceFile const& source, const char* pkgloc,
+ const std::string& config) = 0;
};
void GenerateMacOSXContentStatements(
std::vector<cmSourceFile const*> const& sources,
- MacOSXContentGeneratorType* generator);
- std::string InitMacOSXContentDirectory(const char* pkgloc);
+ MacOSXContentGeneratorType* generator, const std::string& config);
+ std::string InitMacOSXContentDirectory(const char* pkgloc,
+ const std::string& config);
void SetMacContentFolders(std::set<std::string>* macContentFolders)
{
@@ -53,7 +67,6 @@ private:
cmGeneratorTarget* GT;
cmMakefile* Makefile;
cmLocalGenerator* LocalGenerator;
- std::string ConfigName;
std::set<std::string>* MacContentFolders;
};
diff --git a/Source/cmOptionCommand.cxx b/Source/cmOptionCommand.cxx
index 22e59ac..a9adf99 100644
--- a/Source/cmOptionCommand.cxx
+++ b/Source/cmOptionCommand.cxx
@@ -52,7 +52,7 @@ bool cmOptionCommand(std::vector<std::string> const& args,
// See if a cache variable with this name already exists
// If so just make sure the doc state is correct
cmState* state = status.GetMakefile().GetState();
- const char* existingValue = state->GetCacheEntryValue(args[0]);
+ cmProp existingValue = state->GetCacheEntryValue(args[0]);
if (existingValue &&
(state->GetCacheEntryType(args[0]) != cmStateEnums::UNINITIALIZED)) {
state->SetCacheEntryProperty(args[0], "HELPSTRING", args[1]);
@@ -60,7 +60,7 @@ bool cmOptionCommand(std::vector<std::string> const& args,
}
// Nothing in the cache so add it
- std::string initialValue = existingValue ? existingValue : "Off";
+ std::string initialValue = existingValue ? *existingValue : "Off";
if (args.size() == 3) {
initialValue = args[2];
}
diff --git a/Source/cmOrderDirectories.cxx b/Source/cmOrderDirectories.cxx
index 073222c..0369af0 100644
--- a/Source/cmOrderDirectories.cxx
+++ b/Source/cmOrderDirectories.cxx
@@ -8,7 +8,9 @@
#include <sstream>
#include <vector>
-#include "cmAlgorithms.h"
+#include <cm/memory>
+#include <cmext/algorithm>
+
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmMessageType.h"
@@ -248,11 +250,7 @@ cmOrderDirectories::cmOrderDirectories(cmGlobalGenerator* gg,
this->Computed = false;
}
-cmOrderDirectories::~cmOrderDirectories()
-{
- cmDeleteAll(this->ConstraintEntries);
- cmDeleteAll(this->ImplicitDirEntries);
-}
+cmOrderDirectories::~cmOrderDirectories() = default;
std::vector<std::string> const& cmOrderDirectories::GetOrderedDirectories()
{
@@ -286,14 +284,16 @@ void cmOrderDirectories::AddRuntimeLibrary(std::string const& fullPath,
if (this->IsImplicitDirectory(dir)) {
this->ImplicitDirEntries.push_back(
- new cmOrderDirectoriesConstraintSOName(this, fullPath, soname));
+ cm::make_unique<cmOrderDirectoriesConstraintSOName>(this, fullPath,
+ soname));
return;
}
}
// Construct the runtime information entry for this library.
this->ConstraintEntries.push_back(
- new cmOrderDirectoriesConstraintSOName(this, fullPath, soname));
+ cm::make_unique<cmOrderDirectoriesConstraintSOName>(this, fullPath,
+ soname));
} else {
// This can happen if the same library is linked multiple times.
// In that case the runtime information check need be done only
@@ -314,27 +314,28 @@ void cmOrderDirectories::AddLinkLibrary(std::string const& fullPath)
std::string dir = cmSystemTools::GetFilenamePath(fullPath);
if (this->IsImplicitDirectory(dir)) {
this->ImplicitDirEntries.push_back(
- new cmOrderDirectoriesConstraintLibrary(this, fullPath));
+ cm::make_unique<cmOrderDirectoriesConstraintLibrary>(this,
+ fullPath));
return;
}
}
// Construct the link library entry.
this->ConstraintEntries.push_back(
- new cmOrderDirectoriesConstraintLibrary(this, fullPath));
+ cm::make_unique<cmOrderDirectoriesConstraintLibrary>(this, fullPath));
}
}
void cmOrderDirectories::AddUserDirectories(
std::vector<std::string> const& extra)
{
- cmAppend(this->UserDirectories, extra);
+ cm::append(this->UserDirectories, extra);
}
void cmOrderDirectories::AddLanguageDirectories(
std::vector<std::string> const& dirs)
{
- cmAppend(this->LanguageDirectories, dirs);
+ cm::append(this->LanguageDirectories, dirs);
}
void cmOrderDirectories::SetImplicitDirectories(
@@ -369,7 +370,7 @@ void cmOrderDirectories::CollectOriginalDirectories()
this->AddOriginalDirectories(this->UserDirectories);
// Add directories containing constraints.
- for (cmOrderDirectoriesConstraint* entry : this->ConstraintEntries) {
+ for (const auto& entry : this->ConstraintEntries) {
entry->AddDirectory();
}
@@ -454,7 +455,7 @@ void cmOrderDirectories::FindImplicitConflicts()
// Check for items in implicit link directories that have conflicts
// in the explicit directories.
std::ostringstream conflicts;
- for (cmOrderDirectoriesConstraint* entry : this->ImplicitDirEntries) {
+ for (const auto& entry : this->ImplicitDirEntries) {
entry->FindImplicitConflicts(conflicts);
}
diff --git a/Source/cmOrderDirectories.h b/Source/cmOrderDirectories.h
index 23c5145..8ce53e0 100644
--- a/Source/cmOrderDirectories.h
+++ b/Source/cmOrderDirectories.h
@@ -6,6 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <map>
+#include <memory>
#include <set>
#include <string>
#include <utility>
@@ -46,8 +47,9 @@ private:
std::vector<std::string> OrderedDirectories;
- std::vector<cmOrderDirectoriesConstraint*> ConstraintEntries;
- std::vector<cmOrderDirectoriesConstraint*> ImplicitDirEntries;
+ std::vector<std::unique_ptr<cmOrderDirectoriesConstraint>> ConstraintEntries;
+ std::vector<std::unique_ptr<cmOrderDirectoriesConstraint>>
+ ImplicitDirEntries;
std::vector<std::string> UserDirectories;
std::vector<std::string> LanguageDirectories;
cmsys::RegularExpression RemoveLibraryExtension;
diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx
index e602a6d..dc324cc 100644
--- a/Source/cmOutputConverter.cxx
+++ b/Source/cmOutputConverter.cxx
@@ -26,7 +26,7 @@ std::string cmOutputConverter::ConvertToOutputForExisting(
// already exists, we can use a short-path to reference it without a
// space.
if (this->GetState()->UseWindowsShell() &&
- remote.find(' ') != std::string::npos &&
+ remote.find_first_of(" #") != std::string::npos &&
cmSystemTools::FileExists(remote)) {
std::string tmp;
if (cmSystemTools::GetShortPath(remote, tmp)) {
@@ -43,9 +43,10 @@ std::string cmOutputConverter::ConvertToOutputFormat(cm::string_view source,
{
std::string result(source);
// Convert it to an output path.
- if (output == SHELL || output == WATCOMQUOTE) {
+ if (output == SHELL || output == WATCOMQUOTE || output == NINJAMULTI) {
result = this->ConvertDirectorySeparatorsForShell(source);
- result = this->EscapeForShell(result, true, false, output == WATCOMQUOTE);
+ result = this->EscapeForShell(result, true, false, output == WATCOMQUOTE,
+ output == NINJAMULTI);
} else if (output == RESPONSE) {
result = this->EscapeForShell(result, false, false, false);
}
@@ -79,9 +80,9 @@ static bool cmOutputConverterIsShellOperator(cm::string_view str)
return (shellOperators.count(str) != 0);
}
-std::string cmOutputConverter::EscapeForShell(cm::string_view str,
- bool makeVars, bool forEcho,
- bool useWatcomQuote) const
+std::string cmOutputConverter::EscapeForShell(
+ cm::string_view str, bool makeVars, bool forEcho, bool useWatcomQuote,
+ bool unescapeNinjaConfiguration) const
{
// Do not escape shell operators.
if (cmOutputConverterIsShellOperator(str)) {
@@ -95,6 +96,9 @@ std::string cmOutputConverter::EscapeForShell(cm::string_view str,
} else if (!this->LinkScriptShell) {
flags |= Shell_Flag_Make;
}
+ if (unescapeNinjaConfiguration) {
+ flags |= Shell_Flag_UnescapeNinjaConfiguration;
+ }
if (makeVars) {
flags |= Shell_Flag_AllowMakeVariables;
}
@@ -166,15 +170,6 @@ cmOutputConverter::FortranFormat cmOutputConverter::GetFortranFormat(
return format;
}
-cmOutputConverter::FortranFormat cmOutputConverter::GetFortranFormat(
- const char* value)
-{
- if (!value) {
- return FortranFormatNone;
- }
- return GetFortranFormat(cm::string_view(value));
-}
-
void cmOutputConverter::SetLinkScriptShell(bool linkScriptShell)
{
this->LinkScriptShell = linkScriptShell;
@@ -511,5 +506,14 @@ std::string cmOutputConverter::Shell__GetArgument(cm::string_view in,
}
}
+ if (flags & Shell_Flag_UnescapeNinjaConfiguration) {
+ std::string ninjaConfigReplace;
+ if (flags & Shell_Flag_IsUnix) {
+ ninjaConfigReplace += '\\';
+ }
+ ninjaConfigReplace += "$${CONFIGURATION}";
+ cmSystemTools::ReplaceString(out, ninjaConfigReplace, "${CONFIGURATION}");
+ }
+
return out;
}
diff --git a/Source/cmOutputConverter.h b/Source/cmOutputConverter.h
index 349a069..28582df 100644
--- a/Source/cmOutputConverter.h
+++ b/Source/cmOutputConverter.h
@@ -22,6 +22,7 @@ public:
{
SHELL,
WATCOMQUOTE,
+ NINJAMULTI,
RESPONSE
};
std::string ConvertToOutputFormat(cm::string_view source,
@@ -70,12 +71,14 @@ public:
/** The target shell quoting uses extra single Quotes for Watcom tools. */
Shell_Flag_WatcomQuote = (1 << 7),
- Shell_Flag_IsUnix = (1 << 8)
+ Shell_Flag_IsUnix = (1 << 8),
+
+ Shell_Flag_UnescapeNinjaConfiguration = (1 << 9),
};
std::string EscapeForShell(cm::string_view str, bool makeVars = false,
- bool forEcho = false,
- bool useWatcomQuote = false) const;
+ bool forEcho = false, bool useWatcomQuote = false,
+ bool unescapeNinjaConfiguration = false) const;
static std::string EscapeForCMake(cm::string_view str);
@@ -91,7 +94,6 @@ public:
FortranFormatFree
};
static FortranFormat GetFortranFormat(cm::string_view value);
- static FortranFormat GetFortranFormat(const char* value);
private:
cmState* GetState() const;
diff --git a/Source/cmOutputRequiredFilesCommand.cxx b/Source/cmOutputRequiredFilesCommand.cxx
index e093be0..b18c205 100644
--- a/Source/cmOutputRequiredFilesCommand.cxx
+++ b/Source/cmOutputRequiredFilesCommand.cxx
@@ -7,10 +7,11 @@
#include <set>
#include <utility>
+#include <cm/memory>
+
#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmMakefile.h"
@@ -19,6 +20,8 @@
#include "cmSystemTools.h"
#include "cmTarget.h"
+using cmProp = const std::string*;
+
namespace {
/** \class cmDependInformation
* \brief Store dependency information for a single source file.
@@ -94,7 +97,7 @@ public:
/**
* Destructor.
*/
- ~cmLBDepend() { cmDeleteAll(this->DependInformationMap); }
+ ~cmLBDepend() = default;
cmLBDepend(const cmLBDepend&) = delete;
cmLBDepend& operator=(const cmLBDepend&) = delete;
@@ -116,14 +119,13 @@ public:
std::set<std::string> uniqueIncludes;
std::vector<std::string> orderedAndUniqueIncludes;
for (auto const& target : this->Makefile->GetTargets()) {
- const char* incDirProp =
- target.second.GetProperty("INCLUDE_DIRECTORIES");
+ cmProp incDirProp = target.second.GetProperty("INCLUDE_DIRECTORIES");
if (!incDirProp) {
continue;
}
std::string incDirs = cmGeneratorExpression::Preprocess(
- incDirProp, cmGeneratorExpression::StripAllGeneratorExpressions);
+ *incDirProp, cmGeneratorExpression::StripAllGeneratorExpressions);
std::vector<std::string> includes = cmExpandedList(incDirs);
@@ -152,9 +154,9 @@ public:
* Generate dependencies for the file given. Returns a pointer to
* the cmDependInformation object for the file.
*/
- const cmDependInformation* FindDependencies(const char* file)
+ const cmDependInformation* FindDependencies(const std::string& file)
{
- cmDependInformation* info = this->GetDependInformation(file, nullptr);
+ cmDependInformation* info = this->GetDependInformation(file, "");
this->GenerateDependInformation(info);
return info;
}
@@ -203,7 +205,7 @@ protected:
}
// Add this file and all its dependencies.
- this->AddDependency(info, includeFile.c_str());
+ this->AddDependency(info, includeFile);
/// add the cxx file if it exists
std::string cxxFile = includeFile;
std::string::size_type pos = cxxFile.rfind('.');
@@ -254,7 +256,7 @@ protected:
}
}
if (found) {
- this->AddDependency(info, cxxFile.c_str());
+ this->AddDependency(info, cxxFile);
}
}
}
@@ -264,10 +266,10 @@ protected:
/**
* Add a dependency. Possibly walk it for more dependencies.
*/
- void AddDependency(cmDependInformation* info, const char* file)
+ void AddDependency(cmDependInformation* info, const std::string& file)
{
cmDependInformation* dependInfo =
- this->GetDependInformation(file, info->PathOnly.c_str());
+ this->GetDependInformation(file, info->PathOnly);
this->GenerateDependInformation(dependInfo);
info->AddDependencies(dependInfo);
}
@@ -313,7 +315,7 @@ protected:
// Dependency hints have been given. Use them to begin the
// recursion.
for (std::string const& file : cFile.GetDepends()) {
- this->AddDependency(info, file.c_str());
+ this->AddDependency(info, file);
}
// Found dependency information. We are done.
@@ -361,8 +363,8 @@ protected:
* Get an instance of cmDependInformation corresponding to the given file
* name.
*/
- cmDependInformation* GetDependInformation(const char* file,
- const char* extraPath)
+ cmDependInformation* GetDependInformation(const std::string& file,
+ const std::string& extraPath)
{
// Get the full path for the file so that lookup is unambiguous.
std::string fullPath = this->FullPath(file, extraPath);
@@ -371,15 +373,16 @@ protected:
auto result = this->DependInformationMap.find(fullPath);
if (result != this->DependInformationMap.end()) {
// Found an instance, return it.
- return result->second;
+ return result->second.get();
}
// Didn't find an instance. Create a new one and save it.
- cmDependInformation* info = new cmDependInformation;
+ auto info = cm::make_unique<cmDependInformation>();
+ auto ptr = info.get();
info->FullPath = fullPath;
info->PathOnly = cmSystemTools::GetFilenamePath(fullPath);
info->IncludeName = file;
- this->DependInformationMap[fullPath] = info;
- return info;
+ this->DependInformationMap[fullPath] = std::move(info);
+ return ptr;
}
/**
@@ -387,14 +390,9 @@ protected:
* This uses the include directories.
* TODO: Cache path conversions to reduce FileExists calls.
*/
- std::string FullPath(const char* fname, const char* extraPath)
+ std::string FullPath(const std::string& fname, const std::string& extraPath)
{
- DirectoryToFileToPathMapType::iterator m;
- if (extraPath) {
- m = this->DirectoryToFileToPathMap.find(extraPath);
- } else {
- m = this->DirectoryToFileToPathMap.find("");
- }
+ auto m = this->DirectoryToFileToPathMap.find(extraPath);
if (m != this->DirectoryToFileToPathMap.end()) {
FileToPathMapType& map = m->second;
@@ -406,7 +404,7 @@ protected:
if (cmSystemTools::FileExists(fname, true)) {
std::string fp = cmSystemTools::CollapseFullPath(fname);
- this->DirectoryToFileToPathMap[extraPath ? extraPath : ""][fname] = fp;
+ this->DirectoryToFileToPathMap[extraPath][fname] = fp;
return fp;
}
@@ -418,12 +416,12 @@ protected:
if (cmSystemTools::FileExists(path, true) &&
!cmSystemTools::FileIsDirectory(path)) {
std::string fp = cmSystemTools::CollapseFullPath(path);
- this->DirectoryToFileToPathMap[extraPath ? extraPath : ""][fname] = fp;
+ this->DirectoryToFileToPathMap[extraPath][fname] = fp;
return fp;
}
}
- if (extraPath) {
+ if (!extraPath.empty()) {
std::string path = extraPath;
if (!path.empty() && path.back() != '/') {
path = path + "/";
@@ -438,7 +436,7 @@ protected:
}
// Couldn't find the file.
- return std::string(fname);
+ return fname;
}
cmMakefile* Makefile;
@@ -449,7 +447,8 @@ protected:
using FileToPathMapType = std::map<std::string, std::string>;
using DirectoryToFileToPathMapType =
std::map<std::string, FileToPathMapType>;
- using DependInformationMapType = std::map<std::string, cmDependInformation*>;
+ using DependInformationMapType =
+ std::map<std::string, std::unique_ptr<cmDependInformation>>;
DependInformationMapType DependInformationMap;
DirectoryToFileToPathMapType DirectoryToFileToPathMap;
};
@@ -476,7 +475,7 @@ bool cmOutputRequiredFilesCommand(std::vector<std::string> const& args,
md.SetMakefile(&status.GetMakefile());
md.AddSearchPath(status.GetMakefile().GetCurrentSourceDirectory());
// find the depends for a file
- const cmDependInformation* info = md.FindDependencies(file.c_str());
+ const cmDependInformation* info = md.FindDependencies(file);
if (info) {
// write them out
FILE* fout = cmsys::SystemTools::Fopen(outputFile, "w");
diff --git a/Source/cmPipeConnection.h b/Source/cmPipeConnection.h
index 81f8a49..1215716 100644
--- a/Source/cmPipeConnection.h
+++ b/Source/cmPipeConnection.h
@@ -6,7 +6,7 @@
#include <string>
-#include "cm_uv.h"
+#include <cm3p/uv.h>
#include "cmConnection.h"
#include "cmUVHandlePtr.h"
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index 5c8bc98..dea3f8a 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -72,6 +72,7 @@ static const char* idToVersion(cmPolicies::PolicyID id)
#define POLICY_CASE(ID, V_MAJOR, V_MINOR, V_PATCH) \
case cmPolicies::ID: \
return #V_MAJOR "." #V_MINOR "." #V_PATCH;
+ // NOLINTNEXTLINE(bugprone-branch-clone)
CM_FOR_EACH_POLICY_ID_VERSION(POLICY_CASE)
#undef POLICY_CASE
case cmPolicies::CMPCOUNT:
@@ -90,6 +91,7 @@ static bool isPolicyNewerThan(cmPolicies::PolicyID id, unsigned int majorV,
(majorV == (V_MAJOR) && minorV + 1 < (V_MINOR) + 1) || \
(majorV == (V_MAJOR) && minorV == (V_MINOR) && \
patchV + 1 < (V_PATCH) + 1));
+ // NOLINTNEXTLINE(bugprone-branch-clone)
CM_FOR_EACH_POLICY_ID_VERSION(POLICY_CASE)
#undef POLICY_CASE
case cmPolicies::CMPCOUNT:
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 92c80bb..4abfa1f 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -290,7 +290,33 @@ class cmMakefile;
SELECT(POLICY, CMP0097, \
"ExternalProject_Add with GIT_SUBMODULES \"\" initializes no " \
"submodules.", \
- 3, 16, 0, cmPolicies::WARN)
+ 3, 16, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0098, \
+ "FindFLEX runs flex in CMAKE_CURRENT_BINARY_DIR when executing.", 3, \
+ 17, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0099, \
+ "Link properties are transitive over private dependency on static " \
+ "libraries.", \
+ 3, 17, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0100, "Let AUTOMOC and AUTOUIC process .hh files.", 3, \
+ 17, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0101, \
+ "target_compile_options honors BEFORE keyword in all scopes.", 3, \
+ 17, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0102, \
+ "mark_as_advanced() does nothing if a cache entry does not exist.", \
+ 3, 17, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0103, \
+ "Multiple export() with same FILE without APPEND is not allowed.", \
+ 3, 18, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0104, \
+ "CMAKE_CUDA_ARCHITECTURES now detected for NVCC, empty " \
+ "CUDA_ARCHITECTURES not allowed.", \
+ 3, 18, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0105, "Device link step uses the link options.", 3, 18, \
+ 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0106, "The Documentation module is removed.", 3, 18, 0, \
+ cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \
@@ -319,7 +345,10 @@ class cmMakefile;
F(CMP0076) \
F(CMP0081) \
F(CMP0083) \
- F(CMP0095)
+ F(CMP0095) \
+ F(CMP0099) \
+ F(CMP0104) \
+ F(CMP0105)
/** \class cmPolicies
* \brief Handles changes in CMake behavior and policies
diff --git a/Source/cmProcessOutput.cxx b/Source/cmProcessOutput.cxx
index e80ea5c..0fb4ff7 100644
--- a/Source/cmProcessOutput.cxx
+++ b/Source/cmProcessOutput.cxx
@@ -4,7 +4,10 @@
#include "cmProcessOutput.h"
#if defined(_WIN32)
+# include <cm/memory>
+
# include <windows.h>
+
unsigned int cmProcessOutput::defaultCodepage =
KWSYS_ENCODING_DEFAULT_CODEPAGE;
#endif
@@ -143,9 +146,9 @@ bool cmProcessOutput::DoDecodeText(std::string raw, std::string& decoded,
bool success = false;
const int wlength =
MultiByteToWideChar(codepage, 0, raw.c_str(), int(raw.size()), NULL, 0);
- wchar_t* wdata = new wchar_t[wlength];
- int r = MultiByteToWideChar(codepage, 0, raw.c_str(), int(raw.size()), wdata,
- wlength);
+ auto wdata = cm::make_unique<wchar_t[]>(wlength);
+ int r = MultiByteToWideChar(codepage, 0, raw.c_str(), int(raw.size()),
+ wdata.get(), wlength);
if (r > 0) {
if (lastChar) {
*lastChar = 0;
@@ -154,18 +157,16 @@ bool cmProcessOutput::DoDecodeText(std::string raw, std::string& decoded,
*lastChar = wdata[wlength - 1];
}
}
- int length = WideCharToMultiByte(defaultCodepage, 0, wdata, wlength, NULL,
- 0, NULL, NULL);
- char* data = new char[length];
- r = WideCharToMultiByte(defaultCodepage, 0, wdata, wlength, data, length,
- NULL, NULL);
+ int length = WideCharToMultiByte(defaultCodepage, 0, wdata.get(), wlength,
+ NULL, 0, NULL, NULL);
+ auto data = cm::make_unique<char[]>(length);
+ r = WideCharToMultiByte(defaultCodepage, 0, wdata.get(), wlength,
+ data.get(), length, NULL, NULL);
if (r > 0) {
- decoded = std::string(data, length);
+ decoded = std::string(data.get(), length);
success = true;
}
- delete[] data;
}
- delete[] wdata;
return success;
}
#endif
diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx
index 7bb5209..2ec66d9 100644
--- a/Source/cmProjectCommand.cxx
+++ b/Source/cmProjectCommand.cxx
@@ -39,13 +39,18 @@ bool cmProjectCommand(std::vector<std::string> const& args,
std::string const& projectName = args[0];
+ if (!IncludeByVariable(status,
+ "CMAKE_PROJECT_" + projectName + "_INCLUDE_BEFORE")) {
+ return false;
+ }
+
mf.SetProjectName(projectName);
mf.AddCacheDefinition(projectName + "_BINARY_DIR",
- mf.GetCurrentBinaryDirectory().c_str(),
+ mf.GetCurrentBinaryDirectory(),
"Value Computed by CMake", cmStateEnums::STATIC);
mf.AddCacheDefinition(projectName + "_SOURCE_DIR",
- mf.GetCurrentSourceDirectory().c_str(),
+ mf.GetCurrentSourceDirectory(),
"Value Computed by CMake", cmStateEnums::STATIC);
mf.AddDefinition("PROJECT_BINARY_DIR", mf.GetCurrentBinaryDirectory());
@@ -61,7 +66,7 @@ bool cmProjectCommand(std::vector<std::string> const& args,
// will work.
if (!mf.GetDefinition("CMAKE_PROJECT_NAME") || mf.IsRootMakefile()) {
mf.AddDefinition("CMAKE_PROJECT_NAME", projectName);
- mf.AddCacheDefinition("CMAKE_PROJECT_NAME", projectName.c_str(),
+ mf.AddCacheDefinition("CMAKE_PROJECT_NAME", projectName,
"Value Computed by CMake", cmStateEnums::STATIC);
}
@@ -374,7 +379,7 @@ static void TopLevelCMakeVarCondSet(cmMakefile& mf, std::string const& name,
// CMakeLists.txt file, then go with the last one.
if (!mf.GetDefinition(name) || mf.IsRootMakefile()) {
mf.AddDefinition(name, value);
- mf.AddCacheDefinition(name, value.c_str(), "Value Computed by CMake",
+ mf.AddCacheDefinition(name, value, "Value Computed by CMake",
cmStateEnums::STATIC);
}
}
diff --git a/Source/cmPropertyDefinition.cxx b/Source/cmPropertyDefinition.cxx
index 6a3174c..c8efaf6 100644
--- a/Source/cmPropertyDefinition.cxx
+++ b/Source/cmPropertyDefinition.cxx
@@ -2,19 +2,17 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmPropertyDefinition.h"
-void cmPropertyDefinition::DefineProperty(const std::string& name,
- cmProperty::ScopeType scope,
- const char* shortDescription,
- const char* fullDescription,
- bool chain)
+#include <utility>
+
+cmPropertyDefinition::cmPropertyDefinition(std::string name,
+ cmProperty::ScopeType scope,
+ std::string shortDescription,
+ std::string fullDescription,
+ bool chain)
+ : Name(std::move(name))
+ , ShortDescription(std::move(shortDescription))
+ , FullDescription(std::move(fullDescription))
+ , Scope(scope)
+ , Chained(chain)
{
- this->Name = name;
- this->Scope = scope;
- this->Chained = chain;
- if (shortDescription) {
- this->ShortDescription = shortDescription;
- }
- if (fullDescription) {
- this->FullDescription = fullDescription;
- }
}
diff --git a/Source/cmPropertyDefinition.h b/Source/cmPropertyDefinition.h
index 0d68c32..d2e4467 100644
--- a/Source/cmPropertyDefinition.h
+++ b/Source/cmPropertyDefinition.h
@@ -21,13 +21,10 @@
class cmPropertyDefinition
{
public:
- /// Define this property
- void DefineProperty(const std::string& name, cmProperty::ScopeType scope,
- const char* ShortDescription,
- const char* FullDescription, bool chained);
-
- /// Default constructor
- cmPropertyDefinition() { this->Chained = false; }
+ /// Constructor
+ cmPropertyDefinition(std::string name, cmProperty::ScopeType scope,
+ std::string ShortDescription,
+ std::string FullDescription, bool chained = false);
/// Is the property chained?
bool IsChained() const { return this->Chained; }
diff --git a/Source/cmPropertyDefinitionMap.cxx b/Source/cmPropertyDefinitionMap.cxx
index f752ed7..614d5a4 100644
--- a/Source/cmPropertyDefinitionMap.cxx
+++ b/Source/cmPropertyDefinitionMap.cxx
@@ -2,20 +2,20 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmPropertyDefinitionMap.h"
+#include <tuple>
#include <utility>
-void cmPropertyDefinitionMap::DefineProperty(const std::string& name,
- cmProperty::ScopeType scope,
- const char* ShortDescription,
- const char* FullDescription,
- bool chain)
+void cmPropertyDefinitionMap::DefineProperty(
+ const std::string& name, cmProperty::ScopeType scope,
+ const std::string& ShortDescription, const std::string& FullDescription,
+ bool chain)
{
auto it = this->find(name);
- cmPropertyDefinition* prop;
if (it == this->end()) {
- prop = &(*this)[name];
- prop->DefineProperty(name, scope, ShortDescription, FullDescription,
- chain);
+ // try_emplace() since C++17
+ this->emplace(std::piecewise_construct, std::forward_as_tuple(name),
+ std::forward_as_tuple(name, scope, ShortDescription,
+ FullDescription, chain));
}
}
diff --git a/Source/cmPropertyDefinitionMap.h b/Source/cmPropertyDefinitionMap.h
index 8ec7910..2ae6efb 100644
--- a/Source/cmPropertyDefinitionMap.h
+++ b/Source/cmPropertyDefinitionMap.h
@@ -17,8 +17,8 @@ class cmPropertyDefinitionMap
public:
// define the property
void DefineProperty(const std::string& name, cmProperty::ScopeType scope,
- const char* ShortDescription,
- const char* FullDescription, bool chain);
+ const std::string& ShortDescription,
+ const std::string& FullDescription, bool chain);
// has a named property been defined
bool IsPropertyDefined(const std::string& name) const;
diff --git a/Source/cmPropertyMap.cxx b/Source/cmPropertyMap.cxx
index a3d4946..f22f36d 100644
--- a/Source/cmPropertyMap.cxx
+++ b/Source/cmPropertyMap.cxx
@@ -20,11 +20,11 @@ void cmPropertyMap::SetProperty(const std::string& name, const char* value)
Map_[name] = value;
}
-void cmPropertyMap::AppendProperty(const std::string& name, const char* value,
- bool asString)
+void cmPropertyMap::AppendProperty(const std::string& name,
+ const std::string& value, bool asString)
{
// Skip if nothing to append.
- if (!value || !*value) {
+ if (value.empty()) {
return;
}
@@ -42,13 +42,11 @@ void cmPropertyMap::RemoveProperty(const std::string& name)
Map_.erase(name);
}
-const char* cmPropertyMap::GetPropertyValue(const std::string& name) const
+cmProp cmPropertyMap::GetPropertyValue(const std::string& name) const
{
- {
- auto it = Map_.find(name);
- if (it != Map_.end()) {
- return it->second.c_str();
- }
+ auto it = Map_.find(name);
+ if (it != Map_.end()) {
+ return &it->second;
}
return nullptr;
}
diff --git a/Source/cmPropertyMap.h b/Source/cmPropertyMap.h
index 9aed349..40ac356 100644
--- a/Source/cmPropertyMap.h
+++ b/Source/cmPropertyMap.h
@@ -10,6 +10,8 @@
#include <utility>
#include <vector>
+using cmProp = const std::string*;
+
/** \class cmPropertyMap
* \brief String property map.
*/
@@ -27,11 +29,11 @@ public:
void SetProperty(const std::string& name, const char* value);
//! Append to the property value
- void AppendProperty(const std::string& name, const char* value,
+ void AppendProperty(const std::string& name, const std::string& value,
bool asString = false);
//! Get the property value
- const char* GetPropertyValue(const std::string& name) const;
+ cmProp GetPropertyValue(const std::string& name) const;
//! Remove the property @a name from the map
void RemoveProperty(const std::string& name);
diff --git a/Source/cmQTWrapCPPCommand.cxx b/Source/cmQTWrapCPPCommand.cxx
index cc4df8f..48c4b10 100644
--- a/Source/cmQTWrapCPPCommand.cxx
+++ b/Source/cmQTWrapCPPCommand.cxx
@@ -39,7 +39,8 @@ bool cmQTWrapCPPCommand(std::vector<std::string> const& args,
cmStrCat(mf.GetCurrentBinaryDirectory(), "/moc_", srcName, ".cxx");
cmSourceFile* sf = mf.GetOrCreateSource(newName, true);
if (curr) {
- sf->SetProperty("ABSTRACT", curr->GetProperty("ABSTRACT"));
+ cmProp p = curr->GetProperty("ABSTRACT");
+ sf->SetProperty("ABSTRACT", p ? p->c_str() : nullptr);
}
// Compute the name of the header from which to generate the file.
diff --git a/Source/cmQtAutoGen.cxx b/Source/cmQtAutoGen.cxx
index eb7c900..57fcd2d 100644
--- a/Source/cmQtAutoGen.cxx
+++ b/Source/cmQtAutoGen.cxx
@@ -8,10 +8,11 @@
#include <sstream>
#include <utility>
+#include <cmext/algorithm>
+
#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"
-#include "cmAlgorithms.h"
#include "cmDuration.h"
#include "cmProcessOutput.h"
#include "cmStringAlgorithms.h"
@@ -53,7 +54,7 @@ void MergeOptions(std::vector<std::string>& baseOpts,
}
}
// Test if this is a value option and change the existing value
- if (!optName.empty() && cmContains(valueOpts, optName)) {
+ if (!optName.empty() && cm::contains(valueOpts, optName)) {
const auto existItNext(existIt + 1);
const auto fitNext(fit + 1);
if ((existItNext != baseOpts.end()) && (fitNext != fitEnd)) {
@@ -67,7 +68,7 @@ void MergeOptions(std::vector<std::string>& baseOpts,
}
}
// Append options
- cmAppend(baseOpts, extraOpts);
+ cm::append(baseOpts, extraOpts);
}
// - Class definitions
@@ -328,7 +329,7 @@ bool cmQtAutoGen::RccLister::list(std::string const& qrcFile,
{
std::vector<std::string> cmd;
cmd.emplace_back(this->RccExcutable_);
- cmAppend(cmd, this->ListOptions_);
+ cm::append(cmd, this->ListOptions_);
cmd.emplace_back(cmSystemTools::GetFilenameName(qrcFile));
// Log command
diff --git a/Source/cmQtAutoGenGlobalInitializer.cxx b/Source/cmQtAutoGenGlobalInitializer.cxx
index ef6b886..a32f3e7 100644
--- a/Source/cmQtAutoGenGlobalInitializer.cxx
+++ b/Source/cmQtAutoGenGlobalInitializer.cxx
@@ -7,7 +7,6 @@
#include <cm/memory>
#include "cmCustomCommandLines.h"
-#include "cmCustomCommandTypes.h"
#include "cmDuration.h"
#include "cmGeneratorTarget.h"
#include "cmLocalGenerator.h"
@@ -41,9 +40,9 @@ cmQtAutoGenGlobalInitializer::Keywords::Keywords()
}
cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer(
- std::vector<cmLocalGenerator*> const& localGenerators)
+ std::vector<std::unique_ptr<cmLocalGenerator>> const& localGenerators)
{
- for (cmLocalGenerator* localGen : localGenerators) {
+ for (const auto& localGen : localGenerators) {
// Detect global autogen and autorcc target names
bool globalAutoGenTarget = false;
bool globalAutoRccTarget = false;
@@ -56,7 +55,7 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer(
if (targetName.empty()) {
targetName = "autogen";
}
- GlobalAutoGenTargets_.emplace(localGen, std::move(targetName));
+ GlobalAutoGenTargets_.emplace(localGen.get(), std::move(targetName));
globalAutoGenTarget = true;
}
@@ -67,13 +66,13 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer(
if (targetName.empty()) {
targetName = "autorcc";
}
- GlobalAutoRccTargets_.emplace(localGen, std::move(targetName));
+ GlobalAutoRccTargets_.emplace(localGen.get(), std::move(targetName));
globalAutoRccTarget = true;
}
}
// Find targets that require AUTOMOC/UIC/RCC processing
- for (cmGeneratorTarget* target : localGen->GetGeneratorTargets()) {
+ for (const auto& target : localGen->GetGeneratorTargets()) {
// Process only certain target types
switch (target->GetType()) {
case cmStateEnums::EXECUTABLE:
@@ -96,15 +95,15 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer(
bool const uic = target->GetPropertyAsBool(kw().AUTOUIC);
bool const rcc = target->GetPropertyAsBool(kw().AUTORCC);
if (moc || uic || rcc) {
- std::string const mocExec =
+ std::string const& mocExec =
target->GetSafeProperty(kw().AUTOMOC_EXECUTABLE);
- std::string const uicExec =
+ std::string const& uicExec =
target->GetSafeProperty(kw().AUTOUIC_EXECUTABLE);
- std::string const rccExec =
+ std::string const& rccExec =
target->GetSafeProperty(kw().AUTORCC_EXECUTABLE);
// We support Qt4, Qt5 and Qt6
- auto qtVersion = cmQtAutoGenInitializer::GetQtVersion(target);
+ auto qtVersion = cmQtAutoGenInitializer::GetQtVersion(target.get());
bool const validQt = (qtVersion.first.Major == 4) ||
(qtVersion.first.Major == 5) || (qtVersion.first.Major == 6);
@@ -135,8 +134,8 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer(
if (mocIsValid || uicIsValid || rccIsValid) {
// Create autogen target initializer
Initializers_.emplace_back(cm::make_unique<cmQtAutoGenInitializer>(
- this, target, qtVersion.first, mocIsValid, uicIsValid, rccIsValid,
- globalAutoGenTarget, globalAutoRccTarget));
+ this, target.get(), qtVersion.first, mocIsValid, uicIsValid,
+ rccIsValid, globalAutoGenTarget, globalAutoRccTarget));
}
}
}
@@ -154,20 +153,21 @@ void cmQtAutoGenGlobalInitializer::GetOrCreateGlobalTarget(
cmMakefile* makefile = localGen->GetMakefile();
// Create utility target
- cmTarget* target = makefile->AddUtilityCommand(
- name, cmCommandOrigin::Generator, true,
- makefile->GetHomeOutputDirectory().c_str() /*work dir*/,
- std::vector<std::string>() /*output*/,
- std::vector<std::string>() /*depends*/, cmCustomCommandLines(), false,
- comment.c_str());
- localGen->AddGeneratorTarget(new cmGeneratorTarget(target, localGen));
+ std::vector<std::string> no_byproducts;
+ std::vector<std::string> no_depends;
+ cmCustomCommandLines no_commands;
+ cmTarget* target = localGen->AddUtilityCommand(
+ name, true, makefile->GetHomeOutputDirectory().c_str(), no_byproducts,
+ no_depends, no_commands, false, comment.c_str());
+ localGen->AddGeneratorTarget(
+ cm::make_unique<cmGeneratorTarget>(target, localGen));
// Set FOLDER property in the target
{
- char const* folder =
+ cmProp folder =
makefile->GetState()->GetGlobalProperty("AUTOGEN_TARGETS_FOLDER");
if (folder != nullptr) {
- target->SetProperty("FOLDER", folder);
+ target->SetProperty("FOLDER", *folder);
}
}
}
@@ -180,7 +180,7 @@ void cmQtAutoGenGlobalInitializer::AddToGlobalAutoGen(
if (it != GlobalAutoGenTargets_.end()) {
cmGeneratorTarget* target = localGen->FindGeneratorTargetToUse(it->second);
if (target != nullptr) {
- target->Target->AddUtility(targetName, localGen->GetMakefile());
+ target->Target->AddUtility(targetName, false, localGen->GetMakefile());
}
}
}
@@ -192,7 +192,7 @@ void cmQtAutoGenGlobalInitializer::AddToGlobalAutoRcc(
if (it != GlobalAutoRccTargets_.end()) {
cmGeneratorTarget* target = localGen->FindGeneratorTargetToUse(it->second);
if (target != nullptr) {
- target->Target->AddUtility(targetName, localGen->GetMakefile());
+ target->Target->AddUtility(targetName, false, localGen->GetMakefile());
}
}
}
diff --git a/Source/cmQtAutoGenGlobalInitializer.h b/Source/cmQtAutoGenGlobalInitializer.h
index 806725a..2f6e581 100644
--- a/Source/cmQtAutoGenGlobalInitializer.h
+++ b/Source/cmQtAutoGenGlobalInitializer.h
@@ -48,7 +48,7 @@ public:
public:
cmQtAutoGenGlobalInitializer(
- std::vector<cmLocalGenerator*> const& localGenerators);
+ std::vector<std::unique_ptr<cmLocalGenerator>> const& localGenerators);
~cmQtAutoGenGlobalInitializer();
Keywords const& kw() const { return Keywords_; };
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index 5eb04f7..003a300 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -16,16 +16,15 @@
#include <cm/algorithm>
#include <cm/iterator>
#include <cm/memory>
+#include <cmext/algorithm>
-#include "cmsys/SystemInformation.hxx"
+#include <cm3p/json/value.h>
+#include <cm3p/json/writer.h>
-#include "cm_jsoncpp_value.h"
-#include "cm_jsoncpp_writer.h"
+#include "cmsys/SystemInformation.hxx"
-#include "cmAlgorithms.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandLines.h"
-#include "cmCustomCommandTypes.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
@@ -340,7 +339,7 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
// Targets FOLDER
{
- const char* folder =
+ cmProp folder =
this->Makefile->GetState()->GetGlobalProperty("AUTOMOC_TARGETS_FOLDER");
if (folder == nullptr) {
folder = this->Makefile->GetState()->GetGlobalProperty(
@@ -351,28 +350,42 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
folder = this->GenTarget->GetProperty("FOLDER");
}
if (folder != nullptr) {
- this->TargetsFolder = folder;
+ this->TargetsFolder = *folder;
}
}
- // Check status of policy CMP0071
- {
- cmPolicies::PolicyStatus const CMP0071_status =
- this->Makefile->GetPolicyStatus(cmPolicies::CMP0071);
- switch (CMP0071_status) {
- case cmPolicies::WARN:
- this->CMP0071Warn = true;
- CM_FALLTHROUGH;
- case cmPolicies::OLD:
- // Ignore GENERATED file
- break;
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::NEW:
- // Process GENERATED file
- this->CMP0071Accept = true;
- break;
- }
+ // Check status of policy CMP0071 regarding handling of GENERATED files
+ switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0071)) {
+ case cmPolicies::WARN:
+ // Ignore GENERATED files but warn
+ this->CMP0071Warn = true;
+ CM_FALLTHROUGH;
+ case cmPolicies::OLD:
+ // Ignore GENERATED files
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ // Process GENERATED files
+ this->CMP0071Accept = true;
+ break;
+ }
+
+ // Check status of policy CMP0100 regarding handling of .hh headers
+ switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0100)) {
+ case cmPolicies::WARN:
+ // Ignore but .hh files but warn
+ this->CMP0100Warn = true;
+ CM_FALLTHROUGH;
+ case cmPolicies::OLD:
+ // Ignore .hh files
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ // Process .hh file
+ this->CMP0100Accept = true;
+ break;
}
// Common directories
@@ -427,7 +440,8 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
// Autogen target parallel processing
{
- std::string prop = this->GenTarget->GetSafeProperty("AUTOGEN_PARALLEL");
+ std::string const& prop =
+ this->GenTarget->GetSafeProperty("AUTOGEN_PARALLEL");
if (prop.empty() || (prop == "AUTO")) {
// Autodetect number of CPUs
this->AutogenTarget.Parallel = GetParallelCPUCount();
@@ -458,7 +472,7 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
this->AutogenTarget.DependOrigin =
this->GenTarget->GetPropertyAsBool("AUTOGEN_ORIGIN_DEPENDS");
- std::string const deps =
+ std::string const& deps =
this->GenTarget->GetSafeProperty("AUTOGEN_TARGET_DEPENDS");
if (!deps.empty()) {
for (std::string const& depName : cmExpandedList(deps)) {
@@ -641,7 +655,7 @@ bool cmQtAutoGenInitializer::InitUic()
{
// Uic search paths
{
- std::string const usp =
+ std::string const& usp =
this->GenTarget->GetSafeProperty("AUTOUIC_SEARCH_PATHS");
if (!usp.empty()) {
this->Uic.SearchPaths =
@@ -734,15 +748,26 @@ bool cmQtAutoGenInitializer::InitScanFiles()
return muf;
};
- auto addMUFile = [&](MUFileHandle&& muf, bool isHeader) {
+ auto addMUHeader = [this](MUFileHandle&& muf, cm::string_view extension) {
+ cmSourceFile* sf = muf->SF;
+ const bool muIt = (muf->MocIt || muf->UicIt);
+ if (this->CMP0100Accept || (extension != "hh")) {
+ // Accept
+ if (muIt && muf->Generated) {
+ this->AutogenTarget.FilesGenerated.emplace_back(muf.get());
+ }
+ this->AutogenTarget.Headers.emplace(sf, std::move(muf));
+ } else if (muIt && this->CMP0100Warn) {
+ // Store file for warning message
+ this->AutogenTarget.CMP0100HeadersWarn.push_back(sf);
+ }
+ };
+
+ auto addMUSource = [this](MUFileHandle&& muf) {
if ((muf->MocIt || muf->UicIt) && muf->Generated) {
this->AutogenTarget.FilesGenerated.emplace_back(muf.get());
}
- if (isHeader) {
- this->AutogenTarget.Headers.emplace(muf->SF, std::move(muf));
- } else {
- this->AutogenTarget.Sources.emplace(muf->SF, std::move(muf));
- }
+ this->AutogenTarget.Sources.emplace(muf->SF, std::move(muf));
};
// Scan through target files
@@ -764,11 +789,10 @@ bool cmQtAutoGenInitializer::InitScanFiles()
// Register files that will be scanned by moc or uic
if (this->MocOrUicEnabled()) {
- // FIXME: Add a policy to include .hh files.
- if (cm->IsHeaderExtension(extLower) && extLower != "hh") {
- addMUFile(makeMUFile(sf, fullPath, true), true);
+ if (cm->IsHeaderExtension(extLower)) {
+ addMUHeader(makeMUFile(sf, fullPath, true), extLower);
} else if (cm->IsSourceExtension(extLower)) {
- addMUFile(makeMUFile(sf, fullPath, true), false);
+ addMUSource(makeMUFile(sf, fullPath, true));
}
}
@@ -802,8 +826,6 @@ bool cmQtAutoGenInitializer::InitScanFiles()
// For source files find additional headers and private headers
if (this->MocOrUicEnabled()) {
- std::vector<MUFileHandle> extraHeaders;
- extraHeaders.reserve(this->AutogenTarget.Sources.size() * 2);
// Header search suffixes and extensions
static std::initializer_list<cm::string_view> const suffixes{ "", "_p" };
auto const& exts = cm->GetHeaderExtensions();
@@ -826,7 +848,7 @@ bool cmQtAutoGenInitializer::InitScanFiles()
this->Makefile->GetSource(fullPath, locationKind);
if (sf != nullptr) {
// Check if we know about this header already
- if (cmContains(this->AutogenTarget.Headers, sf)) {
+ if (cm::contains(this->AutogenTarget.Headers, sf)) {
continue;
}
// We only accept not-GENERATED files that do exist.
@@ -848,16 +870,12 @@ bool cmQtAutoGenInitializer::InitScanFiles()
if (!muf.UicIt) {
eMuf->UicIt = false;
}
- extraHeaders.emplace_back(std::move(eMuf));
+ addMUHeader(std::move(eMuf), ext);
}
}
}
}
}
- // Move generated files to main headers list
- for (auto& eMuf : extraHeaders) {
- addMUFile(std::move(eMuf), true);
- }
}
// Scan through all source files in the makefile to extract moc and uic
@@ -865,7 +883,7 @@ bool cmQtAutoGenInitializer::InitScanFiles()
// The reason is that their file names might be discovered from source files
// at generation time.
if (this->MocOrUicEnabled()) {
- for (cmSourceFile* sf : this->Makefile->GetSourceFiles()) {
+ for (const auto& sf : this->Makefile->GetSourceFiles()) {
// sf->GetExtension() is only valid after sf->ResolveFullPath() ...
// Since we're iterating over source files that might be not in the
// target we need to check for path errors (not existing files).
@@ -877,19 +895,18 @@ bool cmQtAutoGenInitializer::InitScanFiles()
std::string const& extLower =
cmSystemTools::LowerCase(sf->GetExtension());
- // FIXME: Add a policy to include .hh files.
- if (cm->IsHeaderExtension(extLower) && extLower != "hh") {
- if (!cmContains(this->AutogenTarget.Headers, sf)) {
- auto muf = makeMUFile(sf, fullPath, false);
+ if (cm->IsHeaderExtension(extLower)) {
+ if (!cm::contains(this->AutogenTarget.Headers, sf.get())) {
+ auto muf = makeMUFile(sf.get(), fullPath, false);
if (muf->SkipMoc || muf->SkipUic) {
- this->AutogenTarget.Headers.emplace(sf, std::move(muf));
+ addMUHeader(std::move(muf), extLower);
}
}
} else if (cm->IsSourceExtension(extLower)) {
- if (!cmContains(this->AutogenTarget.Headers, sf)) {
- auto muf = makeMUFile(sf, fullPath, false);
+ if (!cm::contains(this->AutogenTarget.Sources, sf.get())) {
+ auto muf = makeMUFile(sf.get(), fullPath, false);
if (muf->SkipMoc || muf->SkipUic) {
- this->AutogenTarget.Sources.emplace(sf, std::move(muf));
+ addMUSource(std::move(muf));
}
}
} else if (this->Uic.Enabled && (extLower == kw.ui)) {
@@ -947,6 +964,35 @@ bool cmQtAutoGenInitializer::InitScanFiles()
}
}
+ // Generate CMP0100 warning
+ if (this->MocOrUicEnabled() &&
+ !this->AutogenTarget.CMP0100HeadersWarn.empty()) {
+ cm::string_view property;
+ if (this->Moc.Enabled && this->Uic.Enabled) {
+ property = "SKIP_AUTOGEN";
+ } else if (this->Moc.Enabled) {
+ property = "SKIP_AUTOMOC";
+ } else if (this->Uic.Enabled) {
+ property = "SKIP_AUTOUIC";
+ }
+ std::string files;
+ for (cmSourceFile* sf : this->AutogenTarget.CMP0100HeadersWarn) {
+ files += cmStrCat(" ", Quoted(sf->GetFullPath()), '\n');
+ }
+ this->Makefile->IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat(
+ cmPolicies::GetPolicyWarning(cmPolicies::CMP0100), '\n',
+ "For compatibility, CMake is excluding the header file(s):\n", files,
+ "from processing by ",
+ cmQtAutoGen::Tools(this->Moc.Enabled, this->Uic.Enabled, false),
+ ". If any of the files should be processed, set CMP0100 to NEW. "
+ "If any of the files should not be processed, "
+ "explicitly exclude them by setting the source file property ",
+ property, ":\n set_property(SOURCE file.hh PROPERTY ", property,
+ " ON)\n"));
+ }
+
// Process qrc files
if (!this->Rcc.Qrcs.empty()) {
const bool modernQt = (this->QtVersion.Major >= 5);
@@ -1045,9 +1091,17 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
}
// Compose command lines
- cmCustomCommandLines commandLines = cmMakeSingleCommandLine(
- { cmSystemTools::GetCMakeCommand(), "-E", "cmake_autogen",
- this->AutogenTarget.InfoFile, "$<CONFIGURATION>" });
+ // TODO: Refactor autogen to output a per-config mocs_compilation.cpp instead
+ // of fiddling with the include directories
+ std::vector<std::string> configs;
+ this->GlobalGen->GetQtAutoGenConfigs(configs);
+ bool stdPipesUTF8 = true;
+ cmCustomCommandLines commandLines;
+ for (auto const& config : configs) {
+ commandLines.push_back(cmMakeCommandLine(
+ { cmSystemTools::GetCMakeCommand(), "-E", "cmake_autogen",
+ this->AutogenTarget.InfoFile, config }));
+ }
// Use PRE_BUILD on demand
bool usePRE_BUILD = false;
@@ -1073,7 +1127,7 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
if (usePRE_BUILD) {
// Add additional autogen target dependencies to origin target
for (cmTarget* depTarget : this->AutogenTarget.DependTargets) {
- this->GenTarget->Target->AddUtility(depTarget->GetName(),
+ this->GenTarget->Target->AddUtility(depTarget->GetName(), false,
this->Makefile);
}
@@ -1084,9 +1138,9 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
// PRE_BUILD does not support file dependencies!
const std::vector<std::string> no_output;
const std::vector<std::string> no_deps;
- cmCustomCommand cc(this->Makefile, no_output, autogenProvides, no_deps,
- commandLines, autogenComment.c_str(),
- this->Dir.Work.c_str());
+ cmCustomCommand cc(no_output, autogenProvides, no_deps, commandLines,
+ this->Makefile->GetBacktrace(), autogenComment.c_str(),
+ this->Dir.Work.c_str(), stdPipesUTF8);
cc.SetEscapeOldStyle(false);
cc.SetEscapeAllowMakeVars(true);
this->GenTarget->Target->AddPreBuildCommand(std::move(cc));
@@ -1119,35 +1173,84 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
}
}
+ std::vector<std::string> dependencies(
+ this->AutogenTarget.DependFiles.begin(),
+ this->AutogenTarget.DependFiles.end());
+
+ const bool useNinjaDepfile = this->QtVersion >= IntegerVersion(5, 15) &&
+ this->GlobalGen->GetName().find("Ninja") != std::string::npos;
+ if (useNinjaDepfile) {
+ // Create a custom command that generates a timestamp file and
+ // has a depfile assigned. The depfile is created by JobDepFilesMergeT.
+
+ // Add additional autogen target dependencies
+ for (const cmTarget* t : this->AutogenTarget.DependTargets) {
+ dependencies.push_back(t->GetName());
+ }
+ const char timestampFileName[] = "timestamp";
+ const std::string outputFile =
+ cmStrCat(this->Dir.Build, "/", timestampFileName);
+ this->AutogenTarget.DepFile = cmStrCat(this->Dir.Build, "/deps");
+ auto relativeBinaryDir = cmSystemTools::RelativePath(
+ this->LocalGen->GetBinaryDirectory(),
+ this->LocalGen->GetCurrentBinaryDirectory());
+ if (!relativeBinaryDir.empty()) {
+ relativeBinaryDir = cmStrCat(relativeBinaryDir, "/");
+ }
+ this->AutogenTarget.DepFileRuleName =
+ cmStrCat(relativeBinaryDir, this->GenTarget->GetName(), "_autogen/",
+ timestampFileName);
+ commandLines.push_back(cmMakeCommandLine(
+ { cmSystemTools::GetCMakeCommand(), "-E", "touch", outputFile }));
+
+ this->AddGeneratedSource(outputFile, this->Moc);
+ const std::string no_main_dependency;
+ this->LocalGen->AddCustomCommandToOutput(
+ outputFile, dependencies, no_main_dependency, commandLines,
+ autogenComment.c_str(), this->Dir.Work.c_str(), /*replace=*/false,
+ /*escapeOldStyle=*/false,
+ /*uses_terminal=*/false,
+ /*command_expand_lists=*/false, this->AutogenTarget.DepFile, "",
+ stdPipesUTF8);
+
+ // Alter variables for the autogen target which now merely wraps the
+ // custom command
+ dependencies.clear();
+ dependencies.push_back(outputFile);
+ commandLines.clear();
+ autogenComment.clear();
+ }
+
// Create autogen target
- cmTarget* autogenTarget = this->Makefile->AddUtilityCommand(
- this->AutogenTarget.Name, cmCommandOrigin::Generator, true,
- this->Dir.Work.c_str(), /*byproducts=*/autogenProvides,
- std::vector<std::string>(this->AutogenTarget.DependFiles.begin(),
- this->AutogenTarget.DependFiles.end()),
- commandLines, false, autogenComment.c_str());
+ cmTarget* autogenTarget = this->LocalGen->AddUtilityCommand(
+ this->AutogenTarget.Name, true, this->Dir.Work.c_str(),
+ /*byproducts=*/autogenProvides,
+ /*depends=*/dependencies, commandLines, false, autogenComment.c_str());
// Create autogen generator target
this->LocalGen->AddGeneratorTarget(
- new cmGeneratorTarget(autogenTarget, this->LocalGen));
+ cm::make_unique<cmGeneratorTarget>(autogenTarget, this->LocalGen));
// Forward origin utilities to autogen target
if (this->AutogenTarget.DependOrigin) {
- for (BT<std::string> const& depName : this->GenTarget->GetUtilities()) {
- autogenTarget->AddUtility(depName.Value, this->Makefile);
+ for (BT<std::pair<std::string, bool>> const& depName :
+ this->GenTarget->GetUtilities()) {
+ autogenTarget->AddUtility(depName.Value.first, false, this->Makefile);
}
}
- // Add additional autogen target dependencies to autogen target
- for (cmTarget* depTarget : this->AutogenTarget.DependTargets) {
- autogenTarget->AddUtility(depTarget->GetName(), this->Makefile);
+ if (!useNinjaDepfile) {
+ // Add additional autogen target dependencies to autogen target
+ for (cmTarget* depTarget : this->AutogenTarget.DependTargets) {
+ autogenTarget->AddUtility(depTarget->GetName(), false, this->Makefile);
+ }
}
// Set FOLDER property in autogen target
if (!this->TargetsFolder.empty()) {
- autogenTarget->SetProperty("FOLDER", this->TargetsFolder.c_str());
+ autogenTarget->SetProperty("FOLDER", this->TargetsFolder);
}
// Add autogen target to the origin target dependencies
- this->GenTarget->Target->AddUtility(this->AutogenTarget.Name,
+ this->GenTarget->Target->AddUtility(this->AutogenTarget.Name, false,
this->Makefile);
// Add autogen target to the global autogen target dependencies
@@ -1179,6 +1282,7 @@ bool cmQtAutoGenInitializer::InitRccTargets()
ccDepends.push_back(qrc.QrcFile);
ccDepends.push_back(qrc.InfoFile);
+ bool stdPipesUTF8 = true;
cmCustomCommandLines commandLines;
if (this->MultiConfig) {
// Build for all configurations
@@ -1205,25 +1309,26 @@ bool cmQtAutoGenInitializer::InitRccTargets()
ccName += cmStrCat('_', qrc.QrcPathChecksum);
}
- cmTarget* autoRccTarget = this->Makefile->AddUtilityCommand(
- ccName, cmCommandOrigin::Generator, true, this->Dir.Work.c_str(),
- ccOutput, ccDepends, commandLines, false, ccComment.c_str());
+ cmTarget* autoRccTarget = this->LocalGen->AddUtilityCommand(
+ ccName, true, this->Dir.Work.c_str(), ccOutput, ccDepends,
+ commandLines, false, ccComment.c_str(), false, false, "",
+ stdPipesUTF8);
// Create autogen generator target
this->LocalGen->AddGeneratorTarget(
- new cmGeneratorTarget(autoRccTarget, this->LocalGen));
+ cm::make_unique<cmGeneratorTarget>(autoRccTarget, this->LocalGen));
// Set FOLDER property in autogen target
if (!this->TargetsFolder.empty()) {
- autoRccTarget->SetProperty("FOLDER", this->TargetsFolder.c_str());
+ autoRccTarget->SetProperty("FOLDER", this->TargetsFolder);
}
if (!this->Rcc.ExecutableTargetName.empty()) {
- autoRccTarget->AddUtility(this->Rcc.ExecutableTargetName,
+ autoRccTarget->AddUtility(this->Rcc.ExecutableTargetName, false,
this->Makefile);
}
}
// Add autogen target to the origin target dependencies
- this->GenTarget->Target->AddUtility(ccName, this->Makefile);
+ this->GenTarget->Target->AddUtility(ccName, false, this->Makefile);
// Add autogen target to the global autogen target dependencies
if (this->Rcc.GlobalTarget) {
@@ -1244,10 +1349,11 @@ bool cmQtAutoGenInitializer::InitRccTargets()
}
std::string no_main_dependency;
cmImplicitDependsList no_implicit_depends;
- this->Makefile->AddCustomCommandToOutput(
+ this->LocalGen->AddCustomCommandToOutput(
ccOutput, ccByproducts, ccDepends, no_main_dependency,
no_implicit_depends, commandLines, ccComment.c_str(),
- this->Dir.Work.c_str());
+ this->Dir.Work.c_str(), false, true, false, false, "", "",
+ stdPipesUTF8);
}
// Reconfigure when .qrc file changes
this->Makefile->AddCMakeDependFile(qrc.QrcFile);
@@ -1356,12 +1462,15 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
info.SetConfig("INCLUDE_DIR", this->Dir.Include);
info.SetUInt("QT_VERSION_MAJOR", this->QtVersion.Major);
+ info.SetUInt("QT_VERSION_MINOR", this->QtVersion.Minor);
info.Set("QT_MOC_EXECUTABLE", this->Moc.Executable);
info.Set("QT_UIC_EXECUTABLE", this->Uic.Executable);
info.Set("CMAKE_EXECUTABLE", cmSystemTools::GetCMakeCommand());
info.SetConfig("SETTINGS_FILE", this->AutogenTarget.SettingsFile);
info.SetConfig("PARSE_CACHE_FILE", this->AutogenTarget.ParseCacheFile);
+ info.Set("DEP_FILE", this->AutogenTarget.DepFile);
+ info.Set("DEP_FILE_RULE_NAME", this->AutogenTarget.DepFileRuleName);
info.SetArray("HEADER_EXTENSIONS",
this->Makefile->GetCMakeInstance()->GetHeaderExtensions());
info.SetArrayArray(
@@ -1501,10 +1610,9 @@ void cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName,
cmStrCat(genNameUpper, "_SOURCE_GROUP"), "AUTOGEN_SOURCE_GROUP"
};
for (std::string const& prop : props) {
- const char* propName =
- this->Makefile->GetState()->GetGlobalProperty(prop);
- if ((propName != nullptr) && (*propName != '\0')) {
- groupName = propName;
+ cmProp propName = this->Makefile->GetState()->GetGlobalProperty(prop);
+ if (propName && !propName->empty()) {
+ groupName = *propName;
property = prop;
break;
}
@@ -1528,8 +1636,8 @@ void cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName,
void cmQtAutoGenInitializer::AddCleanFile(std::string const& fileName)
{
- this->GenTarget->Target->AppendProperty("ADDITIONAL_CLEAN_FILES",
- fileName.c_str(), false);
+ this->GenTarget->Target->AppendProperty("ADDITIONAL_CLEAN_FILES", fileName,
+ false);
}
void cmQtAutoGenInitializer::ConfigFileNames(ConfigString& configString,
@@ -1565,6 +1673,13 @@ cmQtAutoGenInitializer::GetQtVersion(cmGeneratorTarget const* target)
}
return 0u;
};
+ auto toUInt2 = [](cmProp input) -> unsigned int {
+ unsigned long tmp = 0;
+ if (input != nullptr && cmStrToULong(*input, &tmp)) {
+ return static_cast<unsigned int>(tmp);
+ }
+ return 0u;
+ };
// Initialize return value to a default
std::pair<IntegerVersion, unsigned int> res(
@@ -1586,9 +1701,9 @@ cmQtAutoGenInitializer::GetQtVersion(cmGeneratorTarget const* target)
knownQtVersions.reserve(keys.size() * 2);
// Adds a version to the result (nullptr safe)
- auto addVersion = [&knownQtVersions, &toUInt](const char* major,
- const char* minor) {
- cmQtAutoGen::IntegerVersion ver(toUInt(major), toUInt(minor));
+ auto addVersion = [&knownQtVersions, &toUInt2](cmProp major,
+ cmProp minor) {
+ cmQtAutoGen::IntegerVersion ver(toUInt2(major), toUInt2(minor));
if (ver.Major != 0) {
knownQtVersions.emplace_back(ver);
}
@@ -1596,8 +1711,8 @@ cmQtAutoGenInitializer::GetQtVersion(cmGeneratorTarget const* target)
// Read versions from variables
for (auto const& keyPair : keys) {
- addVersion(target->Makefile->GetDefinition(std::string(keyPair.first)),
- target->Makefile->GetDefinition(std::string(keyPair.second)));
+ addVersion(target->Makefile->GetDef(std::string(keyPair.first)),
+ target->Makefile->GetDef(std::string(keyPair.second)));
}
// Read versions from directory properties
@@ -1632,21 +1747,39 @@ std::string cmQtAutoGenInitializer::GetMocBuildPath(MUFile const& muf)
if (!muf.MocIt) {
return res;
}
- {
- std::string const basePath =
- cmStrCat(this->PathCheckSum.getPart(muf.FullPath), "/moc_",
- FileNameWithoutLastExtension(muf.FullPath));
- std::string suffix;
- constexpr std::size_t num_tries_max = 256;
- for (std::size_t ii = 0; ii != num_tries_max; ++ii) {
- res = cmStrCat(basePath, suffix, ".cpp");
- if (this->Moc.EmittedBuildPaths.emplace(res).second) {
- break;
- }
- // Compute new suffix
- suffix = cmStrCat('_', ii + 1);
+
+ std::string basePath =
+ cmStrCat(this->PathCheckSum.getPart(muf.FullPath), "/moc_",
+ FileNameWithoutLastExtension(muf.FullPath));
+
+ res = cmStrCat(basePath, ".cpp");
+ if (this->Moc.EmittedBuildPaths.emplace(res).second) {
+ return res;
+ }
+
+ // File name already emitted.
+ // Try appending the header suffix to the base path.
+ basePath = cmStrCat(basePath, '_', muf.SF->GetExtension());
+ res = cmStrCat(basePath, ".cpp");
+ if (this->Moc.EmittedBuildPaths.emplace(res).second) {
+ return res;
+ }
+
+ // File name with header extension already emitted.
+ // Try adding a number to the base path.
+ constexpr std::size_t number_begin = 2;
+ constexpr std::size_t number_end = 256;
+ for (std::size_t ii = number_begin; ii != number_end; ++ii) {
+ res = cmStrCat(basePath, '_', ii, ".cpp");
+ if (this->Moc.EmittedBuildPaths.emplace(res).second) {
+ return res;
}
}
+
+ // Output file name conflict (unlikely, but still...)
+ cmSystemTools::Error(
+ cmStrCat("moc output file name conflict for ", muf.FullPath));
+
return res;
}
@@ -1662,7 +1795,7 @@ bool cmQtAutoGenInitializer::GetQtExecutable(GenVarsT& genVars,
// Custom executable
{
std::string const prop = cmStrCat(genVars.GenNameUpper, "_EXECUTABLE");
- std::string const val = this->GenTarget->Target->GetSafeProperty(prop);
+ std::string const& val = this->GenTarget->Target->GetSafeProperty(prop);
if (!val.empty()) {
// Evaluate generator expression
{
diff --git a/Source/cmQtAutoGenInitializer.h b/Source/cmQtAutoGenInitializer.h
index d55259c..48ec1a0 100644
--- a/Source/cmQtAutoGenInitializer.h
+++ b/Source/cmQtAutoGenInitializer.h
@@ -160,6 +160,8 @@ private:
bool MultiConfig = false;
bool CMP0071Accept = false;
bool CMP0071Warn = false;
+ bool CMP0100Accept = false;
+ bool CMP0100Warn = false;
std::string ConfigDefault;
std::vector<std::string> ConfigsList;
std::string TargetsFolder;
@@ -189,10 +191,13 @@ private:
bool DependOrigin = false;
std::set<std::string> DependFiles;
std::set<cmTarget*> DependTargets;
+ std::string DepFile;
+ std::string DepFileRuleName;
// Sources to process
std::unordered_map<cmSourceFile*, MUFileHandle> Headers;
std::unordered_map<cmSourceFile*, MUFileHandle> Sources;
std::vector<MUFile*> FilesGenerated;
+ std::vector<cmSourceFile*> CMP0100HeadersWarn;
} AutogenTarget;
/** moc variables. */
diff --git a/Source/cmQtAutoGenerator.cxx b/Source/cmQtAutoGenerator.cxx
index da96305..ee2bc09 100644
--- a/Source/cmQtAutoGenerator.cxx
+++ b/Source/cmQtAutoGenerator.cxx
@@ -2,9 +2,9 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmQtAutoGenerator.h"
-#include "cmsys/FStream.hxx"
+#include <cm3p/json/reader.h>
-#include "cm_jsoncpp_reader.h"
+#include "cmsys/FStream.hxx"
#include "cmQtAutoGen.h"
#include "cmStringAlgorithms.h"
diff --git a/Source/cmQtAutoGenerator.h b/Source/cmQtAutoGenerator.h
index bbe6dd0..83fb3ed 100644
--- a/Source/cmQtAutoGenerator.h
+++ b/Source/cmQtAutoGenerator.h
@@ -13,7 +13,7 @@
#include <cm/string_view>
-#include "cm_jsoncpp_value.h"
+#include <cm3p/json/value.h>
#include "cmFileTime.h"
#include "cmQtAutoGen.h"
diff --git a/Source/cmQtAutoMocUic.cxx b/Source/cmQtAutoMocUic.cxx
index f8b8981..9adcabb 100644
--- a/Source/cmQtAutoMocUic.cxx
+++ b/Source/cmQtAutoMocUic.cxx
@@ -16,15 +16,17 @@
#include <cm/memory>
#include <cm/string_view>
+#include <cmext/algorithm>
+
+#include <cm3p/json/value.h>
#include "cmsys/FStream.hxx"
#include "cmsys/RegularExpression.hxx"
-#include "cm_jsoncpp_value.h"
-
-#include "cmAlgorithms.h"
#include "cmCryptoHash.h"
#include "cmFileTime.h"
+#include "cmGccDepfileReader.h"
+#include "cmGccDepfileReaderTypes.h"
#include "cmGeneratedFileStream.h"
#include "cmQtAutoGen.h"
#include "cmQtAutoGenerator.h"
@@ -170,7 +172,7 @@ public:
// -- Attributes
// - Config
bool MultiConfig = false;
- unsigned int QtVersionMajor = 4;
+ IntegerVersion QtVersion = { 4, 0 };
unsigned int ThreadCount = 0;
// - Directories
std::string AutogenBuildDir;
@@ -179,6 +181,8 @@ public:
std::string CMakeExecutable;
cmFileTime CMakeExecutableTime;
std::string ParseCacheFile;
+ std::string DepFile;
+ std::string DepFileRuleName;
std::vector<std::string> HeaderExtensions;
};
@@ -216,6 +220,7 @@ public:
bool SettingsChanged = false;
bool RelaxedMode = false;
bool PathPrefix = false;
+ bool CanOutputDependencies = false;
cmFileTime ExecutableTime;
std::string Executable;
std::string CompFileAbs;
@@ -485,8 +490,17 @@ public:
class JobCompileMocT : public JobCompileT
{
public:
- using JobCompileT::JobCompileT;
+ JobCompileMocT(MappingHandleT uicMapping,
+ std::unique_ptr<std::string> reason,
+ ParseCacheT::FileHandleT cacheEntry)
+ : JobCompileT(std::move(uicMapping), std::move(reason))
+ , CacheEntry(std::move(cacheEntry))
+ {
+ }
void Process() override;
+
+ protected:
+ ParseCacheT::FileHandleT CacheEntry;
};
/** uic compiles a file. */
@@ -504,6 +518,12 @@ public:
void Process() override;
};
+ class JobDepFilesMergeT : public JobFenceT
+ {
+ private:
+ void Process() override;
+ };
+
/** @brief The last job. */
class JobFinishT : public JobFenceT
{
@@ -546,6 +566,9 @@ private:
void Abort(bool error);
// -- Generation
bool CreateDirectories();
+ // -- Support for depfiles
+ static std::vector<std::string> dependenciesFromDepFile(
+ const char* filePath);
private:
// -- Settings
@@ -677,27 +700,27 @@ bool cmQtAutoMocUicT::ParseCacheT::WriteToFile(std::string const& fileName)
if (!ofs) {
return false;
}
- ofs << "# Generated by CMake. Changes will be overwritten." << std::endl;
+ ofs << "# Generated by CMake. Changes will be overwritten.\n";
for (auto const& pair : Map_) {
- ofs << pair.first << std::endl;
+ ofs << pair.first << '\n';
FileT const& file = *pair.second;
if (!file.Moc.Macro.empty()) {
- ofs << " mmc:" << file.Moc.Macro << std::endl;
+ ofs << " mmc:" << file.Moc.Macro << '\n';
}
for (IncludeKeyT const& item : file.Moc.Include.Underscore) {
- ofs << " miu:" << item.Key << std::endl;
+ ofs << " miu:" << item.Key << '\n';
}
for (IncludeKeyT const& item : file.Moc.Include.Dot) {
- ofs << " mid:" << item.Key << std::endl;
+ ofs << " mid:" << item.Key << '\n';
}
for (std::string const& item : file.Moc.Depends) {
- ofs << " mdp:" << item << std::endl;
+ ofs << " mdp:" << item << '\n';
}
for (IncludeKeyT const& item : file.Uic.Include) {
- ofs << " uic:" << item.Key << std::endl;
+ ofs << " uic:" << item.Key << '\n';
}
for (std::string const& item : file.Uic.Depends) {
- ofs << " udp:" << item << std::endl;
+ ofs << " udp:" << item << '\n';
}
}
return ofs.Close();
@@ -808,9 +831,9 @@ void cmQtAutoMocUicT::JobMocPredefsT::Process()
// Compose command
std::vector<std::string> cmd = MocConst().PredefsCmd;
// Add definitions
- cmAppend(cmd, MocConst().OptionsDefinitions);
+ cm::append(cmd, MocConst().OptionsDefinitions);
// Add includes
- cmAppend(cmd, MocConst().OptionsIncludes);
+ cm::append(cmd, MocConst().OptionsIncludes);
// Execute command
if (!RunProcess(GenT::MOC, result, cmd, reason.get())) {
LogCommandError(GenT::MOC,
@@ -951,7 +974,7 @@ void cmQtAutoMocUicT::JobParseT::MocMacro()
void cmQtAutoMocUicT::JobParseT::MocDependecies()
{
- if (MocConst().DependFilters.empty()) {
+ if (MocConst().DependFilters.empty() || MocConst().CanOutputDependencies) {
return;
}
@@ -1674,8 +1697,13 @@ bool cmQtAutoMocUicT::JobProbeDepsMocT::Generate(MappingHandleT const& mapping,
if (Probe(*mapping, reason.get())) {
// Register the parent directory for creation
MocEval().OutputDirs.emplace(cmQtAutoGen::ParentDir(mapping->OutputFile));
+ // Fetch the cache entry for the source file
+ std::string const& sourceFile = mapping->SourceFile->FileName;
+ ParseCacheT::GetOrInsertT cacheEntry =
+ BaseEval().ParseCache.GetOrInsert(sourceFile);
// Add moc job
- Gen()->WorkerPool().EmplaceJob<JobCompileMocT>(mapping, std::move(reason));
+ Gen()->WorkerPool().EmplaceJob<JobCompileMocT>(
+ mapping, std::move(reason), std::move(cacheEntry.first));
// Check if a moc job for a mocs_compilation.cpp entry was generated
if (compFile) {
MocEval().CompUpdated = true;
@@ -1779,6 +1807,14 @@ cmQtAutoMocUicT::JobProbeDepsMocT::FindDependency(
std::string const& sourceDir, std::string const& includeString) const
{
using ResPair = std::pair<std::string, cmFileTime>;
+ // moc's dependency file contains absolute paths
+ if (MocConst().CanOutputDependencies) {
+ ResPair res{ includeString, {} };
+ if (res.second.Load(res.first)) {
+ return res;
+ }
+ return {};
+ }
// Search in vicinity of the source
{
ResPair res{ sourceDir + includeString, {} };
@@ -1898,6 +1934,11 @@ void cmQtAutoMocUicT::JobProbeDepsFinishT::Process()
Gen()->WorkerPool().EmplaceJob<JobMocsCompilationT>();
}
+ if (!BaseConst().DepFile.empty()) {
+ // Add job to merge dep files
+ Gen()->WorkerPool().EmplaceJob<JobDepFilesMergeT>();
+ }
+
// Add finish job
Gen()->WorkerPool().EmplaceJob<JobFinishT>();
}
@@ -1916,9 +1957,9 @@ void cmQtAutoMocUicT::JobCompileMocT::Process()
MocConst().OptionsExtra.size() + 16);
cmd.push_back(MocConst().Executable);
// Add definitions
- cmAppend(cmd, MocConst().OptionsDefinitions);
+ cm::append(cmd, MocConst().OptionsDefinitions);
// Add includes
- cmAppend(cmd, MocConst().OptionsIncludes);
+ cm::append(cmd, MocConst().OptionsIncludes);
// Add predefs include
if (!MocConst().PredefsFileAbs.empty()) {
cmd.emplace_back("--include");
@@ -1946,7 +1987,10 @@ void cmQtAutoMocUicT::JobCompileMocT::Process()
}
}
// Add extra options
- cmAppend(cmd, MocConst().OptionsExtra);
+ cm::append(cmd, MocConst().OptionsExtra);
+ if (MocConst().CanOutputDependencies) {
+ cmd.emplace_back("--output-dep-file");
+ }
// Add output file
cmd.emplace_back("-o");
cmd.push_back(outputFile);
@@ -1956,12 +2000,7 @@ void cmQtAutoMocUicT::JobCompileMocT::Process()
// Execute moc command
cmWorkerPool::ProcessResultT result;
- if (RunProcess(GenT::MOC, result, cmd, Reason.get())) {
- // Moc command success. Print moc output.
- if (!result.StdOut.empty()) {
- Log().Info(GenT::MOC, result.StdOut);
- }
- } else {
+ if (!RunProcess(GenT::MOC, result, cmd, Reason.get())) {
// Moc command failed
std::string includers;
if (!Mapping->IncluderFiles.empty()) {
@@ -1976,6 +2015,28 @@ void cmQtAutoMocUicT::JobCompileMocT::Process()
MessagePath(outputFile), '\n', includers,
result.ErrorMessage),
cmd, result.StdOut);
+ return;
+ }
+
+ // Moc command success. Print moc output.
+ if (!result.StdOut.empty()) {
+ Log().Info(GenT::MOC, result.StdOut);
+ }
+
+ // Extract dependencies from the dep file moc generated for us
+ if (MocConst().CanOutputDependencies) {
+ const std::string depfile = outputFile + ".d";
+ if (Log().Verbose()) {
+ Log().Info(GenT::MOC,
+ "Reading dependencies from " + MessagePath(depfile));
+ }
+ if (!cmSystemTools::FileExists(depfile)) {
+ Log().Warning(GenT::MOC,
+ "Dependency file " + MessagePath(depfile) +
+ " does not exist.");
+ return;
+ }
+ CacheEntry->Moc.Depends = dependenciesFromDepFile(depfile.c_str());
}
}
@@ -1992,9 +2053,9 @@ void cmQtAutoMocUicT::JobCompileUicT::Process()
auto optionIt = UicConst().UiFiles.find(sourceFile);
if (optionIt != UicConst().UiFiles.end()) {
UicMergeOptions(allOpts, optionIt->second.Options,
- (BaseConst().QtVersionMajor == 5));
+ (BaseConst().QtVersion.Major == 5));
}
- cmAppend(cmd, allOpts);
+ cm::append(cmd, allOpts);
}
cmd.emplace_back("-o");
cmd.emplace_back(outputFile);
@@ -2067,6 +2128,105 @@ void cmQtAutoMocUicT::JobMocsCompilationT::Process()
}
}
+/*
+ * Escapes paths for Ninja depfiles.
+ * This is a re-implementation of what moc does when writing depfiles.
+ */
+std::string escapeDependencyPath(cm::string_view path)
+{
+ std::string escapedPath;
+ escapedPath.reserve(path.size());
+ const size_t s = path.size();
+ int backslashCount = 0;
+ for (size_t i = 0; i < s; ++i) {
+ if (path[i] == '\\') {
+ ++backslashCount;
+ } else {
+ if (path[i] == '$') {
+ escapedPath.push_back('$');
+ } else if (path[i] == '#') {
+ escapedPath.push_back('\\');
+ } else if (path[i] == ' ') {
+ // Double the amount of written backslashes,
+ // and add one more to escape the space.
+ while (backslashCount-- >= 0) {
+ escapedPath.push_back('\\');
+ }
+ }
+ backslashCount = 0;
+ }
+ escapedPath.push_back(path[i]);
+ }
+ return escapedPath;
+}
+
+void cmQtAutoMocUicT::JobDepFilesMergeT::Process()
+{
+ if (Log().Verbose()) {
+ Log().Info(GenT::MOC, "Merging MOC dependencies");
+ }
+ auto processDepFile =
+ [](const std::string& mocOutputFile) -> std::vector<std::string> {
+ std::string f = mocOutputFile + ".d";
+ if (!cmSystemTools::FileExists(f)) {
+ return {};
+ }
+ return dependenciesFromDepFile(f.c_str());
+ };
+
+ std::vector<std::string> dependencies;
+ ParseCacheT& parseCache = BaseEval().ParseCache;
+ auto processMappingEntry = [&](const MappingMapT::value_type& m) {
+ auto cacheEntry = parseCache.GetOrInsert(m.first);
+ if (cacheEntry.first->Moc.Depends.empty()) {
+ cacheEntry.first->Moc.Depends = processDepFile(m.second->OutputFile);
+ }
+ dependencies.insert(dependencies.end(),
+ cacheEntry.first->Moc.Depends.begin(),
+ cacheEntry.first->Moc.Depends.end());
+ };
+
+ std::for_each(MocEval().HeaderMappings.begin(),
+ MocEval().HeaderMappings.end(), processMappingEntry);
+ std::for_each(MocEval().SourceMappings.begin(),
+ MocEval().SourceMappings.end(), processMappingEntry);
+
+ // Remove duplicates to make the depfile smaller
+ std::sort(dependencies.begin(), dependencies.end());
+ dependencies.erase(std::unique(dependencies.begin(), dependencies.end()),
+ dependencies.end());
+
+ // Add form files
+ for (const auto& uif : UicEval().UiFiles) {
+ dependencies.push_back(uif.first);
+ }
+
+ // Write the file
+ cmsys::ofstream ofs;
+ ofs.open(BaseConst().DepFile.c_str(),
+ (std::ios::out | std::ios::binary | std::ios::trunc));
+ if (!ofs) {
+ LogError(GenT::GEN,
+ cmStrCat("Cannot open ", MessagePath(BaseConst().DepFile),
+ " for writing."));
+ return;
+ }
+ ofs << BaseConst().DepFileRuleName << ": \\\n";
+ for (const std::string& file : dependencies) {
+ ofs << '\t' << escapeDependencyPath(file) << " \\\n";
+ if (!ofs.good()) {
+ LogError(GenT::GEN,
+ cmStrCat("Writing depfile", MessagePath(BaseConst().DepFile),
+ " failed."));
+ return;
+ }
+ }
+
+ // Add the CMake executable to re-new cache data if necessary.
+ // Also, this is the last entry, so don't add a backslash.
+ ofs << '\t' << escapeDependencyPath(BaseConst().CMakeExecutable) << '\n';
+}
+
void cmQtAutoMocUicT::JobFinishT::Process()
{
Gen()->AbortSuccess();
@@ -2082,7 +2242,8 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info)
{
// -- Required settings
if (!info.GetBool("MULTI_CONFIG", BaseConst_.MultiConfig, true) ||
- !info.GetUInt("QT_VERSION_MAJOR", BaseConst_.QtVersionMajor, true) ||
+ !info.GetUInt("QT_VERSION_MAJOR", BaseConst_.QtVersion.Major, true) ||
+ !info.GetUInt("QT_VERSION_MINOR", BaseConst_.QtVersion.Minor, true) ||
!info.GetUInt("PARALLEL", BaseConst_.ThreadCount, false) ||
!info.GetString("BUILD_DIR", BaseConst_.AutogenBuildDir, true) ||
!info.GetStringConfig("INCLUDE_DIR", BaseConst_.AutogenIncludeDir,
@@ -2090,6 +2251,9 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info)
!info.GetString("CMAKE_EXECUTABLE", BaseConst_.CMakeExecutable, true) ||
!info.GetStringConfig("PARSE_CACHE_FILE", BaseConst_.ParseCacheFile,
true) ||
+ !info.GetString("DEP_FILE", BaseConst_.DepFile, false) ||
+ !info.GetString("DEP_FILE_RULE_NAME", BaseConst_.DepFileRuleName,
+ false) ||
!info.GetStringConfig("SETTINGS_FILE", SettingsFile_, true) ||
!info.GetArray("HEADER_EXTENSIONS", BaseConst_.HeaderExtensions, true) ||
!info.GetString("QT_MOC_EXECUTABLE", MocConst_.Executable, false) ||
@@ -2143,8 +2307,10 @@ bool cmQtAutoMocUicT::InitFromInfo(InfoT const& info)
MocConst_.MacroFilters.emplace_back(
item, ("[\n][ \t]*{?[ \t]*" + item).append("[^a-zA-Z0-9_]"));
}
- // Dependency filters
- {
+ // Can moc output dependencies or do we need to setup dependency filters?
+ if (BaseConst_.QtVersion >= IntegerVersion(5, 15)) {
+ MocConst_.CanOutputDependencies = true;
+ } else {
Json::Value const& val = info.GetValue("MOC_DEPEND_FILTERS");
if (!val.isArray()) {
return info.LogError("MOC_DEPEND_FILTERS JSON value is not an array.");
@@ -2660,6 +2826,19 @@ bool cmQtAutoMocUicT::CreateDirectories()
return true;
}
+std::vector<std::string> cmQtAutoMocUicT::dependenciesFromDepFile(
+ const char* filePath)
+{
+ cmGccDepfileContent content = cmReadGccDepfile(filePath);
+ if (content.empty()) {
+ return {};
+ }
+
+ // Moc outputs a depfile with exactly one rule.
+ // Discard the rule and return the dependencies.
+ return content.front().paths;
+}
+
void cmQtAutoMocUicT::Abort(bool error)
{
if (error) {
diff --git a/Source/cmQtAutoRcc.cxx b/Source/cmQtAutoRcc.cxx
index 3af81ad..08eb4b5 100644
--- a/Source/cmQtAutoRcc.cxx
+++ b/Source/cmQtAutoRcc.cxx
@@ -6,7 +6,8 @@
#include <string>
#include <vector>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmCryptoHash.h"
#include "cmDuration.h"
#include "cmFileLock.h"
@@ -405,7 +406,7 @@ bool cmQtAutoRccT::GenerateRcc()
// Compose rcc command
std::vector<std::string> cmd;
cmd.push_back(RccExecutable_);
- cmAppend(cmd, Options_);
+ cm::append(cmd, Options_);
cmd.emplace_back("-o");
cmd.push_back(RccFileOutput_);
cmd.push_back(QrcFile_);
diff --git a/Source/cmRST.cxx b/Source/cmRST.cxx
index 7f4abf9..26e93bb 100644
--- a/Source/cmRST.cxx
+++ b/Source/cmRST.cxx
@@ -89,7 +89,8 @@ void cmRST::ProcessModule(std::istream& is)
this->ProcessLine(line);
} else {
if (line[0] != '#') {
- this->ProcessLine(line.substr(0, pos));
+ line.resize(pos);
+ this->ProcessLine(line);
}
rst.clear();
this->Reset();
@@ -102,8 +103,9 @@ void cmRST::ProcessModule(std::istream& is)
this->ProcessLine("");
continue;
}
- if (line.substr(0, 2) == "# ") {
- this->ProcessLine(line.substr(2));
+ if (cmHasLiteralPrefix(line, "# ")) {
+ line.erase(0, 2);
+ this->ProcessLine(line);
continue;
}
rst.clear();
@@ -164,6 +166,8 @@ void cmRST::ProcessLine(std::string const& line)
this->Markup =
(line.find_first_not_of(" \t", 2) == std::string::npos ? MarkupEmpty
: MarkupNormal);
+ // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
+ // NOLINTNEXTLINE(bugprone-branch-clone)
if (this->CMakeDirective.find(line)) {
// Output cmake domain directives and their content normally.
this->NormalLine(line);
diff --git a/Source/cmRulePlaceholderExpander.cxx b/Source/cmRulePlaceholderExpander.cxx
index 0a1d109..254131b 100644
--- a/Source/cmRulePlaceholderExpander.cxx
+++ b/Source/cmRulePlaceholderExpander.cxx
@@ -85,6 +85,11 @@ std::string cmRulePlaceholderExpander::ExpandRuleVariable(
return replaceValues.ObjectsQuoted;
}
}
+ if (replaceValues.AIXExports) {
+ if (variable == "AIX_EXPORTS") {
+ return replaceValues.AIXExports;
+ }
+ }
if (replaceValues.Defines && variable == "DEFINES") {
return replaceValues.Defines;
}
@@ -231,8 +236,7 @@ std::string cmRulePlaceholderExpander::ExpandRuleVariable(
}
if (variable == "CMAKE_COMMAND") {
return outputConverter->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(cmSystemTools::GetCMakeCommand()),
- cmOutputConverter::SHELL);
+ cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL);
}
auto compIt = this->Compilers.find(variable);
@@ -329,7 +333,17 @@ void cmRulePlaceholderExpander::ExpandRuleVariables(
std::string replace =
this->ExpandRuleVariable(outputConverter, var, replaceValues);
expandedInput += s.substr(pos, start - pos);
+
+ // Prevent consecutive whitespace in the output if the rule variable
+ // expands to an empty string.
+ bool consecutive = replace.empty() && start > 0 && s[start - 1] == ' ' &&
+ end + 1 < s.size() && s[end + 1] == ' ';
+ if (consecutive) {
+ expandedInput.pop_back();
+ }
+
expandedInput += replace;
+
// move to next one
start = s.find('<', start + var.size() + 2);
pos = end + 1;
diff --git a/Source/cmRulePlaceholderExpander.h b/Source/cmRulePlaceholderExpander.h
index 8f36196..09e8a3b 100644
--- a/Source/cmRulePlaceholderExpander.h
+++ b/Source/cmRulePlaceholderExpander.h
@@ -36,6 +36,7 @@ public:
const char* TargetVersionMajor;
const char* TargetVersionMinor;
const char* Language;
+ const char* AIXExports;
const char* Objects;
const char* Target;
const char* LinkLibraries;
diff --git a/Source/cmRuntimeDependencyArchive.cxx b/Source/cmRuntimeDependencyArchive.cxx
index 7a987c2..0781d29 100644
--- a/Source/cmRuntimeDependencyArchive.cxx
+++ b/Source/cmRuntimeDependencyArchive.cxx
@@ -39,7 +39,7 @@ static void AddVisualStudioPath(std::vector<std::string>& paths,
std::string vsloc;
bool found = false;
# ifndef CMAKE_BOOTSTRAP
- if (gg->GetName().find(prefix) == 0) {
+ if (cmHasPrefix(gg->GetName(), prefix)) {
cmGlobalVisualStudioVersionedGenerator* vsgen =
static_cast<cmGlobalVisualStudioVersionedGenerator*>(gg);
if (vsgen->GetVSInstance(vsloc)) {
@@ -218,6 +218,9 @@ bool cmRuntimeDependencyArchive::GetGetRuntimeDependenciesCommand(
// First see if it was supplied by the user
std::string toolCommand = this->GetMakefile()->GetSafeDefinition(
"CMAKE_GET_RUNTIME_DEPENDENCIES_COMMAND");
+ if (toolCommand.empty() && search == "objdump") {
+ toolCommand = this->GetMakefile()->GetSafeDefinition("CMAKE_OBJDUMP");
+ }
if (!toolCommand.empty()) {
cmExpandList(toolCommand, command);
return true;
diff --git a/Source/cmScriptGenerator.h b/Source/cmScriptGenerator.h
index c8bb1ab..7d676c9 100644
--- a/Source/cmScriptGenerator.h
+++ b/Source/cmScriptGenerator.h
@@ -71,7 +71,7 @@ protected:
std::string CreateConfigTest(const std::string& config);
std::string CreateConfigTest(std::vector<std::string> const& configs);
- std::string CreateComponentTest(const char* component);
+ std::string CreateComponentTest(const std::string& component);
// Information shared by most generator types.
std::string RuntimeConfigVariable;
diff --git a/Source/cmSearchPath.cxx b/Source/cmSearchPath.cxx
index d15ce57..766d347 100644
--- a/Source/cmSearchPath.cxx
+++ b/Source/cmSearchPath.cxx
@@ -181,7 +181,13 @@ void cmSearchPath::AddPrefixPaths(const std::vector<std::string>& paths,
const char* arch =
this->FC->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE");
if (arch && *arch) {
- this->AddPathInternal(dir + subdir + "/" + arch, base);
+ if (this->FC->Makefile->IsDefinitionSet("CMAKE_SYSROOT") &&
+ this->FC->Makefile->IsDefinitionSet(
+ "CMAKE_PREFIX_LIBRARY_ARCHITECTURE")) {
+ this->AddPathInternal(cmStrCat('/', arch, dir, subdir), base);
+ } else {
+ this->AddPathInternal(cmStrCat(dir, subdir, '/', arch), base);
+ }
}
}
std::string add = dir + subdir;
diff --git a/Source/cmSearchPath.h b/Source/cmSearchPath.h
index 2a576ed..3ecc73b 100644
--- a/Source/cmSearchPath.h
+++ b/Source/cmSearchPath.h
@@ -5,6 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <cstddef>
#include <set>
#include <string>
#include <vector>
@@ -27,6 +28,7 @@ public:
~cmSearchPath();
const std::vector<std::string>& GetPaths() const { return this->Paths; }
+ std::size_t size() const { return this->Paths.size(); }
void ExtractWithout(const std::set<std::string>& ignore,
std::vector<std::string>& outPaths,
diff --git a/Source/cmSeparateArgumentsCommand.cxx b/Source/cmSeparateArgumentsCommand.cxx
index 52bde7c..cfe3087 100644
--- a/Source/cmSeparateArgumentsCommand.cxx
+++ b/Source/cmSeparateArgumentsCommand.cxx
@@ -39,6 +39,8 @@ bool cmSeparateArgumentsCommand(std::vector<std::string> const& args,
if (doing == DoingVariable) {
var = arg;
doing = DoingMode;
+ // This will always clone one of the other blocks.
+ // NOLINTNEXTLINE(bugprone-branch-clone)
} else if (doing == DoingMode && arg == "NATIVE_COMMAND") {
#ifdef _WIN32
mode = ModeWindows;
diff --git a/Source/cmServer.cxx b/Source/cmServer.cxx
index 3b2e5f3..7f97406 100644
--- a/Source/cmServer.cxx
+++ b/Source/cmServer.cxx
@@ -4,6 +4,7 @@
#include <algorithm>
#include <cassert>
+#include <csignal>
#include <cstdint>
#include <iostream>
#include <mutex>
@@ -12,10 +13,10 @@
#include <cm/memory>
#include <cm/shared_mutex>
-#include "cmsys/FStream.hxx"
+#include <cm3p/json/reader.h>
+#include <cm3p/json/writer.h>
-#include "cm_jsoncpp_reader.h"
-#include "cm_jsoncpp_writer.h"
+#include "cmsys/FStream.hxx"
#include "cmConnection.h"
#include "cmFileMonitor.h"
@@ -59,16 +60,12 @@ cmServer::cmServer(cmConnection* conn, bool supportExperimental)
, SupportExperimental(supportExperimental)
{
// Register supported protocols:
- this->RegisterProtocol(new cmServerProtocol1);
+ this->RegisterProtocol(cm::make_unique<cmServerProtocol1>());
}
cmServer::~cmServer()
{
Close();
-
- for (cmServerProtocol* p : this->SupportedProtocols) {
- delete p;
- }
}
void cmServer::ProcessRequest(cmConnection* connection,
@@ -117,22 +114,22 @@ void cmServer::ProcessRequest(cmConnection* connection,
}
}
-void cmServer::RegisterProtocol(cmServerProtocol* protocol)
+void cmServer::RegisterProtocol(std::unique_ptr<cmServerProtocol> protocol)
{
if (protocol->IsExperimental() && !this->SupportExperimental) {
- delete protocol;
+ protocol.reset();
return;
}
auto version = protocol->ProtocolVersion();
assert(version.first >= 0);
assert(version.second >= 0);
- auto it = std::find_if(this->SupportedProtocols.begin(),
- this->SupportedProtocols.end(),
- [version](cmServerProtocol* p) {
- return p->ProtocolVersion() == version;
- });
+ auto it = std::find_if(
+ this->SupportedProtocols.begin(), this->SupportedProtocols.end(),
+ [version](const std::unique_ptr<cmServerProtocol>& p) {
+ return p->ProtocolVersion() == version;
+ });
if (it == this->SupportedProtocols.end()) {
- this->SupportedProtocols.push_back(protocol);
+ this->SupportedProtocols.push_back(std::move(protocol));
}
}
@@ -297,19 +294,20 @@ void cmServer::WriteJsonObject(cmConnection* connection,
}
cmServerProtocol* cmServer::FindMatchingProtocol(
- const std::vector<cmServerProtocol*>& protocols, int major, int minor)
+ const std::vector<std::unique_ptr<cmServerProtocol>>& protocols, int major,
+ int minor)
{
cmServerProtocol* bestMatch = nullptr;
- for (auto protocol : protocols) {
+ for (const auto& protocol : protocols) {
auto version = protocol->ProtocolVersion();
if (major != version.first) {
continue;
}
if (minor == version.second) {
- return protocol;
+ return protocol.get();
}
if (!bestMatch || bestMatch->ProtocolVersion().second < version.second) {
- bestMatch = protocol;
+ bestMatch = protocol.get();
}
}
return minor < 0 ? bestMatch : nullptr;
diff --git a/Source/cmServer.h b/Source/cmServer.h
index 3d7027b..9543329 100644
--- a/Source/cmServer.h
+++ b/Source/cmServer.h
@@ -10,8 +10,8 @@
#include <cm/shared_mutex>
-#include "cm_jsoncpp_value.h"
-#include "cm_uv.h"
+#include <cm3p/json/value.h>
+#include <cm3p/uv.h>
#include "cmUVHandlePtr.h"
@@ -103,7 +103,7 @@ public:
cmFileMonitor* FileMonitor() const;
private:
- void RegisterProtocol(cmServerProtocol* protocol);
+ void RegisterProtocol(std::unique_ptr<cmServerProtocol> protocol);
// Callbacks from cmServerConnection:
@@ -149,12 +149,13 @@ private:
const DebugInfo* debug) const;
static cmServerProtocol* FindMatchingProtocol(
- const std::vector<cmServerProtocol*>& protocols, int major, int minor);
+ const std::vector<std::unique_ptr<cmServerProtocol>>& protocols, int major,
+ int minor);
const bool SupportExperimental;
cmServerProtocol* Protocol = nullptr;
- std::vector<cmServerProtocol*> SupportedProtocols;
+ std::vector<std::unique_ptr<cmServerProtocol>> SupportedProtocols;
friend class cmServerProtocol;
friend class cmServerRequest;
diff --git a/Source/cmServerConnection.cxx b/Source/cmServerConnection.cxx
index 2791972..b4f41a0 100644
--- a/Source/cmServerConnection.cxx
+++ b/Source/cmServerConnection.cxx
@@ -4,7 +4,7 @@
#include "cmServerConnection.h"
-#include "cm_uv.h"
+#include <cm3p/uv.h>
#include "cmServer.h"
#include "cmServerDictionary.h"
diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx
index 56003df..6b32de3 100644
--- a/Source/cmServerProtocol.cxx
+++ b/Source/cmServerProtocol.cxx
@@ -10,10 +10,10 @@
#include <vector>
#include <cm/memory>
+#include <cmext/algorithm>
-#include "cm_uv.h"
+#include <cm3p/uv.h>
-#include "cmAlgorithms.h"
#include "cmExternalMakefileProjectGenerator.h"
#include "cmFileMonitor.h"
#include "cmGlobalGenerator.h"
@@ -26,6 +26,8 @@
#include "cmSystemTools.h"
#include "cmake.h"
+using cmProp = const std::string*; // just to silence IWYU
+
// Get rid of some windows macros:
#undef max
@@ -182,7 +184,7 @@ static bool getOrTestHomeDirectory(cmState* state, std::string& value,
std::string* errorMessage)
{
const std::string cachedValue =
- std::string(state->GetCacheEntryValue("CMAKE_HOME_DIRECTORY"));
+ *state->GetCacheEntryValue("CMAKE_HOME_DIRECTORY");
if (value.empty()) {
value = cachedValue;
return true;
@@ -205,9 +207,7 @@ static bool getOrTestValue(cmState* state, const std::string& key,
const std::string& keyDescription,
std::string* errorMessage)
{
- const char* entry = state->GetCacheEntryValue(key);
- const std::string cachedValue =
- entry == nullptr ? std::string() : std::string(entry);
+ const std::string cachedValue = state->GetSafeCacheEntryValue(key);
if (value.empty()) {
value = cachedValue;
}
@@ -435,7 +435,7 @@ cmServerResponse cmServerProtocol1::ProcessCache(
keys = allKeys;
} else {
for (auto const& i : keys) {
- if (!cmContains(allKeys, i)) {
+ if (!cm::contains(allKeys, i)) {
return request.ReportError("Key \"" + i + "\" not found in cache.");
}
}
@@ -452,7 +452,7 @@ cmServerResponse cmServerProtocol1::ProcessCache(
bool haveProperties = false;
for (auto const& prop : state->GetCacheEntryPropertyList(key)) {
haveProperties = true;
- props[prop] = state->GetCacheEntryProperty(key, prop);
+ props[prop] = *state->GetCacheEntryProperty(key, prop);
}
if (haveProperties) {
entry[kPROPERTIES_KEY] = props;
@@ -564,7 +564,7 @@ cmServerResponse cmServerProtocol1::ProcessConfigure(
if (cm->LoadCache(buildDir)) {
// build directory has been set up before
- const std::string* cachedSourceDir =
+ cmProp cachedSourceDir =
cm->GetState()->GetInitializedCacheValue("CMAKE_HOME_DIRECTORY");
if (!cachedSourceDir) {
return request.ReportError("No CMAKE_HOME_DIRECTORY found in cache.");
@@ -574,7 +574,7 @@ cmServerResponse cmServerProtocol1::ProcessConfigure(
cm->SetHomeDirectory(sourceDir);
}
- const std::string* cachedGenerator =
+ cmProp cachedGenerator =
cm->GetState()->GetInitializedCacheValue("CMAKE_GENERATOR");
if (cachedGenerator) {
if (gg && gg->GetName() != *cachedGenerator) {
@@ -744,7 +744,7 @@ void cmServerProtocol1::GeneratorInformation::SetupGenerator(
cm->SetHomeDirectory(SourceDirectory);
cm->SetHomeOutputDirectory(BuildDirectory);
- cmGlobalGenerator* gg = cm->CreateGlobalGenerator(fullGeneratorName);
+ auto gg = cm->CreateGlobalGenerator(fullGeneratorName);
if (!gg) {
setErrorMessage(
errorMessage,
@@ -753,7 +753,7 @@ void cmServerProtocol1::GeneratorInformation::SetupGenerator(
return;
}
- cm->SetGlobalGenerator(gg);
+ cm->SetGlobalGenerator(std::move(gg));
cm->SetGeneratorToolset(Toolset);
cm->SetGeneratorPlatform(Platform);
diff --git a/Source/cmServerProtocol.h b/Source/cmServerProtocol.h
index 8446c3e..c71b7bf 100644
--- a/Source/cmServerProtocol.h
+++ b/Source/cmServerProtocol.h
@@ -8,7 +8,7 @@
#include <string>
#include <utility>
-#include "cm_jsoncpp_value.h"
+#include <cm3p/json/value.h>
#include "cmake.h"
diff --git a/Source/cmSetCommand.cxx b/Source/cmSetCommand.cxx
index 8c3a4cb..5c55427 100644
--- a/Source/cmSetCommand.cxx
+++ b/Source/cmSetCommand.cxx
@@ -121,7 +121,7 @@ bool cmSetCommand(std::vector<std::string> const& args,
if (cache) {
std::string::size_type cacheStart = args.size() - 3 - (force ? 1 : 0);
- if (!cmState::StringToCacheEntryType(args[cacheStart + 1].c_str(), type)) {
+ if (!cmState::StringToCacheEntryType(args[cacheStart + 1], type)) {
std::string m = "implicitly converting '" + args[cacheStart + 1] +
"' to 'STRING' type.";
status.GetMakefile().IssueMessage(MessageType::AUTHOR_WARNING, m);
@@ -135,7 +135,7 @@ bool cmSetCommand(std::vector<std::string> const& args,
// see if this is already in the cache
cmState* state = status.GetMakefile().GetState();
- const char* existingValue = state->GetCacheEntryValue(variable);
+ cmProp existingValue = state->GetCacheEntryValue(variable);
if (existingValue &&
(state->GetCacheEntryType(variable) != cmStateEnums::UNINITIALIZED)) {
// if the set is trying to CACHE the value but the value
@@ -149,8 +149,8 @@ bool cmSetCommand(std::vector<std::string> const& args,
// if it is meant to be in the cache then define it in the cache
if (cache) {
- status.GetMakefile().AddCacheDefinition(variable, value.c_str(), docstring,
- type, force);
+ status.GetMakefile().AddCacheDefinition(variable, value, docstring, type,
+ force);
} else {
// add the definition
status.GetMakefile().AddDefinition(variable, value);
diff --git a/Source/cmSetDirectoryPropertiesCommand.cxx b/Source/cmSetDirectoryPropertiesCommand.cxx
index 35daca6..07ad246 100644
--- a/Source/cmSetDirectoryPropertiesCommand.cxx
+++ b/Source/cmSetDirectoryPropertiesCommand.cxx
@@ -5,12 +5,6 @@
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
-namespace {
-bool RunCommand(cmMakefile& mf, std::vector<std::string>::const_iterator ait,
- std::vector<std::string>::const_iterator aitend,
- std::string& errors);
-}
-
// cmSetDirectoryPropertiesCommand
bool cmSetDirectoryPropertiesCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
@@ -20,38 +14,26 @@ bool cmSetDirectoryPropertiesCommand(std::vector<std::string> const& args,
return false;
}
- std::string errors;
- bool ret =
- RunCommand(status.GetMakefile(), args.begin() + 1, args.end(), errors);
- if (!ret) {
- status.SetError(errors);
+ // PROPERTIES followed by prop value pairs
+ if (args.size() % 2 != 1) {
+ status.SetError("Wrong number of arguments");
+ return false;
}
- return ret;
-}
-namespace {
-bool RunCommand(cmMakefile& mf, std::vector<std::string>::const_iterator ait,
- std::vector<std::string>::const_iterator aitend,
- std::string& errors)
-{
- for (; ait != aitend; ait += 2) {
- if (ait + 1 == aitend) {
- errors = "Wrong number of arguments";
- return false;
- }
- const std::string& prop = *ait;
- const std::string& value = *(ait + 1);
+ for (auto iter = args.begin() + 1; iter != args.end(); iter += 2) {
+ const std::string& prop = *iter;
if (prop == "VARIABLES") {
- errors = "Variables and cache variables should be set using SET command";
+ status.SetError(
+ "Variables and cache variables should be set using SET command");
return false;
}
if (prop == "MACROS") {
- errors = "Commands and macros cannot be set using SET_CMAKE_PROPERTIES";
+ status.SetError(
+ "Commands and macros cannot be set using SET_CMAKE_PROPERTIES");
return false;
}
- mf.SetProperty(prop, value.c_str());
+ status.GetMakefile().SetProperty(prop, (iter + 1)->c_str());
}
return true;
}
-}
diff --git a/Source/cmSetPropertyCommand.cxx b/Source/cmSetPropertyCommand.cxx
index 112d832..07cb7c9 100644
--- a/Source/cmSetPropertyCommand.cxx
+++ b/Source/cmSetPropertyCommand.cxx
@@ -43,7 +43,9 @@ bool HandleSourceMode(cmExecutionStatus& status,
const std::set<std::string>& names,
const std::string& propertyName,
const std::string& propertyValue, bool appendAsString,
- bool appendMode, bool remove);
+ bool appendMode, bool remove,
+ const std::vector<cmMakefile*>& directory_makefiles,
+ bool source_file_paths_should_be_absolute);
bool HandleSource(cmSourceFile* sf, const std::string& propertyName,
const std::string& propertyValue, bool appendAsString,
bool appendMode, bool remove);
@@ -74,6 +76,131 @@ bool HandleInstall(cmInstalledFile* file, cmMakefile& makefile,
bool appendMode, bool remove);
}
+namespace SetPropertyCommand {
+bool HandleSourceFileDirectoryScopes(
+ cmExecutionStatus& status, std::vector<std::string>& source_file_directories,
+ std::vector<std::string>& source_file_target_directories,
+ std::vector<cmMakefile*>& directory_makefiles)
+{
+ cmMakefile* current_dir_mf = &status.GetMakefile();
+ if (!source_file_directories.empty()) {
+ for (const std::string& dir_path : source_file_directories) {
+ const std::string absolute_dir_path = cmSystemTools::CollapseFullPath(
+ dir_path, current_dir_mf->GetCurrentSourceDirectory());
+ cmMakefile* dir_mf =
+ status.GetMakefile().GetGlobalGenerator()->FindMakefile(
+ absolute_dir_path);
+ if (!dir_mf) {
+ status.SetError(cmStrCat("given non-existent DIRECTORY ", dir_path));
+ return false;
+ }
+ directory_makefiles.push_back(dir_mf);
+ }
+ } else if (!source_file_target_directories.empty()) {
+ for (const std::string& target_name : source_file_target_directories) {
+ cmTarget* target = current_dir_mf->FindTargetToUse(target_name);
+ if (!target) {
+ status.SetError(cmStrCat(
+ "given non-existent target for DIRECTORY_TARGET ", target_name));
+ return false;
+ }
+ cmProp target_source_dir = target->GetProperty("SOURCE_DIR");
+ cmMakefile* target_dir_mf =
+ status.GetMakefile().GetGlobalGenerator()->FindMakefile(
+ *target_source_dir);
+ directory_makefiles.push_back(target_dir_mf);
+ }
+ } else {
+ directory_makefiles.push_back(current_dir_mf);
+ }
+ return true;
+}
+
+bool HandleSourceFileDirectoryScopeValidation(
+ cmExecutionStatus& status, bool source_file_directory_option_enabled,
+ bool source_file_target_option_enabled,
+ std::vector<std::string>& source_file_directories,
+ std::vector<std::string>& source_file_target_directories)
+{
+ // Validate source file directory scopes.
+ if (source_file_directory_option_enabled &&
+ source_file_directories.empty()) {
+ std::string errors = "called with incorrect number of arguments "
+ "no value provided to the DIRECTORY option";
+ status.SetError(errors);
+ return false;
+ }
+ if (source_file_target_option_enabled &&
+ source_file_target_directories.empty()) {
+ std::string errors = "called with incorrect number of arguments "
+ "no value provided to the TARGET_DIRECTORY option";
+ status.SetError(errors);
+ return false;
+ }
+ return true;
+}
+
+bool HandleAndValidateSourceFileDirectortoryScopes(
+ cmExecutionStatus& status, bool source_file_directory_option_enabled,
+ bool source_file_target_option_enabled,
+ std::vector<std::string>& source_file_directories,
+ std::vector<std::string>& source_file_target_directories,
+ std::vector<cmMakefile*>& source_file_directory_makefiles)
+{
+ bool scope_options_valid =
+ SetPropertyCommand::HandleSourceFileDirectoryScopeValidation(
+ status, source_file_directory_option_enabled,
+ source_file_target_option_enabled, source_file_directories,
+ source_file_target_directories);
+ if (!scope_options_valid) {
+ return false;
+ }
+
+ scope_options_valid = SetPropertyCommand::HandleSourceFileDirectoryScopes(
+ status, source_file_directories, source_file_target_directories,
+ source_file_directory_makefiles);
+ return scope_options_valid;
+}
+
+std::string MakeSourceFilePathAbsoluteIfNeeded(
+ cmExecutionStatus& status, const std::string& source_file_path,
+ const bool needed)
+{
+ if (!needed) {
+ return source_file_path;
+ }
+ const std::string absolute_file_path = cmSystemTools::CollapseFullPath(
+ source_file_path, status.GetMakefile().GetCurrentSourceDirectory());
+ return absolute_file_path;
+}
+
+void MakeSourceFilePathsAbsoluteIfNeeded(
+ cmExecutionStatus& status,
+ std::vector<std::string>& source_files_absolute_paths,
+ std::vector<std::string>::const_iterator files_it_begin,
+ std::vector<std::string>::const_iterator files_it_end, const bool needed)
+{
+
+ // Make the file paths absolute, so that relative source file paths are
+ // picked up relative to the command calling site, regardless of the
+ // directory scope.
+ std::vector<std::string>::difference_type num_files =
+ files_it_end - files_it_begin;
+ source_files_absolute_paths.reserve(num_files);
+
+ if (!needed) {
+ source_files_absolute_paths.assign(files_it_begin, files_it_end);
+ return;
+ }
+
+ for (; files_it_begin != files_it_end; ++files_it_begin) {
+ const std::string absolute_file_path =
+ MakeSourceFilePathAbsoluteIfNeeded(status, *files_it_begin, true);
+ source_files_absolute_paths.push_back(absolute_file_path);
+ }
+}
+}
+
bool cmSetPropertyCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
@@ -114,13 +241,20 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
std::string propertyName;
std::string propertyValue;
+ std::vector<std::string> source_file_directories;
+ std::vector<std::string> source_file_target_directories;
+ bool source_file_directory_option_enabled = false;
+ bool source_file_target_option_enabled = false;
+
// Parse the rest of the arguments up to the values.
enum Doing
{
DoingNone,
DoingNames,
DoingProperty,
- DoingValues
+ DoingValues,
+ DoingSourceDirectory,
+ DoingSourceTargetDirectory
};
Doing doing = DoingNames;
const char* sep = "";
@@ -137,8 +271,20 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
appendMode = true;
remove = false;
appendAsString = true;
+ } else if (doing == DoingNames && scope == cmProperty::SOURCE_FILE &&
+ arg == "DIRECTORY") {
+ doing = DoingSourceDirectory;
+ source_file_directory_option_enabled = true;
+ } else if (doing == DoingNames && scope == cmProperty::SOURCE_FILE &&
+ arg == "TARGET_DIRECTORY") {
+ doing = DoingSourceTargetDirectory;
+ source_file_target_option_enabled = true;
} else if (doing == DoingNames) {
names.insert(arg);
+ } else if (doing == DoingSourceDirectory) {
+ source_file_directories.push_back(arg);
+ } else if (doing == DoingSourceTargetDirectory) {
+ source_file_target_directories.push_back(arg);
} else if (doing == DoingProperty) {
propertyName = arg;
doing = DoingValues;
@@ -159,6 +305,18 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
return false;
}
+ std::vector<cmMakefile*> source_file_directory_makefiles;
+ bool file_scopes_handled =
+ SetPropertyCommand::HandleAndValidateSourceFileDirectortoryScopes(
+ status, source_file_directory_option_enabled,
+ source_file_target_option_enabled, source_file_directories,
+ source_file_target_directories, source_file_directory_makefiles);
+ if (!file_scopes_handled) {
+ return false;
+ }
+ bool source_file_paths_should_be_absolute =
+ source_file_directory_option_enabled || source_file_target_option_enabled;
+
// Dispatch property setting.
switch (scope) {
case cmProperty::GLOBAL:
@@ -172,7 +330,9 @@ bool cmSetPropertyCommand(std::vector<std::string> const& args,
appendAsString, appendMode, remove);
case cmProperty::SOURCE_FILE:
return HandleSourceMode(status, names, propertyName, propertyValue,
- appendAsString, appendMode, remove);
+ appendAsString, appendMode, remove,
+ source_file_directory_makefiles,
+ source_file_paths_should_be_absolute);
case cmProperty::TEST:
return HandleTestMode(status, names, propertyName, propertyValue,
appendAsString, appendMode, remove);
@@ -194,9 +354,8 @@ namespace {
bool HandleGlobalMode(cmExecutionStatus& status,
const std::set<std::string>& names,
const std::string& propertyName,
- const std::string& propertyValue,
- const bool appendAsString, const bool appendMode,
- const bool remove)
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove)
{
if (!names.empty()) {
status.SetError("given names for GLOBAL scope.");
@@ -205,14 +364,14 @@ bool HandleGlobalMode(cmExecutionStatus& status,
// Set or append the property.
cmake* cm = status.GetMakefile().GetCMakeInstance();
- const char* value = propertyValue.c_str();
- if (remove) {
- value = nullptr;
- }
if (appendMode) {
- cm->AppendProperty(propertyName, value ? value : "", appendAsString);
+ cm->AppendProperty(propertyName, propertyValue, appendAsString);
} else {
- cm->SetProperty(propertyName, value);
+ if (remove) {
+ cm->SetProperty(propertyName, nullptr);
+ } else {
+ cm->SetProperty(propertyName, propertyValue.c_str());
+ }
}
return true;
@@ -221,9 +380,8 @@ bool HandleGlobalMode(cmExecutionStatus& status,
bool HandleDirectoryMode(cmExecutionStatus& status,
const std::set<std::string>& names,
const std::string& propertyName,
- const std::string& propertyValue,
- const bool appendAsString, const bool appendMode,
- const bool remove)
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove)
{
if (names.size() > 1) {
status.SetError("allows at most one name for DIRECTORY scope.");
@@ -237,14 +395,8 @@ bool HandleDirectoryMode(cmExecutionStatus& status,
if (!names.empty()) {
// Construct the directory name. Interpret relative paths with
// respect to the current directory.
- std::string dir = *names.begin();
- if (!cmSystemTools::FileIsFullPath(dir)) {
- dir = cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/',
- *names.begin());
- }
-
- // The local generators are associated with collapsed paths.
- dir = cmSystemTools::CollapseFullPath(dir);
+ std::string dir = cmSystemTools::CollapseFullPath(
+ *names.begin(), status.GetMakefile().GetCurrentSourceDirectory());
mf = status.GetMakefile().GetGlobalGenerator()->FindMakefile(dir);
if (!mf) {
@@ -258,14 +410,14 @@ bool HandleDirectoryMode(cmExecutionStatus& status,
}
// Set or append the property.
- const char* value = propertyValue.c_str();
- if (remove) {
- value = nullptr;
- }
if (appendMode) {
- mf->AppendProperty(propertyName, value ? value : "", appendAsString);
+ mf->AppendProperty(propertyName, propertyValue, appendAsString);
} else {
- mf->SetProperty(propertyName, value);
+ if (remove) {
+ mf->SetProperty(propertyName, nullptr);
+ } else {
+ mf->SetProperty(propertyName, propertyValue.c_str());
+ }
}
return true;
@@ -274,9 +426,8 @@ bool HandleDirectoryMode(cmExecutionStatus& status,
bool HandleTargetMode(cmExecutionStatus& status,
const std::set<std::string>& names,
const std::string& propertyName,
- const std::string& propertyValue,
- const bool appendAsString, const bool appendMode,
- const bool remove)
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove)
{
for (std::string const& name : names) {
if (status.GetMakefile().IsAlias(name)) {
@@ -300,18 +451,18 @@ bool HandleTargetMode(cmExecutionStatus& status,
bool HandleTarget(cmTarget* target, cmMakefile& makefile,
const std::string& propertyName,
- const std::string& propertyValue, const bool appendAsString,
- const bool appendMode, const bool remove)
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove)
{
// Set or append the property.
- const char* value = propertyValue.c_str();
- if (remove) {
- value = nullptr;
- }
if (appendMode) {
- target->AppendProperty(propertyName, value, appendAsString);
+ target->AppendProperty(propertyName, propertyValue, appendAsString);
} else {
- target->SetProperty(propertyName, value);
+ if (remove) {
+ target->SetProperty(propertyName, nullptr);
+ } else {
+ target->SetProperty(propertyName, propertyValue);
+ }
}
// Check the resulting value.
@@ -323,49 +474,57 @@ bool HandleTarget(cmTarget* target, cmMakefile& makefile,
bool HandleSourceMode(cmExecutionStatus& status,
const std::set<std::string>& names,
const std::string& propertyName,
- const std::string& propertyValue,
- const bool appendAsString, const bool appendMode,
- const bool remove)
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove,
+ const std::vector<cmMakefile*>& directory_makefiles,
+ const bool source_file_paths_should_be_absolute)
{
- for (std::string const& name : names) {
- // Get the source file.
- if (cmSourceFile* sf = status.GetMakefile().GetOrCreateSource(name)) {
- if (!HandleSource(sf, propertyName, propertyValue, appendAsString,
- appendMode, remove)) {
+ std::vector<std::string> files_absolute;
+ std::vector<std::string> unique_files(names.begin(), names.end());
+ SetPropertyCommand::MakeSourceFilePathsAbsoluteIfNeeded(
+ status, files_absolute, unique_files.begin(), unique_files.end(),
+ source_file_paths_should_be_absolute);
+
+ for (const auto mf : directory_makefiles) {
+ for (std::string const& name : files_absolute) {
+ // Get the source file.
+ if (cmSourceFile* sf = mf->GetOrCreateSource(name)) {
+ if (!HandleSource(sf, propertyName, propertyValue, appendAsString,
+ appendMode, remove)) {
+ return false;
+ }
+ } else {
+ status.SetError(cmStrCat(
+ "given SOURCE name that could not be found or created: ", name));
return false;
}
- } else {
- status.SetError(cmStrCat(
- "given SOURCE name that could not be found or created: ", name));
- return false;
}
}
+
return true;
}
bool HandleSource(cmSourceFile* sf, const std::string& propertyName,
- const std::string& propertyValue, const bool appendAsString,
- const bool appendMode, const bool remove)
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove)
{
// Set or append the property.
- const char* value = propertyValue.c_str();
- if (remove) {
- value = nullptr;
- }
-
if (appendMode) {
- sf->AppendProperty(propertyName, value, appendAsString);
+ sf->AppendProperty(propertyName, propertyValue, appendAsString);
} else {
- sf->SetProperty(propertyName, value);
+ if (remove) {
+ sf->SetProperty(propertyName, nullptr);
+ } else {
+ sf->SetProperty(propertyName, propertyValue.c_str());
+ }
}
return true;
}
bool HandleTestMode(cmExecutionStatus& status, std::set<std::string>& names,
const std::string& propertyName,
- const std::string& propertyValue,
- const bool appendAsString, const bool appendMode,
- const bool remove)
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove)
{
// Look for tests with all names given.
std::set<std::string>::iterator next;
@@ -396,18 +555,18 @@ bool HandleTestMode(cmExecutionStatus& status, std::set<std::string>& names,
}
bool HandleTest(cmTest* test, const std::string& propertyName,
- const std::string& propertyValue, const bool appendAsString,
- const bool appendMode, const bool remove)
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove)
{
// Set or append the property.
- const char* value = propertyValue.c_str();
- if (remove) {
- value = nullptr;
- }
if (appendMode) {
- test->AppendProperty(propertyName, value, appendAsString);
+ test->AppendProperty(propertyName, propertyValue, appendAsString);
} else {
- test->SetProperty(propertyName, value);
+ if (remove) {
+ test->SetProperty(propertyName, nullptr);
+ } else {
+ test->SetProperty(propertyName, propertyValue.c_str());
+ }
}
return true;
@@ -416,9 +575,8 @@ bool HandleTest(cmTest* test, const std::string& propertyName,
bool HandleCacheMode(cmExecutionStatus& status,
const std::set<std::string>& names,
const std::string& propertyName,
- const std::string& propertyValue,
- const bool appendAsString, const bool appendMode,
- const bool remove)
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove)
{
if (propertyName == "ADVANCED") {
if (!remove && !cmIsOn(propertyValue) && !cmIsOff(propertyValue)) {
@@ -445,7 +603,7 @@ bool HandleCacheMode(cmExecutionStatus& status,
for (std::string const& name : names) {
// Get the source file.
cmake* cm = status.GetMakefile().GetCMakeInstance();
- const char* existingValue = cm->GetState()->GetCacheEntryValue(name);
+ cmProp existingValue = cm->GetState()->GetCacheEntryValue(name);
if (existingValue) {
if (!HandleCacheEntry(name, status.GetMakefile(), propertyName,
propertyValue, appendAsString, appendMode,
@@ -463,21 +621,19 @@ bool HandleCacheMode(cmExecutionStatus& status,
bool HandleCacheEntry(std::string const& cacheKey, const cmMakefile& makefile,
const std::string& propertyName,
- const std::string& propertyValue,
- const bool appendAsString, const bool appendMode,
- const bool remove)
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove)
{
// Set or append the property.
- const char* value = propertyValue.c_str();
cmState* state = makefile.GetState();
if (remove) {
state->RemoveCacheEntryProperty(cacheKey, propertyName);
}
if (appendMode) {
- state->AppendCacheEntryProperty(cacheKey, propertyName, value,
+ state->AppendCacheEntryProperty(cacheKey, propertyName, propertyValue,
appendAsString);
} else {
- state->SetCacheEntryProperty(cacheKey, propertyName, value);
+ state->SetCacheEntryProperty(cacheKey, propertyName, propertyValue);
}
return true;
@@ -486,9 +642,8 @@ bool HandleCacheEntry(std::string const& cacheKey, const cmMakefile& makefile,
bool HandleInstallMode(cmExecutionStatus& status,
const std::set<std::string>& names,
const std::string& propertyName,
- const std::string& propertyValue,
- const bool appendAsString, const bool appendMode,
- const bool remove)
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove)
{
cmake* cm = status.GetMakefile().GetCMakeInstance();
@@ -510,17 +665,17 @@ bool HandleInstallMode(cmExecutionStatus& status,
bool HandleInstall(cmInstalledFile* file, cmMakefile& makefile,
const std::string& propertyName,
- const std::string& propertyValue, const bool appendAsString,
- const bool appendMode, const bool remove)
+ const std::string& propertyValue, bool appendAsString,
+ bool appendMode, bool remove)
{
// Set or append the property.
- const char* value = propertyValue.c_str();
if (remove) {
file->RemoveProperty(propertyName);
} else if (appendMode) {
- file->AppendProperty(&makefile, propertyName, value, appendAsString);
+ file->AppendProperty(&makefile, propertyName, propertyValue,
+ appendAsString);
} else {
- file->SetProperty(&makefile, propertyName, value);
+ file->SetProperty(&makefile, propertyName, propertyValue);
}
return true;
}
diff --git a/Source/cmSetPropertyCommand.h b/Source/cmSetPropertyCommand.h
index ec36f84..af566a3 100644
--- a/Source/cmSetPropertyCommand.h
+++ b/Source/cmSetPropertyCommand.h
@@ -8,9 +8,38 @@
#include <string>
#include <vector>
+class cmMakefile;
class cmExecutionStatus;
bool cmSetPropertyCommand(std::vector<std::string> const& args,
cmExecutionStatus& status);
+namespace SetPropertyCommand {
+bool HandleSourceFileDirectoryScopes(
+ cmExecutionStatus& status, std::vector<std::string>& source_file_directories,
+ std::vector<std::string>& source_file_target_directories,
+ std::vector<cmMakefile*>& directory_makefiles);
+
+bool HandleSourceFileDirectoryScopeValidation(
+ cmExecutionStatus& status, bool source_file_directory_option_enabled,
+ bool source_file_target_option_enabled,
+ std::vector<std::string>& source_file_directories,
+ std::vector<std::string>& source_file_target_directories);
+
+bool HandleAndValidateSourceFileDirectortoryScopes(
+ cmExecutionStatus& status, bool source_directories_option_encountered,
+ bool source_target_directories_option_encountered,
+ std::vector<std::string>& source_directories,
+ std::vector<std::string>& source_target_directories,
+ std::vector<cmMakefile*>& source_file_directory_makefiles);
+
+std::string MakeSourceFilePathAbsoluteIfNeeded(
+ cmExecutionStatus& status, const std::string& source_file_path, bool needed);
+void MakeSourceFilePathsAbsoluteIfNeeded(
+ cmExecutionStatus& status,
+ std::vector<std::string>& source_files_absolute_paths,
+ std::vector<std::string>::const_iterator files_it_begin,
+ std::vector<std::string>::const_iterator files_it_end, bool needed);
+}
+
#endif
diff --git a/Source/cmSetSourceFilesPropertiesCommand.cxx b/Source/cmSetSourceFilesPropertiesCommand.cxx
index 7ff604b..3135a06 100644
--- a/Source/cmSetSourceFilesPropertiesCommand.cxx
+++ b/Source/cmSetSourceFilesPropertiesCommand.cxx
@@ -2,17 +2,23 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmSetSourceFilesPropertiesCommand.h"
+#include <algorithm>
+#include <iterator>
+
+#include <cm/string_view>
+#include <cmext/algorithm>
+
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
+#include "cmSetPropertyCommand.h"
#include "cmSourceFile.h"
#include "cmStringAlgorithms.h"
-static bool RunCommand(cmMakefile* mf,
- std::vector<std::string>::const_iterator filebeg,
- std::vector<std::string>::const_iterator fileend,
- std::vector<std::string>::const_iterator propbeg,
- std::vector<std::string>::const_iterator propend,
- std::string& errors);
+static bool RunCommandForScope(
+ cmMakefile* mf, std::vector<std::string>::const_iterator file_begin,
+ std::vector<std::string>::const_iterator file_end,
+ std::vector<std::string>::const_iterator prop_begin,
+ std::vector<std::string>::const_iterator prop_end, std::string& errors);
bool cmSetSourceFilesPropertiesCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
@@ -23,56 +29,95 @@ bool cmSetSourceFilesPropertiesCommand(std::vector<std::string> const& args,
}
// break the arguments into source file names and properties
- int numFiles = 0;
- std::vector<std::string>::const_iterator j;
- j = args.begin();
// old style allows for specifier before PROPERTIES keyword
- while (j != args.end() && *j != "ABSTRACT" && *j != "WRAP_EXCLUDE" &&
- *j != "GENERATED" && *j != "COMPILE_FLAGS" &&
- *j != "OBJECT_DEPENDS" && *j != "PROPERTIES") {
- numFiles++;
- ++j;
+ static const cm::string_view prop_names[] = {
+ "ABSTRACT", "GENERATED", "WRAP_EXCLUDE", "COMPILE_FLAGS",
+ "OBJECT_DEPENDS", "PROPERTIES", "DIRECTORY", "TARGET_DIRECTORY"
+ };
+
+ auto isNotAPropertyKeyword =
+ [](const std::vector<std::string>::const_iterator& arg_it) {
+ return std::all_of(
+ std::begin(prop_names), std::end(prop_names),
+ [&arg_it](cm::string_view prop_name) { return *arg_it != prop_name; });
+ };
+
+ auto options_begin = std::find_first_of(
+ args.begin(), args.end(), std::begin(prop_names), std::end(prop_names));
+ auto options_it = options_begin;
+
+ // Handle directory options.
+ std::vector<std::string> source_file_directories;
+ std::vector<std::string> source_file_target_directories;
+ bool source_file_directory_option_enabled = false;
+ bool source_file_target_option_enabled = false;
+ std::vector<cmMakefile*> source_file_directory_makefiles;
+
+ if (options_it != args.end() && *options_it == "DIRECTORY") {
+ source_file_directory_option_enabled = true;
+ ++options_it;
+ while (options_it != args.end() && isNotAPropertyKeyword(options_it)) {
+ source_file_directories.push_back(*options_it);
+ ++options_it;
+ }
+ } else if (options_it != args.end() && *options_it == "TARGET_DIRECTORY") {
+ source_file_target_option_enabled = true;
+ ++options_it;
+ while (options_it != args.end() && isNotAPropertyKeyword(options_it)) {
+ source_file_target_directories.push_back(*options_it);
+ ++options_it;
+ }
+ }
+ const auto props_begin = options_it;
+
+ bool file_scopes_handled =
+ SetPropertyCommand::HandleAndValidateSourceFileDirectortoryScopes(
+ status, source_file_directory_option_enabled,
+ source_file_target_option_enabled, source_file_directories,
+ source_file_target_directories, source_file_directory_makefiles);
+ if (!file_scopes_handled) {
+ return false;
}
- cmMakefile& mf = status.GetMakefile();
+ std::vector<std::string> files;
+ bool source_file_paths_should_be_absolute =
+ source_file_directory_option_enabled || source_file_target_option_enabled;
+ SetPropertyCommand::MakeSourceFilePathsAbsoluteIfNeeded(
+ status, files, args.begin(), options_begin,
+ source_file_paths_should_be_absolute);
- // now call the worker function
+ // Now call the worker function for each directory scope represented by a
+ // cmMakefile instance.
std::string errors;
- bool ret = RunCommand(&mf, args.begin(), args.begin() + numFiles,
- args.begin() + numFiles, args.end(), errors);
- if (!ret) {
- status.SetError(errors);
+ for (const auto mf : source_file_directory_makefiles) {
+ bool ret = RunCommandForScope(mf, files.begin(), files.end(), props_begin,
+ args.end(), errors);
+ if (!ret) {
+ status.SetError(errors);
+ return ret;
+ }
}
- return ret;
+
+ return true;
}
-static bool RunCommand(cmMakefile* mf,
- std::vector<std::string>::const_iterator filebeg,
- std::vector<std::string>::const_iterator fileend,
- std::vector<std::string>::const_iterator propbeg,
- std::vector<std::string>::const_iterator propend,
- std::string& errors)
+static bool RunCommandForScope(
+ cmMakefile* mf, std::vector<std::string>::const_iterator file_begin,
+ std::vector<std::string>::const_iterator file_end,
+ std::vector<std::string>::const_iterator prop_begin,
+ std::vector<std::string>::const_iterator prop_end, std::string& errors)
{
std::vector<std::string> propertyPairs;
- bool generated = false;
- std::vector<std::string>::const_iterator j;
// build the property pairs
- for (j = propbeg; j != propend; ++j) {
- // old style allows for specifier before PROPERTIES keyword
- if (*j == "ABSTRACT") {
- propertyPairs.emplace_back("ABSTRACT");
- propertyPairs.emplace_back("1");
- } else if (*j == "WRAP_EXCLUDE") {
- propertyPairs.emplace_back("WRAP_EXCLUDE");
- propertyPairs.emplace_back("1");
- } else if (*j == "GENERATED") {
- generated = true;
- propertyPairs.emplace_back("GENERATED");
+ for (auto j = prop_begin; j != prop_end; ++j) {
+ // consume old style options
+ if (*j == "ABSTRACT" || *j == "GENERATED" || *j == "WRAP_EXCLUDE") {
+ propertyPairs.emplace_back(*j);
propertyPairs.emplace_back("1");
} else if (*j == "COMPILE_FLAGS") {
propertyPairs.emplace_back("COMPILE_FLAGS");
++j;
- if (j == propend) {
+ if (j == prop_end) {
errors = "called with incorrect number of arguments "
"COMPILE_FLAGS with no flags";
return false;
@@ -81,33 +126,22 @@ static bool RunCommand(cmMakefile* mf,
} else if (*j == "OBJECT_DEPENDS") {
propertyPairs.emplace_back("OBJECT_DEPENDS");
++j;
- if (j == propend) {
+ if (j == prop_end) {
errors = "called with incorrect number of arguments "
"OBJECT_DEPENDS with no dependencies";
return false;
}
propertyPairs.push_back(*j);
} else if (*j == "PROPERTIES") {
- // now loop through the rest of the arguments, new style
- ++j;
- while (j != propend) {
- propertyPairs.push_back(*j);
- if (*j == "GENERATED") {
- ++j;
- if (j != propend && cmIsOn(*j)) {
- generated = true;
- }
- } else {
- ++j;
- }
- if (j == propend) {
- errors = "called with incorrect number of arguments.";
- return false;
- }
- propertyPairs.push_back(*j);
- ++j;
+ // PROPERTIES is followed by new style prop value pairs
+ cmStringRange newStyleProps{ j + 1, prop_end };
+ if (newStyleProps.size() % 2 != 0) {
+ errors = "called with incorrect number of arguments.";
+ return false;
}
- // break out of the loop because j is already == end
+ // set newStyleProps as is.
+ cm::append(propertyPairs, newStyleProps);
+ // break out of the loop.
break;
} else {
errors = "called with illegal arguments, maybe missing a "
@@ -116,15 +150,13 @@ static bool RunCommand(cmMakefile* mf,
}
}
- // now loop over all the files
- for (j = filebeg; j != fileend; ++j) {
+ // loop over all the files
+ for (const std::string& sfname : cmStringRange{ file_begin, file_end }) {
// get the source file
- cmSourceFile* sf = mf->GetOrCreateSource(*j, generated);
- if (sf) {
- // now loop through all the props and set them
- unsigned int k;
- for (k = 0; k < propertyPairs.size(); k = k + 2) {
- sf->SetProperty(propertyPairs[k], propertyPairs[k + 1].c_str());
+ if (cmSourceFile* sf = mf->GetOrCreateSource(sfname)) {
+ // loop through the props and set them
+ for (auto k = propertyPairs.begin(); k != propertyPairs.end(); k += 2) {
+ sf->SetProperty(*k, (k + 1)->c_str());
}
}
}
diff --git a/Source/cmSetTargetPropertiesCommand.cxx b/Source/cmSetTargetPropertiesCommand.cxx
index 8d917db..bdc84af 100644
--- a/Source/cmSetTargetPropertiesCommand.cxx
+++ b/Source/cmSetTargetPropertiesCommand.cxx
@@ -2,18 +2,14 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmSetTargetPropertiesCommand.h"
+#include <algorithm>
#include <iterator>
-#include "cmAlgorithms.h"
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
#include "cmTarget.h"
-static bool SetOneTarget(const std::string& tname,
- std::vector<std::string>& propertyPairs,
- cmMakefile* mf);
-
bool cmSetTargetPropertiesCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
@@ -22,61 +18,38 @@ bool cmSetTargetPropertiesCommand(std::vector<std::string> const& args,
return false;
}
- // first collect up the list of files
- std::vector<std::string> propertyPairs;
- int numFiles = 0;
- for (auto j = args.begin(); j != args.end(); ++j) {
- if (*j == "PROPERTIES") {
- // now loop through the rest of the arguments, new style
- ++j;
- if (std::distance(j, args.end()) % 2 != 0) {
- status.SetError("called with incorrect number of arguments.");
- return false;
- }
- cmAppend(propertyPairs, j, args.end());
- break;
- }
- numFiles++;
+ // first identify the properties arguments
+ auto propsIter = std::find(args.begin(), args.end(), "PROPERTIES");
+ if (propsIter == args.end() || propsIter + 1 == args.end()) {
+ status.SetError("called with illegal arguments, maybe missing a "
+ "PROPERTIES specifier?");
+ return false;
}
- if (propertyPairs.empty()) {
- status.SetError("called with illegal arguments, maybe missing "
- "a PROPERTIES specifier?");
+
+ if (std::distance(propsIter, args.end()) % 2 != 1) {
+ status.SetError("called with incorrect number of arguments.");
return false;
}
cmMakefile& mf = status.GetMakefile();
- // now loop over all the targets
- for (int i = 0; i < numFiles; ++i) {
- if (mf.IsAlias(args[i])) {
+ // loop over all the targets
+ for (const std::string& tname : cmStringRange{ args.begin(), propsIter }) {
+ if (mf.IsAlias(tname)) {
status.SetError("can not be used on an ALIAS target.");
return false;
}
- bool ret = SetOneTarget(args[i], propertyPairs, &mf);
- if (!ret) {
+ if (cmTarget* target = mf.FindTargetToUse(tname)) {
+ // loop through all the props and set them
+ for (auto k = propsIter + 1; k != args.end(); k += 2) {
+ target->SetProperty(*k, *(k + 1));
+ target->CheckProperty(*k, &mf);
+ }
+ } else {
status.SetError(
- cmStrCat("Can not find target to add properties to: ", args[i]));
+ cmStrCat("Can not find target to add properties to: ", tname));
return false;
}
}
return true;
}
-
-static bool SetOneTarget(const std::string& tname,
- std::vector<std::string>& propertyPairs,
- cmMakefile* mf)
-{
- if (cmTarget* target = mf->FindTargetToUse(tname)) {
- // now loop through all the props and set them
- unsigned int k;
- for (k = 0; k < propertyPairs.size(); k = k + 2) {
- target->SetProperty(propertyPairs[k], propertyPairs[k + 1].c_str());
- target->CheckProperty(propertyPairs[k], mf);
- }
- }
- // if file is not already in the makefile, then add it
- else {
- return false;
- }
- return true;
-}
diff --git a/Source/cmSetTestsPropertiesCommand.cxx b/Source/cmSetTestsPropertiesCommand.cxx
index de61eda..c4bff76 100644
--- a/Source/cmSetTestsPropertiesCommand.cxx
+++ b/Source/cmSetTestsPropertiesCommand.cxx
@@ -2,18 +2,14 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmSetTestsPropertiesCommand.h"
+#include <algorithm>
#include <iterator>
-#include "cmAlgorithms.h"
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
#include "cmTest.h"
-static bool SetOneTest(const std::string& tname,
- std::vector<std::string>& propertyPairs, cmMakefile* mf,
- std::string& errors);
-
bool cmSetTestsPropertiesCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
@@ -22,61 +18,33 @@ bool cmSetTestsPropertiesCommand(std::vector<std::string> const& args,
return false;
}
- cmMakefile& mf = status.GetMakefile();
-
- // first collect up the list of files
- std::vector<std::string> propertyPairs;
- int numFiles = 0;
- std::vector<std::string>::const_iterator j;
- for (j = args.begin(); j != args.end(); ++j) {
- if (*j == "PROPERTIES") {
- // now loop through the rest of the arguments, new style
- ++j;
- if (std::distance(j, args.end()) % 2 != 0) {
- status.SetError("called with incorrect number of arguments.");
- return false;
- }
- cmAppend(propertyPairs, j, args.end());
- break;
- }
- numFiles++;
- }
- if (propertyPairs.empty()) {
- status.SetError("called with illegal arguments, maybe "
- "missing a PROPERTIES specifier?");
+ // first identify the properties arguments
+ auto propsIter = std::find(args.begin(), args.end(), "PROPERTIES");
+ if (propsIter == args.end() || propsIter + 1 == args.end()) {
+ status.SetError("called with illegal arguments, maybe missing a "
+ "PROPERTIES specifier?");
return false;
}
- // now loop over all the targets
- int i;
- for (i = 0; i < numFiles; ++i) {
- std::string errors;
- bool ret = SetOneTest(args[i], propertyPairs, &mf, errors);
- if (!ret) {
- status.SetError(errors);
- return ret;
- }
+ if (std::distance(propsIter, args.end()) % 2 != 1) {
+ status.SetError("called with incorrect number of arguments.");
+ return false;
}
- return true;
-}
-
-static bool SetOneTest(const std::string& tname,
- std::vector<std::string>& propertyPairs, cmMakefile* mf,
- std::string& errors)
-{
- if (cmTest* test = mf->GetTest(tname)) {
- // now loop through all the props and set them
- unsigned int k;
- for (k = 0; k < propertyPairs.size(); k = k + 2) {
- if (!propertyPairs[k].empty()) {
- test->SetProperty(propertyPairs[k], propertyPairs[k + 1].c_str());
+ // loop over all the tests
+ for (const std::string& tname : cmStringRange{ args.begin(), propsIter }) {
+ if (cmTest* test = status.GetMakefile().GetTest(tname)) {
+ // loop through all the props and set them
+ for (auto k = propsIter + 1; k != args.end(); k += 2) {
+ if (!k->empty()) {
+ test->SetProperty(*k, (k + 1)->c_str());
+ }
}
+ } else {
+ status.SetError(
+ cmStrCat("Can not find test to add properties to: ", tname));
+ return false;
}
- } else {
- errors = cmStrCat("Can not find test to add properties to: ", tname);
- return false;
}
-
return true;
}
diff --git a/Source/cmSiteNameCommand.cxx b/Source/cmSiteNameCommand.cxx
index d47f121..b2d905e 100644
--- a/Source/cmSiteNameCommand.cxx
+++ b/Source/cmSiteNameCommand.cxx
@@ -72,8 +72,7 @@ bool cmSiteNameCommand(std::vector<std::string> const& args,
}
#endif
status.GetMakefile().AddCacheDefinition(
- args[0], siteName.c_str(),
- "Name of the computer/site where compile is being run",
+ args[0], siteName, "Name of the computer/site where compile is being run",
cmStateEnums::STRING);
return true;
diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx
index 2a345eb..f525439 100644
--- a/Source/cmSourceFile.cxx
+++ b/Source/cmSourceFile.cxx
@@ -48,9 +48,9 @@ std::string cmSourceFile::GetObjectLibrary() const
std::string const& cmSourceFile::GetOrDetermineLanguage()
{
// If the language was set explicitly by the user then use it.
- if (const char* lang = this->GetProperty(propLANGUAGE)) {
+ if (cmProp lang = this->GetProperty(propLANGUAGE)) {
// Assign to member in order to return a reference.
- this->Language = lang;
+ this->Language = *lang;
return this->Language;
}
@@ -81,8 +81,8 @@ std::string const& cmSourceFile::GetOrDetermineLanguage()
std::string cmSourceFile::GetLanguage() const
{
// If the language was set explicitly by the user then use it.
- if (const char* lang = this->GetProperty(propLANGUAGE)) {
- return lang;
+ if (cmProp lang = this->GetProperty(propLANGUAGE)) {
+ return *lang;
}
// Use the language determined from the file extension.
@@ -128,7 +128,7 @@ bool cmSourceFile::FindFullPath(std::string* error)
// The file is not generated. It must exist on disk.
cmMakefile const* makefile = this->Location.GetMakefile();
// Location path
- std::string const lPath = this->Location.GetFullPath();
+ std::string const& lPath = this->Location.GetFullPath();
// List of extension lists
std::array<std::vector<std::string> const*, 2> const extsLists = {
{ &makefile->GetCMakeInstance()->GetSourceExtensions(),
@@ -145,7 +145,7 @@ bool cmSourceFile::FindFullPath(std::string* error)
return true;
}
// Try full path with extension
- for (auto exts : extsLists) {
+ for (auto& exts : extsLists) {
for (std::string const& ext : *exts) {
if (!ext.empty()) {
std::string extPath = cmStrCat(fullPath, '.', ext);
@@ -260,21 +260,21 @@ void cmSourceFile::SetProperty(const std::string& prop, const char* value)
}
}
-void cmSourceFile::AppendProperty(const std::string& prop, const char* value,
- bool asString)
+void cmSourceFile::AppendProperty(const std::string& prop,
+ const std::string& value, bool asString)
{
if (prop == propINCLUDE_DIRECTORIES) {
- if (value && *value) {
+ if (!value.empty()) {
cmListFileBacktrace lfbt = this->Location.GetMakefile()->GetBacktrace();
this->IncludeDirectories.emplace_back(value, lfbt);
}
} else if (prop == propCOMPILE_OPTIONS) {
- if (value && *value) {
+ if (!value.empty()) {
cmListFileBacktrace lfbt = this->Location.GetMakefile()->GetBacktrace();
this->CompileOptions.emplace_back(value, lfbt);
}
} else if (prop == propCOMPILE_DEFINITIONS) {
- if (value && *value) {
+ if (!value.empty()) {
cmListFileBacktrace lfbt = this->Location.GetMakefile()->GetBacktrace();
this->CompileDefinitions.emplace_back(value, lfbt);
}
@@ -317,17 +317,18 @@ const char* cmSourceFile::GetPropertyForUser(const std::string& prop)
}
// Perform the normal property lookup.
- return this->GetProperty(prop);
+ cmProp p = this->GetProperty(prop);
+ return p ? p->c_str() : nullptr;
}
-const char* cmSourceFile::GetProperty(const std::string& prop) const
+cmProp cmSourceFile::GetProperty(const std::string& prop) const
{
// Check for computed properties.
if (prop == propLOCATION) {
if (this->FullPath.empty()) {
return nullptr;
}
- return this->FullPath.c_str();
+ return &this->FullPath;
}
// Check for the properties with backtraces.
@@ -338,7 +339,7 @@ const char* cmSourceFile::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(this->IncludeDirectories, ";");
- return output.c_str();
+ return &output;
}
if (prop == propCOMPILE_OPTIONS) {
@@ -348,7 +349,7 @@ const char* cmSourceFile::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(this->CompileOptions, ";");
- return output.c_str();
+ return &output;
}
if (prop == propCOMPILE_DEFINITIONS) {
@@ -358,10 +359,10 @@ const char* cmSourceFile::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(this->CompileDefinitions, ";");
- return output.c_str();
+ return &output;
}
- const char* retVal = this->Properties.GetPropertyValue(prop);
+ cmProp retVal = this->Properties.GetPropertyValue(prop);
if (!retVal) {
cmMakefile const* mf = this->Location.GetMakefile();
const bool chain =
@@ -369,6 +370,7 @@ const char* cmSourceFile::GetProperty(const std::string& prop) const
if (chain) {
return mf->GetProperty(prop, chain);
}
+ return nullptr;
}
return retVal;
@@ -376,16 +378,17 @@ const char* cmSourceFile::GetProperty(const std::string& prop) const
const char* cmSourceFile::GetSafeProperty(const std::string& prop) const
{
- const char* ret = this->GetProperty(prop);
+ cmProp ret = this->GetProperty(prop);
if (!ret) {
return "";
}
- return ret;
+ return ret->c_str();
}
bool cmSourceFile::GetPropertyAsBool(const std::string& prop) const
{
- return cmIsOn(this->GetProperty(prop));
+ cmProp p = this->GetProperty(prop);
+ return p && cmIsOn(*p);
}
void cmSourceFile::SetProperties(cmPropertyMap properties)
diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h
index 82a3625..e527069 100644
--- a/Source/cmSourceFile.h
+++ b/Source/cmSourceFile.h
@@ -17,6 +17,8 @@
class cmMakefile;
+using cmProp = const std::string*;
+
/** \class cmSourceFile
* \brief Represent a class loaded from a makefile.
*
@@ -42,10 +44,10 @@ public:
//! Set/Get a property of this source file
void SetProperty(const std::string& prop, const char* value);
- void AppendProperty(const std::string& prop, const char* value,
+ void AppendProperty(const std::string& prop, const std::string& value,
bool asString = false);
//! Might return a nullptr if the property is not set or invalid
- const char* GetProperty(const std::string& prop) const;
+ cmProp GetProperty(const std::string& prop) const;
//! Always returns a valid pointer
const char* GetSafeProperty(const std::string& prop) const;
bool GetPropertyAsBool(const std::string& prop) const;
@@ -154,9 +156,8 @@ private:
#define CM_HEADER_REGEX "\\.(h|hh|h\\+\\+|hm|hpp|hxx|in|txx|inl)$"
#define CM_SOURCE_REGEX \
- "\\.(C|M|c|c\\+\\+|cc|cpp|cxx|cu|f|f90|for|fpp|ftn|m|mm|rc|def|r|odl|idl|" \
- "hpj" \
- "|bat)$"
+ "\\.(C|F|M|c|c\\+\\+|cc|cpp|cxx|cu|f|f90|for|fpp|ftn|m|mm|" \
+ "rc|def|r|odl|idl|hpj|bat)$"
#define CM_PCH_REGEX "cmake_pch\\.(h|hxx)$"
diff --git a/Source/cmSourceFileLocation.cxx b/Source/cmSourceFileLocation.cxx
index df702b0..e852c05 100644
--- a/Source/cmSourceFileLocation.cxx
+++ b/Source/cmSourceFileLocation.cxx
@@ -4,6 +4,8 @@
#include <cassert>
+#include <cm/string_view>
+
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -31,7 +33,8 @@ cmSourceFileLocation::cmSourceFileLocation(cmMakefile const* mf,
this->AmbiguousExtension = true;
this->Directory = cmSystemTools::GetFilenamePath(name);
if (cmSystemTools::FileIsFullPath(this->Directory)) {
- this->Directory = cmSystemTools::CollapseFullPath(this->Directory);
+ this->Directory = cmSystemTools::CollapseFullPath(
+ this->Directory, mf->GetHomeOutputDirectory());
}
this->Name = cmSystemTools::GetFilenameName(name);
if (kind == cmSourceFileLocationKind::Known) {
@@ -151,7 +154,7 @@ bool cmSourceFileLocation::MatchesAmbiguousExtension(
// Only a fixed set of extensions will be tried to match a file on
// disk. One of these must match if loc refers to this source file.
- std::string const& ext = this->Name.substr(loc.Name.size() + 1);
+ auto ext = cm::string_view(this->Name).substr(loc.Name.size() + 1);
cmMakefile const* mf = this->Makefile;
auto cm = mf->GetCMakeInstance();
return cm->IsSourceExtension(ext) || cm->IsHeaderExtension(ext);
diff --git a/Source/cmSourceGroup.cxx b/Source/cmSourceGroup.cxx
index 8c3ec9f..155068cb 100644
--- a/Source/cmSourceGroup.cxx
+++ b/Source/cmSourceGroup.cxx
@@ -4,6 +4,8 @@
#include <utility>
+#include <cm/memory>
+
#include "cmStringAlgorithms.h"
class cmSourceGroupInternals
@@ -16,7 +18,7 @@ cmSourceGroup::cmSourceGroup(std::string name, const char* regex,
const char* parentName)
: Name(std::move(name))
{
- this->Internal = new cmSourceGroupInternals;
+ this->Internal = cm::make_unique<cmSourceGroupInternals>();
this->SetGroupRegex(regex);
if (parentName) {
this->FullName = cmStrCat(parentName, '\\');
@@ -24,10 +26,7 @@ cmSourceGroup::cmSourceGroup(std::string name, const char* regex,
this->FullName += this->Name;
}
-cmSourceGroup::~cmSourceGroup()
-{
- delete this->Internal;
-}
+cmSourceGroup::~cmSourceGroup() = default;
cmSourceGroup::cmSourceGroup(cmSourceGroup const& r)
{
@@ -36,7 +35,7 @@ cmSourceGroup::cmSourceGroup(cmSourceGroup const& r)
this->GroupRegex = r.GroupRegex;
this->GroupFiles = r.GroupFiles;
this->SourceFiles = r.SourceFiles;
- this->Internal = new cmSourceGroupInternals(*r.Internal);
+ this->Internal = cm::make_unique<cmSourceGroupInternals>(*r.Internal);
}
cmSourceGroup& cmSourceGroup::operator=(cmSourceGroup const& r)
diff --git a/Source/cmSourceGroup.h b/Source/cmSourceGroup.h
index 581dc5d..623cded 100644
--- a/Source/cmSourceGroup.h
+++ b/Source/cmSourceGroup.h
@@ -5,6 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <memory>
#include <set>
#include <string>
#include <vector>
@@ -122,7 +123,7 @@ private:
*/
std::vector<const cmSourceFile*> SourceFiles;
- cmSourceGroupInternals* Internal;
+ std::unique_ptr<cmSourceGroupInternals> Internal;
};
#endif
diff --git a/Source/cmSourceGroupCommand.cxx b/Source/cmSourceGroupCommand.cxx
index cc62952..bb75a14 100644
--- a/Source/cmSourceGroupCommand.cxx
+++ b/Source/cmSourceGroupCommand.cxx
@@ -7,7 +7,8 @@
#include <set>
#include <utility>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmSourceGroup.h"
@@ -30,18 +31,6 @@ std::vector<std::string> tokenizePath(const std::string& path)
return cmTokenize(path, "\\/");
}
-std::string getFullFilePath(const std::string& currentPath,
- const std::string& path)
-{
- std::string fullPath = path;
-
- if (!cmSystemTools::FileIsFullPath(path)) {
- fullPath = cmStrCat(currentPath, '/', path);
- }
-
- return cmSystemTools::CollapseFullPath(fullPath);
-}
-
std::set<std::string> getSourceGroupFilesPaths(
const std::string& root, const std::vector<std::string>& files)
{
@@ -124,7 +113,8 @@ bool addFilesToItsSourceGroups(const std::string& root,
errorMsg = "Could not create source group for file: " + sgFilesPath;
return false;
}
- const std::string fullPath = getFullFilePath(root, sgFilesPath);
+ const std::string fullPath =
+ cmSystemTools::CollapseFullPath(sgFilesPath, root);
sg->AddGroupFile(fullPath);
}
}
@@ -147,7 +137,7 @@ ExpectedOptions getExpectedOptions()
bool isExpectedOption(const std::string& argument,
const ExpectedOptions& expectedOptions)
{
- return cmContains(expectedOptions, argument);
+ return cm::contains(expectedOptions, argument);
}
void parseArguments(const std::vector<std::string>& args,
@@ -255,10 +245,8 @@ bool cmSourceGroupCommand(std::vector<std::string> const& args,
parsedArguments[kFilesOptionName];
for (auto const& filesArg : filesArguments) {
std::string src = filesArg;
- if (!cmSystemTools::FileIsFullPath(src)) {
- src = cmStrCat(mf.GetCurrentSourceDirectory(), '/', filesArg);
- }
- src = cmSystemTools::CollapseFullPath(src);
+ src =
+ cmSystemTools::CollapseFullPath(src, mf.GetCurrentSourceDirectory());
sg->AddGroupFile(src);
}
}
diff --git a/Source/cmStandardLexer.h b/Source/cmStandardLexer.h
index 13f7622..cc67ac2 100644
--- a/Source/cmStandardLexer.h
+++ b/Source/cmStandardLexer.h
@@ -3,6 +3,19 @@
#ifndef cmStandardLexer_h
#define cmStandardLexer_h
+#if !defined(_WIN32) && !defined(__sun)
+/* POSIX APIs are needed */
+# define _POSIX_C_SOURCE 200809L
+#endif
+#if defined(__sun) && defined(__GNUC__) && !defined(__cplusplus)
+/* C sources: for fileno and strdup */
+# define _XOPEN_SOURCE 600
+#endif
+#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__)
+/* For isascii */
+# define _XOPEN_SOURCE 700
+#endif
+
#include "cmsys/Configure.h" // IWYU pragma: keep
/* Disable some warnings. */
@@ -50,7 +63,7 @@
#define YY_NO_UNPUT 1
#define ECHO
-#include "cm_kwiml.h"
+#include <cm3p/kwiml/int.h>
typedef KWIML_INT_int8_t flex_int8_t;
typedef KWIML_INT_uint8_t flex_uint8_t;
typedef KWIML_INT_int16_t flex_int16_t;
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index f9b5ed1..df013f4 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -3,9 +3,9 @@
#include "cmState.h"
#include <algorithm>
+#include <array>
#include <cassert>
#include <cstdlib>
-#include <cstring>
#include <utility>
#include <cm/memory>
@@ -26,6 +26,8 @@
#include "cmSystemTools.h"
#include "cmake.h"
+using cmProp = const std::string*;
+
cmState::cmState()
{
this->CacheManager = cm::make_unique<cmCacheManager>();
@@ -34,69 +36,84 @@ cmState::cmState()
cmState::~cmState() = default;
-const char* cmState::GetTargetTypeName(cmStateEnums::TargetType targetType)
-{
+const std::string& cmState::GetTargetTypeName(
+ cmStateEnums::TargetType targetType)
+{
+#define MAKE_STATIC_PROP(PROP) static const std::string prop##PROP = #PROP
+ MAKE_STATIC_PROP(STATIC_LIBRARY);
+ MAKE_STATIC_PROP(MODULE_LIBRARY);
+ MAKE_STATIC_PROP(SHARED_LIBRARY);
+ MAKE_STATIC_PROP(OBJECT_LIBRARY);
+ MAKE_STATIC_PROP(EXECUTABLE);
+ MAKE_STATIC_PROP(UTILITY);
+ MAKE_STATIC_PROP(GLOBAL_TARGET);
+ MAKE_STATIC_PROP(INTERFACE_LIBRARY);
+ MAKE_STATIC_PROP(UNKNOWN_LIBRARY);
+ static const std::string propEmpty;
+#undef MAKE_STATIC_PROP
+
switch (targetType) {
case cmStateEnums::STATIC_LIBRARY:
- return "STATIC_LIBRARY";
+ return propSTATIC_LIBRARY;
case cmStateEnums::MODULE_LIBRARY:
- return "MODULE_LIBRARY";
+ return propMODULE_LIBRARY;
case cmStateEnums::SHARED_LIBRARY:
- return "SHARED_LIBRARY";
+ return propSHARED_LIBRARY;
case cmStateEnums::OBJECT_LIBRARY:
- return "OBJECT_LIBRARY";
+ return propOBJECT_LIBRARY;
case cmStateEnums::EXECUTABLE:
- return "EXECUTABLE";
+ return propEXECUTABLE;
case cmStateEnums::UTILITY:
- return "UTILITY";
+ return propUTILITY;
case cmStateEnums::GLOBAL_TARGET:
- return "GLOBAL_TARGET";
+ return propGLOBAL_TARGET;
case cmStateEnums::INTERFACE_LIBRARY:
- return "INTERFACE_LIBRARY";
+ return propINTERFACE_LIBRARY;
case cmStateEnums::UNKNOWN_LIBRARY:
- return "UNKNOWN_LIBRARY";
+ return propUNKNOWN_LIBRARY;
}
assert(false && "Unexpected target type");
- return nullptr;
+ return propEmpty;
}
-const char* cmCacheEntryTypes[] = { "BOOL", "PATH", "FILEPATH",
- "STRING", "INTERNAL", "STATIC",
- "UNINITIALIZED", nullptr };
+static const std::array<std::string, 7> cmCacheEntryTypes = {
+ { "BOOL", "PATH", "FILEPATH", "STRING", "INTERNAL", "STATIC",
+ "UNINITIALIZED" }
+};
-const char* cmState::CacheEntryTypeToString(cmStateEnums::CacheEntryType type)
+const std::string& cmState::CacheEntryTypeToString(
+ cmStateEnums::CacheEntryType type)
{
- if (type > 6) {
- return cmCacheEntryTypes[6];
+ if (type < cmStateEnums::BOOL || type > cmStateEnums::UNINITIALIZED) {
+ type = cmStateEnums::UNINITIALIZED;
}
return cmCacheEntryTypes[type];
}
-cmStateEnums::CacheEntryType cmState::StringToCacheEntryType(const char* s)
+cmStateEnums::CacheEntryType cmState::StringToCacheEntryType(
+ const std::string& s)
{
cmStateEnums::CacheEntryType type = cmStateEnums::STRING;
StringToCacheEntryType(s, type);
return type;
}
-bool cmState::StringToCacheEntryType(const char* s,
+bool cmState::StringToCacheEntryType(const std::string& s,
cmStateEnums::CacheEntryType& type)
{
- int i = 0;
- while (cmCacheEntryTypes[i]) {
- if (strcmp(s, cmCacheEntryTypes[i]) == 0) {
+ for (size_t i = 0; i < cmCacheEntryTypes.size(); ++i) {
+ if (s == cmCacheEntryTypes[i]) {
type = static_cast<cmStateEnums::CacheEntryType>(i);
return true;
}
- ++i;
}
return false;
}
bool cmState::IsCacheEntryType(std::string const& key)
{
- for (int i = 0; cmCacheEntryTypes[i]; ++i) {
- if (key == cmCacheEntryTypes[i]) {
+ for (const std::string& i : cmCacheEntryTypes) {
+ if (key == i) {
return true;
}
}
@@ -122,26 +139,23 @@ bool cmState::DeleteCache(const std::string& path)
std::vector<std::string> cmState::GetCacheEntryKeys() const
{
- std::vector<std::string> definitions;
- definitions.reserve(this->CacheManager->GetSize());
- cmCacheManager::CacheIterator cit = this->CacheManager->GetCacheIterator();
- for (cit.Begin(); !cit.IsAtEnd(); cit.Next()) {
- definitions.push_back(cit.GetName());
- }
- return definitions;
+ return this->CacheManager->GetCacheEntryKeys();
}
-const char* cmState::GetCacheEntryValue(std::string const& key) const
+cmProp cmState::GetCacheEntryValue(std::string const& key) const
{
- cmCacheManager::CacheEntry* e = this->CacheManager->GetCacheEntry(key);
- if (!e) {
- return nullptr;
+ return this->CacheManager->GetCacheEntryValue(key);
+}
+
+std::string cmState::GetSafeCacheEntryValue(std::string const& key) const
+{
+ if (cmProp val = this->GetCacheEntryValue(key)) {
+ return *val;
}
- return e->Value.c_str();
+ return std::string();
}
-const std::string* cmState::GetInitializedCacheValue(
- std::string const& key) const
+cmProp cmState::GetInitializedCacheValue(std::string const& key) const
{
return this->CacheManager->GetInitializedCacheValue(key);
}
@@ -149,9 +163,7 @@ const std::string* cmState::GetInitializedCacheValue(
cmStateEnums::CacheEntryType cmState::GetCacheEntryType(
std::string const& key) const
{
- cmCacheManager::CacheIterator it =
- this->CacheManager->GetCacheIterator(key.c_str());
- return it.GetType();
+ return this->CacheManager->GetCacheEntryType(key);
}
void cmState::SetCacheEntryValue(std::string const& key,
@@ -164,44 +176,32 @@ void cmState::SetCacheEntryProperty(std::string const& key,
std::string const& propertyName,
std::string const& value)
{
- cmCacheManager::CacheIterator it =
- this->CacheManager->GetCacheIterator(key.c_str());
- it.SetProperty(propertyName, value.c_str());
+ this->CacheManager->SetCacheEntryProperty(key, propertyName, value);
}
void cmState::SetCacheEntryBoolProperty(std::string const& key,
std::string const& propertyName,
bool value)
{
- cmCacheManager::CacheIterator it =
- this->CacheManager->GetCacheIterator(key.c_str());
- it.SetProperty(propertyName, value);
+ this->CacheManager->SetCacheEntryBoolProperty(key, propertyName, value);
}
std::vector<std::string> cmState::GetCacheEntryPropertyList(
const std::string& key)
{
- cmCacheManager::CacheIterator it =
- this->CacheManager->GetCacheIterator(key.c_str());
- return it.GetPropertyList();
+ return this->CacheManager->GetCacheEntryPropertyList(key);
}
-const char* cmState::GetCacheEntryProperty(std::string const& key,
- std::string const& propertyName)
+cmProp cmState::GetCacheEntryProperty(std::string const& key,
+ std::string const& propertyName)
{
- cmCacheManager::CacheIterator it =
- this->CacheManager->GetCacheIterator(key.c_str());
- if (!it.PropertyExists(propertyName)) {
- return nullptr;
- }
- return it.GetProperty(propertyName);
+ return this->CacheManager->GetCacheEntryProperty(key, propertyName);
}
bool cmState::GetCacheEntryPropertyAsBool(std::string const& key,
std::string const& propertyName)
{
- return this->CacheManager->GetCacheIterator(key.c_str())
- .GetPropertyAsBool(propertyName);
+ return this->CacheManager->GetCacheEntryPropertyAsBool(key, propertyName);
}
void cmState::AddCacheEntry(const std::string& key, const char* value,
@@ -253,15 +253,13 @@ void cmState::AppendCacheEntryProperty(const std::string& key,
const std::string& property,
const std::string& value, bool asString)
{
- this->CacheManager->GetCacheIterator(key.c_str())
- .AppendProperty(property, value.c_str(), asString);
+ this->CacheManager->AppendCacheEntryProperty(key, property, value, asString);
}
void cmState::RemoveCacheEntryProperty(std::string const& key,
std::string const& propertyName)
{
- this->CacheManager->GetCacheIterator(key.c_str())
- .SetProperty(propertyName, nullptr);
+ this->CacheManager->RemoveCacheEntryProperty(key, propertyName);
}
cmStateSnapshot cmState::Reset()
@@ -330,8 +328,8 @@ cmStateSnapshot cmState::Reset()
void cmState::DefineProperty(const std::string& name,
cmProperty::ScopeType scope,
- const char* ShortDescription,
- const char* FullDescription, bool chained)
+ const std::string& ShortDescription,
+ const std::string& FullDescription, bool chained)
{
this->PropertyDefinitions[scope].DefineProperty(
name, scope, ShortDescription, FullDescription, chained);
@@ -562,13 +560,13 @@ void cmState::SetGlobalProperty(const std::string& prop, const char* value)
this->GlobalProperties.SetProperty(prop, value);
}
-void cmState::AppendGlobalProperty(const std::string& prop, const char* value,
- bool asString)
+void cmState::AppendGlobalProperty(const std::string& prop,
+ const std::string& value, bool asString)
{
this->GlobalProperties.AppendProperty(prop, value, asString);
}
-const char* cmState::GetGlobalProperty(const std::string& prop)
+cmProp cmState::GetGlobalProperty(const std::string& prop)
{
if (prop == "CACHE_VARIABLES") {
std::vector<std::string> cacheKeys = this->GetCacheEntryKeys();
@@ -592,28 +590,49 @@ const char* cmState::GetGlobalProperty(const std::string& prop)
}
#define STRING_LIST_ELEMENT(F) ";" #F
if (prop == "CMAKE_C_KNOWN_FEATURES") {
- return &FOR_EACH_C_FEATURE(STRING_LIST_ELEMENT)[1];
+ static const std::string s_out(
+ &FOR_EACH_C_FEATURE(STRING_LIST_ELEMENT)[1]);
+ return &s_out;
}
if (prop == "CMAKE_C90_KNOWN_FEATURES") {
- return &FOR_EACH_C90_FEATURE(STRING_LIST_ELEMENT)[1];
+ static const std::string s_out(
+ &FOR_EACH_C90_FEATURE(STRING_LIST_ELEMENT)[1]);
+ return &s_out;
}
if (prop == "CMAKE_C99_KNOWN_FEATURES") {
- return &FOR_EACH_C99_FEATURE(STRING_LIST_ELEMENT)[1];
+ static const std::string s_out(
+ &FOR_EACH_C99_FEATURE(STRING_LIST_ELEMENT)[1]);
+ return &s_out;
}
if (prop == "CMAKE_C11_KNOWN_FEATURES") {
- return &FOR_EACH_C11_FEATURE(STRING_LIST_ELEMENT)[1];
+ static const std::string s_out(
+ &FOR_EACH_C11_FEATURE(STRING_LIST_ELEMENT)[1]);
+ return &s_out;
}
if (prop == "CMAKE_CXX_KNOWN_FEATURES") {
- return &FOR_EACH_CXX_FEATURE(STRING_LIST_ELEMENT)[1];
+ static const std::string s_out(
+ &FOR_EACH_CXX_FEATURE(STRING_LIST_ELEMENT)[1]);
+ return &s_out;
}
if (prop == "CMAKE_CXX98_KNOWN_FEATURES") {
- return &FOR_EACH_CXX98_FEATURE(STRING_LIST_ELEMENT)[1];
+ static const std::string s_out(
+ &FOR_EACH_CXX98_FEATURE(STRING_LIST_ELEMENT)[1]);
+ return &s_out;
}
if (prop == "CMAKE_CXX11_KNOWN_FEATURES") {
- return &FOR_EACH_CXX11_FEATURE(STRING_LIST_ELEMENT)[1];
+ static const std::string s_out(
+ &FOR_EACH_CXX11_FEATURE(STRING_LIST_ELEMENT)[1]);
+ return &s_out;
}
if (prop == "CMAKE_CXX14_KNOWN_FEATURES") {
- return &FOR_EACH_CXX14_FEATURE(STRING_LIST_ELEMENT)[1];
+ static const std::string s_out(
+ &FOR_EACH_CXX14_FEATURE(STRING_LIST_ELEMENT)[1]);
+ return &s_out;
+ }
+ if (prop == "CMAKE_CUDA_KNOWN_FEATURES") {
+ static const std::string s_out(
+ &FOR_EACH_CUDA_FEATURE(STRING_LIST_ELEMENT)[1]);
+ return &s_out;
}
#undef STRING_LIST_ELEMENT
@@ -622,7 +641,8 @@ const char* cmState::GetGlobalProperty(const std::string& prop)
bool cmState::GetGlobalPropertyAsBool(const std::string& prop)
{
- return cmIsOn(this->GetGlobalProperty(prop));
+ cmProp p = this->GetGlobalProperty(prop);
+ return p && cmIsOn(*p);
}
void cmState::SetSourceDirectory(std::string const& sourceDirectory)
@@ -712,6 +732,16 @@ bool cmState::UseMSYSShell() const
return this->MSYSShell;
}
+void cmState::SetNinjaMulti(bool ninjaMulti)
+{
+ this->NinjaMulti = ninjaMulti;
+}
+
+bool cmState::UseNinjaMulti() const
+{
+ return this->NinjaMulti;
+}
+
unsigned int cmState::GetCacheMajorVersion() const
{
return this->CacheManager->GetCacheMajorVersion();
@@ -993,12 +1023,12 @@ bool cmState::ParseCacheEntry(const std::string& entry, std::string& var,
bool flag = false;
if (regQuoted.find(entry)) {
var = regQuoted.match(1);
- type = cmState::StringToCacheEntryType(regQuoted.match(2).c_str());
+ type = cmState::StringToCacheEntryType(regQuoted.match(2));
value = regQuoted.match(3);
flag = true;
} else if (reg.find(entry)) {
var = reg.match(1);
- type = cmState::StringToCacheEntryType(reg.match(2).c_str());
+ type = cmState::StringToCacheEntryType(reg.match(2));
value = reg.match(3);
flag = true;
}
diff --git a/Source/cmState.h b/Source/cmState.h
index a7ca015..e966935 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -30,6 +30,8 @@ class cmStateSnapshot;
class cmMessenger;
class cmExecutionStatus;
+using cmProp = const std::string*;
+
class cmState
{
friend class cmStateSnapshot;
@@ -51,7 +53,8 @@ public:
CPack,
};
- static const char* GetTargetTypeName(cmStateEnums::TargetType targetType);
+ static const std::string& GetTargetTypeName(
+ cmStateEnums::TargetType targetType);
cmStateSnapshot CreateBaseSnapshot();
cmStateSnapshot CreateBuildsystemDirectorySnapshot(
@@ -70,10 +73,12 @@ public:
cmStateSnapshot const& originSnapshot);
cmStateSnapshot Pop(cmStateSnapshot const& originSnapshot);
- static cmStateEnums::CacheEntryType StringToCacheEntryType(const char*);
- static bool StringToCacheEntryType(const char*,
+ static cmStateEnums::CacheEntryType StringToCacheEntryType(
+ const std::string&);
+ static bool StringToCacheEntryType(const std::string&,
cmStateEnums::CacheEntryType& type);
- static const char* CacheEntryTypeToString(cmStateEnums::CacheEntryType);
+ static const std::string& CacheEntryTypeToString(
+ cmStateEnums::CacheEntryType);
static bool IsCacheEntryType(std::string const& key);
bool LoadCache(const std::string& path, bool internal,
@@ -85,8 +90,9 @@ public:
bool DeleteCache(const std::string& path);
std::vector<std::string> GetCacheEntryKeys() const;
- const char* GetCacheEntryValue(std::string const& key) const;
- const std::string* GetInitializedCacheValue(std::string const& key) const;
+ cmProp GetCacheEntryValue(std::string const& key) const;
+ std::string GetSafeCacheEntryValue(std::string const& key) const;
+ cmProp GetInitializedCacheValue(std::string const& key) const;
cmStateEnums::CacheEntryType GetCacheEntryType(std::string const& key) const;
void SetCacheEntryValue(std::string const& key, std::string const& value);
void SetCacheValue(std::string const& key, std::string const& value);
@@ -99,8 +105,8 @@ public:
void SetCacheEntryBoolProperty(std::string const& key,
std::string const& propertyName, bool value);
std::vector<std::string> GetCacheEntryPropertyList(std::string const& key);
- const char* GetCacheEntryProperty(std::string const& key,
- std::string const& propertyName);
+ cmProp GetCacheEntryProperty(std::string const& key,
+ std::string const& propertyName);
bool GetCacheEntryPropertyAsBool(std::string const& key,
std::string const& propertyName);
void AppendCacheEntryProperty(std::string const& key,
@@ -118,8 +124,8 @@ public:
cmStateSnapshot Reset();
// Define a property
void DefineProperty(const std::string& name, cmProperty::ScopeType scope,
- const char* ShortDescription,
- const char* FullDescription, bool chain = false);
+ const std::string& ShortDescription,
+ const std::string& FullDescription, bool chain = false);
// get property definition
cmPropertyDefinition const* GetPropertyDefinition(
@@ -166,9 +172,9 @@ public:
std::vector<std::string> GetCommandNames() const;
void SetGlobalProperty(const std::string& prop, const char* value);
- void AppendGlobalProperty(const std::string& prop, const char* value,
+ void AppendGlobalProperty(const std::string& prop, const std::string& value,
bool asString = false);
- const char* GetGlobalProperty(const std::string& prop);
+ cmProp GetGlobalProperty(const std::string& prop);
bool GetGlobalPropertyAsBool(const std::string& prop);
std::string const& GetSourceDirectory() const;
@@ -190,6 +196,8 @@ public:
bool UseNMake() const;
void SetMSYSShell(bool mSYSShell);
bool UseMSYSShell() const;
+ void SetNinjaMulti(bool ninjaMulti);
+ bool UseNinjaMulti() const;
unsigned int GetCacheMajorVersion() const;
unsigned int GetCacheMinorVersion() const;
@@ -245,6 +253,7 @@ private:
bool MinGWMake = false;
bool NMake = false;
bool MSYSShell = false;
+ bool NinjaMulti = false;
Mode CurrentMode = Unknown;
};
diff --git a/Source/cmStateDirectory.cxx b/Source/cmStateDirectory.cxx
index 1262f53..a4fe663 100644
--- a/Source/cmStateDirectory.cxx
+++ b/Source/cmStateDirectory.cxx
@@ -8,6 +8,7 @@
#include <vector>
#include <cm/iterator>
+#include <cmext/algorithm>
#include "cmAlgorithms.h"
#include "cmProperty.h"
@@ -520,7 +521,7 @@ void cmStateDirectory::SetProperty(const std::string& prop, const char* value,
}
void cmStateDirectory::AppendProperty(const std::string& prop,
- const char* value, bool asString,
+ const std::string& value, bool asString,
cmListFileBacktrace const& lfbt)
{
if (prop == "INCLUDE_DIRECTORIES") {
@@ -547,32 +548,31 @@ void cmStateDirectory::AppendProperty(const std::string& prop,
this->DirectoryState->Properties.AppendProperty(prop, value, asString);
}
-const char* cmStateDirectory::GetProperty(const std::string& prop) const
+cmProp cmStateDirectory::GetProperty(const std::string& prop) const
{
const bool chain =
this->Snapshot_.State->IsPropertyChained(prop, cmProperty::DIRECTORY);
return this->GetProperty(prop, chain);
}
-const char* cmStateDirectory::GetProperty(const std::string& prop,
- bool chain) const
+cmProp cmStateDirectory::GetProperty(const std::string& prop, bool chain) const
{
static std::string output;
output.clear();
if (prop == "PARENT_DIRECTORY") {
cmStateSnapshot parent = this->Snapshot_.GetBuildsystemDirectoryParent();
if (parent.IsValid()) {
- return parent.GetDirectory().GetCurrentSource().c_str();
+ return &parent.GetDirectory().GetCurrentSource();
}
- return "";
+ return &output;
}
if (prop == kBINARY_DIR) {
output = this->GetCurrentBinary();
- return output.c_str();
+ return &output;
}
if (prop == kSOURCE_DIR) {
output = this->GetCurrentSource();
- return output.c_str();
+ return &output;
}
if (prop == kSUBDIRECTORIES) {
std::vector<std::string> child_dirs;
@@ -583,11 +583,11 @@ const char* cmStateDirectory::GetProperty(const std::string& prop,
child_dirs.push_back(ci.GetDirectory().GetCurrentSource());
}
output = cmJoin(child_dirs, ";");
- return output.c_str();
+ return &output;
}
if (prop == kBUILDSYSTEM_TARGETS) {
output = cmJoin(this->DirectoryState->NormalTargetNames, ";");
- return output.c_str();
+ return &output;
}
if (prop == "LISTFILE_STACK") {
@@ -599,41 +599,41 @@ const char* cmStateDirectory::GetProperty(const std::string& prop,
}
std::reverse(listFiles.begin(), listFiles.end());
output = cmJoin(listFiles, ";");
- return output.c_str();
+ return &output;
}
if (prop == "CACHE_VARIABLES") {
output = cmJoin(this->Snapshot_.State->GetCacheEntryKeys(), ";");
- return output.c_str();
+ return &output;
}
if (prop == "VARIABLES") {
std::vector<std::string> res = this->Snapshot_.ClosureKeys();
- cmAppend(res, this->Snapshot_.State->GetCacheEntryKeys());
+ cm::append(res, this->Snapshot_.State->GetCacheEntryKeys());
std::sort(res.begin(), res.end());
output = cmJoin(res, ";");
- return output.c_str();
+ return &output;
}
if (prop == "INCLUDE_DIRECTORIES") {
output = cmJoin(this->GetIncludeDirectoriesEntries(), ";");
- return output.c_str();
+ return &output;
}
if (prop == "COMPILE_OPTIONS") {
output = cmJoin(this->GetCompileOptionsEntries(), ";");
- return output.c_str();
+ return &output;
}
if (prop == "COMPILE_DEFINITIONS") {
output = cmJoin(this->GetCompileDefinitionsEntries(), ";");
- return output.c_str();
+ return &output;
}
if (prop == "LINK_OPTIONS") {
output = cmJoin(this->GetLinkOptionsEntries(), ";");
- return output.c_str();
+ return &output;
}
if (prop == "LINK_DIRECTORIES") {
output = cmJoin(this->GetLinkDirectoriesEntries(), ";");
- return output.c_str();
+ return &output;
}
- const char* retVal = this->DirectoryState->Properties.GetPropertyValue(prop);
+ cmProp retVal = this->DirectoryState->Properties.GetPropertyValue(prop);
if (!retVal && chain) {
cmStateSnapshot parentSnapshot =
this->Snapshot_.GetBuildsystemDirectoryParent();
@@ -648,7 +648,8 @@ const char* cmStateDirectory::GetProperty(const std::string& prop,
bool cmStateDirectory::GetPropertyAsBool(const std::string& prop) const
{
- return cmIsOn(this->GetProperty(prop));
+ cmProp p = this->GetProperty(prop);
+ return p && cmIsOn(*p);
}
std::vector<std::string> cmStateDirectory::GetPropertyKeys() const
diff --git a/Source/cmStateDirectory.h b/Source/cmStateDirectory.h
index fe15563..8144160 100644
--- a/Source/cmStateDirectory.h
+++ b/Source/cmStateDirectory.h
@@ -16,6 +16,8 @@
#include "cmStateSnapshot.h"
#include "cmStringAlgorithms.h"
+using cmProp = const std::string*;
+
class cmStateDirectory
{
cmStateDirectory(
@@ -84,10 +86,10 @@ public:
void SetProperty(const std::string& prop, const char* value,
cmListFileBacktrace const& lfbt);
- void AppendProperty(const std::string& prop, const char* value,
+ void AppendProperty(const std::string& prop, const std::string& value,
bool asString, cmListFileBacktrace const& lfbt);
- const char* GetProperty(const std::string& prop) const;
- const char* GetProperty(const std::string& prop, bool chain) const;
+ cmProp GetProperty(const std::string& prop) const;
+ cmProp GetProperty(const std::string& prop, bool chain) const;
bool GetPropertyAsBool(const std::string& prop) const;
std::vector<std::string> GetPropertyKeys() const;
diff --git a/Source/cmStateSnapshot.cxx b/Source/cmStateSnapshot.cxx
index 645907c..d79df6f 100644
--- a/Source/cmStateSnapshot.cxx
+++ b/Source/cmStateSnapshot.cxx
@@ -315,10 +315,14 @@ void cmStateSnapshot::SetDefaultDefinitions()
this->SetDefinition("UNIX", "1");
this->SetDefinition("CMAKE_HOST_UNIX", "1");
+# if defined(__ANDROID__)
+ this->SetDefinition("CMAKE_HOST_SYSTEM_NAME", "Android");
+# else
struct utsname uts_name;
if (uname(&uts_name) >= 0) {
this->SetDefinition("CMAKE_HOST_SYSTEM_NAME", uts_name.sysname);
}
+# endif
#endif
#if defined(__CYGWIN__)
std::string legacy;
@@ -407,11 +411,12 @@ void cmStateSnapshot::InitializeFromParent()
this->Position->BuildSystemDirectory->LinkDirectoriesBacktraces,
this->Position->LinkDirectoriesPosition);
- const char* include_regex =
+ cmProp include_regex =
parent->BuildSystemDirectory->Properties.GetPropertyValue(
"INCLUDE_REGULAR_EXPRESSION");
this->Position->BuildSystemDirectory->Properties.SetProperty(
- "INCLUDE_REGULAR_EXPRESSION", include_regex);
+ "INCLUDE_REGULAR_EXPRESSION",
+ include_regex ? include_regex->c_str() : nullptr);
}
cmState* cmStateSnapshot::GetState() const
diff --git a/Source/cmString.hxx b/Source/cmString.hxx
index 073f4c9..87bfdff 100644
--- a/Source/cmString.hxx
+++ b/Source/cmString.hxx
@@ -16,8 +16,7 @@
#include <utility>
#include <cm/string_view>
-
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
namespace cm {
@@ -88,18 +87,6 @@ struct IntoString<std::string> : std::true_type
};
template <>
-struct IntoString<string_view> : std::true_type
-{
- static std::string into_string(string_view s) { return std::string(s); }
-};
-
-template <>
-struct IntoString<static_string_view> : std::true_type
-{
- static string_view into_string(static_string_view s) { return s; }
-};
-
-template <>
struct IntoString<char> : std::true_type
{
static std::string into_string(char const& c) { return std::string(1, c); }
@@ -239,6 +226,25 @@ public:
{
}
+ /**
+ * Construct via static_string_view constructor.
+ * explicit is required to avoid ambiguous overloaded operators (i.e ==,
+ * etc...) with the ones provided by string_view.
+ */
+ explicit String(static_string_view s)
+ : String(s, Private())
+ {
+ }
+ /**
+ * Construct via string_view constructor.
+ * explicit is required to avoid ambiguous overloaded operators (i.e ==,
+ * etc...) with the ones provided by string_view.
+ */
+ explicit String(string_view s)
+ : String(std::string(s), Private())
+ {
+ }
+
/** Construct via std::string initializer list constructor. */
String(std::initializer_list<char> il)
: String(std::string(il))
@@ -306,6 +312,17 @@ public:
This shares ownership of the other string's buffer. */
String& operator=(String const&) noexcept = default;
+ String& operator=(static_string_view s)
+ {
+ *this = String(s);
+ return *this;
+ }
+ String& operator=(string_view s)
+ {
+ *this = String(s);
+ return *this;
+ }
+
/** Assign from any type implementing the IntoString trait. */
template <typename T>
typename // NOLINT(*)
@@ -328,6 +345,7 @@ public:
/** Return a view of the string. */
string_view view() const noexcept { return view_; }
+ operator string_view() const noexcept { return this->view(); }
/** Return true if the instance is an empty stringn or null string. */
bool empty() const noexcept { return view_.empty(); }
@@ -638,58 +656,155 @@ private:
string_view view_;
};
-template <typename L, typename R>
-typename std::enable_if<AsStringView<L>::value && AsStringView<R>::value,
- bool>::type
-operator==(L&& l, R&& r)
+/**
+ * Trait for comparable types.
+ */
+template <typename T>
+struct IsComparable : std::false_type
+{
+};
+
+template <typename T>
+struct IsComparable<T&> : IsComparable<T>
+{
+};
+
+template <typename T>
+struct IsComparable<T const> : IsComparable<T>
+{
+};
+
+template <typename T>
+struct IsComparable<T const*> : IsComparable<T*>
+{
+};
+
+template <typename T, std::string::size_type N>
+struct IsComparable<T const[N]> : IsComparable<T[N]>
+{
+};
+
+template <>
+struct IsComparable<char*> : std::true_type
{
- return (AsStringView<L>::view(std::forward<L>(l)) ==
- AsStringView<R>::view(std::forward<R>(r)));
+};
+
+template <std::string::size_type N>
+struct IsComparable<char[N]> : std::true_type
+{
+};
+
+template <>
+struct IsComparable<std::string> : std::true_type
+{
+};
+
+template <>
+struct IsComparable<char> : std::true_type
+{
+};
+
+/** comparison operators */
+inline bool operator==(const String& l, const String& r)
+{
+ return l.view() == r.view();
+}
+template <typename L>
+typename std::enable_if<IsComparable<L>::value, bool>::type operator==(
+ L&& l, const String& r)
+{
+ return AsStringView<L>::view(std::forward<L>(l)) == r.view();
+}
+template <typename R>
+typename std::enable_if<IsComparable<R>::value, bool>::type operator==(
+ const String& l, R&& r)
+{
+ return l.view() == AsStringView<R>::view(std::forward<R>(r));
}
-template <typename L, typename R>
-typename std::enable_if<AsStringView<L>::value && AsStringView<R>::value,
- bool>::type
-operator!=(L&& l, R&& r)
+inline bool operator!=(const String& l, const String& r)
+{
+ return l.view() != r.view();
+}
+template <typename L>
+typename std::enable_if<IsComparable<L>::value, bool>::type operator!=(
+ L&& l, const String& r)
{
- return (AsStringView<L>::view(std::forward<L>(l)) !=
- AsStringView<R>::view(std::forward<R>(r)));
+ return AsStringView<L>::view(std::forward<L>(l)) != r.view();
+}
+template <typename R>
+typename std::enable_if<IsComparable<R>::value, bool>::type operator!=(
+ const String& l, R&& r)
+{
+ return l.view() != AsStringView<R>::view(std::forward<R>(r));
}
-template <typename L, typename R>
-typename std::enable_if<AsStringView<L>::value && AsStringView<R>::value,
- bool>::type
-operator<(L&& l, R&& r)
+inline bool operator<(const String& l, const String& r)
{
- return (AsStringView<L>::view(std::forward<L>(l)) <
- AsStringView<R>::view(std::forward<R>(r)));
+ return l.view() < r.view();
+}
+template <typename L>
+typename std::enable_if<IsComparable<L>::value, bool>::type operator<(
+ L&& l, const String& r)
+{
+ return AsStringView<L>::view(std::forward<L>(l)) < r.view();
+}
+template <typename R>
+typename std::enable_if<IsComparable<R>::value, bool>::type operator<(
+ const String& l, R&& r)
+{
+ return l.view() < AsStringView<R>::view(std::forward<R>(r));
}
-template <typename L, typename R>
-typename std::enable_if<AsStringView<L>::value && AsStringView<R>::value,
- bool>::type
-operator<=(L&& l, R&& r)
+inline bool operator<=(const String& l, const String& r)
+{
+ return l.view() <= r.view();
+}
+template <typename L>
+typename std::enable_if<IsComparable<L>::value, bool>::type operator<=(
+ L&& l, const String& r)
+{
+ return AsStringView<L>::view(std::forward<L>(l)) <= r.view();
+}
+template <typename R>
+typename std::enable_if<IsComparable<R>::value, bool>::type operator<=(
+ const String& l, R&& r)
{
- return (AsStringView<L>::view(std::forward<L>(l)) <=
- AsStringView<R>::view(std::forward<R>(r)));
+ return l.view() <= AsStringView<R>::view(std::forward<R>(r));
}
-template <typename L, typename R>
-typename std::enable_if<AsStringView<L>::value && AsStringView<R>::value,
- bool>::type
-operator>(L&& l, R&& r)
+inline bool operator>(const String& l, const String& r)
+{
+ return l.view() > r.view();
+}
+template <typename L>
+typename std::enable_if<IsComparable<L>::value, bool>::type operator>(
+ L&& l, const String& r)
+{
+ return AsStringView<L>::view(std::forward<L>(l)) > r.view();
+}
+template <typename R>
+typename std::enable_if<IsComparable<R>::value, bool>::type operator>(
+ const String& l, R&& r)
{
- return (AsStringView<L>::view(std::forward<L>(l)) >
- AsStringView<R>::view(std::forward<R>(r)));
+ return l.view() > AsStringView<R>::view(std::forward<R>(r));
}
-template <typename L, typename R>
-typename std::enable_if<AsStringView<L>::value && AsStringView<R>::value,
- bool>::type
-operator>=(L&& l, R&& r)
+inline bool operator>=(const String& l, const String& r)
+{
+ return l.view() >= r.view();
+}
+template <typename L>
+typename std::enable_if<IsComparable<L>::value, bool>::type operator>=(
+ L&& l, const String& r)
+{
+ return AsStringView<L>::view(std::forward<L>(l)) >= r.view();
+}
+template <typename R>
+typename std::enable_if<IsComparable<R>::value, bool>::type operator>=(
+ const String& l, R&& r)
{
- return (AsStringView<L>::view(std::forward<L>(l)) >=
- AsStringView<R>::view(std::forward<R>(r)));
+ return l.view() >= AsStringView<R>::view(std::forward<R>(r));
}
std::ostream& operator<<(std::ostream& os, String const& s);
diff --git a/Source/cmStringAlgorithms.cxx b/Source/cmStringAlgorithms.cxx
index bb6dcd7..71d28a4 100644
--- a/Source/cmStringAlgorithms.cxx
+++ b/Source/cmStringAlgorithms.cxx
@@ -4,7 +4,7 @@
#include <algorithm>
#include <cerrno>
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
#include <cstdio>
#include <cstdlib>
diff --git a/Source/cmStringAlgorithms.h b/Source/cmStringAlgorithms.h
index 0e405de..a5ecca7 100644
--- a/Source/cmStringAlgorithms.h
+++ b/Source/cmStringAlgorithms.h
@@ -87,7 +87,7 @@ void cmExpandLists(InputIt first, InputIt last,
std::vector<std::string>& argsOut)
{
for (; first != last; ++first) {
- ExpandList(*first, argsOut);
+ cmExpandList(*first, argsOut);
}
}
diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx
index 9212195..a7c21cc 100644
--- a/Source/cmStringCommand.cxx
+++ b/Source/cmStringCommand.cxx
@@ -11,11 +11,10 @@
#include <memory>
#include <cm/iterator>
+#include <cmext/string_view>
#include "cmsys/RegularExpression.hxx"
-#include "cm_static_string_view.hxx"
-
#include "cmCryptoHash.h"
#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
@@ -124,6 +123,27 @@ bool HandleAsciiCommand(std::vector<std::string> const& args,
return true;
}
+bool HandleHexCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ if (args.size() != 3) {
+ status.SetError("Incorrect number of arguments");
+ return false;
+ }
+ auto const& instr = args[1];
+ auto const& outvar = args[2];
+ std::string output(instr.size() * 2, ' ');
+
+ std::string::size_type hexIndex = 0;
+ for (auto const& c : instr) {
+ sprintf(&output[hexIndex], "%.2x", static_cast<unsigned char>(c) & 0xFF);
+ hexIndex += 2;
+ }
+
+ status.GetMakefile().AddDefinition(outvar, output);
+ return true;
+}
+
bool HandleConfigureCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
@@ -936,6 +956,7 @@ bool cmStringCommand(std::vector<std::string> const& args,
{ "TOUPPER"_s, HandleToUpperCommand },
{ "COMPARE"_s, HandleCompareCommand },
{ "ASCII"_s, HandleAsciiCommand },
+ { "HEX"_s, HandleHexCommand },
{ "CONFIGURE"_s, HandleConfigureCommand },
{ "LENGTH"_s, HandleLengthCommand },
{ "APPEND"_s, HandleAppendCommand },
diff --git a/Source/cmSubcommandTable.h b/Source/cmSubcommandTable.h
index 65eb8c7..7deaaed 100644
--- a/Source/cmSubcommandTable.h
+++ b/Source/cmSubcommandTable.h
@@ -11,8 +11,7 @@
#include <vector>
#include <cm/string_view>
-
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
class cmExecutionStatus;
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index c4a4220..be799b0 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -1,17 +1,29 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
+
+#if !defined(_WIN32) && !defined(__sun)
+// POSIX APIs are needed
+# define _POSIX_C_SOURCE 200809L
+#endif
+#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__)
+// For isascii
+# define _XOPEN_SOURCE 700
+#endif
+
#include "cmSystemTools.h"
-#include "cm_uv.h"
+#include <cmext/algorithm>
+
+#include <cm3p/uv.h>
-#include "cmAlgorithms.h"
#include "cmDuration.h"
#include "cmProcessOutput.h"
#include "cmRange.h"
#include "cmStringAlgorithms.h"
#if !defined(CMAKE_BOOTSTRAP)
-# include "cm_libarchive.h"
+# include <cm3p/archive.h>
+# include <cm3p/archive_entry.h>
# include "cmArchiveWrite.h"
# include "cmLocale.h"
@@ -24,6 +36,9 @@
#endif
#if !defined(CMAKE_BOOTSTRAP)
+# if defined(_WIN32)
+# include <cm/memory>
+# endif
# include "cmCryptoHash.h"
#endif
@@ -360,7 +375,7 @@ std::vector<std::string> cmSystemTools::HandleResponseFile(
#else
cmSystemTools::ParseUnixCommandLine(line.c_str(), args2);
#endif
- cmAppend(arg_full, args2);
+ cm::append(arg_full, args2);
}
} else {
arg_full.push_back(arg);
@@ -585,7 +600,7 @@ bool cmSystemTools::RunSingleCommand(std::vector<std::string> const& command,
cmSystemTools::Stdout(strdata);
}
if (captureStdOut) {
- cmAppend(tempStdOut, data, data + length);
+ cm::append(tempStdOut, data, data + length);
}
} else if (pipe == cmsysProcess_Pipe_STDERR) {
if (outputflag != OUTPUT_NONE) {
@@ -593,7 +608,7 @@ bool cmSystemTools::RunSingleCommand(std::vector<std::string> const& command,
cmSystemTools::Stderr(strdata);
}
if (captureStdErr) {
- cmAppend(tempStdErr, data, data + length);
+ cm::append(tempStdErr, data, data + length);
}
}
}
@@ -814,6 +829,8 @@ void cmSystemTools::InitializeLibUV()
# else
_fmode = _O_TEXT;
# endif
+ // Replace libuv's report handler with our own to suppress popups.
+ cmSystemTools::EnableMSVCDebugHook();
#endif
}
@@ -905,7 +922,6 @@ std::string cmSystemTools::ComputeCertificateThumbprint(
std::string thumbprint;
#if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32)
- BYTE* certData = NULL;
CRYPT_INTEGER_BLOB cryptBlob;
HCERTSTORE certStore = NULL;
PCCERT_CONTEXT certContext = NULL;
@@ -917,12 +933,12 @@ std::string cmSystemTools::ComputeCertificateThumbprint(
if (certFile != INVALID_HANDLE_VALUE && certFile != NULL) {
DWORD fileSize = GetFileSize(certFile, NULL);
if (fileSize != INVALID_FILE_SIZE) {
- certData = new BYTE[fileSize];
+ auto certData = cm::make_unique<BYTE[]>(fileSize);
if (certData != NULL) {
DWORD dwRead = 0;
- if (ReadFile(certFile, certData, fileSize, &dwRead, NULL)) {
+ if (ReadFile(certFile, certData.get(), fileSize, &dwRead, NULL)) {
cryptBlob.cbData = fileSize;
- cryptBlob.pbData = certData;
+ cryptBlob.pbData = certData.get();
// Verify that this is a valid cert
if (PFXIsPFXBlob(&cryptBlob)) {
@@ -958,7 +974,6 @@ std::string cmSystemTools::ComputeCertificateThumbprint(
}
}
}
- delete[] certData;
}
}
CloseHandle(certFile);
@@ -1051,8 +1066,7 @@ bool cmSystemTools::SimpleGlob(const std::string& glob,
if (type < 0 && !cmSystemTools::FileIsDirectory(fname)) {
continue;
}
- if (sfname.size() >= ppath.size() &&
- sfname.substr(0, ppath.size()) == ppath) {
+ if (cmHasPrefix(sfname, ppath)) {
files.push_back(fname);
res = true;
}
@@ -1308,6 +1322,7 @@ bool cmSystemTools::CreateTar(const std::string& outFileName,
cmArchiveWrite a(fout, compress, format.empty() ? "paxr" : format);
+ a.Open();
a.SetMTime(mtime);
a.SetVerbose(verbose);
bool tarCreatedSuccessfully = true;
@@ -1710,26 +1725,26 @@ int cmSystemTools::WaitForLine(cmsysProcess* process, std::string& line,
processOutput.DecodeText(data, length, strdata, 1);
// Append to the stdout buffer.
std::vector<char>::size_type size = out.size();
- cmAppend(out, strdata);
+ cm::append(out, strdata);
outiter = out.begin() + size;
} else if (pipe == cmsysProcess_Pipe_STDERR) {
processOutput.DecodeText(data, length, strdata, 2);
// Append to the stderr buffer.
std::vector<char>::size_type size = err.size();
- cmAppend(err, strdata);
+ cm::append(err, strdata);
erriter = err.begin() + size;
} else if (pipe == cmsysProcess_Pipe_None) {
// Both stdout and stderr pipes have broken. Return leftover data.
processOutput.DecodeText(std::string(), strdata, 1);
if (!strdata.empty()) {
std::vector<char>::size_type size = out.size();
- cmAppend(out, strdata);
+ cm::append(out, strdata);
outiter = out.begin() + size;
}
processOutput.DecodeText(std::string(), strdata, 2);
if (!strdata.empty()) {
std::vector<char>::size_type size = err.size();
- cmAppend(err, strdata);
+ cm::append(err, strdata);
erriter = err.begin() + size;
}
if (!out.empty()) {
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index cdfd349..d43fbe5 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -12,6 +12,7 @@
#include <unordered_set>
#include <cm/memory>
+#include <cmext/algorithm>
#include "cmsys/RegularExpression.hxx"
@@ -38,13 +39,13 @@
#include "cmake.h"
template <>
-const char* cmTargetPropertyComputer::ComputeLocationForBuild<cmTarget>(
+const std::string& cmTargetPropertyComputer::ComputeLocationForBuild<cmTarget>(
cmTarget const* tgt)
{
static std::string loc;
if (tgt->IsImported()) {
loc = tgt->ImportedGetFullPath("", cmStateEnums::RuntimeBinaryArtifact);
- return loc.c_str();
+ return loc;
}
cmGlobalGenerator* gg = tgt->GetGlobalGenerator();
@@ -53,18 +54,18 @@ const char* cmTargetPropertyComputer::ComputeLocationForBuild<cmTarget>(
}
cmGeneratorTarget* gt = gg->FindGeneratorTarget(tgt->GetName());
loc = gt->GetLocationForBuild();
- return loc.c_str();
+ return loc;
}
template <>
-const char* cmTargetPropertyComputer::ComputeLocation<cmTarget>(
+const std::string& cmTargetPropertyComputer::ComputeLocation<cmTarget>(
cmTarget const* tgt, const std::string& config)
{
static std::string loc;
if (tgt->IsImported()) {
loc =
tgt->ImportedGetFullPath(config, cmStateEnums::RuntimeBinaryArtifact);
- return loc.c_str();
+ return loc;
}
cmGlobalGenerator* gg = tgt->GetGlobalGenerator();
@@ -73,11 +74,11 @@ const char* cmTargetPropertyComputer::ComputeLocation<cmTarget>(
}
cmGeneratorTarget* gt = gg->FindGeneratorTarget(tgt->GetName());
loc = gt->GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact);
- return loc.c_str();
+ return loc;
}
template <>
-const char* cmTargetPropertyComputer::GetSources<cmTarget>(
+cmProp cmTargetPropertyComputer::GetSources<cmTarget>(
cmTarget const* tgt, cmMessenger* messenger,
cmListFileBacktrace const& context)
{
@@ -155,7 +156,7 @@ const char* cmTargetPropertyComputer::GetSources<cmTarget>(
}
static std::string srcs;
srcs = ss.str();
- return srcs.c_str();
+ return &srcs;
}
class cmTargetInternals
@@ -176,7 +177,8 @@ public:
bool IsImportedTarget;
bool ImportedGloballyVisible;
bool BuildInterfaceIncludesAppended;
- std::set<BT<std::string>> Utilities;
+ bool PerConfig;
+ std::set<BT<std::pair<std::string, bool>>> Utilities;
std::vector<cmCustomCommand> PreBuildCommands;
std::vector<cmCustomCommand> PreLinkCommands;
std::vector<cmCustomCommand> PostBuildCommands;
@@ -213,7 +215,7 @@ public:
};
cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
- Visibility vis, cmMakefile* mf)
+ Visibility vis, cmMakefile* mf, bool perConfig)
: impl(cm::make_unique<cmTargetInternals>())
{
assert(mf);
@@ -229,6 +231,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
(vis == VisibilityImported || vis == VisibilityImportedGlobally);
impl->ImportedGloballyVisible = vis == VisibilityImportedGlobally;
impl->BuildInterfaceIncludesAppended = false;
+ impl->PerConfig = perConfig;
// Check whether this is a DLL platform.
impl->IsDLLPlatform =
@@ -300,6 +303,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("PDB_OUTPUT_DIRECTORY");
initProp("COMPILE_PDB_OUTPUT_DIRECTORY");
initProp("FRAMEWORK");
+ initProp("FRAMEWORK_MULTI_CONFIG_POSTFIX");
initProp("Fortran_FORMAT");
initProp("Fortran_MODULE_DIRECTORY");
initProp("Fortran_COMPILER_LAUNCHER");
@@ -358,15 +362,18 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("CUDA_COMPILER_LAUNCHER");
initProp("CUDA_SEPARABLE_COMPILATION");
initProp("CUDA_RESOLVE_DEVICE_SYMBOLS");
+ initProp("CUDA_RUNTIME_LIBRARY");
+ initProp("CUDA_ARCHITECTURES");
initProp("LINK_SEARCH_START_STATIC");
initProp("LINK_SEARCH_END_STATIC");
- initProp("FOLDER");
initProp("Swift_LANGUAGE_VERSION");
initProp("Swift_MODULE_DIRECTORY");
initProp("VS_JUST_MY_CODE_DEBUGGING");
initProp("DISABLE_PRECOMPILE_HEADERS");
initProp("UNITY_BUILD");
initPropValue("UNITY_BUILD_BATCH_SIZE", "8");
+ initPropValue("UNITY_BUILD_MODE", "BATCH");
+ initPropValue("PCH_WARN_INVALID", "ON");
#ifdef __APPLE__
if (this->GetGlobalGenerator()->IsXcode()) {
initProp("XCODE_SCHEME_ADDRESS_SANITIZER");
@@ -376,6 +383,7 @@ 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_WORKING_DIRECTORY");
initProp("XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER");
initProp("XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP");
initProp("XCODE_SCHEME_MALLOC_SCRIBBLE");
@@ -385,11 +393,14 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("XCODE_SCHEME_MALLOC_STACK");
initProp("XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE");
initProp("XCODE_SCHEME_DYNAMIC_LIBRARY_LOADS");
+ initProp("XCODE_SCHEME_ENVIRONMENT");
}
#endif
}
if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
+ initProp("FOLDER");
+
if (this->GetGlobalGenerator()->IsXcode()) {
initProp("XCODE_GENERATE_SCHEME");
}
@@ -431,6 +442,13 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
cmStrCat(cmSystemTools::UpperCase(configName), "_POSTFIX");
initProp(property);
}
+
+ if (impl->TargetType == cmStateEnums::SHARED_LIBRARY ||
+ impl->TargetType == cmStateEnums::STATIC_LIBRARY) {
+ std::string property = cmStrCat("FRAMEWORK_MULTI_CONFIG_POSTFIX_",
+ cmSystemTools::UpperCase(configName));
+ initProp(property);
+ }
}
}
@@ -440,30 +458,30 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
if (!this->IsImported()) {
// Initialize the INCLUDE_DIRECTORIES property based on the current value
// of the same directory property:
- cmAppend(impl->IncludeDirectoriesEntries,
- impl->Makefile->GetIncludeDirectoriesEntries());
- cmAppend(impl->IncludeDirectoriesBacktraces,
- impl->Makefile->GetIncludeDirectoriesBacktraces());
+ cm::append(impl->IncludeDirectoriesEntries,
+ impl->Makefile->GetIncludeDirectoriesEntries());
+ cm::append(impl->IncludeDirectoriesBacktraces,
+ impl->Makefile->GetIncludeDirectoriesBacktraces());
{
auto const& sysInc = impl->Makefile->GetSystemIncludeDirectories();
impl->SystemIncludeDirectories.insert(sysInc.begin(), sysInc.end());
}
- cmAppend(impl->CompileOptionsEntries,
- impl->Makefile->GetCompileOptionsEntries());
- cmAppend(impl->CompileOptionsBacktraces,
- impl->Makefile->GetCompileOptionsBacktraces());
+ cm::append(impl->CompileOptionsEntries,
+ impl->Makefile->GetCompileOptionsEntries());
+ cm::append(impl->CompileOptionsBacktraces,
+ impl->Makefile->GetCompileOptionsBacktraces());
- cmAppend(impl->LinkOptionsEntries,
- impl->Makefile->GetLinkOptionsEntries());
- cmAppend(impl->LinkOptionsBacktraces,
- impl->Makefile->GetLinkOptionsBacktraces());
+ cm::append(impl->LinkOptionsEntries,
+ impl->Makefile->GetLinkOptionsEntries());
+ cm::append(impl->LinkOptionsBacktraces,
+ impl->Makefile->GetLinkOptionsBacktraces());
- cmAppend(impl->LinkDirectoriesEntries,
- impl->Makefile->GetLinkDirectoriesEntries());
- cmAppend(impl->LinkDirectoriesBacktraces,
- impl->Makefile->GetLinkDirectoriesBacktraces());
+ cm::append(impl->LinkDirectoriesEntries,
+ impl->Makefile->GetLinkDirectoriesEntries());
+ cm::append(impl->LinkDirectoriesBacktraces,
+ impl->Makefile->GetLinkDirectoriesBacktraces());
}
if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
@@ -487,6 +505,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
}
if (impl->TargetType == cmStateEnums::SHARED_LIBRARY ||
impl->TargetType == cmStateEnums::EXECUTABLE) {
+ initProp("AIX_EXPORT_ALL_SYMBOLS");
initProp("WINDOWS_EXPORT_ALL_SYMBOLS");
}
@@ -510,14 +529,15 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
this->GetType() != cmStateEnums::UTILITY) {
initProp("JOB_POOL_COMPILE");
initProp("JOB_POOL_LINK");
+ initProp("JOB_POOL_PRECOMPILE_HEADER");
}
if (impl->TargetType <= cmStateEnums::UTILITY) {
+ initProp("DOTNET_TARGET_FRAMEWORK");
initProp("DOTNET_TARGET_FRAMEWORK_VERSION");
}
- if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
- this->GetType() != cmStateEnums::UTILITY) {
+ if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
// check for "CMAKE_VS_GLOBALS" variable and set up target properties
// if any
@@ -577,13 +597,14 @@ cmGlobalGenerator* cmTarget::GetGlobalGenerator() const
return impl->Makefile->GetGlobalGenerator();
}
-void cmTarget::AddUtility(std::string const& name, cmMakefile* mf)
+void cmTarget::AddUtility(std::string const& name, bool cross, cmMakefile* mf)
{
- impl->Utilities.insert(
- BT<std::string>(name, mf ? mf->GetBacktrace() : cmListFileBacktrace()));
+ impl->Utilities.insert(BT<std::pair<std::string, bool>>(
+ { name, cross }, mf ? mf->GetBacktrace() : cmListFileBacktrace()));
}
-std::set<BT<std::string>> const& cmTarget::GetUtilities() const
+std::set<BT<std::pair<std::string, bool>>> const& cmTarget::GetUtilities()
+ const
{
return impl->Utilities;
}
@@ -873,7 +894,7 @@ void cmTarget::GetTllSignatureTraces(std::ostream& s, TLLSignature sig) const
cmListFileContext lfc = cmd.second;
lfc.FilePath = cmDir.ConvertToRelPathIfNotContained(
impl->Makefile->GetState()->GetSourceDirectory(), lfc.FilePath);
- s << " * " << lfc << std::endl;
+ s << " * " << lfc << '\n';
}
}
}
@@ -935,14 +956,7 @@ cmTarget::LinkLibraryVectorType const& cmTarget::GetOriginalLinkLibraries()
return impl->OriginalLinkLibraries;
}
-void cmTarget::AddLinkLibrary(cmMakefile& mf, const std::string& lib,
- cmTargetLinkLibraryType llt)
-{
- this->AddLinkLibrary(mf, lib, lib, llt);
-}
-
void cmTarget::AddLinkLibrary(cmMakefile& mf, std::string const& lib,
- std::string const& libRef,
cmTargetLinkLibraryType llt)
{
cmTarget* tgt = mf.FindTargetToUse(lib);
@@ -951,14 +965,13 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf, std::string const& lib,
const std::string libName =
(isNonImportedTarget && llt != GENERAL_LibraryType)
- ? targetNameGenex(libRef)
- : libRef;
- this->AppendProperty(
- "LINK_LIBRARIES",
- this->GetDebugGeneratorExpressions(libName, llt).c_str());
+ ? targetNameGenex(lib)
+ : lib;
+ this->AppendProperty("LINK_LIBRARIES",
+ this->GetDebugGeneratorExpressions(libName, llt));
}
- if (cmGeneratorExpression::Find(lib) != std::string::npos || lib != libRef ||
+ if (cmGeneratorExpression::Find(lib) != std::string::npos ||
(tgt &&
(tgt->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
tgt->GetType() == cmStateEnums::OBJECT_LIBRARY)) ||
@@ -1000,7 +1013,7 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf, std::string const& lib,
dependencies += ";";
dependencies += lib;
dependencies += ";";
- mf.AddCacheDefinition(targetEntry, dependencies.c_str(),
+ mf.AddCacheDefinition(targetEntry, dependencies,
"Dependencies for the target", cmStateEnums::STATIC);
}
}
@@ -1289,20 +1302,20 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
impl->Properties.SetProperty(prop, reusedFrom.c_str());
- reusedTarget->SetProperty("COMPILE_PDB_NAME", reusedFrom.c_str());
+ reusedTarget->SetProperty("COMPILE_PDB_NAME", reusedFrom);
reusedTarget->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY",
- cmStrCat(reusedFrom, ".dir/").c_str());
+ cmStrCat(reusedFrom, ".dir/"));
- this->SetProperty("COMPILE_PDB_NAME",
- reusedTarget->GetProperty("COMPILE_PDB_NAME"));
- this->AddUtility(reusedFrom, impl->Makefile);
+ cmProp tmp = reusedTarget->GetProperty("COMPILE_PDB_NAME");
+ this->SetProperty("COMPILE_PDB_NAME", tmp ? tmp->c_str() : nullptr);
+ this->AddUtility(reusedFrom, false, impl->Makefile);
} else {
impl->Properties.SetProperty(prop, value);
}
}
-void cmTarget::AppendProperty(const std::string& prop, const char* value,
- bool asString)
+void cmTarget::AppendProperty(const std::string& prop,
+ const std::string& value, bool asString)
{
if (!cmTargetPropertyComputer::PassesWhitelist(
this->GetType(), prop, impl->Makefile->GetMessenger(),
@@ -1337,37 +1350,37 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value,
return;
}
if (prop == "INCLUDE_DIRECTORIES") {
- if (value && *value) {
+ if (!value.empty()) {
impl->IncludeDirectoriesEntries.emplace_back(value);
cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
impl->IncludeDirectoriesBacktraces.push_back(lfbt);
}
} else if (prop == "COMPILE_OPTIONS") {
- if (value && *value) {
+ if (!value.empty()) {
impl->CompileOptionsEntries.emplace_back(value);
cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
impl->CompileOptionsBacktraces.push_back(lfbt);
}
} else if (prop == "COMPILE_FEATURES") {
- if (value && *value) {
+ if (!value.empty()) {
impl->CompileFeaturesEntries.emplace_back(value);
cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
impl->CompileFeaturesBacktraces.push_back(lfbt);
}
} else if (prop == "COMPILE_DEFINITIONS") {
- if (value && *value) {
+ if (!value.empty()) {
impl->CompileDefinitionsEntries.emplace_back(value);
cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
impl->CompileDefinitionsBacktraces.push_back(lfbt);
}
} else if (prop == "LINK_OPTIONS") {
- if (value && *value) {
+ if (!value.empty()) {
impl->LinkOptionsEntries.emplace_back(value);
cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
impl->LinkOptionsBacktraces.push_back(lfbt);
}
} else if (prop == "LINK_DIRECTORIES") {
- if (value && *value) {
+ if (!value.empty()) {
impl->LinkDirectoriesEntries.emplace_back(value);
cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
impl->LinkDirectoriesBacktraces.push_back(lfbt);
@@ -1381,13 +1394,13 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value,
impl->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
return;
}
- if (value && *value) {
+ if (!value.empty()) {
impl->PrecompileHeadersEntries.emplace_back(value);
cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
impl->PrecompileHeadersBacktraces.push_back(lfbt);
}
} else if (prop == "LINK_LIBRARIES") {
- if (value && *value) {
+ if (!value.empty()) {
cmListFileBacktrace lfbt = impl->Makefile->GetBacktrace();
impl->LinkImplementationPropertyEntries.emplace_back(value);
impl->LinkImplementationPropertyBacktraces.push_back(lfbt);
@@ -1426,7 +1439,7 @@ void cmTarget::AppendBuildInterfaceIncludes()
dirs += impl->Makefile->GetCurrentSourceDirectory();
if (!dirs.empty()) {
this->AppendProperty("INTERFACE_INCLUDE_DIRECTORIES",
- ("$<BUILD_INTERFACE:" + dirs + ">").c_str());
+ ("$<BUILD_INTERFACE:" + dirs + ">"));
}
}
}
@@ -1498,7 +1511,7 @@ void cmTarget::InsertPrecompileHeader(std::string const& entry,
}
static void cmTargetCheckLINK_INTERFACE_LIBRARIES(const std::string& prop,
- const char* value,
+ const std::string& value,
cmMakefile* context,
bool imported)
{
@@ -1536,7 +1549,7 @@ static void cmTargetCheckLINK_INTERFACE_LIBRARIES(const std::string& prop,
context->IssueMessage(MessageType::FATAL_ERROR, e.str());
}
-static void cmTargetCheckINTERFACE_LINK_LIBRARIES(const char* value,
+static void cmTargetCheckINTERFACE_LINK_LIBRARIES(const std::string& value,
cmMakefile* context)
{
// Look for link-type keywords in the value.
@@ -1561,8 +1574,12 @@ static void cmTargetCheckINTERFACE_LINK_LIBRARIES(const char* value,
static void cmTargetCheckIMPORTED_GLOBAL(const cmTarget* target,
cmMakefile* context)
{
- std::vector<cmTarget*> targets = context->GetOwnedImportedTargets();
- auto it = std::find(targets.begin(), targets.end(), target);
+ const auto& targets = context->GetOwnedImportedTargets();
+ auto it =
+ std::find_if(targets.begin(), targets.end(),
+ [&](const std::unique_ptr<cmTarget>& importTarget) -> bool {
+ return target == importTarget.get();
+ });
if (it == targets.end()) {
std::ostringstream e;
e << "Attempt to promote imported target \"" << target->GetName()
@@ -1577,18 +1594,18 @@ void cmTarget::CheckProperty(const std::string& prop,
{
// Certain properties need checking.
if (cmHasLiteralPrefix(prop, "LINK_INTERFACE_LIBRARIES")) {
- if (const char* value = this->GetProperty(prop)) {
- cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, value, context, false);
+ if (cmProp value = this->GetProperty(prop)) {
+ cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, *value, context, false);
}
}
if (cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES")) {
- if (const char* value = this->GetProperty(prop)) {
- cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, value, context, true);
+ if (cmProp value = this->GetProperty(prop)) {
+ cmTargetCheckLINK_INTERFACE_LIBRARIES(prop, *value, context, true);
}
}
if (prop == "INTERFACE_LINK_LIBRARIES") {
- if (const char* value = this->GetProperty(prop)) {
- cmTargetCheckINTERFACE_LINK_LIBRARIES(value, context);
+ if (cmProp value = this->GetProperty(prop)) {
+ cmTargetCheckINTERFACE_LINK_LIBRARIES(*value, context);
}
}
if (prop == "IMPORTED_GLOBAL") {
@@ -1598,14 +1615,14 @@ void cmTarget::CheckProperty(const std::string& prop,
}
}
-const char* cmTarget::GetComputedProperty(
- const std::string& prop, cmMessenger* messenger,
- cmListFileBacktrace const& context) const
+cmProp cmTarget::GetComputedProperty(const std::string& prop,
+ cmMessenger* messenger,
+ cmListFileBacktrace const& context) const
{
return cmTargetPropertyComputer::GetProperty(this, prop, messenger, context);
}
-const char* cmTarget::GetProperty(const std::string& prop) const
+cmProp cmTarget::GetProperty(const std::string& prop) const
{
#define MAKE_STATIC_PROP(PROP) static const std::string prop##PROP = #PROP
MAKE_STATIC_PROP(LINK_LIBRARIES);
@@ -1624,6 +1641,8 @@ const char* cmTarget::GetProperty(const std::string& prop) const
MAKE_STATIC_PROP(BINARY_DIR);
MAKE_STATIC_PROP(SOURCE_DIR);
MAKE_STATIC_PROP(SOURCES);
+ MAKE_STATIC_PROP(FALSE);
+ MAKE_STATIC_PROP(TRUE);
#undef MAKE_STATIC_PROP
static std::unordered_set<std::string> const specialProps{
propLINK_LIBRARIES,
@@ -1651,11 +1670,11 @@ const char* cmTarget::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(impl->LinkImplementationPropertyEntries, ";");
- return output.c_str();
+ return &output;
}
// the type property returns what type the target is
if (prop == propTYPE) {
- return cmState::GetTargetTypeName(this->GetType());
+ return &cmState::GetTargetTypeName(this->GetType());
}
if (prop == propINCLUDE_DIRECTORIES) {
if (impl->IncludeDirectoriesEntries.empty()) {
@@ -1664,7 +1683,7 @@ const char* cmTarget::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(impl->IncludeDirectoriesEntries, ";");
- return output.c_str();
+ return &output;
}
if (prop == propCOMPILE_FEATURES) {
if (impl->CompileFeaturesEntries.empty()) {
@@ -1673,7 +1692,7 @@ const char* cmTarget::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(impl->CompileFeaturesEntries, ";");
- return output.c_str();
+ return &output;
}
if (prop == propCOMPILE_OPTIONS) {
if (impl->CompileOptionsEntries.empty()) {
@@ -1682,7 +1701,7 @@ const char* cmTarget::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(impl->CompileOptionsEntries, ";");
- return output.c_str();
+ return &output;
}
if (prop == propCOMPILE_DEFINITIONS) {
if (impl->CompileDefinitionsEntries.empty()) {
@@ -1691,7 +1710,7 @@ const char* cmTarget::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(impl->CompileDefinitionsEntries, ";");
- return output.c_str();
+ return &output;
}
if (prop == propLINK_OPTIONS) {
if (impl->LinkOptionsEntries.empty()) {
@@ -1700,7 +1719,7 @@ const char* cmTarget::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(impl->LinkOptionsEntries, ";");
- return output.c_str();
+ return &output;
}
if (prop == propLINK_DIRECTORIES) {
if (impl->LinkDirectoriesEntries.empty()) {
@@ -1710,7 +1729,7 @@ const char* cmTarget::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(impl->LinkDirectoriesEntries, ";");
- return output.c_str();
+ return &output;
}
if (prop == propMANUALLY_ADDED_DEPENDENCIES) {
if (impl->Utilities.empty()) {
@@ -1718,8 +1737,15 @@ const char* cmTarget::GetProperty(const std::string& prop) const
}
static std::string output;
- output = cmJoin(impl->Utilities, ";");
- return output.c_str();
+ static std::vector<std::string> utilities;
+ utilities.resize(impl->Utilities.size());
+ std::transform(
+ impl->Utilities.cbegin(), impl->Utilities.cend(), utilities.begin(),
+ [](const BT<std::pair<std::string, bool>>& item) -> std::string {
+ return item.Value.first;
+ });
+ output = cmJoin(utilities, ";");
+ return &output;
}
if (prop == propPRECOMPILE_HEADERS) {
if (impl->PrecompileHeadersEntries.empty()) {
@@ -1728,32 +1754,30 @@ const char* cmTarget::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(impl->PrecompileHeadersEntries, ";");
- return output.c_str();
+ return &output;
}
if (prop == propIMPORTED) {
- return this->IsImported() ? "TRUE" : "FALSE";
+ return this->IsImported() ? &propTRUE : &propFALSE;
}
if (prop == propIMPORTED_GLOBAL) {
- return this->IsImportedGloballyVisible() ? "TRUE" : "FALSE";
+ return this->IsImportedGloballyVisible() ? &propTRUE : &propFALSE;
}
if (prop == propNAME) {
- return this->GetName().c_str();
+ return &this->GetName();
}
if (prop == propBINARY_DIR) {
- return impl->Makefile->GetStateSnapshot()
- .GetDirectory()
- .GetCurrentBinary()
- .c_str();
+ return &impl->Makefile->GetStateSnapshot()
+ .GetDirectory()
+ .GetCurrentBinary();
}
if (prop == propSOURCE_DIR) {
- return impl->Makefile->GetStateSnapshot()
- .GetDirectory()
- .GetCurrentSource()
- .c_str();
+ return &impl->Makefile->GetStateSnapshot()
+ .GetDirectory()
+ .GetCurrentSource();
}
}
- const char* retVal = impl->Properties.GetPropertyValue(prop);
+ cmProp retVal = impl->Properties.GetPropertyValue(prop);
if (!retVal) {
const bool chain =
impl->Makefile->GetState()->IsPropertyChained(prop, cmProperty::TARGET);
@@ -1761,22 +1785,26 @@ const char* cmTarget::GetProperty(const std::string& prop) const
return impl->Makefile->GetStateSnapshot().GetDirectory().GetProperty(
prop, chain);
}
+ return nullptr;
}
return retVal;
}
-const char* cmTarget::GetSafeProperty(const std::string& prop) const
+std::string const& cmTarget::GetSafeProperty(std::string const& prop) const
{
- const char* ret = this->GetProperty(prop);
- if (!ret) {
- return "";
+ cmProp ret = this->GetProperty(prop);
+ if (ret) {
+ return *ret;
}
- return ret;
+
+ static std::string const s_empty;
+ return s_empty;
}
bool cmTarget::GetPropertyAsBool(const std::string& prop) const
{
- return cmIsOn(this->GetProperty(prop));
+ cmProp p = this->GetProperty(prop);
+ return p && cmIsOn(*p);
}
cmPropertyMap const& cmTarget::GetProperties() const
@@ -1804,6 +1832,11 @@ bool cmTarget::IsImportedGloballyVisible() const
return impl->ImportedGloballyVisible;
}
+bool cmTarget::IsPerConfig() const
+{
+ return impl->PerConfig;
+}
+
const char* cmTarget::GetSuffixVariableInternal(
cmStateEnums::ArtifactType artifact) const
{
@@ -1900,38 +1933,37 @@ std::string cmTarget::ImportedGetFullPath(
std::string result;
- const char* loc = nullptr;
- const char* imp = nullptr;
+ cmProp loc = nullptr;
+ cmProp imp = nullptr;
std::string suffix;
if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
- this->GetMappedConfig(desired_config, &loc, &imp, suffix)) {
+ this->GetMappedConfig(desired_config, loc, imp, suffix)) {
switch (artifact) {
case cmStateEnums::RuntimeBinaryArtifact:
if (loc) {
- result = loc;
+ result = *loc;
} else {
std::string impProp = cmStrCat("IMPORTED_LOCATION", suffix);
- if (const char* config_location = this->GetProperty(impProp)) {
- result = config_location;
- } else if (const char* location =
+ if (cmProp config_location = this->GetProperty(impProp)) {
+ result = *config_location;
+ } else if (cmProp location =
this->GetProperty("IMPORTED_LOCATION")) {
- result = location;
+ result = *location;
}
}
break;
case cmStateEnums::ImportLibraryArtifact:
if (imp) {
- result = imp;
+ result = *imp;
} else if (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->IsExecutableWithExports()) {
std::string impProp = cmStrCat("IMPORTED_IMPLIB", suffix);
- if (const char* config_implib = this->GetProperty(impProp)) {
- result = config_implib;
- } else if (const char* implib =
- this->GetProperty("IMPORTED_IMPLIB")) {
- result = implib;
+ if (cmProp config_implib = this->GetProperty(impProp)) {
+ result = *config_implib;
+ } else if (cmProp implib = this->GetProperty("IMPORTED_IMPLIB")) {
+ result = *implib;
}
}
break;
@@ -1974,9 +2006,8 @@ bool cmTargetInternals::CheckImportedLibName(std::string const& prop,
return true;
}
-bool cmTarget::GetMappedConfig(std::string const& desired_config,
- const char** loc, const char** imp,
- std::string& suffix) const
+bool cmTarget::GetMappedConfig(std::string const& desired_config, cmProp& loc,
+ cmProp& imp, std::string& suffix) const
{
std::string config_upper;
if (!desired_config.empty()) {
@@ -1998,8 +2029,8 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
std::vector<std::string> mappedConfigs;
{
std::string mapProp = cmStrCat("MAP_IMPORTED_CONFIG_", config_upper);
- if (const char* mapValue = this->GetProperty(mapProp)) {
- cmExpandList(mapValue, mappedConfigs, true);
+ if (cmProp mapValue = this->GetProperty(mapProp)) {
+ cmExpandList(*mapValue, mappedConfigs, true);
}
}
@@ -2013,30 +2044,30 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
// If a mapping was found, check its configurations.
for (auto mci = mappedConfigs.begin();
- !*loc && !*imp && mci != mappedConfigs.end(); ++mci) {
+ !loc && !imp && mci != mappedConfigs.end(); ++mci) {
// Look for this configuration.
if (mci->empty()) {
// An empty string in the mapping has a special meaning:
// look up the config-less properties.
- *loc = this->GetProperty(locPropBase);
+ loc = this->GetProperty(locPropBase);
if (allowImp) {
- *imp = this->GetProperty("IMPORTED_IMPLIB");
+ imp = this->GetProperty("IMPORTED_IMPLIB");
}
// If it was found, set the suffix.
- if (*loc || *imp) {
+ if (loc || imp) {
suffix.clear();
}
} else {
std::string mcUpper = cmSystemTools::UpperCase(*mci);
std::string locProp = cmStrCat(locPropBase, '_', mcUpper);
- *loc = this->GetProperty(locProp);
+ loc = this->GetProperty(locProp);
if (allowImp) {
std::string impProp = cmStrCat("IMPORTED_IMPLIB_", mcUpper);
- *imp = this->GetProperty(impProp);
+ imp = this->GetProperty(impProp);
}
// If it was found, use it for all properties below.
- if (*loc || *imp) {
+ if (loc || imp) {
suffix = cmStrCat('_', mcUpper);
}
}
@@ -2045,59 +2076,59 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
// If we needed to find one of the mapped configurations but did not
// then the target location is not found. The project does not want
// any other configuration.
- if (!mappedConfigs.empty() && !*loc && !*imp) {
+ if (!mappedConfigs.empty() && !loc && !imp) {
// Interface libraries are always available because their
- // library name is optional so it is okay to leave *loc empty.
+ // library name is optional so it is okay to leave loc empty.
return this->GetType() == cmStateEnums::INTERFACE_LIBRARY;
}
// If we have not yet found it then there are no mapped
// configurations. Look for an exact-match.
- if (!*loc && !*imp) {
+ if (!loc && !imp) {
std::string locProp = cmStrCat(locPropBase, suffix);
- *loc = this->GetProperty(locProp);
+ loc = this->GetProperty(locProp);
if (allowImp) {
std::string impProp = cmStrCat("IMPORTED_IMPLIB", suffix);
- *imp = this->GetProperty(impProp);
+ imp = this->GetProperty(impProp);
}
}
// If we have not yet found it then there are no mapped
// configurations and no exact match.
- if (!*loc && !*imp) {
+ if (!loc && !imp) {
// The suffix computed above is not useful.
suffix.clear();
// Look for a configuration-less location. This may be set by
// manually-written code.
- *loc = this->GetProperty(locPropBase);
+ loc = this->GetProperty(locPropBase);
if (allowImp) {
- *imp = this->GetProperty("IMPORTED_IMPLIB");
+ imp = this->GetProperty("IMPORTED_IMPLIB");
}
}
// If we have not yet found it then the project is willing to try
// any available configuration.
- if (!*loc && !*imp) {
+ if (!loc && !imp) {
std::vector<std::string> availableConfigs;
- if (const char* iconfigs = this->GetProperty("IMPORTED_CONFIGURATIONS")) {
- cmExpandList(iconfigs, availableConfigs);
+ if (cmProp iconfigs = this->GetProperty("IMPORTED_CONFIGURATIONS")) {
+ cmExpandList(*iconfigs, availableConfigs);
}
for (auto aci = availableConfigs.begin();
- !*loc && !*imp && aci != availableConfigs.end(); ++aci) {
+ !loc && !imp && aci != availableConfigs.end(); ++aci) {
suffix = cmStrCat('_', cmSystemTools::UpperCase(*aci));
std::string locProp = cmStrCat(locPropBase, suffix);
- *loc = this->GetProperty(locProp);
+ loc = this->GetProperty(locProp);
if (allowImp) {
std::string impProp = cmStrCat("IMPORTED_IMPLIB", suffix);
- *imp = this->GetProperty(impProp);
+ imp = this->GetProperty(impProp);
}
}
}
// If we have not yet found it then the target location is not available.
- if (!*loc && !*imp) {
+ if (!loc && !imp) {
// Interface libraries are always available because their
- // library name is optional so it is okay to leave *loc empty.
+ // library name is optional so it is okay to leave loc empty.
return this->GetType() == cmStateEnums::INTERFACE_LIBRARY;
}
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 65a1ce3..8fecd41 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -28,6 +28,8 @@ class cmPropertyMap;
class cmSourceFile;
class cmTargetInternals;
+using cmProp = const std::string*;
+
/** \class cmTarget
* \brief Represent a library or executable target loaded from a makefile.
*
@@ -44,7 +46,7 @@ public:
};
cmTarget(std::string const& name, cmStateEnums::TargetType type,
- Visibility vis, cmMakefile* mf);
+ Visibility vis, cmMakefile* mf, bool perConfig);
cmTarget(cmTarget const&) = delete;
cmTarget(cmTarget&&) noexcept;
@@ -110,10 +112,8 @@ public:
//! Clear the dependency information recorded for this target, if any.
void ClearDependencyInformation(cmMakefile& mf);
- void AddLinkLibrary(cmMakefile& mf, const std::string& lib,
- cmTargetLinkLibraryType llt);
void AddLinkLibrary(cmMakefile& mf, std::string const& lib,
- std::string const& libRef, cmTargetLinkLibraryType llt);
+ cmTargetLinkLibraryType llt);
enum TLLSignature
{
@@ -158,23 +158,27 @@ public:
* name as would be specified to the ADD_EXECUTABLE or UTILITY_SOURCE
* commands. It is not a full path nor does it have an extension.
*/
- void AddUtility(std::string const& name, cmMakefile* mf = nullptr);
+ void AddUtility(std::string const& name, bool cross,
+ cmMakefile* mf = nullptr);
//! Get the utilities used by this target
- std::set<BT<std::string>> const& GetUtilities() const;
+ std::set<BT<std::pair<std::string, bool>>> const& GetUtilities() const;
//! Set/Get a property of this target file
void SetProperty(const std::string& prop, const char* value);
- void AppendProperty(const std::string& prop, const char* value,
+ void SetProperty(const std::string& prop, const std::string& value)
+ {
+ SetProperty(prop, value.c_str());
+ }
+ void AppendProperty(const std::string& prop, const std::string& value,
bool asString = false);
//! Might return a nullptr if the property is not set or invalid
- const char* GetProperty(const std::string& prop) const;
+ cmProp GetProperty(const std::string& prop) const;
//! Always returns a valid pointer
- const char* GetSafeProperty(const std::string& prop) const;
+ std::string const& GetSafeProperty(std::string const& prop) const;
bool GetPropertyAsBool(const std::string& prop) const;
void CheckProperty(const std::string& prop, cmMakefile* context) const;
- const char* GetComputedProperty(const std::string& prop,
- cmMessenger* messenger,
- cmListFileBacktrace const& context) const;
+ cmProp GetComputedProperty(const std::string& prop, cmMessenger* messenger,
+ cmListFileBacktrace const& context) const;
//! Get all properties
cmPropertyMap const& GetProperties() const;
@@ -186,9 +190,10 @@ public:
bool IsImported() const;
bool IsImportedGloballyVisible() const;
+ bool IsPerConfig() const;
- bool GetMappedConfig(std::string const& desired_config, const char** loc,
- const char** imp, std::string& suffix) const;
+ bool GetMappedConfig(std::string const& desired_config, cmProp& loc,
+ cmProp& imp, std::string& suffix) const;
//! Return whether this target is an executable with symbol exports enabled.
bool IsExecutableWithExports() const;
diff --git a/Source/cmTargetCompileDefinitionsCommand.cxx b/Source/cmTargetCompileDefinitionsCommand.cxx
index edee167..b56b245 100644
--- a/Source/cmTargetCompileDefinitionsCommand.cxx
+++ b/Source/cmTargetCompileDefinitionsCommand.cxx
@@ -28,7 +28,7 @@ private:
const std::vector<std::string>& content,
bool /*prepend*/, bool /*system*/) override
{
- tgt->AppendProperty("COMPILE_DEFINITIONS", this->Join(content).c_str());
+ tgt->AppendProperty("COMPILE_DEFINITIONS", this->Join(content));
return true; // Successfully handled.
}
diff --git a/Source/cmTargetCompileOptionsCommand.cxx b/Source/cmTargetCompileOptionsCommand.cxx
index e39b726..dee2c10 100644
--- a/Source/cmTargetCompileOptionsCommand.cxx
+++ b/Source/cmTargetCompileOptionsCommand.cxx
@@ -5,6 +5,7 @@
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmPolicies.h"
#include "cmStringAlgorithms.h"
#include "cmTarget.h"
#include "cmTargetPropCommandBase.h"
@@ -27,10 +28,16 @@ private:
bool HandleDirectContent(cmTarget* tgt,
const std::vector<std::string>& content,
- bool /*prepend*/, bool /*system*/) override
+ bool prepend, bool /*system*/) override
{
+ cmPolicies::PolicyStatus policyStatus =
+ this->Makefile->GetPolicyStatus(cmPolicies::CMP0101);
+ if (policyStatus == cmPolicies::OLD || policyStatus == cmPolicies::WARN) {
+ prepend = false;
+ }
+
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
- tgt->InsertCompileOption(this->Join(content), lfbt);
+ tgt->InsertCompileOption(this->Join(content), lfbt, prepend);
return true; // Successfully handled.
}
diff --git a/Source/cmTargetDepend.h b/Source/cmTargetDepend.h
index 4ca78fa..5452cc7 100644
--- a/Source/cmTargetDepend.h
+++ b/Source/cmTargetDepend.h
@@ -19,6 +19,7 @@ class cmTargetDepend
// mutable members to achieve a map with set syntax.
mutable bool Link;
mutable bool Util;
+ mutable bool Cross;
mutable cmListFileBacktrace Backtrace;
public:
@@ -26,6 +27,7 @@ public:
: Target(t)
, Link(false)
, Util(false)
+ , Cross(false)
{
}
operator cmGeneratorTarget const*() const { return this->Target; }
@@ -43,12 +45,14 @@ public:
this->Link = true;
}
}
+ void SetCross(bool cross) const { this->Cross = cross; }
void SetBacktrace(cmListFileBacktrace const& bt) const
{
this->Backtrace = bt;
}
bool IsLink() const { return this->Link; }
bool IsUtil() const { return this->Util; }
+ bool IsCross() const { return this->Cross; }
cmListFileBacktrace const& GetBacktrace() const { return this->Backtrace; }
};
diff --git a/Source/cmTargetIncludeDirectoriesCommand.cxx b/Source/cmTargetIncludeDirectoriesCommand.cxx
index 95b69f3..35635b9 100644
--- a/Source/cmTargetIncludeDirectoriesCommand.cxx
+++ b/Source/cmTargetIncludeDirectoriesCommand.cxx
@@ -88,8 +88,7 @@ void TargetIncludeDirectoriesImpl::HandleInterfaceContent(
system);
if (system) {
std::string joined = this->Join(content);
- tgt->AppendProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES",
- joined.c_str());
+ tgt->AppendProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES", joined);
}
}
diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx
index 0d2383a..df751da 100644
--- a/Source/cmTargetLinkLibrariesCommand.cxx
+++ b/Source/cmTargetLinkLibrariesCommand.cxx
@@ -3,7 +3,10 @@
#include "cmTargetLinkLibrariesCommand.h"
#include <cstring>
+#include <memory>
#include <sstream>
+#include <unordered_set>
+#include <utility>
#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
@@ -34,15 +37,30 @@ enum ProcessingState
const char* LinkLibraryTypeNames[3] = { "general", "debug", "optimized" };
+struct TLL
+{
+ cmMakefile& Makefile;
+ cmTarget* Target;
+ bool WarnRemoteInterface = false;
+ bool RejectRemoteLinking = false;
+ bool EncodeRemoteReference = false;
+ std::string DirectoryId;
+ std::unordered_set<std::string> Props;
+
+ TLL(cmMakefile& mf, cmTarget* target);
+ ~TLL();
+
+ bool HandleLibrary(ProcessingState currentProcessingState,
+ const std::string& lib, cmTargetLinkLibraryType llt);
+ void AppendProperty(std::string const& prop, std::string const& value);
+ void AffectsProperty(std::string const& prop);
+};
+
} // namespace
static void LinkLibraryTypeSpecifierWarning(cmMakefile& mf, int left,
int right);
-static bool HandleLibrary(cmMakefile& mf, cmTarget* target,
- ProcessingState currentProcessingState,
- const std::string& lib, cmTargetLinkLibraryType llt);
-
bool cmTargetLinkLibrariesCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
@@ -64,11 +82,9 @@ bool cmTargetLinkLibrariesCommand(std::vector<std::string> const& args,
cmTarget* target =
mf.GetCMakeInstance()->GetGlobalGenerator()->FindTarget(args[0]);
if (!target) {
- const std::vector<cmTarget*>& importedTargets =
- mf.GetOwnedImportedTargets();
- for (cmTarget* importedTarget : importedTargets) {
+ for (const auto& importedTarget : mf.GetOwnedImportedTargets()) {
if (importedTarget->GetName() == args[0]) {
- target = importedTarget;
+ target = importedTarget.get();
break;
}
}
@@ -149,6 +165,8 @@ bool cmTargetLinkLibrariesCommand(std::vector<std::string> const& args,
return true;
}
+ TLL tll(mf, target);
+
// Keep track of link configuration specifiers.
cmTargetLinkLibraryType llt = GENERAL_LibraryType;
bool haveLLT = false;
@@ -247,7 +265,7 @@ bool cmTargetLinkLibrariesCommand(std::vector<std::string> const& args,
} else if (haveLLT) {
// The link type was specified by the previous argument.
haveLLT = false;
- if (!HandleLibrary(mf, target, currentProcessingState, args[i], llt)) {
+ if (!tll.HandleLibrary(currentProcessingState, args[i], llt)) {
return false;
}
} else {
@@ -268,7 +286,7 @@ bool cmTargetLinkLibrariesCommand(std::vector<std::string> const& args,
llt = OPTIMIZED_LibraryType;
}
}
- if (!HandleLibrary(mf, target, currentProcessingState, args[i], llt)) {
+ if (!tll.HandleLibrary(currentProcessingState, args[i], llt)) {
return false;
}
}
@@ -311,21 +329,48 @@ static void LinkLibraryTypeSpecifierWarning(cmMakefile& mf, int left,
"\" instead of a library name. The first specifier will be ignored."));
}
-static bool HandleLibrary(cmMakefile& mf, cmTarget* target,
- ProcessingState currentProcessingState,
- const std::string& lib, cmTargetLinkLibraryType llt)
+namespace {
+
+TLL::TLL(cmMakefile& mf, cmTarget* target)
+ : Makefile(mf)
+ , Target(target)
+{
+ if (&this->Makefile != this->Target->GetMakefile()) {
+ // The LHS target was created in another directory.
+ switch (this->Makefile.GetPolicyStatus(cmPolicies::CMP0079)) {
+ case cmPolicies::WARN:
+ this->WarnRemoteInterface = true;
+ CM_FALLTHROUGH;
+ case cmPolicies::OLD:
+ this->RejectRemoteLinking = true;
+ break;
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::NEW:
+ this->EncodeRemoteReference = true;
+ break;
+ }
+ }
+ if (this->EncodeRemoteReference) {
+ cmDirectoryId const dirId = this->Makefile.GetDirectoryId();
+ this->DirectoryId = cmStrCat(CMAKE_DIRECTORY_ID_SEP, dirId.String);
+ }
+}
+
+bool TLL::HandleLibrary(ProcessingState currentProcessingState,
+ const std::string& lib, cmTargetLinkLibraryType llt)
{
- if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY &&
+ if (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY &&
currentProcessingState != ProcessingKeywordLinkInterface) {
- mf.IssueMessage(
+ this->Makefile.IssueMessage(
MessageType::FATAL_ERROR,
"INTERFACE library can only be used with the INTERFACE keyword of "
"target_link_libraries");
return false;
}
- if (target->IsImported() &&
+ if (this->Target->IsImported() &&
currentProcessingState != ProcessingKeywordLinkInterface) {
- mf.IssueMessage(
+ this->Makefile.IssueMessage(
MessageType::FATAL_ERROR,
"IMPORTED library can only be used with the INTERFACE keyword of "
"target_link_libraries");
@@ -340,11 +385,12 @@ static bool HandleLibrary(cmMakefile& mf, cmTarget* target,
currentProcessingState == ProcessingKeywordLinkInterface)
? cmTarget::KeywordTLLSignature
: cmTarget::PlainTLLSignature;
- if (!target->PushTLLCommandTrace(sig, mf.GetExecutionContext())) {
+ if (!this->Target->PushTLLCommandTrace(
+ sig, this->Makefile.GetExecutionContext())) {
std::ostringstream e;
const char* modal = nullptr;
MessageType messageType = MessageType::AUTHOR_WARNING;
- switch (mf.GetPolicyStatus(cmPolicies::CMP0023)) {
+ switch (this->Makefile.GetPolicyStatus(cmPolicies::CMP0023)) {
case cmPolicies::WARN:
e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0023) << "\n";
modal = "should";
@@ -365,73 +411,38 @@ static bool HandleLibrary(cmMakefile& mf, cmTarget* target,
e << "The " << existingSig
<< " signature for target_link_libraries has "
"already been used with the target \""
- << target->GetName()
+ << this->Target->GetName()
<< "\". All uses of target_link_libraries with a target " << modal
<< " be either all-keyword or all-plain.\n";
- target->GetTllSignatureTraces(e,
- sig == cmTarget::KeywordTLLSignature
- ? cmTarget::PlainTLLSignature
- : cmTarget::KeywordTLLSignature);
- mf.IssueMessage(messageType, e.str());
+ this->Target->GetTllSignatureTraces(e,
+ sig == cmTarget::KeywordTLLSignature
+ ? cmTarget::PlainTLLSignature
+ : cmTarget::KeywordTLLSignature);
+ this->Makefile.IssueMessage(messageType, e.str());
if (messageType == MessageType::FATAL_ERROR) {
return false;
}
}
}
- bool warnRemoteInterface = false;
- bool rejectRemoteLinking = false;
- bool encodeRemoteReference = false;
- if (&mf != target->GetMakefile()) {
- // The LHS target was created in another directory.
- switch (mf.GetPolicyStatus(cmPolicies::CMP0079)) {
- case cmPolicies::WARN:
- warnRemoteInterface = true;
- CM_FALLTHROUGH;
- case cmPolicies::OLD:
- rejectRemoteLinking = true;
- break;
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::NEW:
- encodeRemoteReference = true;
- break;
- }
- }
-
- std::string libRef;
- if (encodeRemoteReference && !cmSystemTools::FileIsFullPath(lib)) {
- // This is a library name added by a caller that is not in the
- // same directory as the target was created. Add a suffix to
- // the name to tell ResolveLinkItem to look up the name in the
- // caller's directory.
- cmDirectoryId const dirId = mf.GetDirectoryId();
- libRef = lib + CMAKE_DIRECTORY_ID_SEP + dirId.String;
- } else {
- // This is an absolute path or a library name added by a caller
- // in the same directory as the target was created. We can use
- // the original name directly.
- libRef = lib;
- }
-
// Handle normal case where the command was called with another keyword than
// INTERFACE / LINK_INTERFACE_LIBRARIES or none at all. (The "LINK_LIBRARIES"
// property of the target on the LHS shall be populated.)
if (currentProcessingState != ProcessingKeywordLinkInterface &&
currentProcessingState != ProcessingPlainLinkInterface) {
- if (rejectRemoteLinking) {
- mf.IssueMessage(
+ if (this->RejectRemoteLinking) {
+ this->Makefile.IssueMessage(
MessageType::FATAL_ERROR,
cmStrCat("Attempt to add link library \"", lib, "\" to target \"",
- target->GetName(),
+ this->Target->GetName(),
"\" which is not built in this "
"directory.\nThis is allowed only when policy CMP0079 "
"is set to NEW."));
return false;
}
- cmTarget* tgt = mf.GetGlobalGenerator()->FindTarget(lib);
+ cmTarget* tgt = this->Makefile.GetGlobalGenerator()->FindTarget(lib);
if (tgt && (tgt->GetType() != cmStateEnums::STATIC_LIBRARY) &&
(tgt->GetType() != cmStateEnums::SHARED_LIBRARY) &&
@@ -439,7 +450,7 @@ static bool HandleLibrary(cmMakefile& mf, cmTarget* target,
(tgt->GetType() != cmStateEnums::OBJECT_LIBRARY) &&
(tgt->GetType() != cmStateEnums::INTERFACE_LIBRARY) &&
!tgt->IsExecutableWithExports()) {
- mf.IssueMessage(
+ this->Makefile.IssueMessage(
MessageType::FATAL_ERROR,
cmStrCat(
"Target \"", lib, "\" of type ",
@@ -449,15 +460,16 @@ static bool HandleLibrary(cmMakefile& mf, cmTarget* target,
"executables with the ENABLE_EXPORTS property set."));
}
- target->AddLinkLibrary(mf, lib, libRef, llt);
+ this->AffectsProperty("LINK_LIBRARIES");
+ this->Target->AddLinkLibrary(this->Makefile, lib, llt);
}
- if (warnRemoteInterface) {
- mf.IssueMessage(
+ if (this->WarnRemoteInterface) {
+ this->Makefile.IssueMessage(
MessageType::AUTHOR_WARNING,
cmStrCat(
cmPolicies::GetPolicyWarning(cmPolicies::CMP0079), "\nTarget\n ",
- target->GetName(),
+ this->Target->GetName(),
"\nis not created in this "
"directory. For compatibility with older versions of CMake, link "
"library\n ",
@@ -472,15 +484,15 @@ static bool HandleLibrary(cmMakefile& mf, cmTarget* target,
// STATIC library.)
if (currentProcessingState == ProcessingKeywordPrivateInterface ||
currentProcessingState == ProcessingPlainPrivateInterface) {
- if (target->GetType() == cmStateEnums::STATIC_LIBRARY ||
- target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
+ if (this->Target->GetType() == cmStateEnums::STATIC_LIBRARY ||
+ this->Target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
std::string configLib =
- target->GetDebugGeneratorExpressions(libRef, llt);
+ this->Target->GetDebugGeneratorExpressions(lib, llt);
if (cmGeneratorExpression::IsValidTargetName(lib) ||
cmGeneratorExpression::Find(lib) != std::string::npos) {
configLib = "$<LINK_ONLY:" + configLib + ">";
}
- target->AppendProperty("INTERFACE_LINK_LIBRARIES", configLib.c_str());
+ this->AppendProperty("INTERFACE_LINK_LIBRARIES", configLib);
}
return true;
}
@@ -488,9 +500,8 @@ static bool HandleLibrary(cmMakefile& mf, cmTarget* target,
// Handle general case where the command was called with another keyword than
// PRIVATE / LINK_PRIVATE or none at all. (The "INTERFACE_LINK_LIBRARIES"
// property of the target on the LHS shall be populated.)
- target->AppendProperty(
- "INTERFACE_LINK_LIBRARIES",
- target->GetDebugGeneratorExpressions(libRef, llt).c_str());
+ this->AppendProperty("INTERFACE_LINK_LIBRARIES",
+ this->Target->GetDebugGeneratorExpressions(lib, llt));
// Stop processing if called without any keyword.
if (currentProcessingState == ProcessingLinkLibraries) {
@@ -498,13 +509,13 @@ static bool HandleLibrary(cmMakefile& mf, cmTarget* target,
}
// Stop processing if policy CMP0022 is set to NEW.
const cmPolicies::PolicyStatus policy22Status =
- target->GetPolicyStatusCMP0022();
+ this->Target->GetPolicyStatusCMP0022();
if (policy22Status != cmPolicies::OLD &&
policy22Status != cmPolicies::WARN) {
return true;
}
// Stop processing if called with an INTERFACE library on the LHS.
- if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+ if (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
return true;
}
@@ -514,7 +525,7 @@ static bool HandleLibrary(cmMakefile& mf, cmTarget* target,
{
// Get the list of configurations considered to be DEBUG.
std::vector<std::string> debugConfigs =
- mf.GetCMakeInstance()->GetDebugConfigs();
+ this->Makefile.GetCMakeInstance()->GetDebugConfigs();
std::string prop;
// Include this library in the link interface for the target.
@@ -522,22 +533,49 @@ static bool HandleLibrary(cmMakefile& mf, cmTarget* target,
// Put in the DEBUG configuration interfaces.
for (std::string const& dc : debugConfigs) {
prop = cmStrCat("LINK_INTERFACE_LIBRARIES_", dc);
- target->AppendProperty(prop, libRef.c_str());
+ this->AppendProperty(prop, lib);
}
}
if (llt == OPTIMIZED_LibraryType || llt == GENERAL_LibraryType) {
// Put in the non-DEBUG configuration interfaces.
- target->AppendProperty("LINK_INTERFACE_LIBRARIES", libRef.c_str());
+ this->AppendProperty("LINK_INTERFACE_LIBRARIES", lib);
// Make sure the DEBUG configuration interfaces exist so that the
// general one will not be used as a fall-back.
for (std::string const& dc : debugConfigs) {
prop = cmStrCat("LINK_INTERFACE_LIBRARIES_", dc);
- if (!target->GetProperty(prop)) {
- target->SetProperty(prop, "");
+ if (!this->Target->GetProperty(prop)) {
+ this->Target->SetProperty(prop, "");
}
}
}
}
return true;
}
+
+void TLL::AppendProperty(std::string const& prop, std::string const& value)
+{
+ this->AffectsProperty(prop);
+ this->Target->AppendProperty(prop, value);
+}
+
+void TLL::AffectsProperty(std::string const& prop)
+{
+ if (!this->EncodeRemoteReference) {
+ return;
+ }
+ // Add a wrapper to the expression to tell LookupLinkItems to look up
+ // names in the caller's directory.
+ if (this->Props.insert(prop).second) {
+ this->Target->AppendProperty(prop, this->DirectoryId);
+ }
+}
+
+TLL::~TLL()
+{
+ for (std::string const& prop : this->Props) {
+ this->Target->AppendProperty(prop, CMAKE_DIRECTORY_ID_SEP);
+ }
+}
+
+} // namespace
diff --git a/Source/cmTargetPrecompileHeadersCommand.cxx b/Source/cmTargetPrecompileHeadersCommand.cxx
index c6e2e5c..0670bd9 100644
--- a/Source/cmTargetPrecompileHeadersCommand.cxx
+++ b/Source/cmTargetPrecompileHeadersCommand.cxx
@@ -47,9 +47,8 @@ private:
bool /*prepend*/, bool /*system*/) override
{
std::string const& base = this->Makefile->GetCurrentSourceDirectory();
- tgt->AppendProperty(
- "PRECOMPILE_HEADERS",
- this->Join(ConvertToAbsoluteContent(content, base)).c_str());
+ tgt->AppendProperty("PRECOMPILE_HEADERS",
+ this->Join(ConvertToAbsoluteContent(content, base)));
return true;
}
diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx
index bbc1e16..6325837 100644
--- a/Source/cmTargetPropCommandBase.cxx
+++ b/Source/cmTargetPropCommandBase.cxx
@@ -9,6 +9,8 @@
#include "cmTarget.h"
#include "cmake.h"
+using cmProp = const std::string*;
+
cmTargetPropCommandBase::cmTargetPropCommandBase(cmExecutionStatus& status)
: Makefile(&status.GetMakefile())
, Status(status)
@@ -84,9 +86,7 @@ bool cmTargetPropCommandBase::HandleArguments(
}
++argIndex;
- this->Target->SetProperty("PRECOMPILE_HEADERS_REUSE_FROM",
- args[argIndex].c_str());
-
+ this->Target->SetProperty("PRECOMPILE_HEADERS_REUSE_FROM", args[argIndex]);
++argIndex;
}
@@ -159,12 +159,11 @@ void cmTargetPropCommandBase::HandleInterfaceContent(
{
if (prepend) {
const std::string propName = std::string("INTERFACE_") + this->Property;
- const char* propValue = tgt->GetProperty(propName);
- const std::string totalContent = this->Join(content) +
- (propValue ? std::string(";") + propValue : std::string());
- tgt->SetProperty(propName, totalContent.c_str());
+ cmProp propValue = tgt->GetProperty(propName);
+ const std::string totalContent =
+ this->Join(content) + (propValue ? (";" + *propValue) : std::string());
+ tgt->SetProperty(propName, totalContent);
} else {
- tgt->AppendProperty("INTERFACE_" + this->Property,
- this->Join(content).c_str());
+ tgt->AppendProperty("INTERFACE_" + this->Property, this->Join(content));
}
}
diff --git a/Source/cmTargetPropertyComputer.cxx b/Source/cmTargetPropertyComputer.cxx
index baab8da..f37995c 100644
--- a/Source/cmTargetPropertyComputer.cxx
+++ b/Source/cmTargetPropertyComputer.cxx
@@ -62,6 +62,7 @@ bool cmTargetPropertyComputer::WhiteListedInterfaceProperty(
"COMPATIBLE_INTERFACE_NUMBER_MAX",
"COMPATIBLE_INTERFACE_NUMBER_MIN",
"COMPATIBLE_INTERFACE_STRING",
+ "DEPRECATION",
"EXPORT_NAME",
"EXPORT_PROPERTIES",
"IMPORTED",
diff --git a/Source/cmTargetPropertyComputer.h b/Source/cmTargetPropertyComputer.h
index 3b11acd..5387e00 100644
--- a/Source/cmTargetPropertyComputer.h
+++ b/Source/cmTargetPropertyComputer.h
@@ -14,15 +14,17 @@
class cmMessenger;
+using cmProp = const std::string*;
+
class cmTargetPropertyComputer
{
public:
template <typename Target>
- static const char* GetProperty(Target const* tgt, const std::string& prop,
- cmMessenger* messenger,
- cmListFileBacktrace const& context)
+ static cmProp GetProperty(Target const* tgt, const std::string& prop,
+ cmMessenger* messenger,
+ cmListFileBacktrace const& context)
{
- if (const char* loc = GetLocation(tgt, prop, messenger, context)) {
+ if (cmProp loc = GetLocation(tgt, prop, messenger, context)) {
return loc;
}
if (cmSystemTools::GetFatalErrorOccured()) {
@@ -46,15 +48,15 @@ private:
cmListFileBacktrace const& context);
template <typename Target>
- static const char* ComputeLocationForBuild(Target const* tgt);
+ static const std::string& ComputeLocationForBuild(Target const* tgt);
template <typename Target>
- static const char* ComputeLocation(Target const* tgt,
- std::string const& config);
+ static const std::string& ComputeLocation(Target const* tgt,
+ std::string const& config);
template <typename Target>
- static const char* GetLocation(Target const* tgt, std::string const& prop,
- cmMessenger* messenger,
- cmListFileBacktrace const& context)
+ static cmProp GetLocation(Target const* tgt, std::string const& prop,
+ cmMessenger* messenger,
+ cmListFileBacktrace const& context)
{
// Watch for special "computed" properties that are dependent on
@@ -71,7 +73,7 @@ private:
context)) {
return nullptr;
}
- return ComputeLocationForBuild(tgt);
+ return &ComputeLocationForBuild(tgt);
}
// Support "LOCATION_<CONFIG>".
@@ -82,7 +84,7 @@ private:
return nullptr;
}
std::string configName = prop.substr(9);
- return ComputeLocation(tgt, configName);
+ return &ComputeLocation(tgt, configName);
}
// Support "<CONFIG>_LOCATION".
@@ -95,7 +97,7 @@ private:
context)) {
return nullptr;
}
- return ComputeLocation(tgt, configName);
+ return &ComputeLocation(tgt, configName);
}
}
}
@@ -103,8 +105,8 @@ private:
}
template <typename Target>
- static const char* GetSources(Target const* tgt, cmMessenger* messenger,
- cmListFileBacktrace const& context);
+ static cmProp GetSources(Target const* tgt, cmMessenger* messenger,
+ cmListFileBacktrace const& context);
};
#endif
diff --git a/Source/cmTargetSourcesCommand.cxx b/Source/cmTargetSourcesCommand.cxx
index c2e0b28..a1fbc9b 100644
--- a/Source/cmTargetSourcesCommand.cxx
+++ b/Source/cmTargetSourcesCommand.cxx
@@ -43,8 +43,7 @@ private:
bool /*prepend*/, bool /*system*/) override
{
tgt->AppendProperty(
- "SOURCES",
- this->Join(ConvertToAbsoluteContent(tgt, content, false)).c_str());
+ "SOURCES", this->Join(ConvertToAbsoluteContent(tgt, content, false)));
return true; // Successfully handled.
}
diff --git a/Source/cmTest.cxx b/Source/cmTest.cxx
index d5c61c1..a26bef3 100644
--- a/Source/cmTest.cxx
+++ b/Source/cmTest.cxx
@@ -34,15 +34,18 @@ void cmTest::SetCommand(std::vector<std::string> const& command)
const char* cmTest::GetProperty(const std::string& prop) const
{
- const char* retVal = this->Properties.GetPropertyValue(prop);
+ cmProp retVal = this->Properties.GetPropertyValue(prop);
if (!retVal) {
const bool chain =
this->Makefile->GetState()->IsPropertyChained(prop, cmProperty::TEST);
if (chain) {
- return this->Makefile->GetProperty(prop, chain);
+ if (cmProp p = this->Makefile->GetProperty(prop, chain)) {
+ return p->c_str();
+ }
}
+ return nullptr;
}
- return retVal;
+ return retVal->c_str();
}
bool cmTest::GetPropertyAsBool(const std::string& prop) const
@@ -55,7 +58,7 @@ void cmTest::SetProperty(const std::string& prop, const char* value)
this->Properties.SetProperty(prop, value);
}
-void cmTest::AppendProperty(const std::string& prop, const char* value,
+void cmTest::AppendProperty(const std::string& prop, const std::string& value,
bool asString)
{
this->Properties.AppendProperty(prop, value, asString);
diff --git a/Source/cmTest.h b/Source/cmTest.h
index dd246c4..72d4ed9 100644
--- a/Source/cmTest.h
+++ b/Source/cmTest.h
@@ -35,7 +35,7 @@ public:
//! Set/Get a property of this source file
void SetProperty(const std::string& prop, const char* value);
- void AppendProperty(const std::string& prop, const char* value,
+ void AppendProperty(const std::string& prop, const std::string& value,
bool asString = false);
const char* GetProperty(const std::string& prop) const;
bool GetPropertyAsBool(const std::string& prop) const;
diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx
index 333d4d5..025a7b3 100644
--- a/Source/cmTestGenerator.cxx
+++ b/Source/cmTestGenerator.cxx
@@ -100,9 +100,9 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
exe = target->GetFullPath(config);
// Prepend with the emulator when cross compiling if required.
- const char* emulator = target->GetProperty("CROSSCOMPILING_EMULATOR");
- if (emulator != nullptr && *emulator) {
- std::vector<std::string> emulatorWithArgs = cmExpandedList(emulator);
+ cmProp emulator = target->GetProperty("CROSSCOMPILING_EMULATOR");
+ if (emulator != nullptr && !emulator->empty()) {
+ std::vector<std::string> emulatorWithArgs = cmExpandedList(*emulator);
std::string emulatorExe(emulatorWithArgs[0]);
cmSystemTools::ConvertToUnixSlashes(emulatorExe);
os << cmOutputConverter::EscapeForCMake(emulatorExe) << " ";
@@ -134,7 +134,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
ge.Parse(i.second)->Evaluate(this->LG, config));
}
this->GenerateInternalProperties(os);
- os << ")" << std::endl;
+ os << ")\n";
}
void cmTestGenerator::GenerateScriptNoConfig(std::ostream& os, Indent indent)
@@ -176,9 +176,9 @@ void cmTestGenerator::GenerateOldStyle(std::ostream& fout, Indent indent)
}
fout << c;
}
- fout << "\"";
+ fout << '"';
}
- fout << ")" << std::endl;
+ fout << ")\n";
// Output properties for the test.
fout << indent << "set_tests_properties(" << this->Test->GetName()
@@ -188,7 +188,7 @@ void cmTestGenerator::GenerateOldStyle(std::ostream& fout, Indent indent)
<< cmOutputConverter::EscapeForCMake(i.second);
}
this->GenerateInternalProperties(fout);
- fout << ")" << std::endl;
+ fout << ")\n";
}
void cmTestGenerator::GenerateInternalProperties(std::ostream& os)
@@ -213,7 +213,7 @@ void cmTestGenerator::GenerateInternalProperties(std::ostream& os)
prependTripleSeparator = true;
}
- os << "\"";
+ os << '"';
}
std::vector<std::string> cmTestGenerator::EvaluateCommandLineArguments(
diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx
index 390fd16..13f73dc 100644
--- a/Source/cmTimestamp.cxx
+++ b/Source/cmTimestamp.cxx
@@ -1,5 +1,15 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
+
+#if !defined(_WIN32) && !defined(__sun)
+// POSIX APIs are needed
+# define _POSIX_C_SOURCE 200809L
+#endif
+#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__)
+// For isascii
+# define _XOPEN_SOURCE 700
+#endif
+
#include "cmTimestamp.h"
#include <cstdlib>
diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx
index 0e8e986..329b3b9 100644
--- a/Source/cmTryRunCommand.cxx
+++ b/Source/cmTryRunCommand.cxx
@@ -242,8 +242,7 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
comment.c_str(), cmStateEnums::STRING);
cmState* state = this->Makefile->GetState();
- const char* existingValue =
- state->GetCacheEntryValue(this->RunResultVariable);
+ cmProp existingValue = state->GetCacheEntryValue(this->RunResultVariable);
if (existingValue) {
state->SetCacheEntryProperty(this->RunResultVariable, "ADVANCED", "1");
}
@@ -265,7 +264,7 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
internalRunOutputName, "PLEASE_FILL_OUT-NOTFOUND", comment.c_str(),
cmStateEnums::STRING);
cmState* state = this->Makefile->GetState();
- const char* existing = state->GetCacheEntryValue(internalRunOutputName);
+ cmProp existing = state->GetCacheEntryValue(internalRunOutputName);
if (existing) {
state->SetCacheEntryProperty(internalRunOutputName, "ADVANCED", "1");
}
diff --git a/Source/cmUVHandlePtr.cxx b/Source/cmUVHandlePtr.cxx
index 23dabb7..df2f64e 100644
--- a/Source/cmUVHandlePtr.cxx
+++ b/Source/cmUVHandlePtr.cxx
@@ -7,7 +7,7 @@
#include <cstdlib>
#include <mutex>
-#include "cm_uv.h"
+#include <cm3p/uv.h>
namespace cm {
diff --git a/Source/cmUVHandlePtr.h b/Source/cmUVHandlePtr.h
index 3083b60..d9de7f3 100644
--- a/Source/cmUVHandlePtr.h
+++ b/Source/cmUVHandlePtr.h
@@ -8,7 +8,7 @@
#include <memory>
#include <type_traits>
-#include "cm_uv.h"
+#include <cm3p/uv.h>
#if defined(__SUNPRO_CC)
diff --git a/Source/cmUVProcessChain.cxx b/Source/cmUVProcessChain.cxx
index 543c330..6040fd8 100644
--- a/Source/cmUVProcessChain.cxx
+++ b/Source/cmUVProcessChain.cxx
@@ -9,7 +9,7 @@
#include <cm/memory>
-#include "cm_uv.h"
+#include <cm3p/uv.h>
#include "cmGetPipes.h"
#include "cmUVHandlePtr.h"
diff --git a/Source/cmUVProcessChain.h b/Source/cmUVProcessChain.h
index 05a7cc8..b5ccb19 100644
--- a/Source/cmUVProcessChain.h
+++ b/Source/cmUVProcessChain.h
@@ -4,14 +4,14 @@
#define cmUVProcessChain_h
#include <array>
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
#include <cstdint>
#include <iosfwd>
#include <memory>
#include <string>
#include <vector>
-#include "cm_uv.h"
+#include <cm3p/uv.h>
class cmUVProcessChain;
diff --git a/Source/cmUVSignalHackRAII.h b/Source/cmUVSignalHackRAII.h
index 63599db..60e4ca8 100644
--- a/Source/cmUVSignalHackRAII.h
+++ b/Source/cmUVSignalHackRAII.h
@@ -3,7 +3,7 @@
#pragma once
#include "cmConfigure.h" // IWYU pragma: keep
-#include "cm_uv.h"
+#include <cm3p/uv.h>
#if defined(CMAKE_USE_SYSTEM_LIBUV) && !defined(_WIN32) && \
UV_VERSION_MAJOR == 1 && UV_VERSION_MINOR < 19
diff --git a/Source/cmUVStreambuf.h b/Source/cmUVStreambuf.h
index 1c8a771..50faede 100644
--- a/Source/cmUVStreambuf.h
+++ b/Source/cmUVStreambuf.h
@@ -8,7 +8,7 @@
#include <streambuf>
#include <vector>
-#include "cm_uv.h"
+#include <cm3p/uv.h>
#include "cmUVHandlePtr.h"
diff --git a/Source/cmUtilitySourceCommand.cxx b/Source/cmUtilitySourceCommand.cxx
index a43165c..5865a19 100644
--- a/Source/cmUtilitySourceCommand.cxx
+++ b/Source/cmUtilitySourceCommand.cxx
@@ -102,15 +102,15 @@ bool cmUtilitySourceCommand(std::vector<std::string> const& args,
cmSystemTools::ReplaceString(utilityExecutable, "/./", "/");
// Enter the value into the cache.
- status.GetMakefile().AddCacheDefinition(
- cacheEntry, utilityExecutable.c_str(), "Path to an internal program.",
- cmStateEnums::FILEPATH);
+ status.GetMakefile().AddCacheDefinition(cacheEntry, utilityExecutable,
+ "Path to an internal program.",
+ cmStateEnums::FILEPATH);
// add a value into the cache that maps from the
// full path to the name of the project
cmSystemTools::ConvertToUnixSlashes(utilityExecutable);
- status.GetMakefile().AddCacheDefinition(
- utilityExecutable, utilityName.c_str(), "Executable to project name.",
- cmStateEnums::INTERNAL);
+ status.GetMakefile().AddCacheDefinition(utilityExecutable, utilityName,
+ "Executable to project name.",
+ cmStateEnums::INTERNAL);
return true;
}
diff --git a/Source/cmVSSetupHelper.h b/Source/cmVSSetupHelper.h
index 0980cef..a2fd3d5 100644
--- a/Source/cmVSSetupHelper.h
+++ b/Source/cmVSSetupHelper.h
@@ -8,13 +8,12 @@
#endif
// Published by Visual Studio Setup team
+#include <cm3p/Setup.Configuration.h>
#include <string>
#include <vector>
#include <windows.h>
-#include "cmvssetup/Setup.Configuration.h"
-
template <class T>
class SmartCOMPtr
{
diff --git a/Source/cmVariableWatch.cxx b/Source/cmVariableWatch.cxx
index 4995da9..35e1c8c 100644
--- a/Source/cmVariableWatch.cxx
+++ b/Source/cmVariableWatch.cxx
@@ -2,19 +2,19 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmVariableWatch.h"
+#include <array>
#include <memory>
#include <utility>
#include <vector>
-static const char* const cmVariableWatchAccessStrings[] = {
- "READ_ACCESS", "UNKNOWN_READ_ACCESS", "UNKNOWN_DEFINED_ACCESS",
- "MODIFIED_ACCESS", "REMOVED_ACCESS", "NO_ACCESS"
-};
-
-const char* cmVariableWatch::GetAccessAsString(int access_type)
+const std::string& cmVariableWatch::GetAccessAsString(int access_type)
{
+ static const std::array<std::string, 6> cmVariableWatchAccessStrings = {
+ { "READ_ACCESS", "UNKNOWN_READ_ACCESS", "UNKNOWN_DEFINED_ACCESS",
+ "MODIFIED_ACCESS", "REMOVED_ACCESS", "NO_ACCESS" }
+ };
if (access_type < 0 || access_type >= cmVariableWatch::NO_ACCESS) {
- return "NO_ACCESS";
+ access_type = cmVariableWatch::NO_ACCESS;
}
return cmVariableWatchAccessStrings[access_type];
}
diff --git a/Source/cmVariableWatch.h b/Source/cmVariableWatch.h
index e4b3b7c..6c418ed 100644
--- a/Source/cmVariableWatch.h
+++ b/Source/cmVariableWatch.h
@@ -46,7 +46,7 @@ public:
*/
enum
{
- VARIABLE_READ_ACCESS = 0,
+ VARIABLE_READ_ACCESS,
UNKNOWN_VARIABLE_READ_ACCESS,
UNKNOWN_VARIABLE_DEFINED_ACCESS,
VARIABLE_MODIFIED_ACCESS,
@@ -57,7 +57,7 @@ public:
/**
* Return the access as string
*/
- static const char* GetAccessAsString(int access_type);
+ static const std::string& GetAccessAsString(int access_type);
protected:
struct Pair
diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx
index f2c8f3c..ecae16d 100644
--- a/Source/cmVariableWatchCommand.cxx
+++ b/Source/cmVariableWatchCommand.cxx
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmVariableWatchCommand.h"
+#include <limits>
#include <memory>
#include <utility>
@@ -14,17 +15,19 @@
#include "cmVariableWatch.h"
#include "cmake.h"
+class cmLocalGenerator;
+
+namespace {
struct cmVariableWatchCallbackData
{
bool InCallback;
std::string Command;
};
-static void cmVariableWatchCommandVariableAccessed(const std::string& variable,
- int access_type,
- void* client_data,
- const char* newValue,
- const cmMakefile* mf)
+void cmVariableWatchCommandVariableAccessed(const std::string& variable,
+ int access_type, void* client_data,
+ const char* newValue,
+ const cmMakefile* mf)
{
cmVariableWatchCallbackData* data =
static_cast<cmVariableWatchCallbackData*>(client_data);
@@ -34,40 +37,35 @@ static void cmVariableWatchCommandVariableAccessed(const std::string& variable,
}
data->InCallback = true;
- cmListFileFunction newLFF;
- cmListFileArgument arg;
- bool processed = false;
- const char* accessString = cmVariableWatch::GetAccessAsString(access_type);
- const char* currentListFile = mf->GetDefinition("CMAKE_CURRENT_LIST_FILE");
+ auto accessString = cmVariableWatch::GetAccessAsString(access_type);
/// Ultra bad!!
cmMakefile* makefile = const_cast<cmMakefile*>(mf);
- std::string stack = makefile->GetProperty("LISTFILE_STACK");
+ std::string stack = *mf->GetProperty("LISTFILE_STACK");
if (!data->Command.empty()) {
- newLFF.Arguments.clear();
- newLFF.Arguments.emplace_back(variable, cmListFileArgument::Quoted, 9999);
- newLFF.Arguments.emplace_back(accessString, cmListFileArgument::Quoted,
- 9999);
- newLFF.Arguments.emplace_back(newValue ? newValue : "",
- cmListFileArgument::Quoted, 9999);
- newLFF.Arguments.emplace_back(currentListFile, cmListFileArgument::Quoted,
- 9999);
- newLFF.Arguments.emplace_back(stack, cmListFileArgument::Quoted, 9999);
+ cmListFileFunction newLFF;
+ const char* const currentListFile =
+ mf->GetDefinition("CMAKE_CURRENT_LIST_FILE");
+ const auto fakeLineNo =
+ std::numeric_limits<decltype(cmListFileArgument::Line)>::max();
+ newLFF.Arguments = {
+ { variable, cmListFileArgument::Quoted, fakeLineNo },
+ { accessString, cmListFileArgument::Quoted, fakeLineNo },
+ { newValue ? newValue : "", cmListFileArgument::Quoted, fakeLineNo },
+ { currentListFile, cmListFileArgument::Quoted, fakeLineNo },
+ { stack, cmListFileArgument::Quoted, fakeLineNo }
+ };
newLFF.Name = data->Command;
- newLFF.Line = 9999;
+ newLFF.Line = fakeLineNo;
cmExecutionStatus status(*makefile);
if (!makefile->ExecuteCommand(newLFF, status)) {
cmSystemTools::Error(
cmStrCat("Error in cmake code at\nUnknown:0:\nA command failed "
"during the invocation of callback \"",
data->Command, "\"."));
- data->InCallback = false;
- return;
}
- processed = true;
- }
- if (!processed) {
+ } else {
makefile->IssueMessage(
MessageType::LOG,
cmStrCat("Variable \"", variable, "\" was accessed using ", accessString,
@@ -77,7 +75,7 @@ static void cmVariableWatchCommandVariableAccessed(const std::string& variable,
data->InCallback = false;
}
-static void deleteVariableWatchCallbackData(void* client_data)
+void deleteVariableWatchCallbackData(void* client_data)
{
cmVariableWatchCallbackData* data =
static_cast<cmVariableWatchCallbackData*>(client_data);
@@ -91,18 +89,18 @@ class FinalAction
public:
/* NOLINTNEXTLINE(performance-unnecessary-value-param) */
FinalAction(cmMakefile* makefile, std::string variable)
- : Action(std::make_shared<Impl>(makefile, std::move(variable)))
+ : Action{ std::make_shared<Impl>(makefile, std::move(variable)) }
{
}
- void operator()(cmMakefile&) const {}
+ void operator()(cmLocalGenerator&, const cmListFileBacktrace&) const {}
private:
struct Impl
{
Impl(cmMakefile* makefile, std::string variable)
- : Makefile(makefile)
- , Variable(std::move(variable))
+ : Makefile{ makefile }
+ , Variable{ std::move(variable) }
{
}
@@ -112,12 +110,13 @@ private:
this->Variable, cmVariableWatchCommandVariableAccessed);
}
- cmMakefile* Makefile;
- std::string Variable;
+ cmMakefile* const Makefile;
+ std::string const Variable;
};
std::shared_ptr<Impl const> Action;
};
+} // anonymous namespace
bool cmVariableWatchCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
@@ -136,10 +135,10 @@ bool cmVariableWatchCommand(std::vector<std::string> const& args,
return false;
}
- cmVariableWatchCallbackData* data = new cmVariableWatchCallbackData;
+ auto* const data = new cmVariableWatchCallbackData;
data->InCallback = false;
- data->Command = command;
+ data->Command = std::move(command);
if (!status.GetMakefile().GetCMakeInstance()->GetVariableWatch()->AddWatch(
variable, cmVariableWatchCommandVariableAccessed, data,
@@ -148,7 +147,7 @@ bool cmVariableWatchCommand(std::vector<std::string> const& args,
return false;
}
- status.GetMakefile().AddFinalAction(
- FinalAction(&status.GetMakefile(), variable));
+ status.GetMakefile().AddGeneratorAction(
+ FinalAction{ &status.GetMakefile(), variable });
return true;
}
diff --git a/Source/cmVersion.h b/Source/cmVersion.h
index bfd994d..932ef04 100644
--- a/Source/cmVersion.h
+++ b/Source/cmVersion.h
@@ -3,7 +3,7 @@
#ifndef cmVersion_h
#define cmVersion_h
-#include "cm_kwiml.h"
+#include <cm3p/kwiml/int.h>
/** \class cmVersion
* \brief Helper class for providing CMake and CTest version information.
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index b33cb50..93c09fe 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -6,10 +6,12 @@
#include <set>
#include <cm/memory>
+#include <cm/string_view>
+#include <cm/vector>
+#include <cmext/algorithm>
#include "windows.h"
-#include "cmAlgorithms.h"
#include "cmComputeLinkInformation.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
@@ -21,6 +23,7 @@
#include "cmLocalVisualStudio10Generator.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmVisualStudioGeneratorOptions.h"
@@ -52,7 +55,7 @@ struct cmVisualStudio10TargetGenerator::Elem
bool HasContent = false;
std::string Tag;
- Elem(std::ostream& s, const char* tag)
+ Elem(std::ostream& s, const std::string& tag)
: S(s)
, Indent(0)
, Tag(tag)
@@ -60,10 +63,10 @@ struct cmVisualStudio10TargetGenerator::Elem
this->StartElement();
}
Elem(const Elem&) = delete;
- Elem(Elem& par, const char* tag)
+ Elem(Elem& par, cm::string_view tag)
: S(par.S)
, Indent(par.Indent + 1)
- , Tag(tag)
+ , Tag(std::string(tag))
{
par.SetHasElements();
this->StartElement();
@@ -71,28 +74,28 @@ struct cmVisualStudio10TargetGenerator::Elem
void SetHasElements()
{
if (!HasElements) {
- this->S << ">\n";
+ this->S << ">";
HasElements = true;
}
}
std::ostream& WriteString(const char* line);
void StartElement() { this->WriteString("<") << this->Tag; }
- void Element(const char* tag, const std::string& val)
+ void Element(cm::string_view tag, std::string val)
{
- Elem(*this, tag).Content(val);
+ Elem(*this, tag).Content(std::move(val));
}
- Elem& Attribute(const char* an, const std::string& av)
+ Elem& Attribute(const char* an, std::string av)
{
- this->S << " " << an << "=\"" << cmVS10EscapeAttr(av) << "\"";
+ this->S << " " << an << "=\"" << cmVS10EscapeAttr(std::move(av)) << "\"";
return *this;
}
- void Content(const std::string& val)
+ void Content(std::string val)
{
if (!this->HasContent) {
this->S << ">";
this->HasContent = true;
}
- this->S << cmVS10EscapeXML(val);
+ this->S << cmVS10EscapeXML(std::move(val));
}
~Elem()
{
@@ -103,19 +106,14 @@ struct cmVisualStudio10TargetGenerator::Elem
if (HasElements) {
this->WriteString("</") << this->Tag << ">";
- if (this->Indent > 0) {
- this->S << '\n';
- } else {
- // special case: don't print EOL at EOF
- }
} else if (HasContent) {
- this->S << "</" << this->Tag << ">\n";
+ this->S << "</" << this->Tag << ">";
} else {
- this->S << " />\n";
+ this->S << " />";
}
}
- void WritePlatformConfigTag(const char* tag, const std::string& cond,
+ void WritePlatformConfigTag(const std::string& tag, const std::string& cond,
const std::string& content);
};
@@ -131,8 +129,8 @@ public:
{
}
- void OutputFlag(std::ostream& /*fout*/, int /*indent*/, const char* tag,
- const std::string& content) override
+ void OutputFlag(std::ostream& /*fout*/, int /*indent*/,
+ const std::string& tag, const std::string& content) override
{
if (!this->GetConfiguration().empty()) {
// if there are configuration specific flags, then
@@ -274,7 +272,7 @@ std::string cmVisualStudio10TargetGenerator::CalcCondition(
}
void cmVisualStudio10TargetGenerator::Elem::WritePlatformConfigTag(
- const char* tag, const std::string& cond, const std::string& content)
+ const std::string& tag, const std::string& cond, const std::string& content)
{
Elem(*this, tag).Attribute("Condition", cond).Content(content);
}
@@ -282,6 +280,7 @@ void cmVisualStudio10TargetGenerator::Elem::WritePlatformConfigTag(
std::ostream& cmVisualStudio10TargetGenerator::Elem::WriteString(
const char* line)
{
+ this->S << '\n';
this->S.fill(' ');
this->S.width(this->Indent * 2);
// write an empty string to get the fill level indent to print
@@ -334,9 +333,9 @@ void cmVisualStudio10TargetGenerator::Generate()
}
// Tell the global generator the name of the project file
this->GeneratorTarget->Target->SetProperty("GENERATOR_FILE_NAME",
- this->Name.c_str());
+ this->Name);
this->GeneratorTarget->Target->SetProperty("GENERATOR_FILE_NAME_EXT",
- ProjectFileExtension.c_str());
+ ProjectFileExtension);
this->DotNetHintReferences.clear();
this->AdditionalUsingDirectories.clear();
if (this->GeneratorTarget->GetType() <= cmStateEnums::OBJECT_LIBRARY) {
@@ -376,8 +375,7 @@ void cmVisualStudio10TargetGenerator::Generate()
char magic[] = { char(0xEF), char(0xBB), char(0xBF) };
BuildFileStream.write(magic, 3);
BuildFileStream << "<?xml version=\"1.0\" encoding=\""
- << this->GlobalGenerator->Encoding() << "\"?>"
- << "\n";
+ << this->GlobalGenerator->Encoding() << "\"?>";
{
Elem e0(BuildFileStream, "Project");
e0.Attribute("DefaultTargets", "Build");
@@ -433,32 +431,32 @@ void cmVisualStudio10TargetGenerator::Generate()
this->VerifyNecessaryFiles();
}
- const char* vsProjectTypes =
+ cmProp vsProjectTypes =
this->GeneratorTarget->GetProperty("VS_GLOBAL_PROJECT_TYPES");
if (vsProjectTypes) {
const char* tagName = "ProjectTypes";
if (this->ProjectType == csproj) {
tagName = "ProjectTypeGuids";
}
- e1.Element(tagName, vsProjectTypes);
+ e1.Element(tagName, *vsProjectTypes);
}
- const char* vsProjectName =
+ cmProp vsProjectName =
this->GeneratorTarget->GetProperty("VS_SCC_PROJECTNAME");
- const char* vsLocalPath =
+ cmProp vsLocalPath =
this->GeneratorTarget->GetProperty("VS_SCC_LOCALPATH");
- const char* vsProvider =
+ cmProp vsProvider =
this->GeneratorTarget->GetProperty("VS_SCC_PROVIDER");
if (vsProjectName && vsLocalPath && vsProvider) {
- e1.Element("SccProjectName", vsProjectName);
- e1.Element("SccLocalPath", vsLocalPath);
- e1.Element("SccProvider", vsProvider);
+ e1.Element("SccProjectName", *vsProjectName);
+ e1.Element("SccLocalPath", *vsLocalPath);
+ e1.Element("SccProvider", *vsProvider);
- const char* vsAuxPath =
+ cmProp vsAuxPath =
this->GeneratorTarget->GetProperty("VS_SCC_AUXPATH");
if (vsAuxPath) {
- e1.Element("SccAuxPath", vsAuxPath);
+ e1.Element("SccAuxPath", *vsAuxPath);
}
}
@@ -466,45 +464,54 @@ void cmVisualStudio10TargetGenerator::Generate()
e1.Element("WinMDAssembly", "true");
}
- const char* vsGlobalKeyword =
+ cmProp vsGlobalKeyword =
this->GeneratorTarget->GetProperty("VS_GLOBAL_KEYWORD");
if (!vsGlobalKeyword) {
e1.Element("Keyword", "Win32Proj");
} else {
- e1.Element("Keyword", vsGlobalKeyword);
+ e1.Element("Keyword", *vsGlobalKeyword);
}
- const char* vsGlobalRootNamespace =
+ cmProp vsGlobalRootNamespace =
this->GeneratorTarget->GetProperty("VS_GLOBAL_ROOTNAMESPACE");
if (vsGlobalRootNamespace) {
- e1.Element("RootNamespace", vsGlobalRootNamespace);
+ e1.Element("RootNamespace", *vsGlobalRootNamespace);
}
e1.Element("Platform", this->Platform);
- const char* projLabel =
- this->GeneratorTarget->GetProperty("PROJECT_LABEL");
+ cmProp projLabel = this->GeneratorTarget->GetProperty("PROJECT_LABEL");
if (!projLabel) {
- projLabel = this->Name.c_str();
+ projLabel = &this->Name;
}
- e1.Element("ProjectName", projLabel);
+ e1.Element("ProjectName", *projLabel);
{
- // TODO: add deprecation warning for VS_* property?
- const char* targetFrameworkVersion =
- this->GeneratorTarget->GetProperty(
+ cmProp targetFramework =
+ this->GeneratorTarget->GetProperty("DOTNET_TARGET_FRAMEWORK");
+ if (targetFramework) {
+ if (std::strchr(targetFramework->c_str(), ';') != nullptr) {
+ e1.Element("TargetFrameworks", *targetFramework);
+ } else {
+ e1.Element("TargetFramework", *targetFramework);
+ }
+ } else {
+ // TODO: add deprecation warning for VS_* property?
+ cmProp p = this->GeneratorTarget->GetProperty(
"VS_DOTNET_TARGET_FRAMEWORK_VERSION");
- if (!targetFrameworkVersion) {
- targetFrameworkVersion = this->GeneratorTarget->GetProperty(
- "DOTNET_TARGET_FRAMEWORK_VERSION");
- }
- if (!targetFrameworkVersion && this->ProjectType == csproj &&
- this->GlobalGenerator->TargetsWindowsCE() &&
- this->GlobalGenerator->GetVersion() ==
- cmGlobalVisualStudioGenerator::VS12) {
- // VS12 .NETCF default to .NET framework 3.9
- targetFrameworkVersion = "v3.9";
- }
- if (targetFrameworkVersion) {
- e1.Element("TargetFrameworkVersion", targetFrameworkVersion);
+ if (!p) {
+ p = this->GeneratorTarget->GetProperty(
+ "DOTNET_TARGET_FRAMEWORK_VERSION");
+ }
+ const char* targetFrameworkVersion = p ? p->c_str() : nullptr;
+ if (!targetFrameworkVersion && this->ProjectType == csproj &&
+ this->GlobalGenerator->TargetsWindowsCE() &&
+ this->GlobalGenerator->GetVersion() ==
+ cmGlobalVisualStudioGenerator::VS12) {
+ // VS12 .NETCF default to .NET framework 3.9
+ targetFrameworkVersion = "v3.9";
+ }
+ if (targetFrameworkVersion) {
+ e1.Element("TargetFrameworkVersion", targetFrameworkVersion);
+ }
}
if (this->ProjectType == vcxproj &&
this->GlobalGenerator->TargetsWindowsCE()) {
@@ -513,18 +520,15 @@ void cmVisualStudio10TargetGenerator::Generate()
}
if (this->ProjectType == csproj &&
this->GlobalGenerator->TargetsWindowsCE()) {
- const char* targetFrameworkId = this->GeneratorTarget->GetProperty(
+ cmProp targetFrameworkId = this->GeneratorTarget->GetProperty(
"VS_TARGET_FRAMEWORK_IDENTIFIER");
- if (!targetFrameworkId) {
- targetFrameworkId = "WindowsEmbeddedCompact";
- }
- e1.Element("TargetFrameworkIdentifier", targetFrameworkId);
- const char* targetFrameworkVer = this->GeneratorTarget->GetProperty(
+ e1.Element("TargetFrameworkIdentifier",
+ targetFrameworkId ? *targetFrameworkId
+ : "WindowsEmbeddedCompact");
+ cmProp targetFrameworkVer = this->GeneratorTarget->GetProperty(
"VS_TARGET_FRAMEWORKS_TARGET_VERSION");
- if (!targetFrameworkVer) {
- targetFrameworkVer = "v8.0";
- }
- e1.Element("TargetFrameworkTargetsVersion", targetFrameworkVer);
+ e1.Element("TargetFrameworkTargetsVersion",
+ targetFrameworkVer ? *targetFrameworkVer : "v8.0");
}
if (!this->GlobalGenerator->GetPlatformToolsetCudaCustomDirString()
.empty()) {
@@ -543,21 +547,27 @@ void cmVisualStudio10TargetGenerator::Generate()
e1.Element("VCProjectUpgraderObjectName", "NoUpgrade");
}
+ if (const char* vcTargetsPath =
+ this->GlobalGenerator->GetCustomVCTargetsPath()) {
+ e1.Element("VCTargetsPath", vcTargetsPath);
+ }
+
std::vector<std::string> keys = this->GeneratorTarget->GetPropertyKeys();
for (std::string const& keyIt : keys) {
- static const char* prefix = "VS_GLOBAL_";
- if (keyIt.find(prefix) != 0)
+ static const cm::string_view prefix = "VS_GLOBAL_";
+ if (!cmHasPrefix(keyIt, prefix))
continue;
- std::string globalKey = keyIt.substr(strlen(prefix));
+ cm::string_view globalKey =
+ cm::string_view(keyIt).substr(prefix.length());
// Skip invalid or separately-handled properties.
if (globalKey.empty() || globalKey == "PROJECT_TYPES" ||
globalKey == "ROOTNAMESPACE" || globalKey == "KEYWORD") {
continue;
}
- const char* value = this->GeneratorTarget->GetProperty(keyIt);
+ cmProp value = this->GeneratorTarget->GetProperty(keyIt);
if (!value)
continue;
- e1.Element(globalKey.c_str(), value);
+ e1.Element(globalKey, *value);
}
if (this->Managed) {
@@ -662,9 +672,8 @@ void cmVisualStudio10TargetGenerator::Generate()
props = VS10_CSharp_USER_PROPS;
break;
}
- if (const char* p =
- this->GeneratorTarget->GetProperty("VS_USER_PROPS")) {
- props = p;
+ if (cmProp p = this->GeneratorTarget->GetProperty("VS_USER_PROPS")) {
+ props = *p;
}
if (!props.empty()) {
ConvertToWindowsSlash(props);
@@ -676,6 +685,8 @@ void cmVisualStudio10TargetGenerator::Generate()
this->WritePlatformExtensions(e1);
}
+
+ this->WriteDotNetDocumentationFile(e0);
Elem(e0, "PropertyGroup").Attribute("Label", "UserMacros");
this->WriteWinRTPackageCertificateKeyFile(e0);
this->WritePathAndIncrementalLinkOptions(e0);
@@ -768,50 +779,41 @@ void cmVisualStudio10TargetGenerator::Generate()
void cmVisualStudio10TargetGenerator::WritePackageReferences(Elem& e0)
{
std::vector<std::string> packageReferences;
- if (const char* vsPackageReferences =
+ if (cmProp vsPackageReferences =
this->GeneratorTarget->GetProperty("VS_PACKAGE_REFERENCES")) {
- cmExpandList(vsPackageReferences, packageReferences);
+ cmExpandList(*vsPackageReferences, packageReferences);
}
if (!packageReferences.empty()) {
Elem e1(e0, "ItemGroup");
for (std::string const& ri : packageReferences) {
size_t versionIndex = ri.find_last_of('_');
if (versionIndex != std::string::npos) {
- WritePackageReference(e1, ri.substr(0, versionIndex),
- ri.substr(versionIndex + 1));
+ Elem e2(e1, "PackageReference");
+ e2.Attribute("Include", ri.substr(0, versionIndex));
+ e2.Attribute("Version", ri.substr(versionIndex + 1));
}
}
}
}
-void cmVisualStudio10TargetGenerator::WritePackageReference(
- Elem& e1, std::string const& ref, std::string const& version)
-{
- Elem e2(e1, "PackageReference");
- e2.Attribute("Include", ref);
- e2.Attribute("Version", version);
-}
-
void cmVisualStudio10TargetGenerator::WriteDotNetReferences(Elem& e0)
{
std::vector<std::string> references;
- if (const char* vsDotNetReferences =
+ if (cmProp vsDotNetReferences =
this->GeneratorTarget->GetProperty("VS_DOTNET_REFERENCES")) {
- cmExpandList(vsDotNetReferences, references);
+ cmExpandList(*vsDotNetReferences, references);
}
cmPropertyMap const& props = this->GeneratorTarget->Target->GetProperties();
for (auto const& i : props.GetList()) {
- if (i.first.find("VS_DOTNET_REFERENCE_") == 0) {
- std::string name = i.first.substr(20);
- if (!name.empty()) {
- std::string path = i.second;
- if (!cmsys::SystemTools::FileIsFullPath(path)) {
- path = this->Makefile->GetCurrentSourceDirectory() + "/" + path;
- }
- ConvertToWindowsSlash(path);
- this->DotNetHintReferences[""].push_back(
- DotNetHintReference(name, path));
+ static const cm::string_view vsDnRef = "VS_DOTNET_REFERENCE_";
+ if (cmHasPrefix(i.first, vsDnRef)) {
+ std::string path = i.second;
+ if (!cmsys::SystemTools::FileIsFullPath(path)) {
+ path = this->Makefile->GetCurrentSourceDirectory() + "/" + path;
}
+ ConvertToWindowsSlash(path);
+ this->DotNetHintReferences[""].emplace_back(
+ DotNetHintReference(i.first.substr(vsDnRef.length()), path));
}
}
if (!references.empty() || !this->DotNetHintReferences.empty()) {
@@ -824,7 +826,7 @@ void cmVisualStudio10TargetGenerator::WriteDotNetReferences(Elem& e0)
cmsys::SystemTools::GetFilenameWithoutLastExtension(ri);
std::string path = ri;
ConvertToWindowsSlash(path);
- this->DotNetHintReferences[""].push_back(
+ this->DotNetHintReferences[""].emplace_back(
DotNetHintReference(name, path));
} else {
this->WriteDotNetReference(e1, ri, "", "");
@@ -856,9 +858,9 @@ void cmVisualStudio10TargetGenerator::WriteDotNetReference(
e2.Element("ReferenceOutputAssembly", "true");
if (!hint.empty()) {
const char* privateReference = "True";
- if (const char* value = this->GeneratorTarget->GetProperty(
+ if (cmProp value = this->GeneratorTarget->GetProperty(
"VS_DOTNET_REFERENCES_COPY_LOCAL")) {
- if (cmIsOff(value)) {
+ if (cmIsOff(*value)) {
privateReference = "False";
}
}
@@ -870,11 +872,10 @@ void cmVisualStudio10TargetGenerator::WriteDotNetReference(
void cmVisualStudio10TargetGenerator::WriteImports(Elem& e0)
{
- const char* imports =
+ cmProp imports =
this->GeneratorTarget->Target->GetProperty("VS_PROJECT_IMPORT");
if (imports) {
- std::vector<std::string> argsSplit =
- cmExpandedList(std::string(imports), false);
+ std::vector<std::string> argsSplit = cmExpandedList(*imports, false);
for (auto& path : argsSplit) {
if (!cmsys::SystemTools::FileIsFullPath(path)) {
path = this->Makefile->GetCurrentSourceDirectory() + "/" + path;
@@ -897,16 +898,24 @@ void cmVisualStudio10TargetGenerator::WriteDotNetReferenceCustomTags(
CustomTags tags;
cmPropertyMap const& props = this->GeneratorTarget->Target->GetProperties();
for (const auto& i : props.GetList()) {
- if (i.first.find(refPropFullPrefix) == 0) {
- std::string refTag = i.first.substr(refPropFullPrefix.length());
- std::string refVal = i.second;
- if (!refTag.empty() && !refVal.empty()) {
- tags[refTag] = refVal;
- }
+ if (cmHasPrefix(i.first, refPropFullPrefix) && !i.second.empty()) {
+ tags[i.first.substr(refPropFullPrefix.length())] = i.second;
}
}
for (auto const& tag : tags) {
- e2.Element(tag.first.c_str(), tag.second);
+ e2.Element(tag.first, tag.second);
+ }
+}
+
+void cmVisualStudio10TargetGenerator::WriteDotNetDocumentationFile(Elem& e0)
+{
+ std::string const& documentationFile =
+ this->GeneratorTarget->GetSafeProperty("VS_DOTNET_DOCUMENTATION_FILE");
+
+ if (this->ProjectType == csproj && !documentationFile.empty()) {
+ Elem e1(e0, "PropertyGroup");
+ Elem e2(e1, "DocumentationFile");
+ e2.Content(documentationFile);
}
}
@@ -927,7 +936,7 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup(Elem& e0)
// subdirectory
// of the .csproj file, we have to use relative pathnames, otherwise
// visual studio does not show the file in the IDE. Sorry.
- if (obj.find(srcDir) == 0) {
+ if (cmHasPrefix(obj, srcDir)) {
obj = this->ConvertPath(obj, true);
ConvertToWindowsSlash(obj);
useRelativePath = true;
@@ -956,17 +965,11 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup(Elem& e0)
// If the resource was NOT added using a relative path (which should
// be the default), we have to provide a link here
if (!useRelativePath) {
- std::string link;
- if (obj.find(srcDir) == 0) {
- link = obj.substr(srcDir.length() + 1);
- } else if (obj.find(binDir) == 0) {
- link = obj.substr(binDir.length() + 1);
- } else {
+ std::string link = this->GetCSharpSourceLink(oi);
+ if (link.empty()) {
link = cmsys::SystemTools::GetFilenameName(obj);
}
- if (!link.empty()) {
- e2.Element("Link", link);
- }
+ e2.Element("Link", link);
}
// Determine if this is a generated resource from a .Designer.cs file
std::string designerResource =
@@ -975,15 +978,15 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup(Elem& e0)
".Designer.cs";
if (cmsys::SystemTools::FileExists(designerResource)) {
std::string generator = "PublicResXFileCodeGenerator";
- if (const char* g = oi->GetProperty("VS_RESOURCE_GENERATOR")) {
- generator = g;
+ if (cmProp g = oi->GetProperty("VS_RESOURCE_GENERATOR")) {
+ generator = *g;
}
if (!generator.empty()) {
e2.Element("Generator", generator);
- if (designerResource.find(srcDir) == 0) {
- designerResource = designerResource.substr(srcDir.length() + 1);
- } else if (designerResource.find(binDir) == 0) {
- designerResource = designerResource.substr(binDir.length() + 1);
+ if (cmHasPrefix(designerResource, srcDir)) {
+ designerResource.erase(0, srcDir.length());
+ } else if (cmHasPrefix(designerResource, binDir)) {
+ designerResource.erase(0, binDir.length());
} else {
designerResource =
cmsys::SystemTools::GetFilenameName(designerResource);
@@ -994,13 +997,14 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup(Elem& e0)
}
const cmPropertyMap& props = oi->GetProperties();
for (const std::string& p : props.GetKeys()) {
- static const std::string propNamePrefix = "VS_CSHARP_";
- if (p.find(propNamePrefix) == 0) {
- std::string tagName = p.substr(propNamePrefix.length());
+ static const cm::string_view propNamePrefix = "VS_CSHARP_";
+ if (cmHasPrefix(p, propNamePrefix)) {
+ cm::string_view tagName =
+ cm::string_view(p).substr(propNamePrefix.length());
if (!tagName.empty()) {
- std::string value = props.GetPropertyValue(p);
+ const std::string& value = *props.GetPropertyValue(p);
if (!value.empty()) {
- e2.Element(tagName.c_str(), value);
+ e2.Element(tagName, value);
}
}
}
@@ -1018,10 +1022,10 @@ void cmVisualStudio10TargetGenerator::WriteXamlFilesGroup(Elem& e0)
Elem e1(e0, "ItemGroup");
for (cmSourceFile const* oi : xamlObjs) {
std::string obj = oi->GetFullPath();
- const char* xamlType;
- const char* xamlTypeProperty = oi->GetProperty("VS_XAML_TYPE");
+ std::string xamlType;
+ cmProp xamlTypeProperty = oi->GetProperty("VS_XAML_TYPE");
if (xamlTypeProperty) {
- xamlType = xamlTypeProperty;
+ xamlType = *xamlTypeProperty;
} else {
xamlType = "Page";
}
@@ -1029,25 +1033,6 @@ void cmVisualStudio10TargetGenerator::WriteXamlFilesGroup(Elem& e0)
Elem e2(e1, xamlType);
this->WriteSource(e2, oi);
e2.SetHasElements();
- if (this->ProjectType == csproj && !this->InSourceBuild) {
- // add <Link> tag to written XAML source if necessary
- const std::string& srcDir =
- this->Makefile->GetCurrentSourceDirectory();
- const std::string& binDir =
- this->Makefile->GetCurrentBinaryDirectory();
- std::string link;
- if (obj.find(srcDir) == 0) {
- link = obj.substr(srcDir.length() + 1);
- } else if (obj.find(binDir) == 0) {
- link = obj.substr(binDir.length() + 1);
- } else {
- link = cmsys::SystemTools::GetFilenameName(obj);
- }
- if (!link.empty()) {
- ConvertToWindowsSlash(link);
- e2.Element("Link", link);
- }
- }
e2.Element("SubType", "Designer");
}
}
@@ -1092,9 +1077,9 @@ void cmVisualStudio10TargetGenerator::WriteTargetsFileReferences(Elem& e1)
void cmVisualStudio10TargetGenerator::WriteWinRTReferences(Elem& e0)
{
std::vector<std::string> references;
- if (const char* vsWinRTReferences =
+ if (cmProp vsWinRTReferences =
this->GeneratorTarget->GetProperty("VS_WINRT_REFERENCES")) {
- cmExpandList(vsWinRTReferences, references);
+ cmExpandList(*vsWinRTReferences, references);
}
if (this->GlobalGenerator->TargetsWindowsPhone() &&
@@ -1135,9 +1120,9 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues(Elem& e0)
if (this->ProjectType != csproj) {
std::string configType;
- if (const char* vsConfigurationType =
+ if (cmProp vsConfigurationType =
this->GeneratorTarget->GetProperty("VS_CONFIGURATION_TYPE")) {
- configType = cmGeneratorExpression::Evaluate(vsConfigurationType,
+ configType = cmGeneratorExpression::Evaluate(*vsConfigurationType,
this->LocalGenerator, c);
} else {
switch (this->GeneratorTarget->GetType()) {
@@ -1193,9 +1178,9 @@ void cmVisualStudio10TargetGenerator::WriteCEDebugProjectConfigurationValues(
if (!this->GlobalGenerator->TargetsWindowsCE()) {
return;
}
- const char* additionalFiles =
+ cmProp additionalFiles =
this->GeneratorTarget->GetProperty("DEPLOYMENT_ADDITIONAL_FILES");
- const char* remoteDirectory =
+ cmProp remoteDirectory =
this->GeneratorTarget->GetProperty("DEPLOYMENT_REMOTE_DIRECTORY");
if (!(additionalFiles || remoteDirectory)) {
return;
@@ -1205,10 +1190,10 @@ void cmVisualStudio10TargetGenerator::WriteCEDebugProjectConfigurationValues(
e1.Attribute("Condition", this->CalcCondition(c));
if (remoteDirectory) {
- e1.Element("RemoteDirectory", remoteDirectory);
+ e1.Element("RemoteDirectory", *remoteDirectory);
}
if (additionalFiles) {
- e1.Element("CEAdditionalFiles", additionalFiles);
+ e1.Element("CEAdditionalFiles", *additionalFiles);
}
}
}
@@ -1246,7 +1231,10 @@ void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValues(
} else {
e1.Element("CharacterSet", "MultiByte");
}
- if (const char* toolset = gg->GetPlatformToolset()) {
+ if (cmProp projectToolsetOverride =
+ this->GeneratorTarget->GetProperty("VS_PLATFORM_TOOLSET")) {
+ e1.Element("PlatformToolset", *projectToolsetOverride);
+ } else if (const char* toolset = gg->GetPlatformToolset()) {
e1.Element("PlatformToolset", toolset);
}
if (this->GeneratorTarget->GetPropertyAsBool("VS_WINRT_COMPONENT") ||
@@ -1289,7 +1277,10 @@ void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValuesManaged(
o.RemoveFlag("Platform");
}
- if (const char* toolset = gg->GetPlatformToolset()) {
+ if (cmProp projectToolsetOverride =
+ this->GeneratorTarget->GetProperty("VS_PLATFORM_TOOLSET")) {
+ e1.Element("PlatformToolset", *projectToolsetOverride);
+ } else if (const char* toolset = gg->GetPlatformToolset()) {
e1.Element("PlatformToolset", toolset);
}
@@ -1297,8 +1288,8 @@ void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValuesManaged(
cmStrCat(cmSystemTools::UpperCase(config), "_POSTFIX");
std::string assemblyName = this->GeneratorTarget->GetOutputName(
config, cmStateEnums::RuntimeBinaryArtifact);
- if (const char* postfix = this->GeneratorTarget->GetProperty(postfixName)) {
- assemblyName += postfix;
+ if (cmProp postfix = this->GeneratorTarget->GetProperty(postfixName)) {
+ assemblyName += *postfix;
}
e1.Element("AssemblyName", assemblyName);
@@ -1318,22 +1309,20 @@ void cmVisualStudio10TargetGenerator::WriteNsightTegraConfigurationValues(
cmGlobalVisualStudio10Generator* gg = this->GlobalGenerator;
const char* toolset = gg->GetPlatformToolset();
e1.Element("NdkToolchainVersion", toolset ? toolset : "Default");
- if (const char* minApi =
- this->GeneratorTarget->GetProperty("ANDROID_API_MIN")) {
- e1.Element("AndroidMinAPI", "android-" + std::string(minApi));
+ if (cmProp minApi = this->GeneratorTarget->GetProperty("ANDROID_API_MIN")) {
+ e1.Element("AndroidMinAPI", "android-" + *minApi);
}
- if (const char* api = this->GeneratorTarget->GetProperty("ANDROID_API")) {
- e1.Element("AndroidTargetAPI", "android-" + std::string(api));
+ if (cmProp api = this->GeneratorTarget->GetProperty("ANDROID_API")) {
+ e1.Element("AndroidTargetAPI", "android-" + *api);
}
- if (const char* cpuArch =
- this->GeneratorTarget->GetProperty("ANDROID_ARCH")) {
- e1.Element("AndroidArch", cpuArch);
+ if (cmProp cpuArch = this->GeneratorTarget->GetProperty("ANDROID_ARCH")) {
+ e1.Element("AndroidArch", *cpuArch);
}
- if (const char* stlType =
+ if (cmProp stlType =
this->GeneratorTarget->GetProperty("ANDROID_STL_TYPE")) {
- e1.Element("AndroidStlType", stlType);
+ e1.Element("AndroidStlType", *stlType);
}
}
@@ -1414,16 +1403,14 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule(
spe2 = cm::make_unique<Elem>(*spe1, "CustomBuild");
this->WriteSource(*spe2, source);
spe2->SetHasElements();
+ if (command.GetStdPipesUTF8()) {
+ this->WriteStdOutEncodingUtf8(*spe2);
+ }
} else {
Elem e1(e0, "ItemGroup");
Elem e2(e1, "None");
- std::string link;
- this->GetCSharpSourceLink(source, link);
this->WriteSource(e2, source);
e2.SetHasElements();
- if (!link.empty()) {
- e2.Element("Link", link);
- }
}
for (std::string const& c : this->Configurations) {
cmCustomCommandGenerator ccg(command, c, lg);
@@ -1598,8 +1585,7 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
fout.write(magic, 3);
fout << "<?xml version=\"1.0\" encoding=\""
- << this->GlobalGenerator->Encoding() << "\"?>"
- << "\n";
+ << this->GlobalGenerator->Encoding() << "\"?>";
{
Elem e0(fout, "Project");
e0.Attribute("ToolsVersion", this->GlobalGenerator->GetToolsVersion());
@@ -1738,7 +1724,7 @@ void cmVisualStudio10TargetGenerator::WriteGroupSources(
std::string const& filter = sourceGroup->GetFullName();
std::string path = this->ConvertPath(source, s.RelativePath);
ConvertToWindowsSlash(path);
- Elem e2(e1, name.c_str());
+ Elem e2(e1, name);
e2.Attribute("Include", path);
if (!filter.empty()) {
e2.Element("Filter", filter);
@@ -1755,25 +1741,70 @@ void cmVisualStudio10TargetGenerator::WriteHeaderSource(Elem& e1,
if (this->IsResxHeader(fileName)) {
e2.Element("FileType", "CppForm");
} else if (this->IsXamlHeader(fileName)) {
- std::string xamlFileName = fileName.substr(0, fileName.find_last_of("."));
- e2.Element("DependentUpon", xamlFileName);
+ e2.Element("DependentUpon",
+ fileName.substr(0, fileName.find_last_of(".")));
}
}
+void cmVisualStudio10TargetGenerator::ParseSettingsProperty(
+ const std::string& settingsPropertyValue, ConfigToSettings& toolSettings)
+{
+ if (!settingsPropertyValue.empty()) {
+ cmGeneratorExpression ge;
+
+ std::unique_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(settingsPropertyValue);
+
+ for (const std::string& config : this->Configurations) {
+ std::string evaluated = cge->Evaluate(this->LocalGenerator, config);
+
+ std::vector<std::string> settings = cmExpandedList(evaluated);
+ for (const std::string& setting : settings) {
+ const std::string::size_type assignment = setting.find('=');
+ if (assignment != std::string::npos) {
+ const std::string propName = setting.substr(0, assignment);
+ const std::string propValue = setting.substr(assignment + 1);
+
+ if (!propValue.empty()) {
+ toolSettings[config][propName] = propValue;
+ }
+ }
+ }
+ }
+ }
+}
+
+bool cmVisualStudio10TargetGenerator::PropertyIsSameInAllConfigs(
+ const ConfigToSettings& toolSettings, const std::string& propName)
+{
+ std::string firstPropValue = "";
+ for (const auto& configToSettings : toolSettings) {
+ const std::unordered_map<std::string, std::string>& settings =
+ configToSettings.second;
+
+ if (firstPropValue.empty()) {
+ if (settings.find(propName) != settings.end()) {
+ firstPropValue = settings.find(propName)->second;
+ }
+ }
+
+ if (settings.find(propName) == settings.end()) {
+ return false;
+ }
+
+ if (settings.find(propName)->second != firstPropValue) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1,
cmSourceFile const* sf)
{
bool toolHasSettings = false;
const char* tool = "None";
- std::string shaderType;
- std::string shaderEntryPoint;
- std::string shaderModel;
- std::string shaderAdditionalFlags;
- std::string shaderDisableOptimizations;
- std::string shaderEnableDebug;
- std::string shaderObjectFileName;
- std::string outputHeaderFile;
- std::string variableName;
std::string settingsGenerator;
std::string settingsLastGenOutput;
std::string sourceLink;
@@ -1781,76 +1812,84 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1,
std::string copyToOutDir;
std::string includeInVsix;
std::string ext = cmSystemTools::LowerCase(sf->GetExtension());
- if (this->ProjectType == csproj) {
- // EVERY extra source file must have a <Link>, otherwise it might not
- // be visible in Visual Studio at all. The path relative to current
- // source- or binary-dir is used within the link, if the file is
- // in none of these paths, it is added with the plain filename without
- // any path. This means the file will show up at root-level of the csproj
- // (where CMakeLists.txt etc. are).
- if (!this->InSourceBuild) {
- toolHasSettings = true;
- std::string fullFileName = sf->GetFullPath();
- std::string srcDir = this->Makefile->GetCurrentSourceDirectory();
- std::string binDir = this->Makefile->GetCurrentBinaryDirectory();
- if (fullFileName.find(binDir) != std::string::npos) {
- sourceLink.clear();
- } else if (fullFileName.find(srcDir) != std::string::npos) {
- sourceLink = fullFileName.substr(srcDir.length() + 1);
- } else {
- // fallback: add plain filename without any path
- sourceLink = cmsys::SystemTools::GetFilenameName(fullFileName);
- }
- if (!sourceLink.empty()) {
- ConvertToWindowsSlash(sourceLink);
- }
- }
+ ConfigToSettings toolSettings;
+ for (const auto& config : this->Configurations) {
+ toolSettings[config];
+ }
+
+ if (this->ProjectType == csproj && !this->InSourceBuild) {
+ toolHasSettings = true;
}
if (ext == "hlsl") {
tool = "FXCompile";
// Figure out the type of shader compiler to use.
- if (const char* st = sf->GetProperty("VS_SHADER_TYPE")) {
- shaderType = st;
- toolHasSettings = true;
+ if (cmProp st = sf->GetProperty("VS_SHADER_TYPE")) {
+ for (const std::string& config : this->Configurations) {
+ toolSettings[config]["ShaderType"] = *st;
+ }
}
// Figure out which entry point to use if any
- if (const char* se = sf->GetProperty("VS_SHADER_ENTRYPOINT")) {
- shaderEntryPoint = se;
- toolHasSettings = true;
+ if (cmProp se = sf->GetProperty("VS_SHADER_ENTRYPOINT")) {
+ for (const std::string& config : this->Configurations) {
+ toolSettings[config]["EntryPointName"] = *se;
+ }
}
// Figure out which shader model to use if any
- if (const char* sm = sf->GetProperty("VS_SHADER_MODEL")) {
- shaderModel = sm;
- toolHasSettings = true;
+ if (cmProp sm = sf->GetProperty("VS_SHADER_MODEL")) {
+ for (const std::string& config : this->Configurations) {
+ toolSettings[config]["ShaderModel"] = *sm;
+ }
}
// Figure out which output header file to use if any
- if (const char* ohf = sf->GetProperty("VS_SHADER_OUTPUT_HEADER_FILE")) {
- outputHeaderFile = ohf;
- toolHasSettings = true;
+ if (cmProp ohf = sf->GetProperty("VS_SHADER_OUTPUT_HEADER_FILE")) {
+ for (const std::string& config : this->Configurations) {
+ toolSettings[config]["HeaderFileOutput"] = *ohf;
+ }
}
// Figure out which variable name to use if any
- if (const char* vn = sf->GetProperty("VS_SHADER_VARIABLE_NAME")) {
- variableName = vn;
- toolHasSettings = true;
+ if (cmProp vn = sf->GetProperty("VS_SHADER_VARIABLE_NAME")) {
+ for (const std::string& config : this->Configurations) {
+ toolSettings[config]["VariableName"] = *vn;
+ }
}
// Figure out if there's any additional flags to use
- if (const char* saf = sf->GetProperty("VS_SHADER_FLAGS")) {
- shaderAdditionalFlags = saf;
- toolHasSettings = true;
+ if (cmProp saf = sf->GetProperty("VS_SHADER_FLAGS")) {
+ for (const std::string& config : this->Configurations) {
+ toolSettings[config]["AdditionalOptions"] = *saf;
+ }
}
// Figure out if debug information should be generated
- if (const char* sed = sf->GetProperty("VS_SHADER_ENABLE_DEBUG")) {
- shaderEnableDebug = sed;
- toolHasSettings = true;
+ if (cmProp sed = sf->GetProperty("VS_SHADER_ENABLE_DEBUG")) {
+ cmGeneratorExpression ge;
+ std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*sed);
+
+ for (const std::string& config : this->Configurations) {
+ std::string evaluated = cge->Evaluate(this->LocalGenerator, config);
+
+ if (!evaluated.empty()) {
+ toolSettings[config]["EnableDebuggingInformation"] =
+ cmIsOn(evaluated) ? "true" : "false";
+ }
+ }
}
// Figure out if optimizations should be disabled
- if (const char* sdo = sf->GetProperty("VS_SHADER_DISABLE_OPTIMIZATIONS")) {
- shaderDisableOptimizations = sdo;
- toolHasSettings = true;
+ if (cmProp sdo = sf->GetProperty("VS_SHADER_DISABLE_OPTIMIZATIONS")) {
+ cmGeneratorExpression ge;
+ std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*sdo);
+
+ for (const std::string& config : this->Configurations) {
+ std::string evaluated = cge->Evaluate(this->LocalGenerator, config);
+
+ if (!evaluated.empty()) {
+ toolSettings[config]["DisableOptimizations"] =
+ cmIsOn(evaluated) ? "true" : "false";
+ }
+ }
}
- if (const char* sofn = sf->GetProperty("VS_SHADER_OBJECT_FILE_NAME")) {
- shaderObjectFileName = sofn;
- toolHasSettings = true;
+ if (cmProp sofn = sf->GetProperty("VS_SHADER_OBJECT_FILE_NAME")) {
+ for (const std::string& config : this->Configurations) {
+ toolSettings[config]["ObjectFileOutput"] = *sofn;
+ }
}
} else if (ext == "jpg" || ext == "png") {
tool = "Image";
@@ -1870,9 +1909,9 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1,
} else if (ext == "vsixmanifest") {
subType = "Designer";
}
- if (const char* c = sf->GetProperty("VS_COPY_TO_OUT_DIR")) {
+ if (cmProp c = sf->GetProperty("VS_COPY_TO_OUT_DIR")) {
tool = "Content";
- copyToOutDir = c;
+ copyToOutDir = *c;
toolHasSettings = true;
}
if (sf->GetPropertyAsBool("VS_INCLUDE_IN_VSIX")) {
@@ -1899,32 +1938,79 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1,
}
}
- const char* toolOverride = sf->GetProperty("VS_TOOL_OVERRIDE");
- if (toolOverride && *toolOverride) {
- tool = toolOverride;
+ cmProp toolOverride = sf->GetProperty("VS_TOOL_OVERRIDE");
+ if (toolOverride && !toolOverride->empty()) {
+ tool = toolOverride->c_str();
}
std::string deployContent;
std::string deployLocation;
if (this->GlobalGenerator->TargetsWindowsPhone() ||
this->GlobalGenerator->TargetsWindowsStore()) {
- const char* content = sf->GetProperty("VS_DEPLOYMENT_CONTENT");
- if (content && *content) {
+ cmProp content = sf->GetProperty("VS_DEPLOYMENT_CONTENT");
+ if (content && !content->empty()) {
toolHasSettings = true;
- deployContent = content;
+ deployContent = *content;
- const char* location = sf->GetProperty("VS_DEPLOYMENT_LOCATION");
- if (location && *location) {
- deployLocation = location;
+ cmProp location = sf->GetProperty("VS_DEPLOYMENT_LOCATION");
+ if (location && !location->empty()) {
+ deployLocation = *location;
}
}
}
+ if (ParsedToolTargetSettings.find(tool) == ParsedToolTargetSettings.end()) {
+ cmProp toolTargetProperty = this->GeneratorTarget->Target->GetProperty(
+ "VS_SOURCE_SETTINGS_" + std::string(tool));
+ ConfigToSettings toolTargetSettings;
+ if (toolTargetProperty) {
+ ParseSettingsProperty(*toolTargetProperty, toolTargetSettings);
+ }
+
+ ParsedToolTargetSettings[tool] = toolTargetSettings;
+ }
+
+ for (const auto& configToSetting : ParsedToolTargetSettings[tool]) {
+ for (const auto& setting : configToSetting.second) {
+ toolSettings[configToSetting.first][setting.first] = setting.second;
+ }
+ }
+
+ if (cmProp p = sf->GetProperty("VS_SETTINGS")) {
+ ParseSettingsProperty(*p, toolSettings);
+ }
+
+ if (!toolSettings.empty()) {
+ toolHasSettings = true;
+ }
+
Elem e2(e1, tool);
this->WriteSource(e2, sf);
if (toolHasSettings) {
e2.SetHasElements();
+ std::vector<std::string> writtenSettings;
+ for (const auto& configSettings : toolSettings) {
+ for (const auto& setting : configSettings.second) {
+
+ if (std::find(writtenSettings.begin(), writtenSettings.end(),
+ setting.first) != writtenSettings.end()) {
+ continue;
+ }
+
+ if (PropertyIsSameInAllConfigs(toolSettings, setting.first)) {
+ e2.Element(setting.first, setting.second);
+ writtenSettings.push_back(setting.first);
+ } else {
+ e2.WritePlatformConfigTag(setting.first,
+ "'$(Configuration)|$(Platform)'=='" +
+ configSettings.first + "|" +
+ this->Platform + "'",
+ setting.second);
+ }
+ }
+ }
+
if (!deployContent.empty()) {
cmGeneratorExpression ge;
std::unique_ptr<cmCompiledGeneratorExpression> cge =
@@ -1950,82 +2036,13 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1,
}
}
}
- if (!shaderType.empty()) {
- e2.Element("ShaderType", shaderType);
- }
- if (!shaderEntryPoint.empty()) {
- e2.Element("EntryPointName", shaderEntryPoint);
- }
- if (!shaderModel.empty()) {
- e2.Element("ShaderModel", shaderModel);
- }
- if (!outputHeaderFile.empty()) {
- for (size_t i = 0; i != this->Configurations.size(); ++i) {
- e2.WritePlatformConfigTag("HeaderFileOutput",
- "'$(Configuration)|$(Platform)'=='" +
- this->Configurations[i] + "|" +
- this->Platform + "'",
- outputHeaderFile);
- }
- }
- if (!variableName.empty()) {
- for (size_t i = 0; i != this->Configurations.size(); ++i) {
- e2.WritePlatformConfigTag("VariableName",
- "'$(Configuration)|$(Platform)'=='" +
- this->Configurations[i] + "|" +
- this->Platform + "'",
- variableName);
- }
- }
- if (!shaderEnableDebug.empty()) {
- cmGeneratorExpression ge;
- std::unique_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(shaderEnableDebug);
-
- for (size_t i = 0; i != this->Configurations.size(); ++i) {
- const std::string& enableDebug =
- cge->Evaluate(this->LocalGenerator, this->Configurations[i]);
- if (!enableDebug.empty()) {
- e2.WritePlatformConfigTag("EnableDebuggingInformation",
- "'$(Configuration)|$(Platform)'=='" +
- this->Configurations[i] + "|" +
- this->Platform + "'",
- cmIsOn(enableDebug) ? "true" : "false");
- }
- }
- }
- if (!shaderDisableOptimizations.empty()) {
- cmGeneratorExpression ge;
- std::unique_ptr<cmCompiledGeneratorExpression> cge =
- ge.Parse(shaderDisableOptimizations);
- for (size_t i = 0; i != this->Configurations.size(); ++i) {
- const std::string& disableOptimizations =
- cge->Evaluate(this->LocalGenerator, this->Configurations[i]);
- if (!disableOptimizations.empty()) {
- e2.WritePlatformConfigTag(
- "DisableOptimizations",
- "'$(Configuration)|$(Platform)'=='" + this->Configurations[i] +
- "|" + this->Platform + "'",
- (cmIsOn(disableOptimizations) ? "true" : "false"));
- }
- }
- }
- if (!shaderObjectFileName.empty()) {
- e2.Element("ObjectFileOutput", shaderObjectFileName);
- }
- if (!shaderAdditionalFlags.empty()) {
- e2.Element("AdditionalOptions", shaderAdditionalFlags);
- }
if (!settingsGenerator.empty()) {
e2.Element("Generator", settingsGenerator);
}
if (!settingsLastGenOutput.empty()) {
e2.Element("LastGenOutput", settingsLastGenOutput);
}
- if (!sourceLink.empty()) {
- e2.Element("Link", sourceLink);
- }
if (!subType.empty()) {
e2.Element("SubType", subType);
}
@@ -2078,6 +2095,20 @@ void cmVisualStudio10TargetGenerator::WriteSource(Elem& e2,
ConvertToWindowsSlash(sourceFile);
e2.Attribute("Include", sourceFile);
+ if (this->ProjectType == csproj && !this->InSourceBuild) {
+ // For out of source projects we have to provide a link (if not specified
+ // via property) for every source file (besides .cs files) otherwise they
+ // will not be visible in VS at all.
+ // First we check if the file is in a source group, then we check if the
+ // file path is relative to current source- or binary-dir, otherwise it is
+ // added with the plain filename without any path. This means the file will
+ // show up at root-level of the csproj (where CMakeLists.txt etc. are).
+ std::string link = this->GetCSharpSourceLink(sf);
+ if (link.empty())
+ link = cmsys::SystemTools::GetFilenameName(sf->GetFullPath());
+ e2.Element("Link", link);
+ }
+
ToolSource toolSource = { sf, forceRelative };
this->Tools[e2.Tag].push_back(toolSource);
}
@@ -2221,7 +2252,7 @@ void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0)
e2.Attribute("CustomUnityFile", "true");
std::string unityDir = cmSystemTools::GetFilenamePath(
- si.Source->GetProperty("UNITY_SOURCE_FILE"));
+ *si.Source->GetProperty("UNITY_SOURCE_FILE"));
e2.Attribute("UnityFilesDirectory", unityDir);
} else {
// Visual Studio versions prior to 2017 15.8 do not know about unity
@@ -2266,25 +2297,25 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
bool configDependentDefines = false;
std::string includes;
bool configDependentIncludes = false;
- if (const char* cflags = sf.GetProperty("COMPILE_FLAGS")) {
+ if (cmProp cflags = sf.GetProperty("COMPILE_FLAGS")) {
configDependentFlags =
- cmGeneratorExpression::Find(cflags) != std::string::npos;
- flags += cflags;
+ cmGeneratorExpression::Find(*cflags) != std::string::npos;
+ flags += *cflags;
}
- if (const char* coptions = sf.GetProperty("COMPILE_OPTIONS")) {
+ if (cmProp coptions = sf.GetProperty("COMPILE_OPTIONS")) {
configDependentOptions =
- cmGeneratorExpression::Find(coptions) != std::string::npos;
- options += coptions;
+ cmGeneratorExpression::Find(*coptions) != std::string::npos;
+ options += *coptions;
}
- if (const char* cdefs = sf.GetProperty("COMPILE_DEFINITIONS")) {
+ if (cmProp cdefs = sf.GetProperty("COMPILE_DEFINITIONS")) {
configDependentDefines =
- cmGeneratorExpression::Find(cdefs) != std::string::npos;
- defines += cdefs;
+ cmGeneratorExpression::Find(*cdefs) != std::string::npos;
+ defines += *cdefs;
}
- if (const char* cincludes = sf.GetProperty("INCLUDE_DIRECTORIES")) {
+ if (cmProp cincludes = sf.GetProperty("INCLUDE_DIRECTORIES")) {
configDependentIncludes =
- cmGeneratorExpression::Find(cincludes) != std::string::npos;
- includes += cincludes;
+ cmGeneratorExpression::Find(*cincludes) != std::string::npos;
+ includes += *cincludes;
}
std::string lang =
this->GlobalGenerator->GetLanguageFromExtension(sf.GetExtension().c_str());
@@ -2323,13 +2354,13 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
std::string configUpper = cmSystemTools::UpperCase(config);
std::string configDefines = defines;
std::string defPropName = cmStrCat("COMPILE_DEFINITIONS_", configUpper);
- if (const char* ccdefs = sf.GetProperty(defPropName)) {
+ if (cmProp ccdefs = sf.GetProperty(defPropName)) {
if (!configDefines.empty()) {
configDefines += ";";
}
configDependentDefines |=
- cmGeneratorExpression::Find(ccdefs) != std::string::npos;
- configDefines += ccdefs;
+ cmGeneratorExpression::Find(*ccdefs) != std::string::npos;
+ configDefines += *ccdefs;
}
// Add precompile headers compile options.
@@ -2430,19 +2461,13 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
}
if (this->IsXamlSource(source->GetFullPath())) {
const std::string& fileName = source->GetFullPath();
- std::string xamlFileName = fileName.substr(0, fileName.find_last_of("."));
- e2.Element("DependentUpon", xamlFileName);
+ e2.Element("DependentUpon",
+ fileName.substr(0, fileName.find_last_of(".")));
}
if (this->ProjectType == csproj) {
std::string f = source->GetFullPath();
using CsPropMap = std::map<std::string, std::string>;
CsPropMap sourceFileTags;
- // set <Link> tag if necessary
- std::string link;
- this->GetCSharpSourceLink(source, link);
- if (!link.empty()) {
- sourceFileTags["Link"] = link;
- }
this->GetCSharpSourceProperties(&sf, sourceFileTags);
// write source file specific tags
if (!sourceFileTags.empty()) {
@@ -2480,34 +2505,34 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions(
const std::string cond = this->CalcCondition(config);
if (ttype <= cmStateEnums::UTILITY) {
- if (const char* workingDir = this->GeneratorTarget->GetProperty(
+ if (cmProp workingDir = this->GeneratorTarget->GetProperty(
"VS_DEBUGGER_WORKING_DIRECTORY")) {
std::string genWorkingDir = cmGeneratorExpression::Evaluate(
- workingDir, this->LocalGenerator, config);
+ *workingDir, this->LocalGenerator, config);
e1.WritePlatformConfigTag("LocalDebuggerWorkingDirectory", cond,
genWorkingDir);
}
- if (const char* environment =
+ if (cmProp environment =
this->GeneratorTarget->GetProperty("VS_DEBUGGER_ENVIRONMENT")) {
std::string genEnvironment = cmGeneratorExpression::Evaluate(
- environment, this->LocalGenerator, config);
+ *environment, this->LocalGenerator, config);
e1.WritePlatformConfigTag("LocalDebuggerEnvironment", cond,
genEnvironment);
}
- if (const char* debuggerCommand =
+ if (cmProp debuggerCommand =
this->GeneratorTarget->GetProperty("VS_DEBUGGER_COMMAND")) {
std::string genDebuggerCommand = cmGeneratorExpression::Evaluate(
- debuggerCommand, this->LocalGenerator, config);
+ *debuggerCommand, this->LocalGenerator, config);
e1.WritePlatformConfigTag("LocalDebuggerCommand", cond,
genDebuggerCommand);
}
- if (const char* commandArguments = this->GeneratorTarget->GetProperty(
+ if (cmProp commandArguments = this->GeneratorTarget->GetProperty(
"VS_DEBUGGER_COMMAND_ARGUMENTS")) {
std::string genCommandArguments = cmGeneratorExpression::Evaluate(
- commandArguments, this->LocalGenerator, config);
+ *commandArguments, this->LocalGenerator, config);
e1.WritePlatformConfigTag("LocalDebuggerCommandArguments", cond,
genCommandArguments);
}
@@ -2624,9 +2649,9 @@ void cmVisualStudio10TargetGenerator::OutputLinkIncremental(
// Some link options belong here. Use them now and remove them so that
// WriteLinkOptions does not use them.
- const char* flags[] = { "LinkDelaySign", "LinkKeyFile", 0 };
- for (const char** f = flags; *f; ++f) {
- const char* flag = *f;
+ static const std::vector<std::string> flags{ "LinkDelaySign",
+ "LinkKeyFile" };
+ for (const std::string& flag : flags) {
if (const char* value = linkOptions.GetFlag(flag)) {
e1.WritePlatformConfigTag(flag, cond, value);
linkOptions.RemoveFlag(flag);
@@ -2692,7 +2717,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
std::string langForClCompile;
if (this->ProjectType == csproj) {
langForClCompile = "CSharp";
- } else if (cmContains(clLangs, linkLanguage)) {
+ } else if (cm::contains(clLangs, linkLanguage)) {
langForClCompile = linkLanguage;
} else {
std::set<std::string> languages;
@@ -2767,9 +2792,9 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
this->Makefile->IssueMessage(MessageType::WARNING, message);
}
}
- if (auto* clr =
+ if (cmProp clr =
this->GeneratorTarget->GetProperty("COMMON_LANGUAGE_RUNTIME")) {
- std::string clrString = clr;
+ std::string clrString = *clr;
if (!clrString.empty()) {
clrString = ":" + clrString;
}
@@ -2790,6 +2815,9 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
case csproj:
this->GeneratorTarget->GetCompileDefinitions(targetDefines, configName,
"CSharp");
+ cm::erase_if(targetDefines, [](std::string const& def) {
+ return def.find('=') != std::string::npos;
+ });
break;
}
clOptions.AddDefines(targetDefines);
@@ -2818,10 +2846,8 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
}
if (this->MSTools) {
- // If we have the VS_WINRT_COMPONENT or CMAKE_VS_WINRT_BY_DEFAULT
- // set then force Compile as WinRT.
- if (this->GeneratorTarget->GetPropertyAsBool("VS_WINRT_COMPONENT") ||
- this->Makefile->IsOn("CMAKE_VS_WINRT_BY_DEFAULT")) {
+ // If we have the VS_WINRT_COMPONENT set then force Compile as WinRT
+ if (this->GeneratorTarget->GetPropertyAsBool("VS_WINRT_COMPONENT")) {
clOptions.AddFlag("CompileAsWinRT", "true");
// For WinRT components, add the _WINRT_DLL define to produce a lib
if (this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY ||
@@ -2829,7 +2855,8 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
clOptions.AddDefine("_WINRT_DLL");
}
} else if (this->GlobalGenerator->TargetsWindowsStore() ||
- this->GlobalGenerator->TargetsWindowsPhone()) {
+ this->GlobalGenerator->TargetsWindowsPhone() ||
+ this->Makefile->IsOn("CMAKE_VS_WINRT_BY_DEFAULT")) {
if (!clOptions.IsWinRt()) {
clOptions.AddFlag("CompileAsWinRT", "false");
}
@@ -2885,9 +2912,9 @@ void cmVisualStudio10TargetGenerator::WriteClOptions(
oh.OutputPreprocessorDefinitions(this->LangForClCompile);
if (this->NsightTegra) {
- if (const char* processMax =
+ if (cmProp processMax =
this->GeneratorTarget->GetProperty("ANDROID_PROCESS_MAX")) {
- e2.Element("ProcessMax", processMax);
+ e2.Element("ProcessMax", *processMax);
}
}
@@ -3156,6 +3183,8 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaLinkOptions(
this->LocalGenerator, Options::CudaCompiler, gg->GetCudaFlagTable());
Options& cudaLinkOptions = *pOptions;
+ cmGeneratorTarget::DeviceLinkSetter setter(*this->GeneratorTarget);
+
// Determine if we need to do a device link
const bool doDeviceLinking = requireDeviceLinking(
*this->GeneratorTarget, *this->LocalGenerator, configName);
@@ -3163,12 +3192,20 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaLinkOptions(
cudaLinkOptions.AddFlag("PerformDeviceLink",
doDeviceLinking ? "true" : "false");
- // Suppress deprecation warnings for default GPU targets during device link.
- if (cmSystemTools::VersionCompareGreaterEq(
- this->GlobalGenerator->GetPlatformToolsetCudaString(), "8.0")) {
- cudaLinkOptions.AppendFlagString("AdditionalOptions",
- "-Wno-deprecated-gpu-targets");
- }
+ // Add extra flags for device linking
+ cudaLinkOptions.AppendFlagString(
+ "AdditionalOptions",
+ this->Makefile->GetSafeDefinition("_CMAKE_CUDA_EXTRA_FLAGS"));
+ cudaLinkOptions.AppendFlagString(
+ "AdditionalOptions",
+ this->Makefile->GetSafeDefinition("_CMAKE_CUDA_EXTRA_DEVICE_LINK_FLAGS"));
+
+ std::vector<std::string> linkOpts;
+ std::string linkFlags;
+ this->GeneratorTarget->GetLinkOptions(linkOpts, configName, "CUDA");
+ // LINK_OPTIONS are escaped.
+ this->LocalGenerator->AppendCompileOptions(linkFlags, linkOpts);
+ cudaLinkOptions.AppendFlagString("AdditionalOptions", linkFlags);
// For static libraries that have device linking enabled compute
// the libraries
@@ -3386,9 +3423,8 @@ void cmVisualStudio10TargetGenerator::WriteLibOptions(
this->GeneratorTarget->GetLinkClosure(config)->LinkerLanguage;
std::string libflags;
- this->LocalGenerator->GetStaticLibraryFlags(
- libflags, cmSystemTools::UpperCase(config), linkLanguage,
- this->GeneratorTarget);
+ this->LocalGenerator->GetStaticLibraryFlags(libflags, config, linkLanguage,
+ this->GeneratorTarget);
if (!libflags.empty()) {
Elem e2(e1, "Lib");
cmGlobalVisualStudio10Generator* gg = this->GlobalGenerator;
@@ -3423,7 +3459,7 @@ void cmVisualStudio10TargetGenerator::WriteManifestOptions(
std::vector<cmSourceFile const*> manifest_srcs;
this->GeneratorTarget->GetManifests(manifest_srcs, config);
- const char* dpiAware = this->GeneratorTarget->GetProperty("VS_DPI_AWARE");
+ cmProp dpiAware = this->GeneratorTarget->GetProperty("VS_DPI_AWARE");
if (!manifest_srcs.empty() || dpiAware) {
Elem e2(e1, "Manifest");
@@ -3437,15 +3473,14 @@ void cmVisualStudio10TargetGenerator::WriteManifestOptions(
e2.Element("AdditionalManifestFiles", oss.str());
}
if (dpiAware) {
- if (!strcmp(dpiAware, "PerMonitor")) {
+ if (*dpiAware == "PerMonitor") {
e2.Element("EnableDpiAwareness", "PerMonitorHighDPIAware");
- } else if (cmIsOn(dpiAware)) {
+ } else if (cmIsOn(*dpiAware)) {
e2.Element("EnableDpiAwareness", "true");
- } else if (cmIsOff(dpiAware)) {
+ } else if (cmIsOff(*dpiAware)) {
e2.Element("EnableDpiAwareness", "false");
} else {
- cmSystemTools::Error("Bad parameter for VS_DPI_AWARE: " +
- std::string(dpiAware));
+ cmSystemTools::Error("Bad parameter for VS_DPI_AWARE: " + *dpiAware);
}
}
}
@@ -3485,51 +3520,51 @@ void cmVisualStudio10TargetGenerator::WriteAntBuildOptions(
e2.Element("EnableProGuard", "true");
}
- if (const char* proGuardConfigLocation =
+ if (cmProp proGuardConfigLocation =
this->GeneratorTarget->GetProperty("ANDROID_PROGUARD_CONFIG_PATH")) {
- e2.Element("ProGuardConfigLocation", proGuardConfigLocation);
+ e2.Element("ProGuardConfigLocation", *proGuardConfigLocation);
}
- if (const char* securePropertiesLocation =
+ if (cmProp securePropertiesLocation =
this->GeneratorTarget->GetProperty("ANDROID_SECURE_PROPS_PATH")) {
- e2.Element("SecurePropertiesLocation", securePropertiesLocation);
+ e2.Element("SecurePropertiesLocation", *securePropertiesLocation);
}
- if (const char* nativeLibDirectoriesExpression =
+ if (cmProp nativeLibDirectoriesExpression =
this->GeneratorTarget->GetProperty("ANDROID_NATIVE_LIB_DIRECTORIES")) {
std::string nativeLibDirs = cmGeneratorExpression::Evaluate(
- nativeLibDirectoriesExpression, this->LocalGenerator, configName);
+ *nativeLibDirectoriesExpression, this->LocalGenerator, configName);
e2.Element("NativeLibDirectories", nativeLibDirs);
}
- if (const char* nativeLibDependenciesExpression =
+ if (cmProp nativeLibDependenciesExpression =
this->GeneratorTarget->GetProperty(
"ANDROID_NATIVE_LIB_DEPENDENCIES")) {
std::string nativeLibDeps = cmGeneratorExpression::Evaluate(
- nativeLibDependenciesExpression, this->LocalGenerator, configName);
+ *nativeLibDependenciesExpression, this->LocalGenerator, configName);
e2.Element("NativeLibDependencies", nativeLibDeps);
}
- if (const char* javaSourceDir =
+ if (cmProp javaSourceDir =
this->GeneratorTarget->GetProperty("ANDROID_JAVA_SOURCE_DIR")) {
- e2.Element("JavaSourceDir", javaSourceDir);
+ e2.Element("JavaSourceDir", *javaSourceDir);
}
- if (const char* jarDirectoriesExpression =
+ if (cmProp jarDirectoriesExpression =
this->GeneratorTarget->GetProperty("ANDROID_JAR_DIRECTORIES")) {
std::string jarDirectories = cmGeneratorExpression::Evaluate(
- jarDirectoriesExpression, this->LocalGenerator, configName);
+ *jarDirectoriesExpression, this->LocalGenerator, configName);
e2.Element("JarDirectories", jarDirectories);
}
- if (const char* jarDeps =
+ if (cmProp jarDeps =
this->GeneratorTarget->GetProperty("ANDROID_JAR_DEPENDENCIES")) {
- e2.Element("JarDependencies", jarDeps);
+ e2.Element("JarDependencies", *jarDeps);
}
- if (const char* assetsDirectories =
+ if (cmProp assetsDirectories =
this->GeneratorTarget->GetProperty("ANDROID_ASSETS_DIRECTORIES")) {
- e2.Element("AssetsDirectories", assetsDirectories);
+ e2.Element("AssetsDirectories", *assetsDirectories);
}
{
@@ -3538,10 +3573,10 @@ void cmVisualStudio10TargetGenerator::WriteAntBuildOptions(
e2.Element("AndroidManifestLocation", manifest_xml);
}
- if (const char* antAdditionalOptions =
+ if (cmProp antAdditionalOptions =
this->GeneratorTarget->GetProperty("ANDROID_ANT_ADDITIONAL_OPTIONS")) {
e2.Element("AdditionalOptions",
- std::string(antAdditionalOptions) + " %(AdditionalOptions)");
+ *antAdditionalOptions + " %(AdditionalOptions)");
}
}
@@ -3593,17 +3628,15 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
std::string linkFlagVar = linkFlagVarBase + "_" + CONFIG;
flags += " ";
flags += this->Makefile->GetRequiredDefinition(linkFlagVar);
- const char* targetLinkFlags =
- this->GeneratorTarget->GetProperty("LINK_FLAGS");
+ cmProp targetLinkFlags = this->GeneratorTarget->GetProperty("LINK_FLAGS");
if (targetLinkFlags) {
flags += " ";
- flags += targetLinkFlags;
+ flags += *targetLinkFlags;
}
std::string flagsProp = cmStrCat("LINK_FLAGS_", CONFIG);
- if (const char* flagsConfig =
- this->GeneratorTarget->GetProperty(flagsProp)) {
+ if (cmProp flagsConfig = this->GeneratorTarget->GetProperty(flagsProp)) {
flags += " ";
- flags += flagsConfig;
+ flags += *flagsConfig;
}
std::vector<std::string> opts;
@@ -3624,20 +3657,9 @@ bool cmVisualStudio10TargetGenerator::ComputeLinkOptions(
std::vector<std::string> libVec;
std::vector<std::string> vsTargetVec;
this->AddLibraries(cli, libVec, vsTargetVec, config);
- if (cmContains(linkClosure->Languages, "CUDA") &&
+ if (cm::contains(linkClosure->Languages, "CUDA") &&
this->CudaOptions[config] != nullptr) {
- switch (this->CudaOptions[config]->GetCudaRuntime()) {
- case cmVisualStudioGeneratorOptions::CudaRuntimeStatic:
- libVec.push_back("cudadevrt.lib");
- libVec.push_back("cudart_static.lib");
- break;
- case cmVisualStudioGeneratorOptions::CudaRuntimeShared:
- libVec.push_back("cudadevrt.lib");
- libVec.push_back("cudart.lib");
- break;
- case cmVisualStudioGeneratorOptions::CudaRuntimeNone:
- break;
- }
+ this->CudaOptions[config]->FixCudaRuntime(this->GeneratorTarget);
}
std::string standardLibsVar =
cmStrCat("CMAKE_", linkLanguage, "_STANDARD_LIBRARIES");
@@ -3909,7 +3931,7 @@ void cmVisualStudio10TargetGenerator::AddTargetsFileAndConfigPair(
{
for (TargetsFileAndConfigs& i : this->TargetsFileAndConfigsVec) {
if (cmSystemTools::ComparePath(targetsFile, i.File)) {
- if (!cmContains(i.Configs, config)) {
+ if (!cm::contains(i.Configs, config)) {
i.Configs.push_back(config);
}
return;
@@ -4027,8 +4049,8 @@ void cmVisualStudio10TargetGenerator::WriteEvents(
}
void cmVisualStudio10TargetGenerator::WriteEvent(
- Elem& e1, const char* name, std::vector<cmCustomCommand> const& commands,
- std::string const& configName)
+ Elem& e1, const std::string& name,
+ std::vector<cmCustomCommand> const& commands, std::string const& configName)
{
if (commands.empty()) {
return;
@@ -4037,6 +4059,7 @@ void cmVisualStudio10TargetGenerator::WriteEvent(
std::string script;
const char* pre = "";
std::string comment;
+ bool stdPipesUTF8 = false;
for (cmCustomCommand const& cc : commands) {
cmCustomCommandGenerator ccg(cc, configName, lg);
if (!ccg.HasOnlyEmptyCommandLines()) {
@@ -4045,11 +4068,16 @@ void cmVisualStudio10TargetGenerator::WriteEvent(
script += pre;
pre = "\n";
script += lg->ConstructScript(ccg);
+
+ stdPipesUTF8 = stdPipesUTF8 || cc.GetStdPipesUTF8();
}
}
comment = cmVS10EscapeComment(comment);
if (this->ProjectType != csproj) {
Elem e2(e1, name);
+ if (stdPipesUTF8) {
+ this->WriteStdOutEncodingUtf8(e2);
+ }
e2.Element("Message", comment);
e2.Element("Command", script);
} else {
@@ -4087,9 +4115,9 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences(Elem& e0)
cmLocalGenerator* lg = dt->GetLocalGenerator();
std::string name = dt->GetName();
std::string path;
- const char* p = dt->GetProperty("EXTERNAL_MSPROJECT");
+ cmProp p = dt->GetProperty("EXTERNAL_MSPROJECT");
if (p) {
- path = p;
+ path = *p;
} else {
path = cmStrCat(lg->GetCurrentBinaryDirectory(), '/', dt->GetName(),
computeProjectFileExtension(dt));
@@ -4100,6 +4128,9 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences(Elem& e0)
e2.Element("Project", "{" + this->GlobalGenerator->GetGUID(name) + "}");
e2.Element("Name", name);
this->WriteDotNetReferenceCustomTags(e2, name);
+ if (dt->IsCSharpOnly() || cmHasLiteralSuffix(path, "csproj")) {
+ e2.Element("SkipGetTargetFrameworkProperties", "true");
+ }
// Don't reference targets that don't produce any output.
if (dt->GetManagedType("") == cmGeneratorTarget::ManagedType::Undefined) {
@@ -4114,17 +4145,17 @@ void cmVisualStudio10TargetGenerator::WritePlatformExtensions(Elem& e1)
// This only applies to Windows 10 apps
if (this->GlobalGenerator->TargetsWindowsStore() &&
cmHasLiteralPrefix(this->GlobalGenerator->GetSystemVersion(), "10.0")) {
- const char* desktopExtensionsVersion =
+ cmProp desktopExtensionsVersion =
this->GeneratorTarget->GetProperty("VS_DESKTOP_EXTENSIONS_VERSION");
if (desktopExtensionsVersion) {
this->WriteSinglePlatformExtension(e1, "WindowsDesktop",
- desktopExtensionsVersion);
+ *desktopExtensionsVersion);
}
- const char* mobileExtensionsVersion =
+ cmProp mobileExtensionsVersion =
this->GeneratorTarget->GetProperty("VS_MOBILE_EXTENSIONS_VERSION");
if (mobileExtensionsVersion) {
this->WriteSinglePlatformExtension(e1, "WindowsMobile",
- mobileExtensionsVersion);
+ *mobileExtensionsVersion);
}
}
}
@@ -4149,9 +4180,9 @@ void cmVisualStudio10TargetGenerator::WriteSDKReferences(Elem& e0)
{
std::vector<std::string> sdkReferences;
std::unique_ptr<Elem> spe1;
- if (const char* vsSDKReferences =
+ if (cmProp vsSDKReferences =
this->GeneratorTarget->GetProperty("VS_SDK_REFERENCES")) {
- cmExpandList(vsSDKReferences, sdkReferences);
+ cmExpandList(*vsSDKReferences, sdkReferences);
spe1 = cm::make_unique<Elem>(e0, "ItemGroup");
for (std::string const& ri : sdkReferences) {
Elem(*spe1, "SDKReference").Attribute("Include", ri);
@@ -4161,11 +4192,11 @@ void cmVisualStudio10TargetGenerator::WriteSDKReferences(Elem& e0)
// This only applies to Windows 10 apps
if (this->GlobalGenerator->TargetsWindowsStore() &&
cmHasLiteralPrefix(this->GlobalGenerator->GetSystemVersion(), "10.0")) {
- const char* desktopExtensionsVersion =
+ cmProp desktopExtensionsVersion =
this->GeneratorTarget->GetProperty("VS_DESKTOP_EXTENSIONS_VERSION");
- const char* mobileExtensionsVersion =
+ cmProp mobileExtensionsVersion =
this->GeneratorTarget->GetProperty("VS_MOBILE_EXTENSIONS_VERSION");
- const char* iotExtensionsVersion =
+ cmProp iotExtensionsVersion =
this->GeneratorTarget->GetProperty("VS_IOT_EXTENSIONS_VERSION");
if (desktopExtensionsVersion || mobileExtensionsVersion ||
@@ -4175,15 +4206,15 @@ void cmVisualStudio10TargetGenerator::WriteSDKReferences(Elem& e0)
}
if (desktopExtensionsVersion) {
this->WriteSingleSDKReference(*spe1, "WindowsDesktop",
- desktopExtensionsVersion);
+ *desktopExtensionsVersion);
}
if (mobileExtensionsVersion) {
this->WriteSingleSDKReference(*spe1, "WindowsMobile",
- mobileExtensionsVersion);
+ *mobileExtensionsVersion);
}
if (iotExtensionsVersion) {
this->WriteSingleSDKReference(*spe1, "WindowsIoT",
- iotExtensionsVersion);
+ *iotExtensionsVersion);
}
}
}
@@ -4334,10 +4365,10 @@ void cmVisualStudio10TargetGenerator::WriteApplicationTypeSettings(Elem& e1)
if (!targetPlatformVersion.empty()) {
e1.Element("WindowsTargetPlatformVersion", targetPlatformVersion);
}
- const char* targetPlatformMinVersion = this->GeneratorTarget->GetProperty(
+ cmProp targetPlatformMinVersion = this->GeneratorTarget->GetProperty(
"VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION");
if (targetPlatformMinVersion) {
- e1.Element("WindowsTargetPlatformMinVersion", targetPlatformMinVersion);
+ e1.Element("WindowsTargetPlatformMinVersion", *targetPlatformMinVersion);
} else if (isWindowsStore && rev == "10.0") {
// If the min version is not set, then use the TargetPlatformVersion
if (!targetPlatformVersion.empty()) {
@@ -4827,11 +4858,11 @@ void cmVisualStudio10TargetGenerator::GetCSharpSourceProperties(
if (this->ProjectType == csproj) {
const cmPropertyMap& props = sf->GetProperties();
for (const std::string& p : props.GetKeys()) {
- static const std::string propNamePrefix = "VS_CSHARP_";
- if (p.find(propNamePrefix) == 0) {
+ static const cm::string_view propNamePrefix = "VS_CSHARP_";
+ if (cmHasPrefix(p, propNamePrefix)) {
std::string tagName = p.substr(propNamePrefix.length());
if (!tagName.empty()) {
- const std::string val = props.GetPropertyValue(p);
+ const std::string& val = *props.GetPropertyValue(p);
if (!val.empty()) {
tags[tagName] = val;
} else {
@@ -4847,28 +4878,38 @@ void cmVisualStudio10TargetGenerator::WriteCSharpSourceProperties(
Elem& e2, const std::map<std::string, std::string>& tags)
{
for (const auto& i : tags) {
- e2.Element(i.first.c_str(), i.second);
+ e2.Element(i.first, i.second);
}
}
-void cmVisualStudio10TargetGenerator::GetCSharpSourceLink(
- cmSourceFile const* sf, std::string& link)
+std::string cmVisualStudio10TargetGenerator::GetCSharpSourceLink(
+ cmSourceFile const* source)
{
- std::string const& sourceFilePath = sf->GetFullPath();
- std::string const& binaryDir = LocalGenerator->GetCurrentBinaryDirectory();
-
- if (!cmSystemTools::IsSubDirectory(sourceFilePath, binaryDir)) {
- const std::string& stripFromPath =
- this->Makefile->GetCurrentSourceDirectory();
- if (sourceFilePath.find(stripFromPath) == 0) {
- if (const char* l = sf->GetProperty("VS_CSHARP_Link")) {
- link = l;
- } else {
- link = sourceFilePath.substr(stripFromPath.length() + 1);
- }
- ConvertToWindowsSlash(link);
- }
- }
+ // For out of source files, we first check if a matching source group
+ // for this file exists, otherwise we check if the path relative to current
+ // source- or binary-dir is used within the link and return that
+ std::string link;
+ std::string const& fullFileName = source->GetFullPath();
+ std::string const& srcDir = this->Makefile->GetCurrentSourceDirectory();
+ std::string const& binDir = this->Makefile->GetCurrentBinaryDirectory();
+ // unfortunately we have to copy the source groups, because
+ // FindSourceGroup uses a regex which is modifying the group
+ std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();
+ cmSourceGroup* sourceGroup =
+ this->Makefile->FindSourceGroup(fullFileName, sourceGroups);
+ if (sourceGroup && !sourceGroup->GetFullName().empty()) {
+ link = sourceGroup->GetFullName() + "/" +
+ cmsys::SystemTools::GetFilenameName(fullFileName);
+ } else if (cmHasPrefix(fullFileName, srcDir)) {
+ link = fullFileName.substr(srcDir.length() + 1);
+ } else if (cmHasPrefix(fullFileName, binDir)) {
+ link = fullFileName.substr(binDir.length() + 1);
+ } else if (cmProp l = source->GetProperty("VS_CSHARP_Link")) {
+ link = *l;
+ }
+
+ ConvertToWindowsSlash(link);
+ return link;
}
std::string cmVisualStudio10TargetGenerator::GetCMakeFilePath(
@@ -4881,3 +4922,8 @@ std::string cmVisualStudio10TargetGenerator::GetCMakeFilePath(
return path;
}
+
+void cmVisualStudio10TargetGenerator::WriteStdOutEncodingUtf8(Elem& e1)
+{
+ e1.Element("StdOutEncoding", "UTF-8");
+}
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index a18a33d..e3782f4 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -10,6 +10,7 @@
#include <memory>
#include <set>
#include <string>
+#include <unordered_map>
#include <vector>
class cmComputeLinkInformation;
@@ -73,12 +74,11 @@ private:
std::vector<size_t> const& exclude_configs);
void WriteAllSources(Elem& e0);
void WritePackageReferences(Elem& e0);
- void WritePackageReference(Elem& e1, std::string const& ref,
- std::string const& version);
void WriteDotNetReferences(Elem& e0);
void WriteDotNetReference(Elem& e1, std::string const& ref,
std::string const& hint,
std::string const& config);
+ void WriteDotNetDocumentationFile(Elem& e0);
void WriteImports(Elem& e0);
void WriteDotNetReferenceCustomTags(Elem& e2, std::string const& ref);
void WriteEmbeddedResourceGroup(Elem& e0);
@@ -164,7 +164,7 @@ private:
void WriteLibOptions(Elem& e1, std::string const& config);
void WriteManifestOptions(Elem& e1, std::string const& config);
void WriteEvents(Elem& e1, std::string const& configName);
- void WriteEvent(Elem& e1, const char* name,
+ void WriteEvent(Elem& e1, std::string const& name,
std::vector<cmCustomCommand> const& commands,
std::string const& configName);
void WriteGroupSources(Elem& e0, std::string const& name,
@@ -182,7 +182,9 @@ private:
std::map<std::string, std::string>& tags);
void WriteCSharpSourceProperties(
Elem& e2, const std::map<std::string, std::string>& tags);
- void GetCSharpSourceLink(cmSourceFile const* sf, std::string& link);
+ std::string GetCSharpSourceLink(cmSourceFile const* source);
+
+ void WriteStdOutEncodingUtf8(Elem& e1);
private:
friend class cmVS10GeneratorOptions;
@@ -235,6 +237,15 @@ private:
using ToolSourceMap = std::map<std::string, ToolSources>;
ToolSourceMap Tools;
+
+ using ConfigToSettings =
+ std::unordered_map<std::string,
+ std::unordered_map<std::string, std::string>>;
+ std::unordered_map<std::string, ConfigToSettings> ParsedToolTargetSettings;
+ bool PropertyIsSameInAllConfigs(const ConfigToSettings& toolSettings,
+ const std::string& propName);
+ void ParseSettingsProperty(const std::string& settingsPropertyValue,
+ ConfigToSettings& toolSettings);
std::string GetCMakeFilePath(const char* name) const;
};
diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx
index 1139aa9..7775f62 100644
--- a/Source/cmVisualStudioGeneratorOptions.cxx
+++ b/Source/cmVisualStudioGeneratorOptions.cxx
@@ -3,6 +3,8 @@
#include <cm/iterator>
#include "cmAlgorithms.h"
+#include "cmGeneratorExpression.h"
+#include "cmGeneratorTarget.h"
#include "cmLocalVisualStudioGenerator.h"
#include "cmOutputConverter.h"
#include "cmSystemTools.h"
@@ -149,25 +151,32 @@ bool cmVisualStudioGeneratorOptions::UsingSBCS() const
return false;
}
-cmVisualStudioGeneratorOptions::CudaRuntime
-cmVisualStudioGeneratorOptions::GetCudaRuntime() const
+void cmVisualStudioGeneratorOptions::FixCudaRuntime(cmGeneratorTarget* target)
{
std::map<std::string, FlagValue>::const_iterator i =
this->FlagMap.find("CudaRuntime");
- if (i != this->FlagMap.end() && i->second.size() == 1) {
- std::string const& cudaRuntime = i->second[0];
- if (cudaRuntime == "Static") {
- return CudaRuntimeStatic;
- }
- if (cudaRuntime == "Shared") {
- return CudaRuntimeShared;
- }
- if (cudaRuntime == "None") {
- return CudaRuntimeNone;
+ if (i == this->FlagMap.end()) {
+ // User didn't provide am override so get the property value
+ cmProp runtimeLibraryValue = target->GetProperty("CUDA_RUNTIME_LIBRARY");
+ if (runtimeLibraryValue) {
+ std::string cudaRuntime =
+ cmSystemTools::UpperCase(cmGeneratorExpression::Evaluate(
+ *runtimeLibraryValue, this->LocalGenerator, this->Configuration,
+ target));
+ if (cudaRuntime == "STATIC") {
+ this->AddFlag("CudaRuntime", "Static");
+ }
+ if (cudaRuntime == "SHARED") {
+ this->AddFlag("CudaRuntime", "Shared");
+ }
+ if (cudaRuntime == "NONE") {
+ this->AddFlag("CudaRuntime", "None");
+ }
+ } else {
+ // nvcc default is static
+ this->AddFlag("CudaRuntime", "Static");
}
}
- // nvcc default is static
- return CudaRuntimeStatic;
}
void cmVisualStudioGeneratorOptions::FixCudaCodeGeneration()
@@ -431,7 +440,7 @@ void cmVisualStudioGeneratorOptions::OutputPreprocessorDefinitions(
if (this->Defines.empty()) {
return;
}
- const char* tag = "PreprocessorDefinitions";
+ std::string tag = "PreprocessorDefinitions";
if (lang == "CUDA") {
tag = "Defines";
}
@@ -473,7 +482,7 @@ void cmVisualStudioGeneratorOptions::OutputAdditionalIncludeDirectories(
return;
}
- const char* tag = "AdditionalIncludeDirectories";
+ std::string tag = "AdditionalIncludeDirectories";
if (lang == "CUDA") {
tag = "Include";
} else if (lang == "ASM_MASM" || lang == "ASM_NASM") {
@@ -528,6 +537,6 @@ void cmVisualStudioGeneratorOptions::OutputFlagMap(std::ostream& fout,
sep = ";";
}
- this->OutputFlag(fout, indent, m.first.c_str(), oss.str());
+ this->OutputFlag(fout, indent, m.first, oss.str());
}
}
diff --git a/Source/cmVisualStudioGeneratorOptions.h b/Source/cmVisualStudioGeneratorOptions.h
index 560593e..b335694 100644
--- a/Source/cmVisualStudioGeneratorOptions.h
+++ b/Source/cmVisualStudioGeneratorOptions.h
@@ -13,6 +13,7 @@
#include "cmIDEOptions.h"
class cmLocalVisualStudioGenerator;
+class cmGeneratorTarget;
using cmVS7FlagTable = cmIDEFlagTable;
@@ -61,15 +62,8 @@ public:
bool UsingUnicode() const;
bool UsingSBCS() const;
- enum CudaRuntime
- {
- CudaRuntimeStatic,
- CudaRuntimeShared,
- CudaRuntimeNone
- };
- CudaRuntime GetCudaRuntime() const;
-
void FixCudaCodeGeneration();
+ void FixCudaRuntime(cmGeneratorTarget* target);
void FixManifestUACFlags();
@@ -86,7 +80,8 @@ public:
const std::string& GetConfiguration() const;
protected:
- virtual void OutputFlag(std::ostream& fout, int indent, const char* tag,
+ virtual void OutputFlag(std::ostream& fout, int indent,
+ const std::string& tag,
const std::string& content) = 0;
private:
diff --git a/Source/cmVisualStudioSlnParser.cxx b/Source/cmVisualStudioSlnParser.cxx
index 4533e9b..d7822b1 100644
--- a/Source/cmVisualStudioSlnParser.cxx
+++ b/Source/cmVisualStudioSlnParser.cxx
@@ -517,7 +517,7 @@ bool cmVisualStudioSlnParser::ParseMultiValueTag(const std::string& line,
State& state)
{
size_t idxEqualSign = line.find('=');
- const std::string& fullTag = line.substr(0, idxEqualSign);
+ auto fullTag = cm::string_view(line).substr(0, idxEqualSign);
if (!this->ParseTag(fullTag, parsedLine, state))
return false;
if (idxEqualSign != line.npos) {
@@ -560,7 +560,7 @@ bool cmVisualStudioSlnParser::ParseSingleValueTag(const std::string& line,
State& state)
{
size_t idxEqualSign = line.find('=');
- const std::string& fullTag = line.substr(0, idxEqualSign);
+ auto fullTag = cm::string_view(line).substr(0, idxEqualSign);
if (!this->ParseTag(fullTag, parsedLine, state))
return false;
if (idxEqualSign != line.npos) {
@@ -586,17 +586,17 @@ bool cmVisualStudioSlnParser::ParseKeyValuePair(const std::string& line,
return true;
}
-bool cmVisualStudioSlnParser::ParseTag(const std::string& fullTag,
+bool cmVisualStudioSlnParser::ParseTag(cm::string_view fullTag,
ParsedLine& parsedLine, State& state)
{
size_t idxLeftParen = fullTag.find('(');
- if (idxLeftParen == fullTag.npos) {
+ if (idxLeftParen == cm::string_view::npos) {
parsedLine.SetTag(cmTrimWhitespace(fullTag));
return true;
}
parsedLine.SetTag(cmTrimWhitespace(fullTag.substr(0, idxLeftParen)));
size_t idxRightParen = fullTag.rfind(')');
- if (idxRightParen == fullTag.npos) {
+ if (idxRightParen == cm::string_view::npos) {
this->LastResult.SetError(ResultErrorInputStructure,
state.GetCurrentLine());
return false;
diff --git a/Source/cmVisualStudioSlnParser.h b/Source/cmVisualStudioSlnParser.h
index 6c05633..4557cdb 100644
--- a/Source/cmVisualStudioSlnParser.h
+++ b/Source/cmVisualStudioSlnParser.h
@@ -9,6 +9,8 @@
#include <iosfwd>
#include <string>
+#include <cm/string_view>
+
#include <stddef.h>
class cmSlnData;
@@ -97,8 +99,7 @@ protected:
bool ParseKeyValuePair(const std::string& line, ParsedLine& parsedLine,
State& state);
- bool ParseTag(const std::string& fullTag, ParsedLine& parsedLine,
- State& state);
+ bool ParseTag(cm::string_view fullTag, ParsedLine& parsedLine, State& state);
bool ParseValue(const std::string& value, ParsedLine& parsedLine);
};
diff --git a/Source/cmWhileCommand.cxx b/Source/cmWhileCommand.cxx
index 26e7c75..0d8e894 100644
--- a/Source/cmWhileCommand.cxx
+++ b/Source/cmWhileCommand.cxx
@@ -7,8 +7,7 @@
#include <cm/memory>
#include <cm/string_view>
-
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
#include "cmConditionEvaluator.h"
#include "cmExecutionStatus.h"
diff --git a/Source/cmWorkerPool.cxx b/Source/cmWorkerPool.cxx
index aa0d6b3..9fec936 100644
--- a/Source/cmWorkerPool.cxx
+++ b/Source/cmWorkerPool.cxx
@@ -13,7 +13,7 @@
#include <cm/memory>
-#include "cm_uv.h"
+#include <cm3p/uv.h>
#include "cmRange.h"
#include "cmStringAlgorithms.h"
diff --git a/Source/cmWorkingDirectory.h b/Source/cmWorkingDirectory.h
index d4a164d..4c7576d 100644
--- a/Source/cmWorkingDirectory.h
+++ b/Source/cmWorkingDirectory.h
@@ -37,6 +37,8 @@ public:
*/
int GetLastResult() const { return ResultCode; }
+ std::string const& GetOldDirectory() const { return this->OldDir; }
+
private:
std::string OldDir;
int ResultCode;
diff --git a/Source/cmWriteFileCommand.cxx b/Source/cmWriteFileCommand.cxx
index 34e21b2..666ba87 100644
--- a/Source/cmWriteFileCommand.cxx
+++ b/Source/cmWriteFileCommand.cxx
@@ -72,7 +72,7 @@ bool cmWriteFileCommand(std::vector<std::string> const& args,
status.SetError(error);
return false;
}
- file << message << std::endl;
+ file << message << '\n';
file.close();
if (mode && !writable) {
cmSystemTools::SetPermissions(fileName.c_str(), mode);
diff --git a/Source/cmXCode21Object.cxx b/Source/cmXCode21Object.cxx
index a9bb2ef..6b133a9 100644
--- a/Source/cmXCode21Object.cxx
+++ b/Source/cmXCode21Object.cxx
@@ -30,11 +30,12 @@ void cmXCode21Object::PrintComment(std::ostream& out)
out << " */";
}
-void cmXCode21Object::PrintList(std::vector<cmXCodeObject*> const& v,
- std::ostream& out, PBXType t)
+void cmXCode21Object::PrintList(
+ std::vector<std::unique_ptr<cmXCodeObject>> const& v, std::ostream& out,
+ PBXType t)
{
bool hasOne = false;
- for (auto obj : v) {
+ for (const auto& obj : v) {
if (obj->GetType() == OBJECT && obj->GetIsA() == t) {
hasOne = true;
break;
@@ -44,7 +45,7 @@ void cmXCode21Object::PrintList(std::vector<cmXCodeObject*> const& v,
return;
}
out << "\n/* Begin " << PBXTypeNames[t] << " section */\n";
- for (auto obj : v) {
+ for (const auto& obj : v) {
if (obj->GetType() == OBJECT && obj->GetIsA() == t) {
obj->Print(out);
}
@@ -52,8 +53,8 @@ void cmXCode21Object::PrintList(std::vector<cmXCodeObject*> const& v,
out << "/* End " << PBXTypeNames[t] << " section */\n";
}
-void cmXCode21Object::PrintList(std::vector<cmXCodeObject*> const& v,
- std::ostream& out)
+void cmXCode21Object::PrintList(
+ std::vector<std::unique_ptr<cmXCodeObject>> const& v, std::ostream& out)
{
cmXCodeObject::Indent(1, out);
out << "objects = {\n";
diff --git a/Source/cmXCode21Object.h b/Source/cmXCode21Object.h
index 8e4b80f..76fad23 100644
--- a/Source/cmXCode21Object.h
+++ b/Source/cmXCode21Object.h
@@ -6,6 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <iosfwd>
+#include <memory>
#include <vector>
#include "cmXCodeObject.h"
@@ -15,8 +16,9 @@ class cmXCode21Object : public cmXCodeObject
public:
cmXCode21Object(PBXType ptype, Type type);
void PrintComment(std::ostream&) override;
- static void PrintList(std::vector<cmXCodeObject*> const&, std::ostream& out,
- PBXType t);
- static void PrintList(std::vector<cmXCodeObject*> const&, std::ostream& out);
+ static void PrintList(std::vector<std::unique_ptr<cmXCodeObject>> const&,
+ std::ostream& out, PBXType t);
+ static void PrintList(std::vector<std::unique_ptr<cmXCodeObject>> const&,
+ std::ostream& out);
};
#endif
diff --git a/Source/cmXCodeObject.h b/Source/cmXCodeObject.h
index d9be3d2..24ecaa2 100644
--- a/Source/cmXCodeObject.h
+++ b/Source/cmXCodeObject.h
@@ -12,7 +12,7 @@
#include <utility>
#include <vector>
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
class cmGeneratorTarget;
@@ -82,10 +82,13 @@ public:
void SetObject(cmXCodeObject* value) { this->Object = value; }
cmXCodeObject* GetObject() { return this->Object; }
void AddObject(cmXCodeObject* value) { this->List.push_back(value); }
- bool HasObject(cmXCodeObject* o) const { return cmContains(this->List, o); }
+ bool HasObject(cmXCodeObject* o) const
+ {
+ return cm::contains(this->List, o);
+ }
void AddUniqueObject(cmXCodeObject* value)
{
- if (!cmContains(this->List, value)) {
+ if (!cm::contains(this->List, value)) {
this->List.push_back(value);
}
}
diff --git a/Source/cmXCodeScheme.cxx b/Source/cmXCodeScheme.cxx
index afc95f5..9ac1457 100644
--- a/Source/cmXCodeScheme.cxx
+++ b/Source/cmXCodeScheme.cxx
@@ -7,14 +7,19 @@
#include <sstream>
#include <utility>
+#include <cmext/algorithm>
+
#include "cmGeneratedFileStream.h"
+#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmXMLSafe.h"
-cmXCodeScheme::cmXCodeScheme(cmXCodeObject* xcObj, TestObjects tests,
+cmXCodeScheme::cmXCodeScheme(cmLocalGenerator* lg, cmXCodeObject* xcObj,
+ TestObjects tests,
const std::vector<std::string>& configList,
unsigned int xcVersion)
- : Target(xcObj)
+ : LocalGenerator(lg)
+ , Target(xcObj)
, Tests(std::move(tests))
, TargetName(xcObj->GetTarget()->GetName())
, ConfigList(configList)
@@ -135,7 +140,8 @@ void cmXCodeScheme::WriteLaunchAction(cmXMLWriter& xout,
xout.Attribute("selectedLauncherIdentifier",
"Xcode.DebuggerFoundation.Launcher.LLDB");
xout.Attribute("launchStyle", "0");
- xout.Attribute("useCustomWorkingDirectory", "NO");
+ WriteCustomWorkingDirectory(xout, configuration);
+
xout.Attribute("ignoresPersistentStateOnLaunch", "NO");
WriteLaunchActionBooleanAttribute(xout, "debugDocumentVersioning",
"XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING",
@@ -198,14 +204,14 @@ void cmXCodeScheme::WriteLaunchAction(cmXMLWriter& xout,
// Info tab begin
- if (const char* exe =
+ if (cmProp exe =
this->Target->GetTarget()->GetProperty("XCODE_SCHEME_EXECUTABLE")) {
xout.StartElement("PathRunnable");
xout.BreakAttributes();
xout.Attribute("runnableDebuggingMode", "0");
- xout.Attribute("FilePath", exe);
+ xout.Attribute("FilePath", *exe);
xout.EndElement(); // PathRunnable
}
@@ -214,9 +220,9 @@ void cmXCodeScheme::WriteLaunchAction(cmXMLWriter& xout,
// Arguments tab begin
- if (const char* argList =
+ if (cmProp argList =
this->Target->GetTarget()->GetProperty("XCODE_SCHEME_ARGUMENTS")) {
- std::vector<std::string> arguments = cmExpandedList(argList);
+ std::vector<std::string> arguments = cmExpandedList(*argList);
if (!arguments.empty()) {
xout.StartElement("CommandLineArguments");
@@ -234,9 +240,9 @@ void cmXCodeScheme::WriteLaunchAction(cmXMLWriter& xout,
}
}
- if (const char* envList =
+ if (cmProp envList =
this->Target->GetTarget()->GetProperty("XCODE_SCHEME_ENVIRONMENT")) {
- std::vector<std::string> envs = cmExpandedList(envList);
+ std::vector<std::string> envs = cmExpandedList(*envList);
if (!envs.empty()) {
xout.StartElement("EnvironmentVariables");
@@ -317,8 +323,9 @@ bool cmXCodeScheme::WriteLaunchActionBooleanAttribute(
cmXMLWriter& xout, const std::string& attrName, const std::string& varName,
bool defaultValue)
{
- auto property = Target->GetTarget()->GetProperty(varName);
- bool isOn = (property == nullptr && defaultValue) || cmIsOn(property);
+ cmProp property = Target->GetTarget()->GetProperty(varName);
+ bool isOn =
+ (property == nullptr && defaultValue) || (property && cmIsOn(*property));
if (isOn) {
xout.Attribute(attrName.c_str(), "YES");
@@ -355,7 +362,7 @@ void cmXCodeScheme::WriteProfileAction(cmXMLWriter& xout,
xout.Attribute("buildConfiguration", configuration);
xout.Attribute("shouldUseLaunchSchemeArgsEnv", "YES");
xout.Attribute("savedToolIdentifier", "");
- xout.Attribute("useCustomWorkingDirectory", "NO");
+ WriteCustomWorkingDirectory(xout, configuration);
WriteLaunchActionBooleanAttribute(xout, "debugDocumentVersioning",
"XCODE_SCHEME_DEBUG_DOCUMENT_VERSIONING",
true);
@@ -395,6 +402,23 @@ void cmXCodeScheme::WriteBuildableReference(cmXMLWriter& xout,
xout.EndElement();
}
+void cmXCodeScheme::WriteCustomWorkingDirectory(
+ cmXMLWriter& xout, const std::string& configuration)
+{
+ std::string const& propertyValue =
+ this->Target->GetTarget()->GetSafeProperty(
+ "XCODE_SCHEME_WORKING_DIRECTORY");
+ if (propertyValue.empty()) {
+ xout.Attribute("useCustomWorkingDirectory", "NO");
+ } else {
+ xout.Attribute("useCustomWorkingDirectory", "YES");
+
+ auto customWorkingDirectory = cmGeneratorExpression::Evaluate(
+ propertyValue, this->LocalGenerator, configuration);
+ xout.Attribute("customWorkingDirectory", customWorkingDirectory);
+ }
+}
+
std::string cmXCodeScheme::WriteVersionString()
{
std::ostringstream v;
@@ -407,7 +431,7 @@ std::string cmXCodeScheme::FindConfiguration(const std::string& name)
// Try to find the desired configuration by name,
// and if it's not found return first from the list
//
- if (!cmContains(this->ConfigList, name) && !this->ConfigList.empty()) {
+ if (!cm::contains(this->ConfigList, name) && !this->ConfigList.empty()) {
return this->ConfigList[0];
}
diff --git a/Source/cmXCodeScheme.h b/Source/cmXCodeScheme.h
index dff5e35..da40856 100644
--- a/Source/cmXCodeScheme.h
+++ b/Source/cmXCodeScheme.h
@@ -20,7 +20,7 @@ class cmXCodeScheme
public:
using TestObjects = std::vector<const cmXCodeObject*>;
- cmXCodeScheme(cmXCodeObject* xcObj, TestObjects tests,
+ cmXCodeScheme(cmLocalGenerator* lg, cmXCodeObject* xcObj, TestObjects tests,
const std::vector<std::string>& configList,
unsigned int xcVersion);
@@ -28,6 +28,7 @@ public:
const std::string& container);
private:
+ cmLocalGenerator* const LocalGenerator;
const cmXCodeObject* const Target;
const TestObjects Tests;
const std::string& TargetName;
@@ -63,6 +64,9 @@ private:
void WriteBuildableReference(cmXMLWriter& xout, const cmXCodeObject* xcObj,
const std::string& container);
+ void WriteCustomWorkingDirectory(cmXMLWriter& xout,
+ const std::string& configuration);
+
std::string WriteVersionString();
std::string FindConfiguration(const std::string& name);
diff --git a/Source/cmXMLParser.cxx b/Source/cmXMLParser.cxx
index ad5c4ba..24da8c6 100644
--- a/Source/cmXMLParser.cxx
+++ b/Source/cmXMLParser.cxx
@@ -7,9 +7,9 @@
#include <iostream>
#include <sstream>
-#include "cmsys/FStream.hxx"
+#include <cm3p/expat.h>
-#include "cm_expat.h"
+#include "cmsys/FStream.hxx"
cmXMLParser::cmXMLParser()
{
diff --git a/Source/cmXMLWriter.h b/Source/cmXMLWriter.h
index bc445aa..00ea08c 100644
--- a/Source/cmXMLWriter.h
+++ b/Source/cmXMLWriter.h
@@ -6,7 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <chrono>
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
#include <ctime>
#include <ostream>
#include <stack>
diff --git a/Source/cm_get_date.c b/Source/cm_get_date.c
index 4bef803..49f5577 100644
--- a/Source/cm_get_date.c
+++ b/Source/cm_get_date.c
@@ -2,6 +2,10 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cm_get_date.h"
+// FIXME: This suppresses use of localtime_r because archive_getdate.c
+// depends the rest of libarchive's checks for that.
+#define CM_GET_DATE
+
#define __archive_get_date cm_get_date
#include "../Utilities/cmlibarchive/libarchive/archive_getdate.c"
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index f63a264..65d5f10 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -2,15 +2,31 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmake.h"
+#include <algorithm>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <initializer_list>
+#include <iostream>
+#include <sstream>
+#include <stdexcept>
+#include <utility>
+
#include <cm/memory>
#include <cm/string_view>
#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(CMAKE_BOOT_MINGW)
# include <cm/iterator>
#endif
+#include <cmext/algorithm>
+#include <cmext/string_view>
+
+#include "cmsys/FStream.hxx"
+#include "cmsys/Glob.hxx"
+#include "cmsys/RegularExpression.hxx"
+
#include "cm_sys_stat.h"
-#include "cmAlgorithms.h"
#include "cmCommands.h"
#include "cmDocumentation.h"
#include "cmDocumentationEntry.h"
@@ -24,6 +40,9 @@
#include "cmLinkLineComputer.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
+#if !defined(CMAKE_BOOTSTRAP)
+# include "cmMakefileProfilingData.h"
+#endif
#include "cmMessenger.h"
#include "cmState.h"
#include "cmStateDirectory.h"
@@ -38,7 +57,7 @@
#if !defined(CMAKE_BOOTSTRAP)
# include <unordered_map>
-# include "cm_jsoncpp_writer.h"
+# include <cm3p/json/writer.h>
# include "cmFileAPI.h"
# include "cmGraphVizWriter.h"
@@ -56,6 +75,8 @@
// include the generator
#if defined(_WIN32) && !defined(__CYGWIN__)
# if !defined(CMAKE_BOOT_MINGW)
+# include <cmext/memory>
+
# include "cmGlobalBorlandMakefileGenerator.h"
# include "cmGlobalJOMMakefileGenerator.h"
# include "cmGlobalNMakeMakefileGenerator.h"
@@ -106,19 +127,6 @@
# include <sys/time.h>
#endif
-#include <algorithm>
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-#include <initializer_list>
-#include <iostream>
-#include <sstream>
-#include <utility>
-
-#include "cmsys/FStream.hxx"
-#include "cmsys/Glob.hxx"
-#include "cmsys/RegularExpression.hxx"
-
namespace {
#if !defined(CMAKE_BOOTSTRAP)
@@ -130,6 +138,7 @@ using JsonValueMapType = std::unordered_map<std::string, Json::Value>;
static bool cmakeCheckStampFile(const std::string& stampName);
static bool cmakeCheckStampList(const std::string& stampList);
+#ifndef CMAKE_BOOTSTRAP
static void cmWarnUnusedCliWarning(const std::string& variable, int /*unused*/,
void* ctx, const char* /*unused*/,
const cmMakefile* /*unused*/)
@@ -137,6 +146,7 @@ static void cmWarnUnusedCliWarning(const std::string& variable, int /*unused*/,
cmake* cm = reinterpret_cast<cmake*>(ctx);
cm->MarkCliAsUsed(variable);
}
+#endif
cmake::cmake(Role role, cmState::Mode mode)
: FileTimeCache(cm::make_unique<cmFileTimeCache>())
@@ -201,14 +211,7 @@ cmake::cmake(Role role, cmState::Mode mode)
}
}
-cmake::~cmake()
-{
- if (this->GlobalGenerator) {
- delete this->GlobalGenerator;
- this->GlobalGenerator = nullptr;
- }
- cmDeleteAll(this->Generators);
-}
+cmake::~cmake() = default;
#if !defined(CMAKE_BOOTSTRAP)
Json::Value cmake::ReportVersionJson() const
@@ -288,10 +291,11 @@ void cmake::CleanupCommandsAndMacros()
// Parse the args
bool cmake::SetCacheArgs(const std::vector<std::string>& args)
{
- bool findPackageMode = false;
+ auto findPackageMode = false;
+ auto seenScriptOption = false;
for (unsigned int i = 1; i < args.size(); ++i) {
std::string const& arg = args[i];
- if (arg.find("-D", 0) == 0) {
+ if (cmHasLiteralPrefix(arg, "-D")) {
std::string entry = arg.substr(2);
if (entry.empty()) {
++i;
@@ -312,8 +316,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
bool haveValue = false;
std::string cachedValue;
if (this->WarnUnusedCli) {
- if (const std::string* v =
- this->State->GetInitializedCacheValue(var)) {
+ if (cmProp v = this->State->GetInitializedCacheValue(var)) {
haveValue = true;
cachedValue = *v;
}
@@ -330,9 +333,8 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
}
}
} else {
- std::cerr << "Parse error in command line argument: " << arg << "\n"
- << "Should be: VAR:type=value\n";
- cmSystemTools::Error("No cmake script provided.");
+ cmSystemTools::Error("Parse error in command line argument: " + arg +
+ "\n" + "Should be: VAR:type=value\n");
return false;
}
} else if (cmHasLiteralPrefix(arg, "-W")) {
@@ -381,7 +383,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
// -Wno-error=<name>
this->DiagLevels[name] = std::min(this->DiagLevels[name], DIAG_WARN);
}
- } else if (arg.find("-U", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "-U")) {
std::string entryPattern = arg.substr(2);
if (entryPattern.empty()) {
++i;
@@ -393,7 +395,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
}
}
cmsys::RegularExpression regex(
- cmsys::Glob::PatternToRegex(entryPattern, true, true).c_str());
+ cmsys::Glob::PatternToRegex(entryPattern, true, true));
// go through all cache entries and collect the vars which will be
// removed
std::vector<std::string> entriesToDelete;
@@ -411,7 +413,7 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
for (std::string const& currentEntry : entriesToDelete) {
this->State->RemoveCacheEntry(currentEntry);
}
- } else if (arg.find("-C", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "-C")) {
std::string path = arg.substr(2);
if (path.empty()) {
++i;
@@ -422,11 +424,11 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
return false;
}
}
- std::cout << "loading initial cache file " << path << "\n";
+ cmSystemTools::Stdout("loading initial cache file " + path + "\n");
// Resolve script path specified on command line relative to $PWD.
path = cmSystemTools::CollapseFullPath(path);
this->ReadListFile(args, path);
- } else if (arg.find("-P", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "-P")) {
i++;
if (i >= args.size()) {
cmSystemTools::Error("-P must be followed by a file name.");
@@ -445,7 +447,12 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
this->SetHomeOutputDirectory(
cmSystemTools::GetCurrentWorkingDirectory());
this->ReadListFile(args, path);
- } else if (arg.find("--find-package", 0) == 0) {
+ seenScriptOption = true;
+ } else if (arg == "--" && seenScriptOption) {
+ // Stop processing CMake args and avoid possible errors
+ // when arbitrary args are given to CMake script.
+ break;
+ } else if (cmHasLiteralPrefix(arg, "--find-package")) {
findPackageMode = true;
}
}
@@ -462,12 +469,12 @@ void cmake::ReadListFile(const std::vector<std::string>& args,
{
// if a generator was not yet created, temporarily create one
cmGlobalGenerator* gg = this->GetGlobalGenerator();
- bool created = false;
// if a generator was not specified use a generic one
+ std::unique_ptr<cmGlobalGenerator> gen;
if (!gg) {
- gg = new cmGlobalGenerator(this);
- created = true;
+ gen = cm::make_unique<cmGlobalGenerator>(this);
+ gg = gen.get();
}
// read in the list file to fill the cache
@@ -489,11 +496,6 @@ void cmake::ReadListFile(const std::vector<std::string>& args,
cmSystemTools::Error("Error processing file: " + path);
}
}
-
- // free generic one if generated
- if (created) {
- delete gg;
- }
}
bool cmake::FindPackage(const std::vector<std::string>& args)
@@ -501,9 +503,7 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
this->SetHomeDirectory(cmSystemTools::GetCurrentWorkingDirectory());
this->SetHomeOutputDirectory(cmSystemTools::GetCurrentWorkingDirectory());
- // if a generator was not yet created, temporarily create one
- cmGlobalGenerator* gg = new cmGlobalGenerator(this);
- this->SetGlobalGenerator(gg);
+ this->SetGlobalGenerator(cm::make_unique<cmGlobalGenerator>(this));
cmStateSnapshot snapshot = this->GetCurrentSnapshot();
snapshot.GetDirectory().SetCurrentBinary(
@@ -512,8 +512,9 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
cmSystemTools::GetCurrentWorkingDirectory());
// read in the list file to fill the cache
snapshot.SetDefaultDefinitions();
- cmMakefile* mf = new cmMakefile(gg, snapshot);
- gg->AddMakefile(mf);
+ auto mfu = cm::make_unique<cmMakefile>(this->GetGlobalGenerator(), snapshot);
+ cmMakefile* mf = mfu.get();
+ this->GlobalGenerator->AddMakefile(std::move(mfu));
mf->SetArgcArgv(args);
@@ -530,26 +531,26 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
if (!quiet) {
printf("%s not found.\n", packageName.c_str());
}
- } else if (mode == "EXIST") {
+ } else if (mode == "EXIST"_s) {
if (!quiet) {
printf("%s found.\n", packageName.c_str());
}
- } else if (mode == "COMPILE") {
+ } else if (mode == "COMPILE"_s) {
std::string includes = mf->GetSafeDefinition("PACKAGE_INCLUDE_DIRS");
std::vector<std::string> includeDirs = cmExpandedList(includes);
- gg->CreateGenerationObjects();
- cmLocalGenerator* lg = gg->LocalGenerators[0];
+ this->GlobalGenerator->CreateGenerationObjects();
+ const auto& lg = this->GlobalGenerator->LocalGenerators[0];
std::string includeFlags =
lg->GetIncludeFlags(includeDirs, nullptr, language);
std::string definitions = mf->GetSafeDefinition("PACKAGE_DEFINITIONS");
printf("%s %s\n", includeFlags.c_str(), definitions.c_str());
- } else if (mode == "LINK") {
+ } else if (mode == "LINK"_s) {
const char* targetName = "dummy";
std::vector<std::string> srcs;
cmTarget* tgt = mf->AddExecutable(targetName, srcs, true);
- tgt->SetProperty("LINKER_LANGUAGE", language.c_str());
+ tgt->SetProperty("LINKER_LANGUAGE", language);
std::string libs = mf->GetSafeDefinition("PACKAGE_LIBRARIES");
std::vector<std::string> libList = cmExpandedList(libs);
@@ -565,8 +566,9 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
std::string linkPath;
std::string flags;
std::string linkFlags;
- gg->CreateGenerationObjects();
- cmGeneratorTarget* gtgt = gg->FindGeneratorTarget(tgt->GetName());
+ this->GlobalGenerator->CreateGenerationObjects();
+ cmGeneratorTarget* gtgt =
+ this->GlobalGenerator->FindGeneratorTarget(tgt->GetName());
cmLocalGenerator* lg = gtgt->GetLocalGenerator();
cmLinkLineComputer linkLineComputer(lg,
lg->GetStateSnapshot().GetDirectory());
@@ -586,10 +588,6 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
}*/
}
- // free generic one if generated
- // this->SetGlobalGenerator(0); // setting 0-pointer is not possible
- // delete gg; // this crashes inside the cmake instance
-
return packageFound;
}
@@ -626,9 +624,13 @@ void cmake::SetArgs(const std::vector<std::string>& args)
{
bool haveToolset = false;
bool havePlatform = false;
+#if !defined(CMAKE_BOOTSTRAP)
+ std::string profilingFormat;
+ std::string profilingOutput;
+#endif
for (unsigned int i = 1; i < args.size(); ++i) {
std::string const& arg = args[i];
- if (arg.find("-H", 0) == 0 || arg.find("-S", 0) == 0) {
+ if (cmHasLiteralPrefix(arg, "-H") || cmHasLiteralPrefix(arg, "-S")) {
std::string path = arg.substr(2);
if (path.empty()) {
++i;
@@ -646,9 +648,11 @@ void cmake::SetArgs(const std::vector<std::string>& args)
path = cmSystemTools::CollapseFullPath(path);
cmSystemTools::ConvertToUnixSlashes(path);
this->SetHomeDirectory(path);
- } else if (arg.find("-O", 0) == 0) {
+ // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
+ // NOLINTNEXTLINE(bugprone-branch-clone)
+ } else if (cmHasLiteralPrefix(arg, "-O")) {
// There is no local generate anymore. Ignore -O option.
- } else if (arg.find("-B", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "-B")) {
std::string path = arg.substr(2);
if (path.empty()) {
++i;
@@ -667,52 +671,43 @@ void cmake::SetArgs(const std::vector<std::string>& args)
cmSystemTools::ConvertToUnixSlashes(path);
this->SetHomeOutputDirectory(path);
} else if ((i < args.size() - 2) &&
- (arg.find("--check-build-system", 0) == 0)) {
+ cmHasLiteralPrefix(arg, "--check-build-system")) {
this->CheckBuildSystemArgument = args[++i];
this->ClearBuildSystem = (atoi(args[++i].c_str()) > 0);
} else if ((i < args.size() - 1) &&
- (arg.find("--check-stamp-file", 0) == 0)) {
+ cmHasLiteralPrefix(arg, "--check-stamp-file")) {
this->CheckStampFile = args[++i];
} else if ((i < args.size() - 1) &&
- (arg.find("--check-stamp-list", 0) == 0)) {
+ cmHasLiteralPrefix(arg, "--check-stamp-list")) {
this->CheckStampList = args[++i];
+ } else if (arg == "--regenerate-during-build"_s) {
+ this->RegenerateDuringBuild = true;
}
#if defined(CMAKE_HAVE_VS_GENERATORS)
else if ((i < args.size() - 1) &&
- (arg.find("--vs-solution-file", 0) == 0)) {
+ cmHasLiteralPrefix(arg, "--vs-solution-file")) {
this->VSSolutionFile = args[++i];
}
#endif
- else if (arg.find("-D", 0) == 0) {
+ else if (cmHasLiteralPrefix(arg, "-D") || cmHasLiteralPrefix(arg, "-U") ||
+ cmHasLiteralPrefix(arg, "-C")) {
// skip for now
- // in case '-D var=val' is given, also skip the next
- // in case '-Dvar=val' is given, don't skip the next
+ // in case '-[DUC] argval' var' is given, also skip the next
+ // in case '-[DUC]argval' is given, don't skip the next
if (arg.size() == 2) {
++i;
}
- } else if (arg.find("-U", 0) == 0) {
- // skip for now
- // in case '-U var' is given, also skip the next
- // in case '-Uvar' is given, don't skip the next
- if (arg.size() == 2) {
- ++i;
- }
- } else if (arg.find("-C", 0) == 0) {
- // skip for now
- // in case '-C path' is given, also skip the next
- // in case '-Cpath' is given, don't skip the next
- if (arg.size() == 2) {
- ++i;
- }
- } else if (arg.find("-P", 0) == 0) {
+ // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
+ // NOLINTNEXTLINE(bugprone-branch-clone)
+ } else if (cmHasLiteralPrefix(arg, "-P")) {
// skip for now
i++;
- } else if (arg.find("--find-package", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "--find-package")) {
// skip for now
i++;
- } else if (arg.find("-W", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "-W")) {
// skip for now
- } else if (arg.find("--graphviz=", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "--graphviz=")) {
std::string path = arg.substr(strlen("--graphviz="));
path = cmSystemTools::CollapseFullPath(path);
cmSystemTools::ConvertToUnixSlashes(path);
@@ -721,13 +716,13 @@ void cmake::SetArgs(const std::vector<std::string>& args)
cmSystemTools::Error("No file specified for --graphviz");
return;
}
- } else if (arg.find("--debug-trycompile", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "--debug-trycompile")) {
std::cout << "debug trycompile on\n";
this->DebugTryCompileOn();
- } else if (arg.find("--debug-output", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "--debug-output")) {
std::cout << "Running with debug output on.\n";
this->SetDebugOutputOn(true);
- } else if (arg.find("--log-level=", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "--log-level=")) {
const auto logLevel =
StringToLogLevel(arg.substr(sizeof("--log-level=") - 1));
if (logLevel == LogLevel::LOG_UNDEFINED) {
@@ -735,7 +730,8 @@ void cmake::SetArgs(const std::vector<std::string>& args)
return;
}
this->SetLogLevel(logLevel);
- } else if (arg.find("--loglevel=", 0) == 0) {
+ this->LogLevelWasSetViaCLI = true;
+ } else if (cmHasLiteralPrefix(arg, "--loglevel=")) {
// This is supported for backward compatibility. This option only
// appeared in the 3.15.x release series and was renamed to
// --log-level in 3.16.0
@@ -746,39 +742,55 @@ void cmake::SetArgs(const std::vector<std::string>& args)
return;
}
this->SetLogLevel(logLevel);
- } else if (arg.find("--trace-expand", 0) == 0) {
+ this->LogLevelWasSetViaCLI = true;
+ } else if (arg == "--log-context"_s) {
+ this->SetShowLogContext(true);
+ } else if (cmHasLiteralPrefix(arg, "--debug-find")) {
+ std::cout << "Running with debug output on for the `find` commands.\n";
+ this->SetDebugFindOutputOn(true);
+ } else if (cmHasLiteralPrefix(arg, "--trace-expand")) {
std::cout << "Running with expanded trace output on.\n";
this->SetTrace(true);
this->SetTraceExpand(true);
- } else if (arg.find("--trace-source=", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "--trace-format=")) {
+ this->SetTrace(true);
+ const auto traceFormat =
+ StringToTraceFormat(arg.substr(strlen("--trace-format=")));
+ if (traceFormat == TraceFormat::TRACE_UNDEFINED) {
+ cmSystemTools::Error("Invalid format specified for --trace-format. "
+ "Valid formats are human, json-v1.");
+ return;
+ }
+ this->SetTraceFormat(traceFormat);
+ } else if (cmHasLiteralPrefix(arg, "--trace-source=")) {
std::string file = arg.substr(strlen("--trace-source="));
cmSystemTools::ConvertToUnixSlashes(file);
this->AddTraceSource(file);
this->SetTrace(true);
- } else if (arg.find("--trace-redirect=", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "--trace-redirect=")) {
std::string file = arg.substr(strlen("--trace-redirect="));
cmSystemTools::ConvertToUnixSlashes(file);
this->SetTraceFile(file);
this->SetTrace(true);
- } else if (arg.find("--trace", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "--trace")) {
std::cout << "Running with trace output on.\n";
this->SetTrace(true);
this->SetTraceExpand(false);
- } else if (arg.find("--warn-uninitialized", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "--warn-uninitialized")) {
std::cout << "Warn about uninitialized values.\n";
this->SetWarnUninitialized(true);
- } else if (arg.find("--warn-unused-vars", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "--warn-unused-vars")) {
std::cout << "Finding unused variables.\n";
this->SetWarnUnused(true);
- } else if (arg.find("--no-warn-unused-cli", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "--no-warn-unused-cli")) {
std::cout << "Not searching for unused variables given on the "
<< "command line.\n";
this->SetWarnUnusedCli(false);
- } else if (arg.find("--check-system-vars", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "--check-system-vars")) {
std::cout << "Also check system files when warning about unused and "
<< "uninitialized variables.\n";
this->SetCheckSystemVars(true);
- } else if (arg.find("-A", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "-A")) {
std::string value = arg.substr(2);
if (value.empty()) {
++i;
@@ -794,7 +806,7 @@ void cmake::SetArgs(const std::vector<std::string>& args)
}
this->SetGeneratorPlatform(value);
havePlatform = true;
- } else if (arg.find("-T", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "-T")) {
std::string value = arg.substr(2);
if (value.empty()) {
++i;
@@ -810,7 +822,7 @@ void cmake::SetArgs(const std::vector<std::string>& args)
}
this->SetGeneratorToolset(value);
haveToolset = true;
- } else if (arg.find("-G", 0) == 0) {
+ } else if (cmHasLiteralPrefix(arg, "-G")) {
std::string value = arg.substr(2);
if (value.empty()) {
++i;
@@ -821,7 +833,7 @@ void cmake::SetArgs(const std::vector<std::string>& args)
}
value = args[i];
}
- cmGlobalGenerator* gen = this->CreateGlobalGenerator(value);
+ auto gen = this->CreateGlobalGenerator(value);
if (!gen) {
std::string kdevError;
if (value.find("KDevelop3", 0) != std::string::npos) {
@@ -833,7 +845,21 @@ void cmake::SetArgs(const std::vector<std::string>& args)
this->PrintGeneratorList();
return;
}
- this->SetGlobalGenerator(gen);
+ this->SetGlobalGenerator(std::move(gen));
+#if !defined(CMAKE_BOOTSTRAP)
+ } else if (cmHasLiteralPrefix(arg, "--profiling-format")) {
+ profilingFormat = arg.substr(strlen("--profiling-format="));
+ if (profilingFormat.empty()) {
+ cmSystemTools::Error("No format specified for --profiling-format");
+ }
+ } else if (cmHasLiteralPrefix(arg, "--profiling-output")) {
+ profilingOutput = arg.substr(strlen("--profiling-output="));
+ profilingOutput = cmSystemTools::CollapseFullPath(profilingOutput);
+ cmSystemTools::ConvertToUnixSlashes(profilingOutput);
+ if (profilingOutput.empty()) {
+ cmSystemTools::Error("No path specified for --profiling-output");
+ }
+#endif
}
// no option assume it is the path to the source or an existing build
else {
@@ -851,6 +877,29 @@ void cmake::SetArgs(const std::vector<std::string>& args)
}
}
+#if !defined(CMAKE_BOOTSTRAP)
+ if (!profilingOutput.empty() || !profilingFormat.empty()) {
+ if (profilingOutput.empty()) {
+ cmSystemTools::Error(
+ "--profiling-format specified but no --profiling-output!");
+ return;
+ }
+ if (profilingFormat == "google-trace"_s) {
+ try {
+ this->ProfilingOutput =
+ cm::make_unique<cmMakefileProfilingData>(profilingOutput);
+ } catch (std::runtime_error& e) {
+ cmSystemTools::Error(
+ cmStrCat("Could not start profiling: ", e.what()));
+ return;
+ }
+ } else {
+ cmSystemTools::Error("Invalid format specified for --profiling-format");
+ return;
+ }
+ }
+#endif
+
const bool haveSourceDir = !this->GetHomeDirectory().empty();
const bool haveBinaryDir = !this->GetHomeOutputDirectory().empty();
@@ -890,6 +939,23 @@ cmake::LogLevel cmake::StringToLogLevel(const std::string& levelStr)
return (it != levels.cend()) ? it->second : LogLevel::LOG_UNDEFINED;
}
+cmake::TraceFormat cmake::StringToTraceFormat(const std::string& traceStr)
+{
+ using TracePair = std::pair<std::string, TraceFormat>;
+ static const std::vector<TracePair> levels = {
+ { "human", TraceFormat::TRACE_HUMAN },
+ { "json-v1", TraceFormat::TRACE_JSON_V1 },
+ };
+
+ const auto traceStrLowCase = cmSystemTools::LowerCase(traceStr);
+
+ const auto it = std::find_if(levels.cbegin(), levels.cend(),
+ [&traceStrLowCase](const TracePair& p) {
+ return p.first == traceStrLowCase;
+ });
+ return (it != levels.cend()) ? it->second : TraceFormat::TRACE_UNDEFINED;
+}
+
void cmake::SetTraceFile(const std::string& file)
{
this->TraceFile.close();
@@ -904,6 +970,48 @@ void cmake::SetTraceFile(const std::string& file)
std::cout << "Trace will be written to " << file << "\n";
}
+void cmake::PrintTraceFormatVersion()
+{
+ if (!this->GetTrace()) {
+ return;
+ }
+
+ std::string msg;
+
+ switch (this->GetTraceFormat()) {
+ case TraceFormat::TRACE_JSON_V1: {
+#ifndef CMAKE_BOOTSTRAP
+ Json::Value val;
+ Json::Value version;
+ Json::StreamWriterBuilder builder;
+ builder["indentation"] = "";
+ version["major"] = 1;
+ version["minor"] = 0;
+ val["version"] = version;
+ msg = Json::writeString(builder, val);
+#endif
+ break;
+ }
+ case TraceFormat::TRACE_HUMAN:
+ msg = "";
+ break;
+ case TraceFormat::TRACE_UNDEFINED:
+ msg = "INTERNAL ERROR: Trace format is TRACE_UNDEFINED";
+ break;
+ }
+
+ if (msg.empty()) {
+ return;
+ }
+
+ auto& f = this->GetTraceFile();
+ if (f) {
+ f << msg << '\n';
+ } else {
+ cmSystemTools::Message(msg);
+ }
+}
+
void cmake::SetDirectoriesFromFile(const std::string& arg)
{
// Check if the argument refers to a CMakeCache.txt or
@@ -927,9 +1035,9 @@ void cmake::SetDirectoriesFromFile(const std::string& arg)
std::string fullPath = cmSystemTools::CollapseFullPath(arg);
std::string name = cmSystemTools::GetFilenameName(fullPath);
name = cmSystemTools::LowerCase(name);
- if (name == "cmakecache.txt") {
+ if (name == "cmakecache.txt"_s) {
cachePath = cmSystemTools::GetFilenamePath(fullPath);
- } else if (name == "cmakelists.txt") {
+ } else if (name == "cmakelists.txt"_s) {
listPath = cmSystemTools::GetFilenamePath(fullPath);
}
} else {
@@ -938,7 +1046,7 @@ void cmake::SetDirectoriesFromFile(const std::string& arg)
std::string fullPath = cmSystemTools::CollapseFullPath(arg);
std::string name = cmSystemTools::GetFilenameName(fullPath);
name = cmSystemTools::LowerCase(name);
- if (name == "cmakecache.txt" || name == "cmakelists.txt") {
+ if (name == "cmakecache.txt"_s || name == "cmakelists.txt"_s) {
argIsFile = true;
listPath = cmSystemTools::GetFilenamePath(fullPath);
} else {
@@ -949,11 +1057,11 @@ void cmake::SetDirectoriesFromFile(const std::string& arg)
// If there is a CMakeCache.txt file, use its settings.
if (!cachePath.empty()) {
if (this->LoadCache(cachePath)) {
- const char* existingValue =
+ cmProp existingValue =
this->State->GetCacheEntryValue("CMAKE_HOME_DIRECTORY");
if (existingValue) {
this->SetHomeOutputDirectory(cachePath);
- this->SetHomeDirectory(existingValue);
+ this->SetHomeDirectory(*existingValue);
return;
}
}
@@ -1042,11 +1150,11 @@ void cmake::AddDefaultExtraGenerators()
void cmake::GetRegisteredGenerators(std::vector<GeneratorInfo>& generators,
bool includeNamesWithPlatform) const
{
- for (cmGlobalGeneratorFactory* gen : this->Generators) {
+ for (const auto& gen : this->Generators) {
std::vector<std::string> names = gen->GetGeneratorNames();
if (includeNamesWithPlatform) {
- cmAppend(names, gen->GetGeneratorNamesWithPlatform());
+ cm::append(names, gen->GetGeneratorNamesWithPlatform());
}
for (std::string const& name : names) {
@@ -1091,7 +1199,8 @@ void cmake::GetRegisteredGenerators(std::vector<GeneratorInfo>& generators,
}
}
-static std::pair<cmExternalMakefileProjectGenerator*, std::string>
+static std::pair<std::unique_ptr<cmExternalMakefileProjectGenerator>,
+ std::string>
createExtraGenerator(
const std::vector<cmExternalMakefileProjectGeneratorFactory*>& in,
const std::string& name)
@@ -1114,15 +1223,17 @@ createExtraGenerator(
return { nullptr, name };
}
-cmGlobalGenerator* cmake::CreateGlobalGenerator(const std::string& gname)
+std::unique_ptr<cmGlobalGenerator> cmake::CreateGlobalGenerator(
+ const std::string& gname)
{
- std::pair<cmExternalMakefileProjectGenerator*, std::string> extra =
- createExtraGenerator(this->ExtraGenerators, gname);
- cmExternalMakefileProjectGenerator* extraGenerator = extra.first;
- const std::string name = extra.second;
+ std::pair<std::unique_ptr<cmExternalMakefileProjectGenerator>, std::string>
+ extra = createExtraGenerator(this->ExtraGenerators, gname);
+ std::unique_ptr<cmExternalMakefileProjectGenerator>& extraGenerator =
+ extra.first;
+ const std::string& name = extra.second;
- cmGlobalGenerator* generator = nullptr;
- for (cmGlobalGeneratorFactory* g : this->Generators) {
+ std::unique_ptr<cmGlobalGenerator> generator;
+ for (const auto& g : this->Generators) {
generator = g->CreateGlobalGenerator(name, this);
if (generator) {
break;
@@ -1130,9 +1241,7 @@ cmGlobalGenerator* cmake::CreateGlobalGenerator(const std::string& gname)
}
if (generator) {
- generator->SetExternalMakefileProjectGenerator(extraGenerator);
- } else {
- delete extraGenerator;
+ generator->SetExternalMakefileProjectGenerator(std::move(extraGenerator));
}
return generator;
@@ -1184,15 +1293,13 @@ std::string cmake::FindCacheFile(const std::string& binaryDir)
return cachePath;
}
-void cmake::SetGlobalGenerator(cmGlobalGenerator* gg)
+void cmake::SetGlobalGenerator(std::unique_ptr<cmGlobalGenerator> gg)
{
if (!gg) {
cmSystemTools::Error("Error SetGlobalGenerator called with null");
return;
}
- // delete the old generator
if (this->GlobalGenerator) {
- delete this->GlobalGenerator;
// restore the original environment variables CXX and CC
// Restore CC
std::string env = "CC=";
@@ -1208,7 +1315,7 @@ void cmake::SetGlobalGenerator(cmGlobalGenerator* gg)
}
// set the new
- this->GlobalGenerator = gg;
+ this->GlobalGenerator = std::move(gg);
// set the global flag for unix style paths on cmSystemTools as soon as
// the generator is set. This allows gmake to be used on windows.
@@ -1297,12 +1404,12 @@ int cmake::HandleDeleteCacheVariables(const std::string& var)
i++;
save.value = *i;
warning << *i << "\n";
- const char* existingValue = this->State->GetCacheEntryValue(save.key);
+ cmProp existingValue = this->State->GetCacheEntryValue(save.key);
if (existingValue) {
save.type = this->State->GetCacheEntryType(save.key);
- if (const char* help =
+ if (cmProp help =
this->State->GetCacheEntryProperty(save.key, "HELPSTRING")) {
- save.help = help;
+ save.help = *help;
}
}
saved.push_back(std::move(save));
@@ -1347,9 +1454,9 @@ int cmake::Configure()
if (this->DiagLevels.count("dev") == 1) {
bool setDeprecatedVariables = false;
- const char* cachedWarnDeprecated =
+ cmProp cachedWarnDeprecated =
this->State->GetCacheEntryValue("CMAKE_WARN_DEPRECATED");
- const char* cachedErrorDeprecated =
+ cmProp cachedErrorDeprecated =
this->State->GetCacheEntryValue("CMAKE_ERROR_DEPRECATED");
// don't overwrite deprecated warning setting from a previous invocation
@@ -1388,23 +1495,23 @@ int cmake::Configure()
// Cache variables may have already been set by a previous invocation,
// so we cannot rely on command line options alone. Always ensure our
// messenger is in sync with the cache.
- const char* value = this->State->GetCacheEntryValue("CMAKE_WARN_DEPRECATED");
- this->Messenger->SetSuppressDeprecatedWarnings(value && cmIsOff(value));
+ cmProp value = this->State->GetCacheEntryValue("CMAKE_WARN_DEPRECATED");
+ this->Messenger->SetSuppressDeprecatedWarnings(value && cmIsOff(*value));
value = this->State->GetCacheEntryValue("CMAKE_ERROR_DEPRECATED");
- this->Messenger->SetDeprecatedWarningsAsErrors(cmIsOn(value));
+ this->Messenger->SetDeprecatedWarningsAsErrors(value && cmIsOn(*value));
value = this->State->GetCacheEntryValue("CMAKE_SUPPRESS_DEVELOPER_WARNINGS");
- this->Messenger->SetSuppressDevWarnings(cmIsOn(value));
+ this->Messenger->SetSuppressDevWarnings(value && cmIsOn(*value));
value = this->State->GetCacheEntryValue("CMAKE_SUPPRESS_DEVELOPER_ERRORS");
- this->Messenger->SetDevWarningsAsErrors(value && cmIsOff(value));
+ this->Messenger->SetDevWarningsAsErrors(value && cmIsOff(*value));
int ret = this->ActualConfigure();
- const char* delCacheVars =
+ cmProp delCacheVars =
this->State->GetGlobalProperty("__CMAKE_DELETE_CACHE_CHANGE_VARS_");
- if (delCacheVars && delCacheVars[0] != 0) {
- return this->HandleDeleteCacheVariables(delCacheVars);
+ if (delCacheVars && !delCacheVars->empty()) {
+ return this->HandleDeleteCacheVariables(*delCacheVars);
}
return ret;
}
@@ -1429,9 +1536,8 @@ int cmake::ActualConfigure()
// no generator specified on the command line
if (!this->GlobalGenerator) {
- const std::string* genName =
- this->State->GetInitializedCacheValue("CMAKE_GENERATOR");
- const std::string* extraGenName =
+ cmProp genName = this->State->GetInitializedCacheValue("CMAKE_GENERATOR");
+ cmProp extraGenName =
this->State->GetInitializedCacheValue("CMAKE_EXTRA_GENERATOR");
if (genName) {
std::string fullName =
@@ -1454,8 +1560,7 @@ int cmake::ActualConfigure()
}
}
- const std::string* genName =
- this->State->GetInitializedCacheValue("CMAKE_GENERATOR");
+ cmProp genName = this->State->GetInitializedCacheValue("CMAKE_GENERATOR");
if (genName) {
if (!this->GlobalGenerator->MatchesGeneratorName(*genName)) {
std::string message =
@@ -1477,7 +1582,7 @@ int cmake::ActualConfigure()
cmStateEnums::INTERNAL);
}
- if (const std::string* instance =
+ if (cmProp instance =
this->State->GetInitializedCacheValue("CMAKE_GENERATOR_INSTANCE")) {
if (this->GeneratorInstanceSet && this->GeneratorInstance != *instance) {
std::string message =
@@ -1494,7 +1599,7 @@ int cmake::ActualConfigure()
"Generator instance identifier.", cmStateEnums::INTERNAL);
}
- if (const std::string* platformName =
+ if (cmProp platformName =
this->State->GetInitializedCacheValue("CMAKE_GENERATOR_PLATFORM")) {
if (this->GeneratorPlatformSet &&
this->GeneratorPlatform != *platformName) {
@@ -1512,7 +1617,7 @@ int cmake::ActualConfigure()
"Name of generator platform.", cmStateEnums::INTERNAL);
}
- if (const std::string* tsName =
+ if (cmProp tsName =
this->State->GetInitializedCacheValue("CMAKE_GENERATOR_TOOLSET")) {
if (this->GeneratorToolsetSet && this->GeneratorToolset != *tsName) {
std::string message =
@@ -1571,7 +1676,7 @@ int cmake::ActualConfigure()
}
}
- cmMakefile* mf = this->GlobalGenerator->GetMakefiles()[0];
+ auto& mf = this->GlobalGenerator->GetMakefiles()[0];
if (mf->IsOn("CTEST_USE_LAUNCHERS") &&
!this->State->GetGlobalProperty("RULE_LAUNCH_COMPILE")) {
cmSystemTools::Error(
@@ -1592,13 +1697,12 @@ int cmake::ActualConfigure()
std::unique_ptr<cmGlobalGenerator> cmake::EvaluateDefaultGlobalGenerator()
{
if (!this->EnvironmentGenerator.empty()) {
- cmGlobalGenerator* gen =
- this->CreateGlobalGenerator(this->EnvironmentGenerator);
+ auto gen = this->CreateGlobalGenerator(this->EnvironmentGenerator);
if (!gen) {
cmSystemTools::Error("CMAKE_GENERATOR was set but the specified "
"generator doesn't exist. Using CMake default.");
} else {
- return std::unique_ptr<cmGlobalGenerator>(gen);
+ return gen;
}
}
#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(CMAKE_BOOT_MINGW)
@@ -1648,13 +1752,14 @@ std::unique_ptr<cmGlobalGenerator> cmake::EvaluateDefaultGlobalGenerator()
}
}
}
- cmGlobalGenerator* gen = this->CreateGlobalGenerator(found);
+ auto gen = this->CreateGlobalGenerator(found);
if (!gen) {
- gen = new cmGlobalNMakeMakefileGenerator(this);
+ gen = cm::make_unique<cmGlobalNMakeMakefileGenerator>(this);
}
- return std::unique_ptr<cmGlobalGenerator>(gen);
+ return std::unique_ptr<cmGlobalGenerator>(std::move(gen));
#else
- return cm::make_unique<cmGlobalUnixMakefileGenerator3>(this);
+ return std::unique_ptr<cmGlobalGenerator>(
+ cm::make_unique<cmGlobalUnixMakefileGenerator3>(this));
#endif
}
@@ -1665,7 +1770,7 @@ void cmake::CreateDefaultGlobalGenerator()
// This print could be unified for all platforms
std::cout << "-- Building for: " << gen->GetName() << "\n";
#endif
- this->SetGlobalGenerator(gen.release());
+ this->SetGlobalGenerator(std::move(gen));
}
void cmake::PreLoadCMakeFiles()
@@ -1696,6 +1801,11 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure)
return -1;
}
+ // Log the trace format version to the desired output
+ if (this->GetTrace()) {
+ this->PrintTraceFormatVersion();
+ }
+
// If we are given a stamp list file check if it is really out of date.
if (!this->CheckStampList.empty() &&
cmakeCheckStampList(this->CheckStampList)) {
@@ -1763,10 +1873,11 @@ int cmake::Run(const std::vector<std::string>& args, bool noconfigure)
cmSystemTools::Message("CMake Configure step failed. "
"Build files cannot be regenerated correctly. "
"Attempting to stop IDE build.");
- cmGlobalVisualStudioGenerator* gg =
- static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator);
- gg->CallVisualStudioMacro(cmGlobalVisualStudioGenerator::MacroStop,
- this->VSSolutionFile);
+ cmGlobalVisualStudioGenerator& gg =
+ cm::static_reference_cast<cmGlobalVisualStudioGenerator>(
+ this->GlobalGenerator);
+ gg.CallVisualStudioMacro(cmGlobalVisualStudioGenerator::MacroStop,
+ this->VSSolutionFile);
}
#endif
return ret;
@@ -1821,13 +1932,13 @@ void cmake::AddCacheEntry(const std::string& key, const char* value,
cmStateEnums::CacheEntryType(type));
this->UnwatchUnusedCli(key);
- if (key == "CMAKE_WARN_DEPRECATED") {
+ if (key == "CMAKE_WARN_DEPRECATED"_s) {
this->Messenger->SetSuppressDeprecatedWarnings(value && cmIsOff(value));
- } else if (key == "CMAKE_ERROR_DEPRECATED") {
+ } else if (key == "CMAKE_ERROR_DEPRECATED"_s) {
this->Messenger->SetDeprecatedWarningsAsErrors(cmIsOn(value));
- } else if (key == "CMAKE_SUPPRESS_DEVELOPER_WARNINGS") {
+ } else if (key == "CMAKE_SUPPRESS_DEVELOPER_WARNINGS"_s) {
this->Messenger->SetSuppressDevWarnings(cmIsOn(value));
- } else if (key == "CMAKE_SUPPRESS_DEVELOPER_ERRORS") {
+ } else if (key == "CMAKE_SUPPRESS_DEVELOPER_ERRORS"_s) {
this->Messenger->SetDevWarningsAsErrors(value && cmIsOff(value));
}
}
@@ -1863,9 +1974,10 @@ std::string cmake::StripExtension(const std::string& file) const
{
auto dotpos = file.rfind('.');
if (dotpos != std::string::npos) {
- auto ext = file.substr(dotpos + 1);
#if defined(_WIN32) || defined(__APPLE__)
- ext = cmSystemTools::LowerCase(ext);
+ auto ext = cmSystemTools::LowerCase(file.substr(dotpos + 1));
+#else
+ auto ext = cm::string_view(file).substr(dotpos + 1);
#endif
if (this->IsSourceExtension(ext) || this->IsHeaderExtension(ext)) {
return file.substr(0, dotpos);
@@ -1876,7 +1988,7 @@ std::string cmake::StripExtension(const std::string& file) const
const char* cmake::GetCacheDefinition(const std::string& name) const
{
- const std::string* p = this->State->GetInitializedCacheValue(name);
+ cmProp p = this->State->GetInitializedCacheValue(name);
return p ? p->c_str() : nullptr;
}
@@ -1916,6 +2028,7 @@ void cmake::AddDefaultGenerators()
this->Generators.push_back(cmGlobalGhsMultiGenerator::NewFactory());
# endif
this->Generators.push_back(cmGlobalNinjaGenerator::NewFactory());
+ this->Generators.push_back(cmGlobalNinjaMultiGenerator::NewFactory());
#endif
#if defined(CMAKE_USE_WMAKE)
this->Generators.push_back(cmGlobalWatcomWMakeGenerator::NewFactory());
@@ -2021,7 +2134,7 @@ void cmake::AppendGlobalGeneratorsDocumentation(
const std::string defaultName = defaultGenerator->GetName();
bool foundDefaultOne = false;
- for (cmGlobalGeneratorFactory* g : this->Generators) {
+ for (const auto& g : this->Generators) {
cmDocumentationEntry e;
g->GetDocumentation(e);
if (!foundDefaultOne && cmHasPrefix(e.Name, defaultName)) {
@@ -2082,7 +2195,7 @@ void cmake::PrintGeneratorList()
void cmake::UpdateConversionPathTable()
{
// Update the path conversion table with any specified file:
- const std::string* tablepath =
+ cmProp tablepath =
this->State->GetInitializedCacheValue("CMAKE_PATH_TRANSLATION_FILE");
if (tablepath) {
@@ -2161,12 +2274,12 @@ int cmake::CheckBuildSystem()
}
// Create the generator and use it to clear the dependencies.
- std::unique_ptr<cmGlobalGenerator> ggd(
- this->CreateGlobalGenerator(genName));
+ std::unique_ptr<cmGlobalGenerator> ggd =
+ this->CreateGlobalGenerator(genName);
if (ggd) {
cm.GetCurrentSnapshot().SetDefaultDefinitions();
cmMakefile mfd(ggd.get(), cm.GetCurrentSnapshot());
- std::unique_ptr<cmLocalGenerator> lgd(ggd->CreateLocalGenerator(&mfd));
+ auto lgd = ggd->CreateLocalGenerator(&mfd);
lgd->ClearDependencies(&mfd, verbose);
}
}
@@ -2287,7 +2400,7 @@ void cmake::MarkCliAsUsed(const std::string& variable)
void cmake::GenerateGraphViz(const std::string& fileName) const
{
#ifndef CMAKE_BOOTSTRAP
- cmGraphVizWriter gvWriter(this->GetGlobalGenerator());
+ cmGraphVizWriter gvWriter(fileName, this->GetGlobalGenerator());
std::string settingsFile =
cmStrCat(this->GetHomeOutputDirectory(), "/CMakeGraphVizOptions.cmake");
@@ -2295,9 +2408,8 @@ void cmake::GenerateGraphViz(const std::string& fileName) const
cmStrCat(this->GetHomeDirectory(), "/CMakeGraphVizOptions.cmake");
gvWriter.ReadSettings(settingsFile, fallbackSettingsFile);
- gvWriter.WritePerTargetFiles(fileName);
- gvWriter.WriteTargetDependersFiles(fileName);
- gvWriter.WriteGlobalFile(fileName);
+
+ gvWriter.Write();
#endif
}
@@ -2307,13 +2419,13 @@ void cmake::SetProperty(const std::string& prop, const char* value)
this->State->SetGlobalProperty(prop, value);
}
-void cmake::AppendProperty(const std::string& prop, const char* value,
+void cmake::AppendProperty(const std::string& prop, const std::string& value,
bool asString)
{
this->State->AppendGlobalProperty(prop, value, asString);
}
-const char* cmake::GetProperty(const std::string& prop)
+cmProp cmake::GetProperty(const std::string& prop)
{
return this->State->GetGlobalProperty(prop);
}
@@ -2365,7 +2477,7 @@ int cmake::GetSystemInformation(std::vector<std::string>& args)
bool writeToStdout = true;
for (unsigned int i = 1; i < args.size(); ++i) {
std::string const& arg = args[i];
- if (arg.find("-G", 0) == 0) {
+ if (cmHasLiteralPrefix(arg, "-G")) {
std::string value = arg.substr(2);
if (value.empty()) {
++i;
@@ -2376,12 +2488,12 @@ int cmake::GetSystemInformation(std::vector<std::string>& args)
}
value = args[i];
}
- cmGlobalGenerator* gen = this->CreateGlobalGenerator(value);
+ auto gen = this->CreateGlobalGenerator(value);
if (!gen) {
cmSystemTools::Error("Could not create named generator " + value);
this->PrintGeneratorList();
} else {
- this->SetGlobalGenerator(gen);
+ this->SetGlobalGenerator(std::move(gen));
}
}
// no option assume it is the output file
@@ -2554,10 +2666,10 @@ void cmake::IssueMessage(MessageType t, std::string const& text,
std::vector<std::string> cmake::GetDebugConfigs()
{
std::vector<std::string> configs;
- if (const char* config_list =
+ if (cmProp config_list =
this->State->GetGlobalProperty("DEBUG_CONFIGURATIONS")) {
// Expand the specified list and convert to upper-case.
- cmExpandList(config_list, configs);
+ cmExpandList(*config_list, configs);
std::transform(configs.begin(), configs.end(), configs.begin(),
cmSystemTools::UpperCase);
}
@@ -2587,48 +2699,58 @@ int cmake::Build(int jobs, const std::string& dir,
std::cerr << "Error: could not load cache\n";
return 1;
}
- const char* cachedGenerator =
- this->State->GetCacheEntryValue("CMAKE_GENERATOR");
+ cmProp cachedGenerator = this->State->GetCacheEntryValue("CMAKE_GENERATOR");
if (!cachedGenerator) {
std::cerr << "Error: could not find CMAKE_GENERATOR in Cache\n";
return 1;
}
- cmGlobalGenerator* gen = this->CreateGlobalGenerator(cachedGenerator);
+ auto gen = this->CreateGlobalGenerator(*cachedGenerator);
if (!gen) {
- std::cerr << "Error: could create CMAKE_GENERATOR \"" << cachedGenerator
+ std::cerr << "Error: could create CMAKE_GENERATOR \"" << *cachedGenerator
<< "\"\n";
return 1;
}
- this->SetGlobalGenerator(gen);
- const char* cachedGeneratorInstance =
+ this->SetGlobalGenerator(std::move(gen));
+ cmProp cachedGeneratorInstance =
this->State->GetCacheEntryValue("CMAKE_GENERATOR_INSTANCE");
if (cachedGeneratorInstance) {
- cmMakefile mf(gen, this->GetCurrentSnapshot());
- if (!gen->SetGeneratorInstance(cachedGeneratorInstance, &mf)) {
+ cmMakefile mf(this->GetGlobalGenerator(), this->GetCurrentSnapshot());
+ if (!this->GlobalGenerator->SetGeneratorInstance(*cachedGeneratorInstance,
+ &mf)) {
return 1;
}
}
- const char* cachedGeneratorPlatform =
+ cmProp cachedGeneratorPlatform =
this->State->GetCacheEntryValue("CMAKE_GENERATOR_PLATFORM");
if (cachedGeneratorPlatform) {
- cmMakefile mf(gen, this->GetCurrentSnapshot());
- if (!gen->SetGeneratorPlatform(cachedGeneratorPlatform, &mf)) {
+ cmMakefile mf(this->GetGlobalGenerator(), this->GetCurrentSnapshot());
+ if (!this->GlobalGenerator->SetGeneratorPlatform(*cachedGeneratorPlatform,
+ &mf)) {
+ return 1;
+ }
+ }
+ cmProp cachedGeneratorToolset =
+ this->State->GetCacheEntryValue("CMAKE_GENERATOR_TOOLSET");
+ if (cachedGeneratorToolset) {
+ cmMakefile mf(this->GetGlobalGenerator(), this->GetCurrentSnapshot());
+ if (!this->GlobalGenerator->SetGeneratorToolset(*cachedGeneratorToolset,
+ true, &mf)) {
return 1;
}
}
std::string output;
std::string projName;
- const char* cachedProjectName =
+ cmProp cachedProjectName =
this->State->GetCacheEntryValue("CMAKE_PROJECT_NAME");
if (!cachedProjectName) {
std::cerr << "Error: could not find CMAKE_PROJECT_NAME in Cache\n";
return 1;
}
- projName = cachedProjectName;
+ projName = *cachedProjectName;
- const char* cachedVerbose =
+ cmProp cachedVerbose =
this->State->GetCacheEntryValue("CMAKE_VERBOSE_MAKEFILE");
- if (cmIsOn(cachedVerbose)) {
+ if (cachedVerbose && cmIsOn(*cachedVerbose)) {
verbose = true;
}
@@ -2687,10 +2809,15 @@ int cmake::Build(int jobs, const std::string& dir,
}
#endif
- gen->PrintBuildCommandAdvice(std::cerr, jobs);
- return gen->Build(jobs, "", dir, projName, targets, output, "", config,
- clean, false, verbose, cmDuration::zero(),
- cmSystemTools::OUTPUT_PASSTHROUGH, nativeOptions);
+ if (!this->GlobalGenerator->ReadCacheEntriesForBuild(*this->State)) {
+ return 1;
+ }
+
+ this->GlobalGenerator->PrintBuildCommandAdvice(std::cerr, jobs);
+ return this->GlobalGenerator->Build(
+ jobs, "", dir, projName, targets, output, "", config, clean, false,
+ verbose, cmDuration::zero(), cmSystemTools::OUTPUT_PASSTHROUGH,
+ nativeOptions);
}
bool cmake::Open(const std::string& dir, bool dryRun)
@@ -2707,40 +2834,40 @@ bool cmake::Open(const std::string& dir, bool dryRun)
std::cerr << "Error: could not load cache\n";
return false;
}
- const char* genName = this->State->GetCacheEntryValue("CMAKE_GENERATOR");
+ cmProp genName = this->State->GetCacheEntryValue("CMAKE_GENERATOR");
if (!genName) {
std::cerr << "Error: could not find CMAKE_GENERATOR in Cache\n";
return false;
}
- const std::string* extraGenName =
+ cmProp extraGenName =
this->State->GetInitializedCacheValue("CMAKE_EXTRA_GENERATOR");
std::string fullName =
cmExternalMakefileProjectGenerator::CreateFullGeneratorName(
- genName, extraGenName ? *extraGenName : "");
+ *genName, extraGenName ? *extraGenName : "");
- std::unique_ptr<cmGlobalGenerator> gen(
- this->CreateGlobalGenerator(fullName));
+ std::unique_ptr<cmGlobalGenerator> gen =
+ this->CreateGlobalGenerator(fullName);
if (!gen) {
std::cerr << "Error: could create CMAKE_GENERATOR \"" << fullName
<< "\"\n";
return false;
}
- const char* cachedProjectName =
+ cmProp cachedProjectName =
this->State->GetCacheEntryValue("CMAKE_PROJECT_NAME");
if (!cachedProjectName) {
std::cerr << "Error: could not find CMAKE_PROJECT_NAME in Cache\n";
return false;
}
- return gen->Open(dir, cachedProjectName, dryRun);
+ return gen->Open(dir, *cachedProjectName, dryRun);
}
void cmake::WatchUnusedCli(const std::string& var)
{
#ifndef CMAKE_BOOTSTRAP
this->VariableWatch->AddWatch(var, cmWarnUnusedCliWarning, this);
- if (!cmContains(this->UsedCliVariables, var)) {
+ if (!cm::contains(this->UsedCliVariables, var)) {
this->UsedCliVariables[var] = false;
}
#endif
@@ -2867,3 +2994,15 @@ void cmake::SetDeprecatedWarningsAsErrors(bool b)
" and functions.",
cmStateEnums::INTERNAL);
}
+
+#if !defined(CMAKE_BOOTSTRAP)
+cmMakefileProfilingData& cmake::GetProfilingOutput()
+{
+ return *(this->ProfilingOutput);
+}
+
+bool cmake::IsProfilingEnabled() const
+{
+ return static_cast<bool>(this->ProfilingOutput);
+}
+#endif
diff --git a/Source/cmake.h b/Source/cmake.h
index 687c105..cd152cb 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -5,14 +5,19 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <cstddef>
#include <functional>
#include <map>
#include <memory>
#include <set>
+#include <stack>
#include <string>
#include <unordered_set>
+#include <utility>
#include <vector>
+#include <cm/string_view>
+
#include "cmGeneratedFileStream.h"
#include "cmInstalledFile.h"
#include "cmListFileCache.h"
@@ -22,7 +27,7 @@
#include "cmStateTypes.h"
#if !defined(CMAKE_BOOTSTRAP)
-# include "cm_jsoncpp_value.h"
+# include <cm3p/json/value.h>
#endif
class cmExternalMakefileProjectGeneratorFactory;
@@ -31,6 +36,9 @@ class cmFileTimeCache;
class cmGlobalGenerator;
class cmGlobalGeneratorFactory;
class cmMakefile;
+#if !defined(CMAKE_BOOTSTRAP)
+class cmMakefileProfilingData;
+#endif
class cmMessenger;
class cmVariableWatch;
struct cmDocumentationEntry;
@@ -110,6 +118,14 @@ public:
LOG_TRACE
};
+ /** \brief Define supported trace formats **/
+ enum TraceFormat
+ {
+ TRACE_UNDEFINED,
+ TRACE_HUMAN,
+ TRACE_JSON_V1,
+ };
+
struct GeneratorInfo
{
std::string name;
@@ -124,13 +140,13 @@ public:
struct FileExtensions
{
- bool Test(std::string const& ext) const
+ bool Test(cm::string_view ext) const
{
return (this->unordered.find(ext) != this->unordered.end());
}
std::vector<std::string> ordered;
- std::unordered_set<std::string> unordered;
+ std::unordered_set<cm::string_view> unordered;
};
using InstalledFilesMap = std::map<std::string, cmInstalledFile>;
@@ -202,21 +218,25 @@ public:
void PreLoadCMakeFiles();
//! Create a GlobalGenerator
- cmGlobalGenerator* CreateGlobalGenerator(const std::string& name);
+ std::unique_ptr<cmGlobalGenerator> CreateGlobalGenerator(
+ const std::string& name);
//! Return the global generator assigned to this instance of cmake
- cmGlobalGenerator* GetGlobalGenerator() { return this->GlobalGenerator; }
+ cmGlobalGenerator* GetGlobalGenerator()
+ {
+ return this->GlobalGenerator.get();
+ }
//! Return the global generator assigned to this instance of cmake, const
const cmGlobalGenerator* GetGlobalGenerator() const
{
- return this->GlobalGenerator;
+ return this->GlobalGenerator.get();
}
//! Return the full path to where the CMakeCache.txt file should be.
static std::string FindCacheFile(const std::string& binaryDir);
//! Return the global generator assigned to this instance of cmake
- void SetGlobalGenerator(cmGlobalGenerator*);
+ void SetGlobalGenerator(std::unique_ptr<cmGlobalGenerator>);
//! Get the names of the current registered generators
void GetRegisteredGenerators(std::vector<GeneratorInfo>& generators,
@@ -248,7 +268,7 @@ public:
return this->SourceFileExtensions.ordered;
}
- bool IsSourceExtension(const std::string& ext) const
+ bool IsSourceExtension(cm::string_view ext) const
{
return this->SourceFileExtensions.Test(ext);
}
@@ -258,7 +278,7 @@ public:
return this->HeaderFileExtensions.ordered;
}
- bool IsHeaderExtension(const std::string& ext) const
+ bool IsHeaderExtension(cm::string_view ext) const
{
return this->HeaderFileExtensions.Test(ext);
}
@@ -268,7 +288,7 @@ public:
return this->CudaFileExtensions.ordered;
}
- bool IsCudaExtension(const std::string& ext) const
+ bool IsCudaExtension(cm::string_view ext) const
{
return this->CudaFileExtensions.Test(ext);
}
@@ -278,7 +298,7 @@ public:
return this->FortranFileExtensions.ordered;
}
- bool IsFortranExtension(const std::string& ext) const
+ bool IsFortranExtension(cm::string_view ext) const
{
return this->FortranFileExtensions.Test(ext);
}
@@ -344,9 +364,9 @@ public:
//! Set/Get a property of this target file
void SetProperty(const std::string& prop, const char* value);
- void AppendProperty(const std::string& prop, const char* value,
+ void AppendProperty(const std::string& prop, const std::string& value,
bool asString = false);
- const char* GetProperty(const std::string& prop);
+ cmProp GetProperty(const std::string& prop);
bool GetPropertyAsBool(const std::string& prop);
//! Get or create an cmInstalledFile instance and return a pointer to it
@@ -380,20 +400,52 @@ public:
*/
cmFileTimeCache* GetFileTimeCache() { return this->FileTimeCache.get(); }
+ 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);
+ static TraceFormat StringToTraceFormat(const std::string& levelStr);
+
+ bool HasCheckInProgress() const
+ {
+ return !this->CheckInProgressMessages.empty();
+ }
+ std::size_t GetCheckInProgressSize() const
+ {
+ return this->CheckInProgressMessages.size();
+ }
+ std::string GetTopCheckInProgressMessage()
+ {
+ auto message = this->CheckInProgressMessages.top();
+ this->CheckInProgressMessages.pop();
+ return message;
+ }
+ void PushCheckInProgressMessage(std::string message)
+ {
+ this->CheckInProgressMessages.emplace(std::move(message));
+ }
+
+ //! Should `message` command display context.
+ bool GetShowLogContext() const { return this->LogContext; }
+ void SetShowLogContext(bool b) { this->LogContext = b; }
//! Do we want debug output during the cmake run.
bool GetDebugOutput() { return this->DebugOutput; }
void SetDebugOutputOn(bool b) { this->DebugOutput = b; }
+ //! Do we want debug output from the find commands during the cmake run.
+ bool GetDebugFindOutput() { return this->DebugFindOutput; }
+ void SetDebugFindOutputOn(bool b) { this->DebugFindOutput = b; }
+
//! Do we want trace output during the cmake run.
- bool GetTrace() { return this->Trace; }
+ bool GetTrace() const { return this->Trace; }
void SetTrace(bool b) { this->Trace = b; }
- bool GetTraceExpand() { return this->TraceExpand; }
+ bool GetTraceExpand() const { return this->TraceExpand; }
void SetTraceExpand(bool b) { this->TraceExpand = b; }
+ TraceFormat GetTraceFormat() const { return this->TraceFormatVar; }
+ void SetTraceFormat(TraceFormat f) { this->TraceFormatVar = f; }
void AddTraceSource(std::string const& file)
{
this->TraceOnlyThisSources.push_back(file);
@@ -404,6 +456,7 @@ public:
}
cmGeneratedFileStream& GetTraceFile() { return this->TraceFile; }
void SetTraceFile(std::string const& file);
+ void PrintTraceFormatVersion();
bool GetWarnUninitialized() { return this->WarnUninitialized; }
void SetWarnUninitialized(bool b) { this->WarnUninitialized = b; }
@@ -499,11 +552,19 @@ public:
}
cmStateSnapshot GetCurrentSnapshot() const { return this->CurrentSnapshot; }
+ bool GetRegenerateDuringBuild() const { return this->RegenerateDuringBuild; }
+
+#if !defined(CMAKE_BOOTSTRAP)
+ cmMakefileProfilingData& GetProfilingOutput();
+ bool IsProfilingEnabled() const;
+#endif
+
protected:
void RunCheckForUnusedVariables();
int HandleDeleteCacheVariables(const std::string& var);
- using RegisteredGeneratorsVector = std::vector<cmGlobalGeneratorFactory*>;
+ using RegisteredGeneratorsVector =
+ std::vector<std::unique_ptr<cmGlobalGeneratorFactory>>;
RegisteredGeneratorsVector Generators;
using RegisteredExtraGeneratorsVector =
std::vector<cmExternalMakefileProjectGeneratorFactory*>;
@@ -513,7 +574,6 @@ protected:
void AddDefaultGenerators();
void AddDefaultExtraGenerators();
- cmGlobalGenerator* GlobalGenerator = nullptr;
std::map<std::string, DiagLevel> DiagLevels;
std::string GeneratorInstance;
std::string GeneratorPlatform;
@@ -549,8 +609,10 @@ private:
ProgressCallbackType ProgressCallback;
WorkingMode CurrentWorkingMode = NORMAL_MODE;
bool DebugOutput = false;
+ bool DebugFindOutput = false;
bool Trace = false;
bool TraceExpand = false;
+ TraceFormat TraceFormatVar = TRACE_HUMAN;
cmGeneratedFileStream TraceFile;
bool WarnUninitialized = false;
bool WarnUnused = false;
@@ -571,6 +633,7 @@ private:
FileExtensions FortranFileExtensions;
bool ClearBuildSystem = false;
bool DebugTryCompile = false;
+ bool RegenerateDuringBuild = false;
std::unique_ptr<cmFileTimeCache> FileTimeCache;
std::string GraphVizFile;
InstalledFilesMap InstalledFiles;
@@ -587,6 +650,12 @@ private:
std::vector<std::string> TraceOnlyThisSources;
LogLevel MessageLogLevel = LogLevel::LOG_STATUS;
+ bool LogLevelWasSetViaCLI = false;
+ bool LogContext = false;
+
+ std::stack<std::string> CheckInProgressMessages;
+
+ std::unique_ptr<cmGlobalGenerator> GlobalGenerator;
void UpdateConversionPathTable();
@@ -598,6 +667,10 @@ private:
void AppendGlobalGeneratorsDocumentation(std::vector<cmDocumentationEntry>&);
void AppendExtraGeneratorsDocumentation(std::vector<cmDocumentationEntry>&);
+
+#if !defined(CMAKE_BOOTSTRAP)
+ std::unique_ptr<cmMakefileProfilingData> ProfilingOutput;
+#endif
};
#define CMAKE_STANDARD_OPTIONS_TABLE \
@@ -714,4 +787,11 @@ private:
FOR_EACH_CXX11_FEATURE(F) \
FOR_EACH_CXX14_FEATURE(F)
+#define FOR_EACH_CUDA_FEATURE(F) \
+ F(cuda_std_03) \
+ F(cuda_std_11) \
+ F(cuda_std_14) \
+ F(cuda_std_17) \
+ F(cuda_std_20)
+
#endif
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index 6d3e6ee..b12990b 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -1,7 +1,20 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
-#include "cmAlgorithms.h"
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <cassert>
+#include <cctype>
+#include <climits>
+#include <cstring>
+#include <iostream>
+#include <string>
+#include <vector>
+
+#include <cmext/algorithm>
+
+#include <cm3p/uv.h>
+
#include "cmDocumentationEntry.h" // IWYU pragma: keep
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
@@ -18,20 +31,10 @@
#endif
#include "cmsys/Encoding.hxx"
-
-#include "cm_uv.h"
#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
# include "cmsys/ConsoleBuf.hxx"
#endif
-#include <cassert>
-#include <cctype>
-#include <climits>
-#include <cstring>
-#include <iostream>
-#include <string>
-#include <vector>
-
namespace {
#ifndef CMAKE_BOOTSTRAP
const char* cmDocumentationName[][2] = {
@@ -73,12 +76,15 @@ const char* cmDocumentationOptions[][2] = {
{ "--log-level=<ERROR|WARNING|NOTICE|STATUS|VERBOSE|DEBUG|TRACE>",
"Set the verbosity of messages from CMake files. "
"--loglevel is also accepted for backward compatibility reasons." },
+ { "--log-context", "Prepend log messages with context, if given" },
{ "--debug-trycompile",
"Do not delete the try_compile build tree. Only "
"useful on one try_compile at a time." },
{ "--debug-output", "Put cmake in a debug mode." },
+ { "--debug-find", "Put cmake find in a debug mode." },
{ "--trace", "Put cmake in trace mode." },
{ "--trace-expand", "Put cmake in trace mode with variable expansion." },
+ { "--trace-format=<human|json-v1>", "Set the output format of the trace." },
{ "--trace-source=<file>",
"Trace only this CMake file/module. Multiple options allowed." },
{ "--trace-redirect=<file>",
@@ -89,6 +95,12 @@ const char* cmDocumentationOptions[][2] = {
{ "--check-system-vars",
"Find problems with variable usage in system "
"files." },
+# if !defined(CMAKE_BOOTSTRAP)
+ { "--profiling-format=<fmt>", "Output data for profiling CMake scripts." },
+ { "--profiling-output=<file>",
+ "Select an output path for the profiling data enabled through "
+ "--profiling-format." },
+# endif
{ nullptr, nullptr }
};
@@ -99,7 +111,7 @@ int do_command(int ac, char const* const* av)
std::vector<std::string> args;
args.reserve(ac - 1);
args.emplace_back(av[0]);
- cmAppend(args, av + 2, av + ac);
+ cm::append(args, av + 2, av + ac);
return cmcmd::ExecuteCMakeCommand(args);
}
@@ -282,16 +294,16 @@ int do_cmake(int ac, char const* const* av)
cmStateEnums::CacheEntryType t = cm.GetState()->GetCacheEntryType(k);
if (t != cmStateEnums::INTERNAL && t != cmStateEnums::STATIC &&
t != cmStateEnums::UNINITIALIZED) {
- const char* advancedProp =
+ cmProp advancedProp =
cm.GetState()->GetCacheEntryProperty(k, "ADVANCED");
if (list_all_cached || !advancedProp) {
if (list_help) {
- std::cout << "// "
- << cm.GetState()->GetCacheEntryProperty(k, "HELPSTRING")
- << std::endl;
+ cmProp help =
+ cm.GetState()->GetCacheEntryProperty(k, "HELPSTRING");
+ std::cout << "// " << (help ? *help : "") << std::endl;
}
std::cout << k << ":" << cmState::CacheEntryTypeToString(t) << "="
- << cm.GetState()->GetCacheEntryValue(k) << std::endl;
+ << cm.GetState()->GetSafeCacheEntryValue(k) << std::endl;
if (list_help) {
std::cout << std::endl;
}
@@ -308,6 +320,7 @@ int do_cmake(int ac, char const* const* av)
return 0;
}
+#ifndef CMAKE_BOOTSTRAP
int extract_job_number(int& index, char const* current, char const* next,
int len_of_flag)
{
@@ -337,6 +350,7 @@ int extract_job_number(int& index, char const* current, char const* next,
}
return jobs;
}
+#endif
int do_build(int ac, char const* const* av)
{
@@ -346,7 +360,7 @@ int do_build(int ac, char const* const* av)
#else
int jobs = cmake::NO_BUILD_PARALLEL_LEVEL;
std::vector<std::string> targets;
- std::string config = "Debug";
+ std::string config;
std::string dir;
std::vector<std::string> nativeOptions;
bool cleanFirst = false;
@@ -682,7 +696,6 @@ int main(int ac, char const* const* av)
ac = args.argc();
av = args.argv();
- cmSystemTools::EnableMSVCDebugHook();
cmSystemTools::InitializeLibUV();
cmSystemTools::FindCMakeResources(av[0]);
if (ac > 1) {
diff --git a/Source/cmcldeps.cxx b/Source/cmcldeps.cxx
index caf6453..5c27ac1 100644
--- a/Source/cmcldeps.cxx
+++ b/Source/cmcldeps.cxx
@@ -25,6 +25,7 @@
#include "cmsys/Encoding.hxx"
+#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
// We don't want any wildcard expansion.
@@ -63,7 +64,7 @@ static void usage(const char* msg)
msg);
}
-static std::string trimLeadingSpace(const std::string& cmdline)
+static cm::string_view trimLeadingSpace(cm::string_view cmdline)
{
int i = 0;
for (; cmdline[i] == ' '; ++i)
@@ -81,34 +82,30 @@ static void replaceAll(std::string& str, const std::string& search,
}
}
-bool startsWith(const std::string& str, const std::string& what)
-{
- return str.compare(0, what.size(), what) == 0;
-}
-
// Strips one argument from the cmdline and returns it. "surrounding quotes"
// are removed from the argument if there were any.
static std::string getArg(std::string& cmdline)
{
- std::string ret;
bool in_quoted = false;
unsigned int i = 0;
- cmdline = trimLeadingSpace(cmdline);
+ cm::string_view cmdview = trimLeadingSpace(cmdline);
+ size_t spaceCnt = cmdline.size() - cmdview.size();
for (;; ++i) {
- if (i >= cmdline.size())
+ if (i >= cmdview.size())
usage("Couldn't parse arguments.");
- if (!in_quoted && cmdline[i] == ' ')
+ if (!in_quoted && cmdview[i] == ' ')
break; // "a b" "x y"
- if (cmdline[i] == '"')
+ if (cmdview[i] == '"')
in_quoted = !in_quoted;
}
- ret = cmdline.substr(0, i);
- if (ret[0] == '"' && ret[i - 1] == '"')
- ret = ret.substr(1, ret.size() - 2);
- cmdline = cmdline.substr(i);
+ cmdview = cmdview.substr(0, i);
+ if (cmdview[0] == '"' && cmdview[i - 1] == '"')
+ cmdview = cmdview.substr(1, i - 2);
+ std::string ret(cmdview);
+ cmdline.erase(0, spaceCnt + i);
return ret;
}
@@ -127,7 +124,7 @@ static void parseCommandLine(LPWSTR wincmdline, std::string& lang,
prefix = getArg(cmdline);
clpath = getArg(cmdline);
binpath = getArg(cmdline);
- rest = trimLeadingSpace(cmdline);
+ rest = std::string(trimLeadingSpace(cmdline));
}
// Not all backslashes need to be escaped in a depfile, but it's easier that
@@ -169,8 +166,8 @@ static void outputDepFile(const std::string& dfile, const std::string& objfile,
// build.ninja file. Therefore we need to canonicalize the path to use
// backward slashes and relativize the path to the build directory.
replaceAll(tmp, "/", "\\");
- if (startsWith(tmp, cwd))
- tmp = tmp.substr(cwd.size());
+ if (cmHasPrefix(tmp, cwd))
+ tmp.erase(0, cwd.size());
escapePath(tmp);
fprintf(out, "%s \\\n", tmp.c_str());
}
@@ -194,7 +191,7 @@ std::string replace(const std::string& str, const std::string& what,
return replaced.replace(pos, what.size(), replacement);
}
-static int process(const std::string& srcfilename, const std::string& dfile,
+static int process(cm::string_view srcfilename, const std::string& dfile,
const std::string& objfile, const std::string& prefix,
const std::string& cmd, const std::string& dir = "",
bool quiet = false)
@@ -221,13 +218,14 @@ static int process(const std::string& srcfilename, const std::string& dfile,
std::vector<std::string> includes;
bool isFirstLine = true; // cl prints always first the source filename
while (std::getline(ss, line)) {
- if (startsWith(line, prefix)) {
- std::string inc = trimLeadingSpace(line.substr(prefix.size()).c_str());
+ cm::string_view inc(line);
+ if (cmHasPrefix(inc, prefix)) {
+ inc = trimLeadingSpace(inc.substr(prefix.size()));
if (inc.back() == '\r') // blech, stupid \r\n
inc = inc.substr(0, inc.size() - 1);
- includes.push_back(inc);
+ includes.emplace_back(std::string(inc));
} else {
- if (!isFirstLine || !startsWith(line, srcfilename)) {
+ if (!isFirstLine || !cmHasPrefix(inc, srcfilename)) {
if (!quiet || exit_code != 0) {
fprintf(stdout, "%s\n", line.c_str());
}
@@ -258,14 +256,10 @@ int main()
cl, binpath, rest);
// needed to suppress filename output of msvc tools
- std::string srcfilename;
- {
- std::string::size_type pos = srcfile.rfind('\\');
- if (pos == std::string::npos) {
- srcfilename = srcfile;
- } else {
- srcfilename = srcfile.substr(pos + 1);
- }
+ cm::string_view srcfilename(srcfile);
+ std::string::size_type pos = srcfile.rfind('\\');
+ if (pos != std::string::npos) {
+ srcfilename = srcfilename.substr(pos + 1);
}
std::string nol = " /nologo ";
@@ -286,7 +280,7 @@ int main()
// call cl in object dir so the .i is generated there
std::string objdir;
{
- std::string::size_type pos = objfile.rfind("\\");
+ pos = objfile.rfind("\\");
if (pos != std::string::npos) {
objdir = objfile.substr(0, pos);
}
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index d05e3c8..de76d73 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -2,7 +2,11 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmcmd.h"
-#include "cmAlgorithms.h"
+#include <cmext/algorithm>
+
+#include <cm3p/uv.h>
+#include <fcntl.h>
+
#include "cmDuration.h"
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
@@ -15,22 +19,22 @@
#include "cmStateSnapshot.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmUVProcessChain.h"
#include "cmUtils.hxx"
#include "cmVersion.h"
#include "cmake.h"
#if !defined(CMAKE_BOOTSTRAP)
# include "cmDependsFortran.h" // For -E cmake_copy_f90_mod callback.
+# include "cmFileTime.h"
# include "cmServer.h"
# include "cmServerConnection.h"
+
+# include "bindexplib.h"
#endif
#if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32)
# include "cmsys/ConsoleBuf.hxx"
-
-# include "cmFileTime.h"
-
-# include "bindexplib.h"
#endif
#if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32) && !defined(__CYGWIN__)
@@ -84,6 +88,7 @@ void CMakeCommandUsage(const char* program)
<< "Available commands: \n"
<< " capabilities - Report capabilities built into cmake "
"in JSON format\n"
+ << " cat <files>... - concat the files and print them to the standard output\n"
<< " chdir dir cmd [args...] - run command in a given directory\n"
<< " compare_files [--ignore-eol] file1 file2\n"
<< " - check if file1 is same as file2\n"
@@ -107,10 +112,12 @@ void CMakeCommandUsage(const char* program)
<< " sha384sum <file>... - create SHA384 checksum of files\n"
<< " sha512sum <file>... - create SHA512 checksum of files\n"
<< " remove [-f] <file>... - remove the file(s), use -f to force "
- "it\n"
- << " remove_directory <dir>... - remove directories and their contents\n"
+ "it (deprecated: use rm instead)\n"
+ << " remove_directory <dir>... - remove directories and their contents (deprecated: use rm instead)\n"
<< " rename oldname newname - rename a file or directory "
"(on one volume)\n"
+ << " rm [-rRf] <file/dir>... - remove files or directories, use -f to "
+ "force it, r or R to remove directories and their contents recursively\n"
<< " server - start cmake in server mode\n"
<< " sleep <number>... - sleep for given number of seconds\n"
<< " tar [cxt][vf][zjJ] file.tar [file/dir1 file/dir2 ...]\n"
@@ -172,6 +179,31 @@ static bool cmTarFilesFrom(std::string const& file,
return true;
}
+static void cmCatFile(const std::string& fileToAppend)
+{
+ cmsys::ifstream source(fileToAppend.c_str(),
+ (std::ios::binary | std::ios::in));
+ std::cout << source.rdbuf();
+}
+
+static bool cmRemoveDirectory(const std::string& dir, bool recursive = true)
+{
+ if (cmSystemTools::FileIsSymlink(dir)) {
+ if (!cmSystemTools::RemoveFile(dir)) {
+ std::cerr << "Error removing directory symlink \"" << dir << "\".\n";
+ return false;
+ }
+ } else if (!recursive) {
+ std::cerr << "Error removing directory \"" << dir
+ << "\" without recursive option.\n";
+ return false;
+ } else if (!cmSystemTools::RemoveADirectory(dir)) {
+ std::cerr << "Error removing directory \"" << dir << "\".\n";
+ return false;
+ }
+ return true;
+}
+
static int HandleIWYU(const std::string& runCmd,
const std::string& /* sourceFile */,
const std::vector<std::string>& orig_cmd)
@@ -179,7 +211,7 @@ static int HandleIWYU(const std::string& runCmd,
// Construct the iwyu command line by taking what was given
// and adding all the arguments we give to the compiler.
std::vector<std::string> iwyu_cmd = cmExpandedList(runCmd, true);
- cmAppend(iwyu_cmd, orig_cmd.begin() + 1, orig_cmd.end());
+ cm::append(iwyu_cmd, orig_cmd.begin() + 1, orig_cmd.end());
// Run the iwyu command line. Capture its stderr and hide its stdout.
// Ignore its return code because the tool always returns non-zero.
std::string stdErr;
@@ -210,7 +242,7 @@ static int HandleTidy(const std::string& runCmd, const std::string& sourceFile,
std::vector<std::string> tidy_cmd = cmExpandedList(runCmd, true);
tidy_cmd.push_back(sourceFile);
tidy_cmd.emplace_back("--");
- cmAppend(tidy_cmd, orig_cmd);
+ cm::append(tidy_cmd, orig_cmd);
// Run the tidy command line. Capture its stdout and hide its stderr.
std::string stdOut;
@@ -561,11 +593,11 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
return 0;
}
-#if defined(_WIN32) && !defined(CMAKE_BOOTSTRAP)
- else if (args[1] == "__create_def") {
+#if !defined(CMAKE_BOOTSTRAP)
+ if (args[1] == "__create_def") {
if (args.size() < 4) {
std::cerr << "__create_def Usage: -E __create_def outfile.def "
- "objlistfile [-nm=nm-path]\n";
+ "objlistfile [--nm=nm-path]\n";
return 1;
}
cmsys::ifstream fin(args[3].c_str(), std::ios::in | std::ios::binary);
@@ -592,7 +624,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
return 0;
}
}
- FILE* fout = cmsys::SystemTools::Fopen(args[2].c_str(), "w+");
+ FILE* fout = cmsys::SystemTools::Fopen(args[2], "w+");
if (!fout) {
std::cerr << "could not open output .def file: " << args[2].c_str()
<< "\n";
@@ -652,7 +684,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
} 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::cerr << "cmake -E env: unknown option '" << a << '\''
<< std::endl;
return 1;
} else if (a.find('=') != std::string::npos) {
@@ -706,14 +738,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
bool return_value = false;
for (auto const& arg : cmMakeRange(args).advance(2)) {
if (cmSystemTools::FileIsDirectory(arg)) {
- if (cmSystemTools::FileIsSymlink(arg)) {
- if (!cmSystemTools::RemoveFile(arg)) {
- std::cerr << "Error removing directory symlink \"" << arg
- << "\".\n";
- return_value = true;
- }
- } else if (!cmSystemTools::RemoveADirectory(arg)) {
- std::cerr << "Error removing directory \"" << arg << "\".\n";
+ if (!cmRemoveDirectory(arg)) {
return_value = true;
}
}
@@ -739,6 +764,65 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
return 0;
}
+ // Remove directories or files with rm
+ if (args[1] == "rm" && args.size() > 2) {
+ // If an error occurs, we want to continue removing the remaining
+ // files/directories.
+ int return_value = 0;
+ bool force = false;
+ bool recursive = false;
+ bool doing_options = true;
+ bool at_least_one_file = false;
+ for (auto const& arg : cmMakeRange(args).advance(2)) {
+ if (doing_options && cmHasLiteralPrefix(arg, "-")) {
+ if (arg == "--") {
+ doing_options = false;
+ }
+ if (arg.find('f') != std::string::npos) {
+ force = true;
+ }
+ if (arg.find_first_of("rR") != std::string::npos) {
+ recursive = true;
+ }
+ if (arg.find_first_not_of("-frR") != std::string::npos) {
+ cmSystemTools::Error("Unknown -E rm argument: " + arg);
+ return 1;
+ }
+ } else {
+ if (arg.empty()) {
+ continue;
+ }
+ at_least_one_file = true;
+ // Complain if the -f option was not given and
+ // either file does not exist or
+ // file could not be removed and still exists
+ bool file_exists_or_forced_remove = cmSystemTools::FileExists(arg) ||
+ cmSystemTools::FileIsSymlink(arg) || force;
+ if (cmSystemTools::FileIsDirectory(arg)) {
+ if (!cmRemoveDirectory(arg, recursive)) {
+ return_value = 1;
+ }
+ } else if ((!file_exists_or_forced_remove) ||
+ (!cmSystemTools::RemoveFile(arg) &&
+ cmSystemTools::FileExists(arg))) {
+ if (!file_exists_or_forced_remove) {
+ cmSystemTools::Error(
+ "File to remove does not exist and force is not set: " + arg);
+ } else {
+ cmSystemTools::Error("File can't be removed and still exist: " +
+ arg);
+ }
+ return_value = 1;
+ }
+ }
+ }
+ if (!at_least_one_file) {
+ cmSystemTools::Error("Missing file/directory to remove");
+ return 1;
+ }
+ return return_value;
+ }
+
// Touch file
if (args[1] == "touch" && args.size() > 2) {
for (auto const& arg : cmMakeRange(args).advance(2)) {
@@ -849,6 +933,33 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
return HashSumFile(args, cmCryptoHash::AlgoSHA512);
}
+ // Command to concat files into one
+ if (args[1] == "cat" && args.size() >= 3) {
+ int return_value = 0;
+ for (auto const& arg : cmMakeRange(args).advance(2)) {
+ if (cmHasLiteralPrefix(arg, "-")) {
+ if (arg != "--") {
+ cmSystemTools::Error(arg + ": option not handled");
+ return_value = 1;
+ }
+ } else if (!cmSystemTools::TestFileAccess(arg,
+ cmsys::TEST_FILE_READ) &&
+ cmSystemTools::TestFileAccess(arg, cmsys::TEST_FILE_OK)) {
+ cmSystemTools::Error(arg + ": permission denied (ignoring)");
+ return_value = 1;
+ } else if (cmSystemTools::FileIsDirectory(arg)) {
+ cmSystemTools::Error(arg + ": is a directory (ignoring)");
+ return_value = 1;
+ } else if (!cmSystemTools::FileExists(arg)) {
+ cmSystemTools::Error(arg + ": no such file or directory (ignoring)");
+ return_value = 1;
+ } else {
+ cmCatFile(arg);
+ }
+ }
+ return return_value;
+ }
+
// Command to change directory and run a program.
if (args[1] == "chdir" && args.size() >= 4) {
std::string const& directory = args[2];
@@ -976,8 +1087,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
homeOutDir = args[5];
startOutDir = args[6];
depInfo = args[7];
- if (args.size() >= 9 && args[8].length() >= 8 &&
- args[8].substr(0, 8) == "--color=") {
+ if (args.size() >= 9 && cmHasLiteralPrefix(args[8], "--color=")) {
// Enable or disable color based on the switch value.
color = (args[8].size() == 8 || cmIsOn(args[8].substr(8)));
}
@@ -1007,13 +1117,13 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
cm.SetHomeDirectory(homeDir);
cm.SetHomeOutputDirectory(homeOutDir);
cm.GetCurrentSnapshot().SetDefaultDefinitions();
- if (cmGlobalGenerator* ggd = cm.CreateGlobalGenerator(gen)) {
- cm.SetGlobalGenerator(ggd);
+ if (auto ggd = cm.CreateGlobalGenerator(gen)) {
+ cm.SetGlobalGenerator(std::move(ggd));
cmStateSnapshot snapshot = cm.GetCurrentSnapshot();
snapshot.GetDirectory().SetCurrentBinary(startOutDir);
snapshot.GetDirectory().SetCurrentSource(startDir);
- cmMakefile mf(ggd, snapshot);
- std::unique_ptr<cmLocalGenerator> lgd(ggd->CreateLocalGenerator(&mf));
+ cmMakefile mf(cm.GetGlobalGenerator(), snapshot);
+ auto lgd = cm.GetGlobalGenerator()->CreateLocalGenerator(&mf);
// Actually scan dependencies.
return lgd->UpdateDependencies(depInfo, verbose, color) ? 0 : 2;
@@ -1056,6 +1166,10 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
return cmcmd::VisualStudioLink(args, 2);
}
+ if (args[1] == "cmake_llvm_rc") {
+ return cmcmd::RunLLVMRC(args);
+ }
+
// Internal CMake color makefile support.
if (args[1] == "cmake_echo_color") {
return cmcmd::ExecuteEchoColor(args);
@@ -1104,7 +1218,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
}
} else if (cmHasLiteralPrefix(arg, "--format=")) {
format = arg.substr(9);
- if (!cmContains(knownFormats, format)) {
+ if (!cm::contains(knownFormats, format)) {
cmSystemTools::Error("Unknown -E tar --format= argument: " +
format);
return 1;
@@ -1222,7 +1336,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
} else if (arg == "--debug") {
pipe.clear();
isDebug = true;
- } else if (arg.substr(0, pipePrefix.size()) == pipePrefix) {
+ } else if (cmHasPrefix(arg, pipePrefix)) {
isDebug = false;
pipe = arg.substr(pipePrefix.size());
if (pipe.empty()) {
@@ -1429,7 +1543,7 @@ int cmcmd::ExecuteEchoColor(std::vector<std::string> const& args)
bool newline = true;
std::string progressDir;
for (auto const& arg : cmMakeRange(args).advance(2)) {
- if (arg.find("--switch=") == 0) {
+ if (cmHasLiteralPrefix(arg, "--switch=")) {
// Enable or disable color based on the switch value.
std::string value = arg.substr(9);
if (!value.empty()) {
@@ -1484,7 +1598,7 @@ int cmcmd::ExecuteLinkScript(std::vector<std::string> const& args)
// args[3] == --verbose=?
bool verbose = false;
if (args.size() >= 4) {
- if (args[3].find("--verbose=") == 0) {
+ if (cmHasLiteralPrefix(args[3], "--verbose=")) {
if (!cmIsOff(args[3].substr(10))) {
verbose = true;
}
@@ -1572,11 +1686,13 @@ int cmcmd::WindowsCEEnvironment(const char* version, const std::string& name)
cmVisualStudioWCEPlatformParser parser(name.c_str());
parser.ParseVersion(version);
if (parser.Found()) {
- std::cout << "@echo off" << std::endl;
- std::cout << "echo Environment Selection: " << name << std::endl;
- std::cout << "set PATH=" << parser.GetPathDirectories() << std::endl;
- std::cout << "set INCLUDE=" << parser.GetIncludeDirectories() << std::endl;
- std::cout << "set LIB=" << parser.GetLibraryDirectories() << std::endl;
+ /* clang-format off */
+ std::cout << "@echo off\n"
+ "echo Environment Selection: " << name << "\n"
+ "set PATH=" << parser.GetPathDirectories() << "\n"
+ "set INCLUDE=" << parser.GetIncludeDirectories() << "\n"
+ "set LIB=" << parser.GetLibraryDirectories() << std::endl;
+ /* clang-format on */
return 0;
}
#else
@@ -1587,6 +1703,127 @@ int cmcmd::WindowsCEEnvironment(const char* version, const std::string& name)
return -1;
}
+int cmcmd::RunPreprocessor(const std::vector<std::string>& command,
+ const std::string& intermediate_file)
+{
+
+ cmUVProcessChainBuilder builder;
+
+ uv_fs_t fs_req;
+ int preprocessedFile =
+ uv_fs_open(nullptr, &fs_req, intermediate_file.c_str(), O_CREAT | O_RDWR,
+ 0644, nullptr);
+ uv_fs_req_cleanup(&fs_req);
+
+ builder
+ .SetExternalStream(cmUVProcessChainBuilder::Stream_OUTPUT,
+ preprocessedFile)
+ .SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR)
+ .AddCommand(command);
+ auto process = builder.Start();
+ if (!process.Valid()) {
+ std::cerr << "Failed to start preprocessor.";
+ return 1;
+ }
+ if (!process.Wait()) {
+ std::cerr << "Failed to wait for preprocessor";
+ return 1;
+ }
+ auto status = process.GetStatus();
+ if (!status[0] || status[0]->ExitStatus != 0) {
+ auto errorStream = process.ErrorStream();
+ if (errorStream) {
+ std::cerr << errorStream->rdbuf();
+ }
+
+ return 1;
+ }
+
+ return 0;
+}
+
+int cmcmd::RunLLVMRC(std::vector<std::string> const& args)
+{
+ // The arguments are
+ // args[0] == <cmake-executable>
+ // args[1] == cmake_llvm_rc
+ // args[2] == source_file_path
+ // args[3] == intermediate_file
+ // args[4..n] == preprocess+args
+ // args[n+1] == --
+ // args[n+2...] == llvm-rc+args
+ if (args.size() < 3) {
+ std::cerr << "Invalid cmake_llvm_rc arguments";
+ return 1;
+ }
+ const std::string& intermediate_file = args[3];
+ const std::string& source_file = args[2];
+ std::vector<std::string> preprocess;
+ std::vector<std::string> resource_compile;
+ std::vector<std::string>* pArgTgt = &preprocess;
+ for (std::string const& arg : cmMakeRange(args).advance(4)) {
+ if (arg == "--") {
+ pArgTgt = &resource_compile;
+ } else {
+ if (arg.find("SOURCE_DIR") != std::string::npos) {
+ std::string sourceDirArg = arg;
+ cmSystemTools::ReplaceString(
+ sourceDirArg, "SOURCE_DIR",
+ cmSystemTools::GetFilenamePath(source_file));
+ pArgTgt->push_back(sourceDirArg);
+ } else {
+ pArgTgt->push_back(arg);
+ }
+ }
+ }
+ if (preprocess.empty()) {
+ std::cerr << "Empty preprocessing command";
+ return 1;
+ }
+ if (resource_compile.empty()) {
+ std::cerr << "Empty resource compilation command";
+ return 1;
+ }
+
+ auto result = RunPreprocessor(preprocess, intermediate_file);
+ if (result != 0) {
+
+ cmSystemTools::RemoveFile(intermediate_file);
+ return result;
+ }
+ cmUVProcessChainBuilder builder;
+
+ builder.SetBuiltinStream(cmUVProcessChainBuilder::Stream_OUTPUT)
+ .SetBuiltinStream(cmUVProcessChainBuilder::Stream_ERROR)
+ .AddCommand(resource_compile);
+ auto process = builder.Start();
+ result = 0;
+ if (!process.Valid()) {
+ std::cerr << "Failed to start resource compiler.";
+ result = 1;
+ } else {
+ if (!process.Wait()) {
+ std::cerr << "Failed to wait for resource compiler";
+ result = 1;
+ }
+ }
+
+ cmSystemTools::RemoveFile(intermediate_file);
+ if (result != 0) {
+ return result;
+ }
+ auto status = process.GetStatus();
+ if (!status[0] || status[0]->ExitStatus != 0) {
+ auto errorStream = process.ErrorStream();
+ if (errorStream) {
+ std::cerr << errorStream->rdbuf();
+ }
+ return 1;
+ }
+
+ return 0;
+}
+
class cmVSLink
{
int Type;
@@ -1642,7 +1879,7 @@ int cmcmd::VisualStudioLink(std::vector<std::string> const& args, int type)
std::vector<std::string> expandedArgs;
for (std::string const& i : args) {
// check for nmake temporary files
- if (i[0] == '@' && i.find("@CMakeFiles") != 0) {
+ if (i[0] == '@' && !cmHasLiteralPrefix(i, "@CMakeFiles")) {
cmsys::ifstream fin(i.substr(1).c_str());
std::string line;
while (cmSystemTools::GetLineFromStream(fin, line)) {
@@ -1768,9 +2005,8 @@ 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) {
- this->Incremental = true;
- } else if (cmSystemTools::Strucmp(arg->c_str(), "/INCREMENTAL") == 0) {
+ if (cmSystemTools::Strucmp(arg->c_str(), "/INCREMENTAL:YES") == 0 ||
+ cmSystemTools::Strucmp(arg->c_str(), "/INCREMENTAL") == 0) {
this->Incremental = true;
} else if (cmSystemTools::Strucmp(arg->c_str(), "/MANIFEST:NO") == 0) {
this->LinkGeneratesManifest = false;
@@ -1880,12 +2116,18 @@ int cmVSLink::LinkIncremental()
}
// If we have not previously generated a manifest file,
- // generate an empty one so the resource compiler succeeds.
+ // generate a manifest file so the resource compiler succeeds.
if (!cmSystemTools::FileExists(this->ManifestFile)) {
if (this->Verbose) {
std::cout << "Create empty: " << this->ManifestFile << "\n";
}
- cmsys::ofstream foutTmp(this->ManifestFile.c_str());
+ if (this->UserManifests.empty()) {
+ // generate an empty manifest because there are no user provided
+ // manifest files.
+ cmsys::ofstream foutTmp(this->ManifestFile.c_str());
+ } else {
+ this->RunMT("/out:" + this->ManifestFile, false);
+ }
}
// Compile the resource file.
@@ -1953,10 +2195,13 @@ int cmVSLink::RunMT(std::string const& out, bool notify)
mtCommand.push_back(this->MtPath.empty() ? "mt" : this->MtPath);
mtCommand.emplace_back("/nologo");
mtCommand.emplace_back("/manifest");
- if (this->LinkGeneratesManifest) {
+
+ // add the linker generated manifest if the file exists.
+ if (this->LinkGeneratesManifest &&
+ cmSystemTools::FileExists(this->LinkerManifestFile)) {
mtCommand.push_back(this->LinkerManifestFile);
}
- cmAppend(mtCommand, this->UserManifests);
+ cm::append(mtCommand, this->UserManifests);
mtCommand.push_back(out);
if (notify) {
// Add an undocumented option that enables a special return
diff --git a/Source/cmcmd.h b/Source/cmcmd.h
index 17f2f9a..5b6c813 100644
--- a/Source/cmcmd.h
+++ b/Source/cmcmd.h
@@ -31,6 +31,9 @@ protected:
static int ExecuteLinkScript(std::vector<std::string> const& args);
static int WindowsCEEnvironment(const char* version,
const std::string& name);
+ static int RunPreprocessor(const std::vector<std::string>& command,
+ const std::string& intermediate_file);
+ static int RunLLVMRC(std::vector<std::string> const& args);
static int VisualStudioLink(std::vector<std::string> const& args, int type);
};
diff --git a/Source/ctest.cxx b/Source/ctest.cxx
index 0d65902..3b5bf8c 100644
--- a/Source/ctest.cxx
+++ b/Source/ctest.cxx
@@ -35,6 +35,7 @@ static const char* cmDocumentationOptions[][2] = {
{ "--output-on-failure",
"Output anything outputted by the test program "
"if the test should fail." },
+ { "--stop-on-failure", "Stop running the tests after one has failed." },
{ "--test-output-size-passed <size>",
"Limit the output for passed tests "
"to <size> bytes" },
@@ -98,9 +99,12 @@ static const char* cmDocumentationOptions[][2] = {
"Run a specific number of tests by number." },
{ "-U, --union", "Take the Union of -I and -R" },
{ "--rerun-failed", "Run only the tests that failed previously" },
- { "--repeat-until-fail <n>",
- "Require each test to run <n> "
- "times without failing in order to pass" },
+ { "--repeat until-fail:<n>, --repeat-until-fail <n>",
+ "Require each test to run <n> times without failing in order to pass" },
+ { "--repeat until-pass:<n>",
+ "Allow each test to run up to <n> times in order to pass" },
+ { "--repeat after-timeout:<n>",
+ "Allow each test to run up to <n> times if it times out" },
{ "--max-width <width>", "Set the max width for a test name to output" },
{ "--interactive-debug-mode [0|1]", "Set the interactive mode to 0 or 1." },
{ "--resource-spec-file <file>", "Set the resource spec file to use." },
@@ -141,6 +145,8 @@ static const char* cmDocumentationOptions[][2] = {
{ "--http1.0", "Submit using HTTP 1.0." },
{ "--no-compress-output", "Do not compress test output when submitting." },
{ "--print-labels", "Print all available test labels." },
+ { "--no-tests=<[error|ignore]>",
+ "Regard no tests found either as 'error' or 'ignore' it." },
{ nullptr, nullptr }
};
@@ -161,7 +167,6 @@ int main(int argc, char const* const* argv)
argv = encoding_args.argv();
cmSystemTools::DoNotInheritStdPipes();
- cmSystemTools::EnableMSVCDebugHook();
cmSystemTools::InitializeLibUV();
cmSystemTools::FindCMakeResources(argv[0]);
diff --git a/Source/kwsys/Base64.c b/Source/kwsys/Base64.c
index bf876f2..4265018 100644
--- a/Source/kwsys/Base64.c
+++ b/Source/kwsys/Base64.c
@@ -130,7 +130,10 @@ size_t kwsysBase64_Encode(const unsigned char* input, size_t length,
/* Decode 4 bytes into a 3 byte string. */
int kwsysBase64_Decode3(const unsigned char* src, unsigned char* dest)
{
- unsigned char d0, d1, d2, d3;
+ unsigned char d0;
+ unsigned char d1;
+ unsigned char d2;
+ unsigned char d3;
d0 = kwsysBase64DecodeChar(src[0]);
d1 = kwsysBase64DecodeChar(src[1]);
diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt
index 09bcdb9..d8f7e57 100644
--- a/Source/kwsys/CMakeLists.txt
+++ b/Source/kwsys/CMakeLists.txt
@@ -11,9 +11,9 @@
# be used. All classes are disabled by default. The CMake listfile
# above this one configures the library as follows:
#
-# SET(KWSYS_NAMESPACE foosys)
-# SET(KWSYS_USE_Directory 1) # Enable Directory class.
-# SUBDIRS(kwsys)
+# set(KWSYS_NAMESPACE foosys)
+# set(KWSYS_USE_Directory 1) # Enable Directory class.
+# add_subdirectory(kwsys)
#
# Optional settings are as follows:
#
@@ -39,8 +39,8 @@
#
# Example:
#
-# SET(KWSYS_HEADER_ROOT ${PROJECT_BINARY_DIR})
-# INCLUDE_DIRECTORIES(${PROJECT_BINARY_DIR})
+# set(KWSYS_HEADER_ROOT ${PROJECT_BINARY_DIR})
+# include_directories(${PROJECT_BINARY_DIR})
#
# KWSYS_CXX_STANDARD = A value for CMAKE_CXX_STANDARD within KWSys.
# Set to empty string to use no default value.
@@ -65,11 +65,11 @@
#
# Example:
#
-# SET(KWSYS_INSTALL_BIN_DIR bin)
-# SET(KWSYS_INSTALL_LIB_DIR lib)
-# SET(KWSYS_INSTALL_INCLUDE_DIR include)
-# SET(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME Runtime)
-# SET(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT Development)
+# set(KWSYS_INSTALL_BIN_DIR bin)
+# set(KWSYS_INSTALL_LIB_DIR lib)
+# set(KWSYS_INSTALL_INCLUDE_DIR include)
+# set(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME Runtime)
+# set(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT Development)
# Once configured, kwsys should be used as follows from C or C++ code:
#
@@ -86,33 +86,33 @@
# any outside mailing list and no documentation of the change will be
# written.
-CMAKE_MINIMUM_REQUIRED(VERSION 3.1 FATAL_ERROR)
-FOREACH(p
+cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
+foreach(p
CMP0056 # CMake 3.2, Honor link flags in try_compile() source-file signature.
CMP0063 # CMake 3.3, Honor visibility properties for all target types.
CMP0067 # CMake 3.8, Honor language standard in try_compile source-file signature.
CMP0069 # CMake 3.9, INTERPROCEDURAL_OPTIMIZATION is enforced when enabled.
)
- IF(POLICY ${p})
- CMAKE_POLICY(SET ${p} NEW)
- ENDIF()
-ENDFOREACH()
+ if(POLICY ${p})
+ cmake_policy(SET ${p} NEW)
+ endif()
+endforeach()
#-----------------------------------------------------------------------------
# If a namespace is not specified, use "kwsys" and enable testing.
# This should be the case only when kwsys is not included inside
# another project and is being tested.
-IF(NOT KWSYS_NAMESPACE)
- SET(KWSYS_NAMESPACE "kwsys")
- SET(KWSYS_STANDALONE 1)
-ENDIF()
+if(NOT KWSYS_NAMESPACE)
+ set(KWSYS_NAMESPACE "kwsys")
+ set(KWSYS_STANDALONE 1)
+endif()
#-----------------------------------------------------------------------------
# The project name is that of the specified namespace.
-PROJECT(${KWSYS_NAMESPACE})
+project(${KWSYS_NAMESPACE})
# Tell CMake how to follow dependencies of sources in this directory.
-SET_PROPERTY(DIRECTORY
+set_property(DIRECTORY
PROPERTY IMPLICIT_DEPENDS_INCLUDE_TRANSFORM
"KWSYS_HEADER(%)=<${KWSYS_NAMESPACE}/%>"
)
@@ -131,229 +131,229 @@ elseif(NOT DEFINED CMAKE_CXX_STANDARD AND NOT DEFINED KWSYS_CXX_STANDARD)
endif()
# Select library components.
-IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
- SET(KWSYS_ENABLE_C 1)
+if(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
+ set(KWSYS_ENABLE_C 1)
# Enable all components.
- SET(KWSYS_USE_Base64 1)
- SET(KWSYS_USE_Directory 1)
- SET(KWSYS_USE_DynamicLoader 1)
- SET(KWSYS_USE_Encoding 1)
- SET(KWSYS_USE_Glob 1)
- SET(KWSYS_USE_MD5 1)
- SET(KWSYS_USE_Process 1)
- SET(KWSYS_USE_RegularExpression 1)
- SET(KWSYS_USE_System 1)
- SET(KWSYS_USE_SystemTools 1)
- SET(KWSYS_USE_CommandLineArguments 1)
- SET(KWSYS_USE_Terminal 1)
- SET(KWSYS_USE_IOStream 1)
- SET(KWSYS_USE_FStream 1)
- SET(KWSYS_USE_String 1)
- SET(KWSYS_USE_SystemInformation 1)
- SET(KWSYS_USE_ConsoleBuf 1)
-ENDIF()
+ set(KWSYS_USE_Base64 1)
+ set(KWSYS_USE_Directory 1)
+ set(KWSYS_USE_DynamicLoader 1)
+ set(KWSYS_USE_Encoding 1)
+ set(KWSYS_USE_Glob 1)
+ set(KWSYS_USE_MD5 1)
+ set(KWSYS_USE_Process 1)
+ set(KWSYS_USE_RegularExpression 1)
+ set(KWSYS_USE_System 1)
+ set(KWSYS_USE_SystemTools 1)
+ set(KWSYS_USE_CommandLineArguments 1)
+ set(KWSYS_USE_Terminal 1)
+ set(KWSYS_USE_IOStream 1)
+ set(KWSYS_USE_FStream 1)
+ set(KWSYS_USE_String 1)
+ set(KWSYS_USE_SystemInformation 1)
+ set(KWSYS_USE_ConsoleBuf 1)
+endif()
# Enforce component dependencies.
-IF(KWSYS_USE_SystemTools)
- SET(KWSYS_USE_Directory 1)
- SET(KWSYS_USE_FStream 1)
- SET(KWSYS_USE_Encoding 1)
-ENDIF()
-IF(KWSYS_USE_Glob)
- SET(KWSYS_USE_Directory 1)
- SET(KWSYS_USE_SystemTools 1)
- SET(KWSYS_USE_RegularExpression 1)
- SET(KWSYS_USE_FStream 1)
- SET(KWSYS_USE_Encoding 1)
-ENDIF()
-IF(KWSYS_USE_Process)
- SET(KWSYS_USE_System 1)
- SET(KWSYS_USE_Encoding 1)
-ENDIF()
-IF(KWSYS_USE_SystemInformation)
- SET(KWSYS_USE_Process 1)
-ENDIF()
-IF(KWSYS_USE_System)
- SET(KWSYS_USE_Encoding 1)
-ENDIF()
-IF(KWSYS_USE_Directory)
- SET(KWSYS_USE_Encoding 1)
-ENDIF()
-IF(KWSYS_USE_DynamicLoader)
- SET(KWSYS_USE_Encoding 1)
-ENDIF()
-IF(KWSYS_USE_FStream)
- SET(KWSYS_USE_Encoding 1)
-ENDIF()
-IF(KWSYS_USE_ConsoleBuf)
- SET(KWSYS_USE_Encoding 1)
-ENDIF()
+if(KWSYS_USE_SystemTools)
+ set(KWSYS_USE_Directory 1)
+ set(KWSYS_USE_FStream 1)
+ set(KWSYS_USE_Encoding 1)
+endif()
+if(KWSYS_USE_Glob)
+ set(KWSYS_USE_Directory 1)
+ set(KWSYS_USE_SystemTools 1)
+ set(KWSYS_USE_RegularExpression 1)
+ set(KWSYS_USE_FStream 1)
+ set(KWSYS_USE_Encoding 1)
+endif()
+if(KWSYS_USE_Process)
+ set(KWSYS_USE_System 1)
+ set(KWSYS_USE_Encoding 1)
+endif()
+if(KWSYS_USE_SystemInformation)
+ set(KWSYS_USE_Process 1)
+endif()
+if(KWSYS_USE_System)
+ set(KWSYS_USE_Encoding 1)
+endif()
+if(KWSYS_USE_Directory)
+ set(KWSYS_USE_Encoding 1)
+endif()
+if(KWSYS_USE_DynamicLoader)
+ set(KWSYS_USE_Encoding 1)
+endif()
+if(KWSYS_USE_FStream)
+ set(KWSYS_USE_Encoding 1)
+endif()
+if(KWSYS_USE_ConsoleBuf)
+ set(KWSYS_USE_Encoding 1)
+endif()
# Specify default 8 bit encoding for Windows
-IF(NOT KWSYS_ENCODING_DEFAULT_CODEPAGE)
- SET(KWSYS_ENCODING_DEFAULT_CODEPAGE CP_ACP)
-ENDIF()
+if(NOT KWSYS_ENCODING_DEFAULT_CODEPAGE)
+ set(KWSYS_ENCODING_DEFAULT_CODEPAGE CP_ACP)
+endif()
# Enable testing if building standalone.
-IF(KWSYS_STANDALONE)
- INCLUDE(Dart)
- MARK_AS_ADVANCED(BUILD_TESTING DART_ROOT TCL_TCLSH)
- IF(BUILD_TESTING)
- ENABLE_TESTING()
- ENDIF()
-ENDIF()
+if(KWSYS_STANDALONE)
+ include(Dart)
+ mark_as_advanced(BUILD_TESTING DART_ROOT TCL_TCLSH)
+ if(BUILD_TESTING)
+ enable_testing()
+ endif()
+endif()
# Choose default shared/static build if not specified.
-IF(NOT DEFINED KWSYS_BUILD_SHARED)
- SET(KWSYS_BUILD_SHARED ${BUILD_SHARED_LIBS})
-ENDIF()
+if(NOT DEFINED KWSYS_BUILD_SHARED)
+ set(KWSYS_BUILD_SHARED ${BUILD_SHARED_LIBS})
+endif()
# Include helper macros.
-INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/kwsysPlatformTests.cmake)
-INCLUDE(CheckTypeSize)
+include(${CMAKE_CURRENT_SOURCE_DIR}/kwsysPlatformTests.cmake)
+include(CheckTypeSize)
# Do full dependency headers.
-INCLUDE_REGULAR_EXPRESSION("^.*$")
+include_regular_expression("^.*$")
# Use new KWSYS_INSTALL_*_DIR variable names to control installation.
# Take defaults from the old names. Note that there was no old name
# for the bin dir, so we take the old lib dir name so DLLs will be
# installed in a compatible way for old code.
-IF(NOT KWSYS_INSTALL_INCLUDE_DIR)
- STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_INCLUDE_DIR
+if(NOT KWSYS_INSTALL_INCLUDE_DIR)
+ string(REGEX REPLACE "^/" "" KWSYS_INSTALL_INCLUDE_DIR
"${KWSYS_HEADER_INSTALL_DIR}")
-ENDIF()
-IF(NOT KWSYS_INSTALL_LIB_DIR)
- STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_LIB_DIR
+endif()
+if(NOT KWSYS_INSTALL_LIB_DIR)
+ string(REGEX REPLACE "^/" "" KWSYS_INSTALL_LIB_DIR
"${KWSYS_LIBRARY_INSTALL_DIR}")
-ENDIF()
-IF(NOT KWSYS_INSTALL_BIN_DIR)
- STRING(REGEX REPLACE "^/" "" KWSYS_INSTALL_BIN_DIR
+endif()
+if(NOT KWSYS_INSTALL_BIN_DIR)
+ string(REGEX REPLACE "^/" "" KWSYS_INSTALL_BIN_DIR
"${KWSYS_LIBRARY_INSTALL_DIR}")
-ENDIF()
+endif()
# Setup header install rules.
-SET(KWSYS_INSTALL_INCLUDE_OPTIONS)
-IF(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT)
- SET(KWSYS_INSTALL_INCLUDE_OPTIONS ${KWSYS_INSTALL_INCLUDE_OPTIONS}
+set(KWSYS_INSTALL_INCLUDE_OPTIONS)
+if(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT)
+ set(KWSYS_INSTALL_INCLUDE_OPTIONS ${KWSYS_INSTALL_INCLUDE_OPTIONS}
COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT}
)
-ENDIF()
+endif()
# Setup library install rules.
-SET(KWSYS_INSTALL_LIBRARY_RULE)
-SET(KWSYS_INSTALL_NAMELINK_RULE)
-IF(KWSYS_INSTALL_LIB_DIR)
- IF(KWSYS_INSTALL_EXPORT_NAME)
- LIST(APPEND KWSYS_INSTALL_LIBRARY_RULE EXPORT ${KWSYS_INSTALL_EXPORT_NAME})
- ENDIF()
+set(KWSYS_INSTALL_LIBRARY_RULE)
+set(KWSYS_INSTALL_NAMELINK_RULE)
+if(KWSYS_INSTALL_LIB_DIR)
+ if(KWSYS_INSTALL_EXPORT_NAME)
+ list(APPEND KWSYS_INSTALL_LIBRARY_RULE EXPORT ${KWSYS_INSTALL_EXPORT_NAME})
+ endif()
# Install the shared library to the lib directory.
- SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
+ set(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
LIBRARY DESTINATION ${KWSYS_INSTALL_LIB_DIR} NAMELINK_SKIP
)
# Assign the shared library to the runtime component.
- IF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME)
- SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
+ if(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME)
+ set(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_RUNTIME}
)
- ENDIF()
- IF(KWSYS_BUILD_SHARED)
- SET(KWSYS_INSTALL_NAMELINK_RULE ${KWSYS_INSTALL_NAMELINK_RULE}
+ endif()
+ if(KWSYS_BUILD_SHARED)
+ set(KWSYS_INSTALL_NAMELINK_RULE ${KWSYS_INSTALL_NAMELINK_RULE}
LIBRARY DESTINATION ${KWSYS_INSTALL_LIB_DIR} NAMELINK_ONLY
)
# Assign the namelink to the development component.
- IF(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT)
- SET(KWSYS_INSTALL_NAMELINK_RULE ${KWSYS_INSTALL_NAMELINK_RULE}
+ if(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT)
+ set(KWSYS_INSTALL_NAMELINK_RULE ${KWSYS_INSTALL_NAMELINK_RULE}
COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT}
)
- ENDIF()
- ENDIF()
+ endif()
+ endif()
# Install the archive to the lib directory.
- SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
+ set(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
ARCHIVE DESTINATION ${KWSYS_INSTALL_LIB_DIR}
)
# Assign the archive to the development component.
- IF(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT)
- SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
+ if(KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT)
+ set(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_DEVELOPMENT}
)
- ENDIF()
-ENDIF()
-IF(KWSYS_INSTALL_BIN_DIR)
+ endif()
+endif()
+if(KWSYS_INSTALL_BIN_DIR)
# Install the runtime library to the bin directory.
- SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
+ set(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
RUNTIME DESTINATION ${KWSYS_INSTALL_BIN_DIR}
)
# Assign the runtime library to the runtime component.
- IF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME)
- SET(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
+ if(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME)
+ set(KWSYS_INSTALL_LIBRARY_RULE ${KWSYS_INSTALL_LIBRARY_RULE}
COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_RUNTIME}
)
- ENDIF()
-ENDIF()
+ endif()
+endif()
# Do not support old KWSYS_*a_INSTALL_DIR variable names.
-SET(KWSYS_HEADER_INSTALL_DIR)
-SET(KWSYS_LIBRARY_INSTALL_DIR)
+set(KWSYS_HEADER_INSTALL_DIR)
+set(KWSYS_LIBRARY_INSTALL_DIR)
# Generated source files will need this header.
-STRING(COMPARE EQUAL "${PROJECT_SOURCE_DIR}" "${PROJECT_BINARY_DIR}"
+string(COMPARE EQUAL "${PROJECT_SOURCE_DIR}" "${PROJECT_BINARY_DIR}"
KWSYS_IN_SOURCE_BUILD)
-IF(NOT KWSYS_IN_SOURCE_BUILD)
- CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/kwsysPrivate.h
+if(NOT KWSYS_IN_SOURCE_BUILD)
+ configure_file(${PROJECT_SOURCE_DIR}/kwsysPrivate.h
${PROJECT_BINARY_DIR}/kwsysPrivate.h COPYONLY IMMEDIATE)
-ENDIF()
+endif()
# Select plugin module file name convention.
-IF(NOT KWSYS_DynamicLoader_PREFIX)
- SET(KWSYS_DynamicLoader_PREFIX ${CMAKE_SHARED_MODULE_PREFIX})
-ENDIF()
-IF(NOT KWSYS_DynamicLoader_SUFFIX)
- SET(KWSYS_DynamicLoader_SUFFIX ${CMAKE_SHARED_MODULE_SUFFIX})
-ENDIF()
+if(NOT KWSYS_DynamicLoader_PREFIX)
+ set(KWSYS_DynamicLoader_PREFIX ${CMAKE_SHARED_MODULE_PREFIX})
+endif()
+if(NOT KWSYS_DynamicLoader_SUFFIX)
+ set(KWSYS_DynamicLoader_SUFFIX ${CMAKE_SHARED_MODULE_SUFFIX})
+endif()
#-----------------------------------------------------------------------------
# We require ANSI support from the C compiler. Add any needed flags.
-IF(CMAKE_ANSI_CFLAGS)
- SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_ANSI_CFLAGS}")
-ENDIF()
+if(CMAKE_ANSI_CFLAGS)
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_ANSI_CFLAGS}")
+endif()
#-----------------------------------------------------------------------------
# Adjust compiler flags for some platforms.
-IF(NOT CMAKE_COMPILER_IS_GNUCXX)
- IF(CMAKE_SYSTEM MATCHES "OSF1-V.*")
- STRING(REGEX MATCH "-timplicit_local"
+if(NOT CMAKE_COMPILER_IS_GNUCXX)
+ if(CMAKE_SYSTEM MATCHES "OSF1-V.*")
+ string(REGEX MATCH "-timplicit_local"
KWSYS_CXX_FLAGS_HAVE_IMPLICIT_LOCAL "${CMAKE_CXX_FLAGS}")
- STRING(REGEX MATCH "-no_implicit_include"
+ string(REGEX MATCH "-no_implicit_include"
KWSYS_CXX_FLAGS_HAVE_NO_IMPLICIT_INCLUDE "${CMAKE_CXX_FLAGS}")
- IF(NOT KWSYS_CXX_FLAGS_HAVE_IMPLICIT_LOCAL)
- SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -timplicit_local")
- ENDIF()
- IF(NOT KWSYS_CXX_FLAGS_HAVE_NO_IMPLICIT_INCLUDE)
- SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -no_implicit_include")
- ENDIF()
- ENDIF()
- IF(CMAKE_SYSTEM MATCHES "HP-UX")
- SET(KWSYS_PLATFORM_CXX_TEST_EXTRA_FLAGS "+p")
- IF(CMAKE_CXX_COMPILER_ID MATCHES "HP")
+ if(NOT KWSYS_CXX_FLAGS_HAVE_IMPLICIT_LOCAL)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -timplicit_local")
+ endif()
+ if(NOT KWSYS_CXX_FLAGS_HAVE_NO_IMPLICIT_INCLUDE)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -no_implicit_include")
+ endif()
+ endif()
+ if(CMAKE_SYSTEM MATCHES "HP-UX")
+ set(KWSYS_PLATFORM_CXX_TEST_EXTRA_FLAGS "+p")
+ if(CMAKE_CXX_COMPILER_ID MATCHES "HP")
# it is known that version 3.85 fails and 6.25 works without these flags
- IF(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4)
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4)
# use new C++ library and improved template support
- SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -AA +hpxstd98")
- ENDIF()
- ENDIF()
- ENDIF()
-ENDIF()
-IF(KWSYS_STANDALONE)
- IF(CMAKE_CXX_COMPILER_ID STREQUAL SunPro)
- IF(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.13)
- SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++03")
- ELSE()
- SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -library=stlport4")
- ENDIF()
- ENDIF()
-ENDIF()
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -AA +hpxstd98")
+ endif()
+ endif()
+ endif()
+endif()
+if(KWSYS_STANDALONE)
+ if(CMAKE_CXX_COMPILER_ID STREQUAL SunPro)
+ if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.13)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++03")
+ else()
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -library=stlport4")
+ endif()
+ endif()
+endif()
#-----------------------------------------------------------------------------
# Configure the standard library header wrappers based on compiler's
@@ -365,75 +365,75 @@ KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_LONG_LONG
"Checking whether C++ compiler has 'long long'" DIRECT)
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS___INT64
"Checking whether C++ compiler has '__int64'" DIRECT)
-IF(KWSYS_CXX_HAS___INT64)
+if(KWSYS_CXX_HAS___INT64)
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_SAME_LONG_AND___INT64
"Checking whether long and __int64 are the same type" DIRECT)
- IF(KWSYS_CXX_HAS_LONG_LONG)
+ if(KWSYS_CXX_HAS_LONG_LONG)
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_SAME_LONG_LONG_AND___INT64
"Checking whether long long and __int64 are the same type" DIRECT)
- ENDIF()
-ENDIF()
+ endif()
+endif()
# Enable the "long long" type if it is available. It is standard in
# C99 and C++03 but not in earlier standards.
-IF(KWSYS_CXX_HAS_LONG_LONG)
- SET(KWSYS_USE_LONG_LONG 1)
-ELSE()
- SET(KWSYS_USE_LONG_LONG 0)
-ENDIF()
+if(KWSYS_CXX_HAS_LONG_LONG)
+ set(KWSYS_USE_LONG_LONG 1)
+else()
+ set(KWSYS_USE_LONG_LONG 0)
+endif()
# Enable the "__int64" type if it is available and unique. It is not
# standard.
-SET(KWSYS_USE___INT64 0)
-IF(KWSYS_CXX_HAS___INT64)
- IF(NOT KWSYS_CXX_SAME_LONG_AND___INT64)
- IF(NOT KWSYS_CXX_SAME_LONG_LONG_AND___INT64)
- SET(KWSYS_USE___INT64 1)
- ENDIF()
- ENDIF()
-ENDIF()
-
-IF(KWSYS_USE_Encoding)
+set(KWSYS_USE___INT64 0)
+if(KWSYS_CXX_HAS___INT64)
+ if(NOT KWSYS_CXX_SAME_LONG_AND___INT64)
+ if(NOT KWSYS_CXX_SAME_LONG_LONG_AND___INT64)
+ set(KWSYS_USE___INT64 1)
+ endif()
+ endif()
+endif()
+
+if(KWSYS_USE_Encoding)
# Look for type size helper macros.
KWSYS_PLATFORM_CXX_TEST(KWSYS_STL_HAS_WSTRING
"Checking whether wstring is available" DIRECT)
-ENDIF()
+endif()
-IF(KWSYS_USE_IOStream)
+if(KWSYS_USE_IOStream)
# Determine whether iostreams support long long.
- IF(KWSYS_CXX_HAS_LONG_LONG)
+ if(KWSYS_CXX_HAS_LONG_LONG)
KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_ISTREAM_LONG_LONG
"Checking if istream supports long long" DIRECT)
KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_OSTREAM_LONG_LONG
"Checking if ostream supports long long" DIRECT)
- ELSE()
- SET(KWSYS_IOS_HAS_ISTREAM_LONG_LONG 0)
- SET(KWSYS_IOS_HAS_OSTREAM_LONG_LONG 0)
- ENDIF()
- IF(KWSYS_CXX_HAS___INT64)
+ else()
+ set(KWSYS_IOS_HAS_ISTREAM_LONG_LONG 0)
+ set(KWSYS_IOS_HAS_OSTREAM_LONG_LONG 0)
+ endif()
+ if(KWSYS_CXX_HAS___INT64)
KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_ISTREAM___INT64
"Checking if istream supports __int64" DIRECT)
KWSYS_PLATFORM_CXX_TEST(KWSYS_IOS_HAS_OSTREAM___INT64
"Checking if ostream supports __int64" DIRECT)
- ELSE()
- SET(KWSYS_IOS_HAS_ISTREAM___INT64 0)
- SET(KWSYS_IOS_HAS_OSTREAM___INT64 0)
- ENDIF()
-ENDIF()
-
-IF(KWSYS_NAMESPACE MATCHES "^kwsys$")
- SET(KWSYS_NAME_IS_KWSYS 1)
-ELSE()
- SET(KWSYS_NAME_IS_KWSYS 0)
-ENDIF()
-
-IF(KWSYS_BUILD_SHARED)
- SET(KWSYS_BUILD_SHARED 1)
- SET(KWSYS_LIBRARY_TYPE SHARED)
-ELSE()
- SET(KWSYS_BUILD_SHARED 0)
- SET(KWSYS_LIBRARY_TYPE STATIC)
-ENDIF()
+ else()
+ set(KWSYS_IOS_HAS_ISTREAM___INT64 0)
+ set(KWSYS_IOS_HAS_OSTREAM___INT64 0)
+ endif()
+endif()
+
+if(KWSYS_NAMESPACE MATCHES "^kwsys$")
+ set(KWSYS_NAME_IS_KWSYS 1)
+else()
+ set(KWSYS_NAME_IS_KWSYS 0)
+endif()
+
+if(KWSYS_BUILD_SHARED)
+ set(KWSYS_BUILD_SHARED 1)
+ set(KWSYS_LIBRARY_TYPE SHARED)
+else()
+ set(KWSYS_BUILD_SHARED 0)
+ set(KWSYS_LIBRARY_TYPE STATIC)
+endif()
if(NOT DEFINED KWSYS_BUILD_PIC)
set(KWSYS_BUILD_PIC 0)
@@ -446,32 +446,32 @@ KWSYS_PLATFORM_C_TEST(KWSYS_C_HAS_PTRDIFF_T
"Checking whether C compiler has ptrdiff_t in stddef.h" DIRECT)
KWSYS_PLATFORM_C_TEST(KWSYS_C_HAS_SSIZE_T
"Checking whether C compiler has ssize_t in unistd.h" DIRECT)
-IF(KWSYS_USE_Process)
+if(KWSYS_USE_Process)
KWSYS_PLATFORM_C_TEST(KWSYS_C_HAS_CLOCK_GETTIME_MONOTONIC
"Checking whether C compiler has clock_gettime" DIRECT)
-ENDIF()
+endif()
-SET_SOURCE_FILES_PROPERTIES(ProcessUNIX.c System.c PROPERTIES
+set_source_files_properties(ProcessUNIX.c System.c PROPERTIES
COMPILE_FLAGS "-DKWSYS_C_HAS_PTRDIFF_T=${KWSYS_C_HAS_PTRDIFF_T} -DKWSYS_C_HAS_SSIZE_T=${KWSYS_C_HAS_SSIZE_T} -DKWSYS_C_HAS_CLOCK_GETTIME_MONOTONIC=${KWSYS_C_HAS_CLOCK_GETTIME_MONOTONIC}"
)
-IF(DEFINED KWSYS_PROCESS_USE_SELECT)
- GET_PROPERTY(ProcessUNIX_FLAGS SOURCE ProcessUNIX.c PROPERTY COMPILE_FLAGS)
- SET_PROPERTY(SOURCE ProcessUNIX.c PROPERTY COMPILE_FLAGS "${ProcessUNIX_FLAGS} -DKWSYSPE_USE_SELECT=${KWSYSPE_USE_SELECT}")
-ENDIF()
-
-IF(KWSYS_USE_DynamicLoader)
- GET_PROPERTY(KWSYS_SUPPORTS_SHARED_LIBS GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS)
- IF(KWSYS_SUPPORTS_SHARED_LIBS)
- SET(KWSYS_SUPPORTS_SHARED_LIBS 1)
- ELSE()
- SET(KWSYS_SUPPORTS_SHARED_LIBS 0)
- ENDIF()
- SET_PROPERTY(SOURCE DynamicLoader.cxx APPEND PROPERTY COMPILE_DEFINITIONS
+if(DEFINED KWSYS_PROCESS_USE_SELECT)
+ get_property(ProcessUNIX_FLAGS SOURCE ProcessUNIX.c PROPERTY COMPILE_FLAGS)
+ set_property(SOURCE ProcessUNIX.c PROPERTY COMPILE_FLAGS "${ProcessUNIX_FLAGS} -DKWSYSPE_USE_SELECT=${KWSYSPE_USE_SELECT}")
+endif()
+
+if(KWSYS_USE_DynamicLoader)
+ get_property(KWSYS_SUPPORTS_SHARED_LIBS GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS)
+ if(KWSYS_SUPPORTS_SHARED_LIBS)
+ set(KWSYS_SUPPORTS_SHARED_LIBS 1)
+ else()
+ set(KWSYS_SUPPORTS_SHARED_LIBS 0)
+ endif()
+ set_property(SOURCE DynamicLoader.cxx APPEND PROPERTY COMPILE_DEFINITIONS
KWSYS_SUPPORTS_SHARED_LIBS=${KWSYS_SUPPORTS_SHARED_LIBS})
-ENDIF()
+endif()
-IF(KWSYS_USE_SystemTools)
+if(KWSYS_USE_SystemTools)
if (NOT DEFINED KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP)
set(KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP 1)
endif ()
@@ -494,7 +494,7 @@ IF(KWSYS_USE_SystemTools)
"Checking whether CXX compiler struct stat has st_mtim member" DIRECT)
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_STAT_HAS_ST_MTIMESPEC
"Checking whether CXX compiler struct stat has st_mtimespec member" DIRECT)
- SET_PROPERTY(SOURCE SystemTools.cxx APPEND PROPERTY COMPILE_DEFINITIONS
+ set_property(SOURCE SystemTools.cxx APPEND PROPERTY COMPILE_DEFINITIONS
KWSYS_CXX_HAS_SETENV=${KWSYS_CXX_HAS_SETENV}
KWSYS_CXX_HAS_UNSETENV=${KWSYS_CXX_HAS_UNSETENV}
KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H=${KWSYS_CXX_HAS_ENVIRON_IN_STDLIB_H}
@@ -503,623 +503,623 @@ IF(KWSYS_USE_SystemTools)
KWSYS_CXX_STAT_HAS_ST_MTIM=${KWSYS_CXX_STAT_HAS_ST_MTIM}
KWSYS_CXX_STAT_HAS_ST_MTIMESPEC=${KWSYS_CXX_STAT_HAS_ST_MTIMESPEC}
)
- IF(NOT WIN32)
- IF(KWSYS_STANDALONE)
- OPTION(KWSYS_SYSTEMTOOLS_SUPPORT_WINDOWS_SLASHES "If true, Windows paths will be supported on Unix as well" ON)
- ENDIF()
- IF(KWSYS_SYSTEMTOOLS_SUPPORT_WINDOWS_SLASHES)
- SET_PROPERTY(SOURCE SystemTools.cxx testSystemTools.cxx APPEND PROPERTY COMPILE_DEFINITIONS
+ if(NOT WIN32)
+ if(KWSYS_STANDALONE)
+ option(KWSYS_SYSTEMTOOLS_SUPPORT_WINDOWS_SLASHES "If true, Windows paths will be supported on Unix as well" ON)
+ endif()
+ if(KWSYS_SYSTEMTOOLS_SUPPORT_WINDOWS_SLASHES)
+ set_property(SOURCE SystemTools.cxx testSystemTools.cxx APPEND PROPERTY COMPILE_DEFINITIONS
KWSYS_SYSTEMTOOLS_SUPPORT_WINDOWS_SLASHES
)
- ENDIF()
- ENDIF()
+ endif()
+ endif()
# Disable getpwnam for static linux builds since it depends on shared glibc
- GET_PROPERTY(SHARED_LIBS_SUPPORTED GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS)
- IF(CMAKE_SYSTEM_NAME MATCHES "Linux" AND NOT SHARED_LIBS_SUPPORTED)
- SET_PROPERTY(SOURCE SystemTools.cxx APPEND PROPERTY COMPILE_DEFINITIONS
+ get_property(SHARED_LIBS_SUPPORTED GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS)
+ if(CMAKE_SYSTEM_NAME MATCHES "Linux" AND NOT SHARED_LIBS_SUPPORTED)
+ set_property(SOURCE SystemTools.cxx APPEND PROPERTY COMPILE_DEFINITIONS
HAVE_GETPWNAM=0
)
- ENDIF()
-ENDIF()
+ endif()
+endif()
-IF(KWSYS_USE_SystemInformation)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+if(KWSYS_USE_SystemInformation)
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS SIZEOF_VOID_P=${CMAKE_SIZEOF_VOID_P})
- IF(NOT CYGWIN)
- INCLUDE(CheckIncludeFiles)
+ if(NOT CYGWIN)
+ include(CheckIncludeFiles)
CHECK_INCLUDE_FILES("sys/types.h;ifaddrs.h" KWSYS_SYS_HAS_IFADDRS_H)
- IF(KWSYS_SYS_HAS_IFADDRS_H)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ if(KWSYS_SYS_HAS_IFADDRS_H)
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_SYS_HAS_IFADDRS_H=1)
- ENDIF()
- ENDIF()
- IF(WIN32)
- INCLUDE(CheckSymbolExists)
- SET(CMAKE_REQUIRED_LIBRARIES Psapi)
+ endif()
+ endif()
+ if(WIN32)
+ include(CheckSymbolExists)
+ set(CMAKE_REQUIRED_LIBRARIES psapi)
CHECK_SYMBOL_EXISTS(GetProcessMemoryInfo "windows.h;psapi.h" KWSYS_SYS_HAS_PSAPI)
- UNSET(CMAKE_REQUIRED_LIBRARIES)
- IF(KWSYS_SYS_HAS_PSAPI)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ unset(CMAKE_REQUIRED_LIBRARIES)
+ if(KWSYS_SYS_HAS_PSAPI)
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_SYS_HAS_PSAPI=1)
- IF(MSVC70 OR MSVC71)
+ if(MSVC70 OR MSVC71)
# Suppress LNK4089: all references to 'PSAPI.DLL' discarded by /OPT:REF
- SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /IGNORE:4089")
- ENDIF()
- ENDIF()
- ENDIF()
- IF(CMAKE_SYSTEM MATCHES "HP-UX")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /IGNORE:4089")
+ endif()
+ endif()
+ endif()
+ if(CMAKE_SYSTEM MATCHES "HP-UX")
CHECK_INCLUDE_FILES("sys/mpctl.h" KWSYS_SYS_HAS_MPCTL_H)
- IF(KWSYS_SYS_HAS_MPCTL_H)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ if(KWSYS_SYS_HAS_MPCTL_H)
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_SYS_HAS_MPCTL_H=1)
- ENDIF()
- ENDIF()
- IF(CMAKE_SYSTEM MATCHES "BSD")
+ endif()
+ endif()
+ if(CMAKE_SYSTEM MATCHES "BSD")
CHECK_INCLUDE_FILES("machine/cpu.h" KWSYS_SYS_HAS_MACHINE_CPU_H)
- IF(KWSYS_SYS_HAS_MACHINE_CPU_H)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ if(KWSYS_SYS_HAS_MACHINE_CPU_H)
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_SYS_HAS_MACHINE_CPU_H=1)
- ENDIF()
- ENDIF()
+ endif()
+ endif()
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_RLIMIT64
"Checking whether CXX compiler has rlimit64" DIRECT)
- SET(KWSYS_PLATFORM_CXX_TEST_DEFINES)
- IF(KWSYS_CXX_HAS_RLIMIT64)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ set(KWSYS_PLATFORM_CXX_TEST_DEFINES)
+ if(KWSYS_CXX_HAS_RLIMIT64)
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_CXX_HAS_RLIMIT64=1)
- ENDIF()
+ endif()
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_ATOL
"Checking whether CXX compiler has atol" DIRECT)
- IF(KWSYS_CXX_HAS_ATOL)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ if(KWSYS_CXX_HAS_ATOL)
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_CXX_HAS_ATOL=1)
- ENDIF()
+ endif()
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_ATOLL
"Checking whether CXX compiler has atoll" DIRECT)
- IF(KWSYS_CXX_HAS_ATOLL)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ if(KWSYS_CXX_HAS_ATOLL)
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_CXX_HAS_ATOLL=1)
- ENDIF()
+ endif()
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS__ATOI64
"Checking whether CXX compiler has _atoi64" DIRECT)
- IF(KWSYS_CXX_HAS__ATOI64)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ if(KWSYS_CXX_HAS__ATOI64)
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_CXX_HAS__ATOI64=1)
- ENDIF()
- IF(UNIX)
- INCLUDE(CheckIncludeFileCXX)
+ endif()
+ if(UNIX)
+ include(CheckIncludeFileCXX)
# check for simple stack trace
# usually it's in libc but on FreeBSD
# it's in libexecinfo
- FIND_LIBRARY(EXECINFO_LIB "execinfo")
- MARK_AS_ADVANCED(EXECINFO_LIB)
- IF (NOT EXECINFO_LIB)
- SET(EXECINFO_LIB "")
- ENDIF()
+ find_library(EXECINFO_LIB "execinfo")
+ mark_as_advanced(EXECINFO_LIB)
+ if (NOT EXECINFO_LIB)
+ set(EXECINFO_LIB "")
+ endif()
CHECK_INCLUDE_FILE_CXX("execinfo.h" KWSYS_CXX_HAS_EXECINFOH)
- IF (KWSYS_CXX_HAS_EXECINFOH)
+ if (KWSYS_CXX_HAS_EXECINFOH)
# we have the backtrace header check if it
# can be used with this compiler
- SET(KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES ${EXECINFO_LIB})
+ set(KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES ${EXECINFO_LIB})
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_BACKTRACE
"Checking whether backtrace works with this C++ compiler" DIRECT)
- SET(KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES)
- IF (KWSYS_CXX_HAS_BACKTRACE)
+ set(KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES)
+ if (KWSYS_CXX_HAS_BACKTRACE)
# backtrace is supported by this system and compiler.
# now check for the more advanced capabilities.
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_SYSTEMINFORMATION_HAS_BACKTRACE=1)
# check for symbol lookup using dladdr
CHECK_INCLUDE_FILE_CXX("dlfcn.h" KWSYS_CXX_HAS_DLFCNH)
- IF (KWSYS_CXX_HAS_DLFCNH)
+ if (KWSYS_CXX_HAS_DLFCNH)
# we have symbol lookup libraries and headers
# check if they can be used with this compiler
- SET(KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES ${CMAKE_DL_LIBS})
+ set(KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES ${CMAKE_DL_LIBS})
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_DLADDR
"Checking whether dladdr works with this C++ compiler" DIRECT)
- SET(KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES)
- IF (KWSYS_CXX_HAS_DLADDR)
+ set(KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES)
+ if (KWSYS_CXX_HAS_DLADDR)
# symbol lookup is supported by this system
# and compiler.
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP=1)
- ENDIF()
- ENDIF()
+ endif()
+ endif()
# c++ demangling support
# check for cxxabi headers
CHECK_INCLUDE_FILE_CXX("cxxabi.h" KWSYS_CXX_HAS_CXXABIH)
- IF (KWSYS_CXX_HAS_CXXABIH)
+ if (KWSYS_CXX_HAS_CXXABIH)
# check if cxxabi can be used with this
# system and compiler.
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_CXXABI
"Checking whether cxxabi works with this C++ compiler" DIRECT)
- IF (KWSYS_CXX_HAS_CXXABI)
+ if (KWSYS_CXX_HAS_CXXABI)
# c++ demangle using cxxabi is supported with
# this system and compiler
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_SYSTEMINFORMATION_HAS_CPP_DEMANGLE=1)
- ENDIF()
- ENDIF()
+ endif()
+ endif()
# basic backtrace works better with release build
# don't bother with advanced features for release
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS_DEBUG KWSYS_SYSTEMINFORMATION_HAS_DEBUG_BUILD=1)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS_RELWITHDEBINFO KWSYS_SYSTEMINFORMATION_HAS_DEBUG_BUILD=1)
- ENDIF()
- ENDIF()
- ENDIF()
- IF(BORLAND)
+ endif()
+ endif()
+ endif()
+ if(BORLAND)
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_BORLAND_ASM
"Checking whether Borland CXX compiler supports assembler instructions" DIRECT)
- IF(KWSYS_CXX_HAS_BORLAND_ASM)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ if(KWSYS_CXX_HAS_BORLAND_ASM)
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_CXX_HAS_BORLAND_ASM=1)
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_BORLAND_ASM_CPUID
"Checking whether Borland CXX compiler supports CPUID assembler instruction" DIRECT)
- IF(KWSYS_CXX_HAS_BORLAND_ASM_CPUID)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ if(KWSYS_CXX_HAS_BORLAND_ASM_CPUID)
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_CXX_HAS_BORLAND_ASM_CPUID=1)
- ENDIF()
- ENDIF()
- ENDIF()
- IF(KWSYS_USE___INT64)
- SET_PROPERTY(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
+ endif()
+ endif()
+ endif()
+ if(KWSYS_USE___INT64)
+ set_property(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_USE___INT64=1)
- ENDIF()
- IF(KWSYS_USE_LONG_LONG)
- SET_PROPERTY(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
+ endif()
+ if(KWSYS_USE_LONG_LONG)
+ set_property(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_USE_LONG_LONG=1)
- ENDIF()
- IF(KWSYS_IOS_HAS_OSTREAM_LONG_LONG)
- SET_PROPERTY(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
+ endif()
+ if(KWSYS_IOS_HAS_OSTREAM_LONG_LONG)
+ set_property(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_IOS_HAS_OSTREAM_LONG_LONG=1)
- ENDIF()
- IF(KWSYS_IOS_HAS_OSTREAM___INT64)
- SET_PROPERTY(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
+ endif()
+ if(KWSYS_IOS_HAS_OSTREAM___INT64)
+ set_property(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_IOS_HAS_OSTREAM___INT64=1)
- ENDIF()
- IF(KWSYS_BUILD_SHARED)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ endif()
+ if(KWSYS_BUILD_SHARED)
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_BUILD_SHARED=1)
- ENDIF()
+ endif()
- IF(UNIX AND NOT CYGWIN)
+ if(UNIX AND NOT CYGWIN)
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_GETLOADAVG
"Checking whether CXX compiler has getloadavg" DIRECT)
- IF(KWSYS_CXX_HAS_GETLOADAVG)
- SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ if(KWSYS_CXX_HAS_GETLOADAVG)
+ set_property(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_CXX_HAS_GETLOADAVG=1)
- ENDIF()
- ENDIF()
-ENDIF()
+ endif()
+ endif()
+endif()
-IF(KWSYS_USE_FStream)
+if(KWSYS_USE_FStream)
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H
"Checking whether <ext/stdio_filebuf.h> is available" DIRECT)
-ENDIF()
+endif()
#-----------------------------------------------------------------------------
# Choose a directory for the generated headers.
-IF(NOT KWSYS_HEADER_ROOT)
- SET(KWSYS_HEADER_ROOT "${PROJECT_BINARY_DIR}")
-ENDIF()
-SET(KWSYS_HEADER_DIR "${KWSYS_HEADER_ROOT}/${KWSYS_NAMESPACE}")
-INCLUDE_DIRECTORIES(${KWSYS_HEADER_ROOT})
+if(NOT KWSYS_HEADER_ROOT)
+ set(KWSYS_HEADER_ROOT "${PROJECT_BINARY_DIR}")
+endif()
+set(KWSYS_HEADER_DIR "${KWSYS_HEADER_ROOT}/${KWSYS_NAMESPACE}")
+include_directories(${KWSYS_HEADER_ROOT})
#-----------------------------------------------------------------------------
-IF(KWSYS_INSTALL_DOC_DIR)
+if(KWSYS_INSTALL_DOC_DIR)
# Assign the license to the runtime component since it must be
# distributed with binary forms of this software.
- IF(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME)
- SET(KWSYS_INSTALL_LICENSE_OPTIONS ${KWSYS_INSTALL_LICENSE_OPTIONS}
+ if(KWSYS_INSTALL_COMPONENT_NAME_RUNTIME)
+ set(KWSYS_INSTALL_LICENSE_OPTIONS ${KWSYS_INSTALL_LICENSE_OPTIONS}
COMPONENT ${KWSYS_INSTALL_COMPONENT_NAME_RUNTIME}
)
- ENDIF()
+ endif()
# Install the license under the documentation directory.
- INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/Copyright.txt
+ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/Copyright.txt
DESTINATION ${KWSYS_INSTALL_DOC_DIR}/${KWSYS_NAMESPACE}
${KWSYS_INSTALL_LICENSE_OPTIONS})
-ENDIF()
+endif()
#-----------------------------------------------------------------------------
# Build a list of classes and headers we need to implement the
# selected components. Initialize with required components.
-SET(KWSYS_CLASSES)
-SET(KWSYS_H_FILES Configure SharedForward)
-SET(KWSYS_HXX_FILES Configure String)
+set(KWSYS_CLASSES)
+set(KWSYS_H_FILES Configure SharedForward)
+set(KWSYS_HXX_FILES Configure String)
-IF(NOT CMake_SOURCE_DIR)
- SET(KWSYS_HXX_FILES ${KWSYS_HXX_FILES}
+if(NOT CMake_SOURCE_DIR)
+ set(KWSYS_HXX_FILES ${KWSYS_HXX_FILES}
hashtable hash_fun hash_map hash_set
)
-ENDIF()
+endif()
# Add selected C++ classes.
-SET(cppclasses
+set(cppclasses
Directory DynamicLoader Encoding Glob RegularExpression SystemTools
CommandLineArguments IOStream FStream SystemInformation ConsoleBuf
)
-FOREACH(cpp ${cppclasses})
- IF(KWSYS_USE_${cpp})
+foreach(cpp ${cppclasses})
+ if(KWSYS_USE_${cpp})
# Use the corresponding class.
- SET(KWSYS_CLASSES ${KWSYS_CLASSES} ${cpp})
+ set(KWSYS_CLASSES ${KWSYS_CLASSES} ${cpp})
# Load component-specific CMake code.
- IF(EXISTS ${PROJECT_SOURCE_DIR}/kwsys${cpp}.cmake)
- INCLUDE(${PROJECT_SOURCE_DIR}/kwsys${cpp}.cmake)
- ENDIF()
- ENDIF()
-ENDFOREACH()
+ if(EXISTS ${PROJECT_SOURCE_DIR}/kwsys${cpp}.cmake)
+ include(${PROJECT_SOURCE_DIR}/kwsys${cpp}.cmake)
+ endif()
+ endif()
+endforeach()
# Add selected C components.
-FOREACH(c
+foreach(c
Process Base64 Encoding MD5 Terminal System String
)
- IF(KWSYS_USE_${c})
+ if(KWSYS_USE_${c})
# Use the corresponding header file.
- SET(KWSYS_H_FILES ${KWSYS_H_FILES} ${c})
+ set(KWSYS_H_FILES ${KWSYS_H_FILES} ${c})
# Load component-specific CMake code.
- IF(EXISTS ${PROJECT_SOURCE_DIR}/kwsys${c}.cmake)
- INCLUDE(${PROJECT_SOURCE_DIR}/kwsys${c}.cmake)
- ENDIF()
- ENDIF()
-ENDFOREACH()
+ if(EXISTS ${PROJECT_SOURCE_DIR}/kwsys${c}.cmake)
+ include(${PROJECT_SOURCE_DIR}/kwsys${c}.cmake)
+ endif()
+ endif()
+endforeach()
#-----------------------------------------------------------------------------
# Build a list of sources for the library based on components that are
# included.
-SET(KWSYS_C_SRCS)
-SET(KWSYS_CXX_SRCS)
+set(KWSYS_C_SRCS)
+set(KWSYS_CXX_SRCS)
# Add the proper sources for this platform's Process implementation.
-IF(KWSYS_USE_Process)
- IF(NOT UNIX)
+if(KWSYS_USE_Process)
+ if(NOT UNIX)
# Use the Windows implementation.
- SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessWin32.c)
- ELSE()
+ set(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessWin32.c)
+ else()
# Use the UNIX implementation.
- SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessUNIX.c)
- ENDIF()
-ENDIF()
+ set(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessUNIX.c)
+ endif()
+endif()
# Add selected C sources.
-FOREACH(c Base64 Encoding MD5 Terminal System String)
- IF(KWSYS_USE_${c})
- IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}C.c)
- LIST(APPEND KWSYS_C_SRCS ${c}C.c)
- ELSE()
- LIST(APPEND KWSYS_C_SRCS ${c}.c)
- ENDIF()
- ENDIF()
-ENDFOREACH()
+foreach(c Base64 Encoding MD5 Terminal System String)
+ if(KWSYS_USE_${c})
+ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}C.c)
+ list(APPEND KWSYS_C_SRCS ${c}C.c)
+ else()
+ list(APPEND KWSYS_C_SRCS ${c}.c)
+ endif()
+ endif()
+endforeach()
# Configure headers of C++ classes and construct the list of sources.
-FOREACH(c ${KWSYS_CLASSES})
+foreach(c ${KWSYS_CLASSES})
# Add this source to the list of source files for the library.
- IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}CXX.cxx)
- LIST(APPEND KWSYS_CXX_SRCS ${c}CXX.cxx)
- ELSEIF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}.cxx)
- LIST(APPEND KWSYS_CXX_SRCS ${c}.cxx)
- ENDIF()
+ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}CXX.cxx)
+ list(APPEND KWSYS_CXX_SRCS ${c}CXX.cxx)
+ elseif(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${c}.cxx)
+ list(APPEND KWSYS_CXX_SRCS ${c}.cxx)
+ endif()
# Configure the header for this class.
- CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/${c}.hxx.in ${KWSYS_HEADER_DIR}/${c}.hxx
+ configure_file(${PROJECT_SOURCE_DIR}/${c}.hxx.in ${KWSYS_HEADER_DIR}/${c}.hxx
@ONLY IMMEDIATE)
- SET(KWSYS_CXX_SRCS ${KWSYS_CXX_SRCS} ${KWSYS_HEADER_DIR}/${c}.hxx)
+ set(KWSYS_CXX_SRCS ${KWSYS_CXX_SRCS} ${KWSYS_HEADER_DIR}/${c}.hxx)
# Create an install target for the header.
- IF(KWSYS_INSTALL_INCLUDE_DIR)
- INSTALL(FILES ${KWSYS_HEADER_DIR}/${c}.hxx
+ if(KWSYS_INSTALL_INCLUDE_DIR)
+ install(FILES ${KWSYS_HEADER_DIR}/${c}.hxx
DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}
${KWSYS_INSTALL_INCLUDE_OPTIONS})
- ENDIF()
-ENDFOREACH()
+ endif()
+endforeach()
# Configure C headers.
-FOREACH(h ${KWSYS_H_FILES})
+foreach(h ${KWSYS_H_FILES})
# Configure the header into the given directory.
- CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/${h}.h.in ${KWSYS_HEADER_DIR}/${h}.h
+ configure_file(${PROJECT_SOURCE_DIR}/${h}.h.in ${KWSYS_HEADER_DIR}/${h}.h
@ONLY IMMEDIATE)
- SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ${KWSYS_HEADER_DIR}/${h}.h)
+ set(KWSYS_C_SRCS ${KWSYS_C_SRCS} ${KWSYS_HEADER_DIR}/${h}.h)
# Create an install target for the header.
- IF(KWSYS_INSTALL_INCLUDE_DIR)
- INSTALL(FILES ${KWSYS_HEADER_DIR}/${h}.h
+ if(KWSYS_INSTALL_INCLUDE_DIR)
+ install(FILES ${KWSYS_HEADER_DIR}/${h}.h
DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}
${KWSYS_INSTALL_INCLUDE_OPTIONS})
- ENDIF()
-ENDFOREACH()
+ endif()
+endforeach()
# Configure other C++ headers.
-FOREACH(h ${KWSYS_HXX_FILES})
+foreach(h ${KWSYS_HXX_FILES})
# Configure the header into the given directory.
- CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/${h}.hxx.in ${KWSYS_HEADER_DIR}/${h}.hxx
+ configure_file(${PROJECT_SOURCE_DIR}/${h}.hxx.in ${KWSYS_HEADER_DIR}/${h}.hxx
@ONLY IMMEDIATE)
- SET(KWSYS_CXX_SRCS ${KWSYS_CXX_SRCS} ${KWSYS_HEADER_DIR}/${h}.hxx)
+ set(KWSYS_CXX_SRCS ${KWSYS_CXX_SRCS} ${KWSYS_HEADER_DIR}/${h}.hxx)
# Create an install target for the header.
- IF(KWSYS_INSTALL_INCLUDE_DIR)
- INSTALL(FILES ${KWSYS_HEADER_DIR}/${h}.hxx
+ if(KWSYS_INSTALL_INCLUDE_DIR)
+ install(FILES ${KWSYS_HEADER_DIR}/${h}.hxx
DESTINATION ${KWSYS_INSTALL_INCLUDE_DIR}/${KWSYS_NAMESPACE}
${KWSYS_INSTALL_INCLUDE_OPTIONS})
- ENDIF()
-ENDFOREACH()
+ endif()
+endforeach()
#-----------------------------------------------------------------------------
# Add the library with the configured name and list of sources.
-IF(KWSYS_C_SRCS OR KWSYS_CXX_SRCS)
- IF(KWSYS_SPLIT_OBJECTS_FROM_INTERFACE)
- SET(KWSYS_TARGET_INTERFACE ${KWSYS_NAMESPACE})
- SET(KWSYS_TARGET_OBJECT ${KWSYS_NAMESPACE}_objects)
- SET(KWSYS_TARGET_LINK ${KWSYS_NAMESPACE}_private)
- SET(KWSYS_TARGET_INSTALL ${KWSYS_TARGET_INTERFACE} ${KWSYS_TARGET_LINK})
- SET(KWSYS_LINK_DEPENDENCY INTERFACE)
- ADD_LIBRARY(${KWSYS_TARGET_OBJECT} OBJECT
+if(KWSYS_C_SRCS OR KWSYS_CXX_SRCS)
+ if(KWSYS_SPLIT_OBJECTS_FROM_INTERFACE)
+ set(KWSYS_TARGET_INTERFACE ${KWSYS_NAMESPACE})
+ set(KWSYS_TARGET_OBJECT ${KWSYS_NAMESPACE}_objects)
+ set(KWSYS_TARGET_LINK ${KWSYS_NAMESPACE}_private)
+ set(KWSYS_TARGET_INSTALL ${KWSYS_TARGET_INTERFACE} ${KWSYS_TARGET_LINK})
+ set(KWSYS_LINK_DEPENDENCY INTERFACE)
+ add_library(${KWSYS_TARGET_OBJECT} OBJECT
${KWSYS_C_SRCS} ${KWSYS_CXX_SRCS})
- IF(KWSYS_BUILD_SHARED OR KWSYS_BUILD_PIC)
- SET_PROPERTY(TARGET ${KWSYS_TARGET_OBJECT} PROPERTY
+ if(KWSYS_BUILD_SHARED OR KWSYS_BUILD_PIC)
+ set_property(TARGET ${KWSYS_TARGET_OBJECT} PROPERTY
POSITION_INDEPENDENT_CODE TRUE)
- ENDIF()
- ADD_LIBRARY(${KWSYS_TARGET_INTERFACE} INTERFACE)
- ADD_LIBRARY(${KWSYS_TARGET_LINK} INTERFACE)
- TARGET_LINK_LIBRARIES(${KWSYS_TARGET_LINK} INTERFACE
+ endif()
+ add_library(${KWSYS_TARGET_INTERFACE} INTERFACE)
+ add_library(${KWSYS_TARGET_LINK} INTERFACE)
+ target_link_libraries(${KWSYS_TARGET_LINK} INTERFACE
${KWSYS_TARGET_INTERFACE})
- TARGET_SOURCES(${KWSYS_TARGET_LINK} INTERFACE
+ target_sources(${KWSYS_TARGET_LINK} INTERFACE
$<TARGET_OBJECTS:${KWSYS_TARGET_OBJECT}>)
target_compile_features(${KWSYS_TARGET_OBJECT} PRIVATE ${KWSYS_CXX_COMPILE_FEATURES})
target_compile_features(${KWSYS_TARGET_INTERFACE} INTERFACE ${KWSYS_CXX_COMPILE_FEATURES})
- ELSE()
- SET(KWSYS_TARGET_INTERFACE ${KWSYS_NAMESPACE})
- SET(KWSYS_TARGET_OBJECT ${KWSYS_NAMESPACE})
- SET(KWSYS_TARGET_LINK ${KWSYS_NAMESPACE})
+ else()
+ set(KWSYS_TARGET_INTERFACE ${KWSYS_NAMESPACE})
+ set(KWSYS_TARGET_OBJECT ${KWSYS_NAMESPACE})
+ set(KWSYS_TARGET_LINK ${KWSYS_NAMESPACE})
set(KWSYS_TARGET_INSTALL ${KWSYS_TARGET_LINK})
- SET(KWSYS_LINK_DEPENDENCY PUBLIC)
- ADD_LIBRARY(${KWSYS_TARGET_INTERFACE} ${KWSYS_LIBRARY_TYPE}
+ set(KWSYS_LINK_DEPENDENCY PUBLIC)
+ add_library(${KWSYS_TARGET_INTERFACE} ${KWSYS_LIBRARY_TYPE}
${KWSYS_C_SRCS} ${KWSYS_CXX_SRCS})
target_compile_features(${KWSYS_TARGET_INTERFACE} PUBLIC ${KWSYS_CXX_COMPILE_FEATURES})
- ENDIF()
+ endif()
if (KWSYS_ALIAS_TARGET)
add_library(${KWSYS_ALIAS_TARGET} ALIAS ${KWSYS_TARGET_INTERFACE})
endif ()
- SET_TARGET_PROPERTIES(${KWSYS_TARGET_OBJECT} PROPERTIES
+ set_target_properties(${KWSYS_TARGET_OBJECT} PROPERTIES
C_CLANG_TIDY ""
CXX_CLANG_TIDY ""
C_INCLUDE_WHAT_YOU_USE ""
CXX_INCLUDE_WHAT_YOU_USE ""
LABELS "${KWSYS_LABELS_LIB}")
- IF(KWSYS_USE_DynamicLoader)
- IF(UNIX)
- TARGET_LINK_LIBRARIES(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY}
+ if(KWSYS_USE_DynamicLoader)
+ if(UNIX)
+ target_link_libraries(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY}
${CMAKE_DL_LIBS})
- ENDIF()
- ENDIF()
+ endif()
+ endif()
- IF(KWSYS_USE_SystemInformation)
- IF(WIN32)
- TARGET_LINK_LIBRARIES(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY} ws2_32)
+ if(KWSYS_USE_SystemInformation)
+ if(WIN32)
+ target_link_libraries(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY} ws2_32)
# link in dbghelp.dll for symbol lookup if MSVC 1800 or later
# Note that the dbghelp runtime is part of MS Windows OS
- IF(MSVC_VERSION AND NOT MSVC_VERSION VERSION_LESS 1800)
- TARGET_LINK_LIBRARIES(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY} dbghelp)
- ENDIF()
- IF(KWSYS_SYS_HAS_PSAPI)
- TARGET_LINK_LIBRARIES(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY}
- Psapi)
- ENDIF()
- ELSEIF(UNIX)
- IF (EXECINFO_LIB AND KWSYS_CXX_HAS_BACKTRACE)
+ if(MSVC_VERSION AND NOT MSVC_VERSION VERSION_LESS 1800)
+ target_link_libraries(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY} dbghelp)
+ endif()
+ if(KWSYS_SYS_HAS_PSAPI)
+ target_link_libraries(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY}
+ psapi)
+ endif()
+ elseif(UNIX)
+ if (EXECINFO_LIB AND KWSYS_CXX_HAS_BACKTRACE)
# backtrace on FreeBSD is not in libc
- TARGET_LINK_LIBRARIES(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY}
+ target_link_libraries(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY}
${EXECINFO_LIB})
- ENDIF()
- IF (KWSYS_CXX_HAS_DLADDR)
+ endif()
+ if (KWSYS_CXX_HAS_DLADDR)
# for symbol lookup using dladdr
- TARGET_LINK_LIBRARIES(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY}
+ target_link_libraries(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY}
${CMAKE_DL_LIBS})
- ENDIF()
- IF (CMAKE_SYSTEM_NAME STREQUAL "SunOS")
- TARGET_LINK_LIBRARIES(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY}
+ endif()
+ if (CMAKE_SYSTEM_NAME STREQUAL "SunOS")
+ target_link_libraries(${KWSYS_TARGET_INTERFACE} ${KWSYS_LINK_DEPENDENCY}
socket)
- ENDIF()
- ENDIF()
- ENDIF()
+ endif()
+ endif()
+ endif()
# Apply user-defined target properties to the library.
- IF(KWSYS_PROPERTIES_CXX)
- SET_TARGET_PROPERTIES(${KWSYS_TARGET_INTERFACE} PROPERTIES
+ if(KWSYS_PROPERTIES_CXX)
+ set_target_properties(${KWSYS_TARGET_INTERFACE} PROPERTIES
${KWSYS_PROPERTIES_CXX})
- ENDIF()
+ endif()
# Set up include usage requirement
- IF(COMMAND TARGET_INCLUDE_DIRECTORIES)
- TARGET_INCLUDE_DIRECTORIES(${KWSYS_TARGET_INTERFACE} INTERFACE
+ if(COMMAND TARGET_INCLUDE_DIRECTORIES)
+ target_include_directories(${KWSYS_TARGET_INTERFACE} INTERFACE
$<BUILD_INTERFACE:${KWSYS_HEADER_ROOT}>)
- IF(KWSYS_INSTALL_INCLUDE_DIR)
- TARGET_INCLUDE_DIRECTORIES(${KWSYS_TARGET_INTERFACE} INTERFACE
+ if(KWSYS_INSTALL_INCLUDE_DIR)
+ target_include_directories(${KWSYS_TARGET_INTERFACE} INTERFACE
$<INSTALL_INTERFACE:${KWSYS_INSTALL_INCLUDE_DIR}>)
- ENDIF()
- ENDIF()
+ endif()
+ endif()
# Create an install target for the library.
- IF(KWSYS_INSTALL_LIBRARY_RULE)
- INSTALL(TARGETS ${KWSYS_TARGET_INSTALL} ${KWSYS_INSTALL_LIBRARY_RULE})
- ENDIF()
- IF(KWSYS_INSTALL_NAMELINK_RULE)
- INSTALL(TARGETS ${KWSYS_TARGET_INSTALL} ${KWSYS_INSTALL_NAMELINK_RULE})
- ENDIF()
-ENDIF()
+ if(KWSYS_INSTALL_LIBRARY_RULE)
+ install(TARGETS ${KWSYS_TARGET_INSTALL} ${KWSYS_INSTALL_LIBRARY_RULE})
+ endif()
+ if(KWSYS_INSTALL_NAMELINK_RULE)
+ install(TARGETS ${KWSYS_TARGET_INSTALL} ${KWSYS_INSTALL_NAMELINK_RULE})
+ endif()
+endif()
# Add a C-only library if requested.
-IF(KWSYS_ENABLE_C AND KWSYS_C_SRCS)
- IF(KWSYS_SPLIT_OBJECTS_FROM_INTERFACE)
- SET(KWSYS_TARGET_C_INTERFACE ${KWSYS_NAMESPACE}_c)
- SET(KWSYS_TARGET_C_OBJECT ${KWSYS_NAMESPACE}_c_objects)
- SET(KWSYS_TARGET_C_LINK ${KWSYS_NAMESPACE}_c_private)
- SET(KWSYS_TARGET_C_INSTALL
+if(KWSYS_ENABLE_C AND KWSYS_C_SRCS)
+ if(KWSYS_SPLIT_OBJECTS_FROM_INTERFACE)
+ set(KWSYS_TARGET_C_INTERFACE ${KWSYS_NAMESPACE}_c)
+ set(KWSYS_TARGET_C_OBJECT ${KWSYS_NAMESPACE}_c_objects)
+ set(KWSYS_TARGET_C_LINK ${KWSYS_NAMESPACE}_c_private)
+ set(KWSYS_TARGET_C_INSTALL
${KWSYS_TARGET_C_INTERFACE} ${KWSYS_TARGET_C_LINK})
- SET(KWSYS_LINK_DEPENDENCY INTERFACE)
- ADD_LIBRARY(${KWSYS_TARGET_C_OBJECT} OBJECT ${KWSYS_C_SRCS})
- IF(KWSYS_BUILD_SHARED OR KWSYS_BUILD_PIC)
- SET_PROPERTY(TARGET ${KWSYS_TARGET_C_OBJECT} PROPERTY
+ set(KWSYS_LINK_DEPENDENCY INTERFACE)
+ add_library(${KWSYS_TARGET_C_OBJECT} OBJECT ${KWSYS_C_SRCS})
+ if(KWSYS_BUILD_SHARED OR KWSYS_BUILD_PIC)
+ set_property(TARGET ${KWSYS_TARGET_C_OBJECT} PROPERTY
POSITION_INDEPENDENT_CODE TRUE)
- ENDIF()
- ADD_LIBRARY(${KWSYS_TARGET_C_INTERFACE} INTERFACE)
- ADD_LIBRARY(${KWSYS_TARGET_C_LINK} INTERFACE)
- TARGET_LINK_LIBRARIES(${KWSYS_TARGET_C_LINK} INTERFACE
+ endif()
+ add_library(${KWSYS_TARGET_C_INTERFACE} INTERFACE)
+ add_library(${KWSYS_TARGET_C_LINK} INTERFACE)
+ target_link_libraries(${KWSYS_TARGET_C_LINK} INTERFACE
${KWSYS_TARGET_C_INTERFACE})
- TARGET_SOURCES(${KWSYS_TARGET_C_LINK} INTERFACE
+ target_sources(${KWSYS_TARGET_C_LINK} INTERFACE
$<TARGET_OBJECTS:${KWSYS_TARGET_C_OBJECT}>)
- ELSE()
- SET(KWSYS_TARGET_C_INTERFACE ${KWSYS_NAMESPACE}_c)
- SET(KWSYS_TARGET_C_OBJECT ${KWSYS_NAMESPACE}_c)
- SET(KWSYS_TARGET_C_LINK ${KWSYS_NAMESPACE}_c)
- SET(KWSYS_TARGET_C_INSTALL ${KWSYS_TARGET_C_LINK})
- SET(KWSYS_LINK_DEPENDENCY PUBLIC)
- ADD_LIBRARY(${KWSYS_TARGET_C_INTERFACE} ${KWSYS_LIBRARY_TYPE}
+ else()
+ set(KWSYS_TARGET_C_INTERFACE ${KWSYS_NAMESPACE}_c)
+ set(KWSYS_TARGET_C_OBJECT ${KWSYS_NAMESPACE}_c)
+ set(KWSYS_TARGET_C_LINK ${KWSYS_NAMESPACE}_c)
+ set(KWSYS_TARGET_C_INSTALL ${KWSYS_TARGET_C_LINK})
+ set(KWSYS_LINK_DEPENDENCY PUBLIC)
+ add_library(${KWSYS_TARGET_C_INTERFACE} ${KWSYS_LIBRARY_TYPE}
${KWSYS_C_SRCS})
- ENDIF()
- SET_TARGET_PROPERTIES(${KWSYS_TARGET_C_OBJECT} PROPERTIES
+ endif()
+ set_target_properties(${KWSYS_TARGET_C_OBJECT} PROPERTIES
LABELS "${KWSYS_LABELS_LIB}")
# Apply user-defined target properties to the library.
- IF(KWSYS_PROPERTIES_C)
- SET_TARGET_PROPERTIES(${KWSYS_TARGET_C_INTERFACE} PROPERTIES
+ if(KWSYS_PROPERTIES_C)
+ set_target_properties(${KWSYS_TARGET_C_INTERFACE} PROPERTIES
${KWSYS_PROPERTIES_C})
- ENDIF()
+ endif()
# Set up include usage requirement
- IF(COMMAND TARGET_INCLUDE_DIRECTORIES)
- TARGET_INCLUDE_DIRECTORIES(${KWSYS_TARGET_C_INTERFACE} INTERFACE
+ if(COMMAND TARGET_INCLUDE_DIRECTORIES)
+ target_include_directories(${KWSYS_TARGET_C_INTERFACE} INTERFACE
$<BUILD_INTERFACE:${KWSYS_HEADER_ROOT}>)
- IF(KWSYS_INSTALL_INCLUDE_DIR)
- TARGET_INCLUDE_DIRECTORIES(${KWSYS_TARGET_C_INTERFACE} INTERFACE
+ if(KWSYS_INSTALL_INCLUDE_DIR)
+ target_include_directories(${KWSYS_TARGET_C_INTERFACE} INTERFACE
$<INSTALL_INTERFACE:${KWSYS_INSTALL_INCLUDE_DIR}>)
- ENDIF()
- ENDIF()
+ endif()
+ endif()
# Create an install target for the library.
- IF(KWSYS_INSTALL_LIBRARY_RULE)
- INSTALL(TARGETS ${KWSYS_TARGET_C_INSTALL})
- ENDIF()
-ENDIF()
+ if(KWSYS_INSTALL_LIBRARY_RULE)
+ install(TARGETS ${KWSYS_TARGET_C_INSTALL})
+ endif()
+endif()
# For building kwsys itself, we use a macro defined on the command
# line to configure the namespace in the C and C++ source files.
-ADD_DEFINITIONS("-DKWSYS_NAMESPACE=${KWSYS_NAMESPACE}")
+add_definitions("-DKWSYS_NAMESPACE=${KWSYS_NAMESPACE}")
# Disable deprecation warnings for standard C functions.
-IF(MSVC OR (WIN32 AND (CMAKE_C_COMPILER_ID STREQUAL "Intel" OR
+if(MSVC OR (WIN32 AND (CMAKE_C_COMPILER_ID STREQUAL "Intel" OR
(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC"))))
- ADD_DEFINITIONS(
+ add_definitions(
-D_CRT_NONSTDC_NO_DEPRECATE
-D_CRT_SECURE_NO_DEPRECATE
-D_CRT_SECURE_NO_WARNINGS
-D_SCL_SECURE_NO_DEPRECATE
)
-ENDIF()
+endif()
-IF(WIN32)
+if(WIN32)
# Help enforce the use of wide Windows apis.
- ADD_DEFINITIONS(-DUNICODE -D_UNICODE)
-ENDIF()
+ add_definitions(-DUNICODE -D_UNICODE)
+endif()
-IF(KWSYS_USE_String)
+if(KWSYS_USE_String)
# Activate code in "String.c". See the comment in the source.
- SET_SOURCE_FILES_PROPERTIES(String.c PROPERTIES
+ set_source_files_properties(String.c PROPERTIES
COMPILE_FLAGS "-DKWSYS_STRING_C")
-ENDIF()
+endif()
-IF(KWSYS_USE_Encoding)
+if(KWSYS_USE_Encoding)
# Set default 8 bit encoding in "EndcodingC.c".
- SET_PROPERTY(SOURCE EncodingC.c EncodingCXX.cxx APPEND PROPERTY COMPILE_DEFINITIONS
+ set_property(SOURCE EncodingC.c EncodingCXX.cxx APPEND PROPERTY COMPILE_DEFINITIONS
KWSYS_ENCODING_DEFAULT_CODEPAGE=${KWSYS_ENCODING_DEFAULT_CODEPAGE})
-ENDIF()
+endif()
#-----------------------------------------------------------------------------
# Setup testing if not being built as part of another project.
-IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
- IF(BUILD_TESTING)
+if(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
+ if(BUILD_TESTING)
# Compute the location of executables.
- SET(EXEC_DIR "${CMAKE_CURRENT_BINARY_DIR}")
- IF(EXECUTABLE_OUTPUT_PATH)
- SET(EXEC_DIR "${EXECUTABLE_OUTPUT_PATH}")
- ENDIF()
+ set(EXEC_DIR "${CMAKE_CURRENT_BINARY_DIR}")
+ if(CMAKE_RUNTIME_OUTPUT_DIRECTORY)
+ set(EXEC_DIR "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
+ endif()
# C tests
- SET(KWSYS_C_TESTS
+ set(KWSYS_C_TESTS
testEncode.c
testTerminal.c
)
- IF(KWSYS_STANDALONE)
- SET(KWSYS_C_TESTS ${KWSYS_C_TESTS} testFail.c)
- ENDIF()
- CREATE_TEST_SOURCELIST(
+ if(KWSYS_STANDALONE)
+ set(KWSYS_C_TESTS ${KWSYS_C_TESTS} testFail.c)
+ endif()
+ create_test_sourcelist(
KWSYS_C_TEST_SRCS ${KWSYS_NAMESPACE}TestsC.c
${KWSYS_C_TESTS}
)
- ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestsC ${KWSYS_C_TEST_SRCS})
- SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsC PROPERTY LABELS ${KWSYS_LABELS_EXE})
- TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE}TestsC ${KWSYS_TARGET_C_LINK})
- FOREACH(testfile ${KWSYS_C_TESTS})
+ add_executable(${KWSYS_NAMESPACE}TestsC ${KWSYS_C_TEST_SRCS})
+ set_property(TARGET ${KWSYS_NAMESPACE}TestsC PROPERTY LABELS ${KWSYS_LABELS_EXE})
+ target_link_libraries(${KWSYS_NAMESPACE}TestsC ${KWSYS_TARGET_C_LINK})
+ foreach(testfile ${KWSYS_C_TESTS})
get_filename_component(test "${testfile}" NAME_WE)
- ADD_TEST(kwsys.${test} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestsC ${test} ${KWSYS_TEST_ARGS_${test}})
- SET_PROPERTY(TEST kwsys.${test} PROPERTY LABELS ${KWSYS_LABELS_TEST})
- ENDFOREACH()
+ add_test(kwsys.${test} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestsC ${test} ${KWSYS_TEST_ARGS_${test}})
+ set_property(TEST kwsys.${test} PROPERTY LABELS ${KWSYS_LABELS_TEST})
+ endforeach()
# C++ tests
- IF(NOT WATCOM AND NOT CMake_SOURCE_DIR)
- SET(KWSYS_CXX_TESTS
+ if(NOT WATCOM AND NOT CMake_SOURCE_DIR)
+ set(KWSYS_CXX_TESTS
testHashSTL.cxx
)
- ENDIF()
- SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
+ endif()
+ set(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
testConfigure.cxx
testSystemTools.cxx
testCommandLineArguments.cxx
testCommandLineArguments1.cxx
testDirectory.cxx
)
- IF(KWSYS_STL_HAS_WSTRING)
- SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
+ if(KWSYS_STL_HAS_WSTRING)
+ set(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
testEncoding.cxx
)
- ENDIF()
- IF(KWSYS_USE_FStream)
- SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
+ endif()
+ if(KWSYS_USE_FStream)
+ set(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
testFStream.cxx
)
- ENDIF()
- IF(KWSYS_USE_ConsoleBuf)
- ADD_EXECUTABLE(testConsoleBufChild testConsoleBufChild.cxx)
- SET_PROPERTY(TARGET testConsoleBufChild PROPERTY C_CLANG_TIDY "")
- SET_PROPERTY(TARGET testConsoleBufChild PROPERTY CXX_CLANG_TIDY "")
- SET_PROPERTY(TARGET testConsoleBufChild PROPERTY C_INCLUDE_WHAT_YOU_USE "")
- SET_PROPERTY(TARGET testConsoleBufChild PROPERTY CXX_INCLUDE_WHAT_YOU_USE "")
- SET_PROPERTY(TARGET testConsoleBufChild PROPERTY LABELS ${KWSYS_LABELS_EXE})
- TARGET_LINK_LIBRARIES(testConsoleBufChild ${KWSYS_TARGET_LINK})
- SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
+ endif()
+ if(KWSYS_USE_ConsoleBuf)
+ add_executable(testConsoleBufChild testConsoleBufChild.cxx)
+ set_property(TARGET testConsoleBufChild PROPERTY C_CLANG_TIDY "")
+ set_property(TARGET testConsoleBufChild PROPERTY CXX_CLANG_TIDY "")
+ set_property(TARGET testConsoleBufChild PROPERTY C_INCLUDE_WHAT_YOU_USE "")
+ set_property(TARGET testConsoleBufChild PROPERTY CXX_INCLUDE_WHAT_YOU_USE "")
+ set_property(TARGET testConsoleBufChild PROPERTY LABELS ${KWSYS_LABELS_EXE})
+ target_link_libraries(testConsoleBufChild ${KWSYS_TARGET_LINK})
+ set(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
testConsoleBuf.cxx
)
- IF(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND
+ if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND
CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "19.0.23506")
set_property(SOURCE testConsoleBuf.cxx testConsoleBufChild.cxx PROPERTY COMPILE_FLAGS /utf-8)
- ENDIF()
- SET_PROPERTY(SOURCE testConsoleBuf.cxx APPEND PROPERTY COMPILE_DEFINITIONS
+ endif()
+ set_property(SOURCE testConsoleBuf.cxx APPEND PROPERTY COMPILE_DEFINITIONS
KWSYS_ENCODING_DEFAULT_CODEPAGE=${KWSYS_ENCODING_DEFAULT_CODEPAGE})
- ENDIF()
- IF(KWSYS_USE_SystemInformation)
- SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testSystemInformation.cxx)
- ENDIF()
- IF(KWSYS_USE_DynamicLoader)
- SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testDynamicLoader.cxx)
+ endif()
+ if(KWSYS_USE_SystemInformation)
+ set(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testSystemInformation.cxx)
+ endif()
+ if(KWSYS_USE_DynamicLoader)
+ set(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testDynamicLoader.cxx)
# If kwsys contains the DynamicLoader, need extra library
- ADD_LIBRARY(${KWSYS_NAMESPACE}TestDynload MODULE testDynload.c)
- SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestDynload PROPERTY LABELS ${KWSYS_LABELS_LIB})
- ADD_DEPENDENCIES(${KWSYS_NAMESPACE}TestDynload ${KWSYS_TARGET_INTERFACE})
+ add_library(${KWSYS_NAMESPACE}TestDynload MODULE testDynload.c)
+ set_property(TARGET ${KWSYS_NAMESPACE}TestDynload PROPERTY LABELS ${KWSYS_LABELS_LIB})
+ add_dependencies(${KWSYS_NAMESPACE}TestDynload ${KWSYS_TARGET_INTERFACE})
if (WIN32)
# Windows tests supported flags.
@@ -1134,33 +1134,33 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
add_dependencies(${KWSYS_NAMESPACE}TestDynloadUse ${KWSYS_TARGET_INTERFACE})
target_link_libraries(${KWSYS_NAMESPACE}TestDynloadUse PRIVATE ${KWSYS_NAMESPACE}TestDynloadImpl)
endif ()
- ENDIF()
- CREATE_TEST_SOURCELIST(
+ endif()
+ create_test_sourcelist(
KWSYS_CXX_TEST_SRCS ${KWSYS_NAMESPACE}TestsCxx.cxx
${KWSYS_CXX_TESTS}
)
- ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestsCxx ${KWSYS_CXX_TEST_SRCS})
- SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY C_CLANG_TIDY "")
- SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY CXX_CLANG_TIDY "")
- SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY C_INCLUDE_WHAT_YOU_USE "")
- SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY CXX_INCLUDE_WHAT_YOU_USE "")
- SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY LABELS ${KWSYS_LABELS_EXE})
- TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE}TestsCxx ${KWSYS_TARGET_LINK})
-
- SET(TEST_SYSTEMTOOLS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
- SET(TEST_SYSTEMTOOLS_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
- CONFIGURE_FILE(
+ add_executable(${KWSYS_NAMESPACE}TestsCxx ${KWSYS_CXX_TEST_SRCS})
+ set_property(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY C_CLANG_TIDY "")
+ set_property(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY CXX_CLANG_TIDY "")
+ set_property(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY C_INCLUDE_WHAT_YOU_USE "")
+ set_property(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY CXX_INCLUDE_WHAT_YOU_USE "")
+ set_property(TARGET ${KWSYS_NAMESPACE}TestsCxx PROPERTY LABELS ${KWSYS_LABELS_EXE})
+ target_link_libraries(${KWSYS_NAMESPACE}TestsCxx ${KWSYS_TARGET_LINK})
+
+ set(TEST_SYSTEMTOOLS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+ set(TEST_SYSTEMTOOLS_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
+ configure_file(
${PROJECT_SOURCE_DIR}/testSystemTools.h.in
${PROJECT_BINARY_DIR}/testSystemTools.h)
- INCLUDE_DIRECTORIES(${PROJECT_BINARY_DIR})
+ include_directories(${PROJECT_BINARY_DIR})
- IF(CTEST_TEST_KWSYS)
- CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/ExtraTest.cmake.in"
+ if(CTEST_TEST_KWSYS)
+ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/ExtraTest.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/ExtraTest.cmake")
- SET_DIRECTORY_PROPERTIES(PROPERTIES TEST_INCLUDE_FILE "${CMAKE_CURRENT_BINARY_DIR}/ExtraTest.cmake")
- ENDIF()
+ set_directory_properties(PROPERTIES TEST_INCLUDE_FILE "${CMAKE_CURRENT_BINARY_DIR}/ExtraTest.cmake")
+ endif()
- SET(KWSYS_TEST_ARGS_testCommandLineArguments
+ set(KWSYS_TEST_ARGS_testCommandLineArguments
--another-bool-variable
--long3=opt
--set-bool-arg1
@@ -1179,7 +1179,7 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
-C=test
--long2 hello
)
- SET(KWSYS_TEST_ARGS_testCommandLineArguments1
+ set(KWSYS_TEST_ARGS_testCommandLineArguments1
--ignored
-n 24
--second-ignored
@@ -1188,73 +1188,71 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
-p
some junk at the end
)
- FOREACH(testfile ${KWSYS_CXX_TESTS})
+ foreach(testfile ${KWSYS_CXX_TESTS})
get_filename_component(test "${testfile}" NAME_WE)
- ADD_TEST(kwsys.${test} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestsCxx ${test} ${KWSYS_TEST_ARGS_${test}})
- SET_PROPERTY(TEST kwsys.${test} PROPERTY LABELS ${KWSYS_LABELS_TEST})
- ENDFOREACH()
+ add_test(kwsys.${test} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestsCxx ${test} ${KWSYS_TEST_ARGS_${test}})
+ set_property(TEST kwsys.${test} PROPERTY LABELS ${KWSYS_LABELS_TEST})
+ endforeach()
# Process tests.
- ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestProcess testProcess.c)
- SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestProcess PROPERTY LABELS ${KWSYS_LABELS_EXE})
- TARGET_LINK_LIBRARIES(${KWSYS_NAMESPACE}TestProcess ${KWSYS_TARGET_C_LINK})
- IF(NOT CYGWIN)
- SET(KWSYS_TEST_PROCESS_7 7)
- ENDIF()
- FOREACH(n 1 2 3 4 5 6 ${KWSYS_TEST_PROCESS_7} 9 10)
- ADD_TEST(kwsys.testProcess-${n} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestProcess ${n})
- SET_PROPERTY(TEST kwsys.testProcess-${n} PROPERTY LABELS ${KWSYS_LABELS_TEST})
- SET_TESTS_PROPERTIES(kwsys.testProcess-${n} PROPERTIES TIMEOUT 120)
- ENDFOREACH()
-
- SET(testProcess_COMPILE_FLAGS "")
+ add_executable(${KWSYS_NAMESPACE}TestProcess testProcess.c)
+ set_property(TARGET ${KWSYS_NAMESPACE}TestProcess PROPERTY LABELS ${KWSYS_LABELS_EXE})
+ target_link_libraries(${KWSYS_NAMESPACE}TestProcess ${KWSYS_TARGET_C_LINK})
+ #set(KWSYS_TEST_PROCESS_7 7) # uncomment to run timing-sensitive test locally
+ foreach(n 1 2 3 4 5 6 ${KWSYS_TEST_PROCESS_7} 9 10)
+ add_test(kwsys.testProcess-${n} ${EXEC_DIR}/${KWSYS_NAMESPACE}TestProcess ${n})
+ set_property(TEST kwsys.testProcess-${n} PROPERTY LABELS ${KWSYS_LABELS_TEST})
+ set_tests_properties(kwsys.testProcess-${n} PROPERTIES TIMEOUT 120)
+ endforeach()
+
+ set(testProcess_COMPILE_FLAGS "")
# Some Apple compilers produce bad optimizations in this source.
- IF(APPLE AND CMAKE_C_COMPILER_ID MATCHES "^(GNU|LLVM)$")
- SET(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -O0")
- ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "XL")
+ if(APPLE AND CMAKE_C_COMPILER_ID MATCHES "^(GNU|LLVM)$")
+ set(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -O0")
+ elseif(CMAKE_C_COMPILER_ID STREQUAL "XL")
# Tell IBM XL not to warn about our test infinite loop
- IF(CMAKE_SYSTEM MATCHES "Linux.*ppc64le"
+ if(CMAKE_SYSTEM MATCHES "Linux.*ppc64le"
AND CMAKE_C_COMPILER_VERSION VERSION_LESS "16.1.0"
AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS "13.1.1")
# v13.1.[1-6] on Linux ppc64le is clang based and does not accept
# the -qsuppress option, so just suppress all warnings.
- SET(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -w")
- ELSE()
- SET(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -qsuppress=1500-010")
- ENDIF()
- ENDIF()
- IF(CMAKE_C_FLAGS MATCHES "-fsanitize=")
- SET(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -DCRASH_USING_ABORT")
- ENDIF()
- SET_PROPERTY(SOURCE testProcess.c PROPERTY COMPILE_FLAGS "${testProcess_COMPILE_FLAGS}")
+ set(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -w")
+ else()
+ set(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -qsuppress=1500-010")
+ endif()
+ endif()
+ if(CMAKE_C_FLAGS MATCHES "-fsanitize=")
+ set(testProcess_COMPILE_FLAGS "${testProcess_COMPILE_FLAGS} -DCRASH_USING_ABORT")
+ endif()
+ set_property(SOURCE testProcess.c PROPERTY COMPILE_FLAGS "${testProcess_COMPILE_FLAGS}")
# Test SharedForward
- CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/testSharedForward.c.in
+ configure_file(${PROJECT_SOURCE_DIR}/testSharedForward.c.in
${PROJECT_BINARY_DIR}/testSharedForward.c @ONLY IMMEDIATE)
- ADD_EXECUTABLE(${KWSYS_NAMESPACE}TestSharedForward
+ add_executable(${KWSYS_NAMESPACE}TestSharedForward
${PROJECT_BINARY_DIR}/testSharedForward.c)
- SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}TestSharedForward PROPERTY LABELS ${KWSYS_LABELS_EXE})
- ADD_DEPENDENCIES(${KWSYS_NAMESPACE}TestSharedForward ${KWSYS_TARGET_C_LINK})
- ADD_TEST(kwsys.testSharedForward ${EXEC_DIR}/${KWSYS_NAMESPACE}TestSharedForward 1)
- SET_PROPERTY(TEST kwsys.testSharedForward PROPERTY LABELS ${KWSYS_LABELS_TEST})
+ set_property(TARGET ${KWSYS_NAMESPACE}TestSharedForward PROPERTY LABELS ${KWSYS_LABELS_EXE})
+ add_dependencies(${KWSYS_NAMESPACE}TestSharedForward ${KWSYS_TARGET_C_LINK})
+ add_test(kwsys.testSharedForward ${EXEC_DIR}/${KWSYS_NAMESPACE}TestSharedForward 1)
+ set_property(TEST kwsys.testSharedForward PROPERTY LABELS ${KWSYS_LABELS_TEST})
# Configure some test properties.
- IF(KWSYS_STANDALONE)
+ if(KWSYS_STANDALONE)
# We expect test to fail
- SET_TESTS_PROPERTIES(kwsys.testFail PROPERTIES WILL_FAIL ON)
- GET_TEST_PROPERTY(kwsys.testFail WILL_FAIL wfv)
- SET_TESTS_PROPERTIES(kwsys.testFail PROPERTIES MEASUREMENT "Some Key=Some Value")
- MESSAGE(STATUS "GET_TEST_PROPERTY returned: ${wfv}")
- ENDIF()
+ set_tests_properties(kwsys.testFail PROPERTIES WILL_FAIL ON)
+ get_test_property(kwsys.testFail WILL_FAIL wfv)
+ set_tests_properties(kwsys.testFail PROPERTIES MEASUREMENT "Some Key=Some Value")
+ message(STATUS "GET_TEST_PROPERTY returned: ${wfv}")
+ endif()
# Set up ctest custom configuration file.
- CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/CTestCustom.cmake.in
+ configure_file(${PROJECT_SOURCE_DIR}/CTestCustom.cmake.in
${PROJECT_BINARY_DIR}/CTestCustom.cmake @ONLY)
# Suppress known consistent failures on buggy systems.
- IF(KWSYS_TEST_BOGUS_FAILURES)
- SET_TESTS_PROPERTIES(${KWSYS_TEST_BOGUS_FAILURES} PROPERTIES WILL_FAIL ON)
- ENDIF()
+ if(KWSYS_TEST_BOGUS_FAILURES)
+ set_tests_properties(${KWSYS_TEST_BOGUS_FAILURES} PROPERTIES WILL_FAIL ON)
+ endif()
- ENDIF()
-ENDIF()
+ endif()
+endif()
diff --git a/Source/kwsys/CTestCustom.cmake.in b/Source/kwsys/CTestCustom.cmake.in
index 760221b..c07f0f3 100644
--- a/Source/kwsys/CTestCustom.cmake.in
+++ b/Source/kwsys/CTestCustom.cmake.in
@@ -12,3 +12,7 @@
list(APPEND CTEST_CUSTOM_MEMCHECK_IGNORE
kwsys.testProcess-10
)
+
+list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION
+ "LICENSE WARNING"
+ )
diff --git a/Source/kwsys/CommandLineArguments.cxx b/Source/kwsys/CommandLineArguments.cxx
index 3fd1955..e45db36 100644
--- a/Source/kwsys/CommandLineArguments.cxx
+++ b/Source/kwsys/CommandLineArguments.cxx
@@ -20,9 +20,9 @@
#include <sstream>
#include <vector>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
#ifdef _MSC_VER
# pragma warning(disable : 4786)
@@ -66,26 +66,21 @@ class CommandLineArgumentsMapOfStrucs
class CommandLineArgumentsInternal
{
public:
- CommandLineArgumentsInternal()
- : UnknownArgumentCallback{ nullptr }
- , ClientData{ nullptr }
- , LastArgument{ 0 }
- {
- }
+ CommandLineArgumentsInternal() = default;
- typedef CommandLineArgumentsVectorOfStrings VectorOfStrings;
- typedef CommandLineArgumentsMapOfStrucs CallbacksMap;
- typedef kwsys::String String;
- typedef CommandLineArgumentsSetOfStrings SetOfStrings;
+ using VectorOfStrings = CommandLineArgumentsVectorOfStrings;
+ using CallbacksMap = CommandLineArgumentsMapOfStrucs;
+ using String = kwsys::String;
+ using SetOfStrings = CommandLineArgumentsSetOfStrings;
VectorOfStrings Argv;
String Argv0;
CallbacksMap Callbacks;
- CommandLineArguments::ErrorCallbackType UnknownArgumentCallback;
- void* ClientData;
+ CommandLineArguments::ErrorCallbackType UnknownArgumentCallback{ nullptr };
+ void* ClientData{ nullptr };
- VectorOfStrings::size_type LastArgument;
+ VectorOfStrings::size_type LastArgument{ 0 };
VectorOfStrings UnusedArguments;
};
@@ -424,8 +419,7 @@ void CommandLineArguments::SetUnknownArgumentCallback(
const char* CommandLineArguments::GetHelp(const char* arg)
{
- CommandLineArguments::Internal::CallbacksMap::iterator it =
- this->Internals->Callbacks.find(arg);
+ auto it = this->Internals->Callbacks.find(arg);
if (it == this->Internals->Callbacks.end()) {
return nullptr;
}
@@ -434,8 +428,7 @@ const char* CommandLineArguments::GetHelp(const char* arg)
// one point to if this one is pointing to another argument.
CommandLineArgumentsCallbackStructure* cs = &(it->second);
for (;;) {
- CommandLineArguments::Internal::CallbacksMap::iterator hit =
- this->Internals->Callbacks.find(cs->Help);
+ auto hit = this->Internals->Callbacks.find(cs->Help);
if (hit == this->Internals->Callbacks.end()) {
break;
}
@@ -470,9 +463,8 @@ void CommandLineArguments::GenerateHelp()
// Collapse all arguments into the map of vectors of all arguments that do
// the same thing.
CommandLineArguments::Internal::CallbacksMap::iterator it;
- typedef std::map<CommandLineArguments::Internal::String,
- CommandLineArguments::Internal::SetOfStrings>
- MapArgs;
+ using MapArgs = std::map<CommandLineArguments::Internal::String,
+ CommandLineArguments::Internal::SetOfStrings>;
MapArgs mp;
MapArgs::iterator mpit, smpit;
for (it = this->Internals->Callbacks.begin();
@@ -709,7 +701,7 @@ bool CommandLineArguments::PopulateVariable(
if (cs->Callback) {
if (!cs->Callback(cs->Argument, value, cs->CallData)) {
this->Internals->LastArgument--;
- return 0;
+ return false;
}
}
CommandLineArguments_DEBUG("Set argument: " << cs->Argument << " to "
@@ -759,10 +751,10 @@ bool CommandLineArguments::PopulateVariable(
std::cerr << "Got unknown variable type: \"" << cs->VariableType
<< "\"" << std::endl;
this->Internals->LastArgument--;
- return 0;
+ return false;
}
}
- return 1;
+ return true;
}
} // namespace KWSYS_NAMESPACE
diff --git a/Source/kwsys/Directory.cxx b/Source/kwsys/Directory.cxx
index e379182..d640948 100644
--- a/Source/kwsys/Directory.cxx
+++ b/Source/kwsys/Directory.cxx
@@ -35,6 +35,18 @@ Directory::Directory()
this->Internal = new DirectoryInternals;
}
+Directory::Directory(Directory&& other)
+{
+ this->Internal = other.Internal;
+ other.Internal = nullptr;
+}
+
+Directory& Directory::operator=(Directory&& other)
+{
+ std::swap(this->Internal, other.Internal);
+ return *this;
+}
+
Directory::~Directory()
{
delete this->Internal;
@@ -204,15 +216,15 @@ bool Directory::Load(const std::string& name)
DIR* dir = opendir(name.c_str());
if (!dir) {
- return 0;
+ return false;
}
for (kwsys_dirent* d = readdir(dir); d; d = readdir(dir)) {
- this->Internal->Files.push_back(d->d_name);
+ this->Internal->Files.emplace_back(d->d_name);
}
this->Internal->Path = name;
closedir(dir);
- return 1;
+ return true;
}
unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name)
diff --git a/Source/kwsys/Directory.hxx.in b/Source/kwsys/Directory.hxx.in
index ad8c51b..9b0f4c3 100644
--- a/Source/kwsys/Directory.hxx.in
+++ b/Source/kwsys/Directory.hxx.in
@@ -23,6 +23,11 @@ class @KWSYS_NAMESPACE@_EXPORT Directory
{
public:
Directory();
+ Directory(Directory&& other);
+ Directory(const Directory&) = delete;
+ Directory& operator=(const Directory&) = delete;
+ Directory& operator=(Directory&& other);
+ bool operator==(const Directory&) = delete;
~Directory();
/**
@@ -62,10 +67,7 @@ public:
private:
// Private implementation details.
DirectoryInternals* Internal;
-
- Directory(const Directory&); // Not implemented.
- void operator=(const Directory&); // Not implemented.
-}; // End Class: Directory
+}; // End Class: Directory
} // namespace @KWSYS_NAMESPACE@
diff --git a/Source/kwsys/Encoding.hxx.in b/Source/kwsys/Encoding.hxx.in
index b067521..75a2d4d 100644
--- a/Source/kwsys/Encoding.hxx.in
+++ b/Source/kwsys/Encoding.hxx.in
@@ -68,6 +68,8 @@ public:
* absolute paths with Windows-style backslashes.
**/
static std::wstring ToWindowsExtendedPath(std::string const&);
+ static std::wstring ToWindowsExtendedPath(const char* source);
+ static std::wstring ToWindowsExtendedPath(std::wstring const& wsource);
# endif
#endif // @KWSYS_NAMESPACE@_STL_HAS_WSTRING
diff --git a/Source/kwsys/EncodingCXX.cxx b/Source/kwsys/EncodingCXX.cxx
index 4593c92..c68c73c 100644
--- a/Source/kwsys/EncodingCXX.cxx
+++ b/Source/kwsys/EncodingCXX.cxx
@@ -17,8 +17,8 @@
# include "Encoding.hxx.in"
#endif
-#include <stdlib.h>
-#include <string.h>
+#include <cstdlib>
+#include <cstring>
#include <vector>
#ifdef _MSC_VER
@@ -221,8 +221,18 @@ std::string Encoding::ToNarrow(const wchar_t* wcstr)
// Convert local paths to UNC style paths
std::wstring Encoding::ToWindowsExtendedPath(std::string const& source)
{
- std::wstring wsource = Encoding::ToWide(source);
+ return ToWindowsExtendedPath(ToWide(source));
+}
+// Convert local paths to UNC style paths
+std::wstring Encoding::ToWindowsExtendedPath(const char* source)
+{
+ return ToWindowsExtendedPath(ToWide(source));
+}
+
+// Convert local paths to UNC style paths
+std::wstring Encoding::ToWindowsExtendedPath(std::wstring const& wsource)
+{
// Resolve any relative paths
DWORD wfull_len;
@@ -269,7 +279,7 @@ std::wstring Encoding::ToWindowsExtendedPath(std::string const& source)
// If this case has been reached, then the path is invalid. Leave it
// unchanged
- return Encoding::ToWide(source);
+ return wsource;
}
# endif
diff --git a/Source/kwsys/ExtraTest.cmake.in b/Source/kwsys/ExtraTest.cmake.in
index e8c0a1c..4cec9e2 100644
--- a/Source/kwsys/ExtraTest.cmake.in
+++ b/Source/kwsys/ExtraTest.cmake.in
@@ -1 +1 @@
-MESSAGE("*** This message is generated by message inside a file that is included in DartTestfile.txt ***")
+message("*** This message is generated by message inside a file that is included in DartTestfile.txt ***")
diff --git a/Source/kwsys/FStream.hxx.in b/Source/kwsys/FStream.hxx.in
index d79bbdf..b424488 100644
--- a/Source/kwsys/FStream.hxx.in
+++ b/Source/kwsys/FStream.hxx.in
@@ -87,7 +87,7 @@ public:
bool _open(char const* file_name, std::ios_base::openmode mode)
{
- if (is_open() || file_) {
+ if (_is_open() || file_) {
return false;
}
# if defined(_MSC_VER)
@@ -108,7 +108,7 @@ public:
return success;
}
- bool is_open()
+ bool _is_open()
{
if (!buf_) {
return false;
@@ -116,7 +116,7 @@ public:
return buf_->is_open();
}
- bool is_open() const
+ bool _is_open() const
{
if (!buf_) {
return false;
@@ -198,9 +198,11 @@ public:
this->_set_state(this->_open(file_name, mode), this, this);
}
+ bool is_open() { return this->_is_open(); }
+
void close() { this->_set_state(this->_close(), this, this); }
- using basic_efilebuf<CharType, Traits>::is_open;
+ using basic_efilebuf<CharType, Traits>::_is_open;
internal_buffer_type* rdbuf() const { return this->buf_; }
@@ -212,7 +214,7 @@ class basic_ofstream
: public std::basic_ostream<CharType, Traits>
, public basic_efilebuf<CharType, Traits>
{
- using basic_efilebuf<CharType, Traits>::is_open;
+ using basic_efilebuf<CharType, Traits>::_is_open;
public:
typedef typename basic_efilebuf<CharType, Traits>::internal_buffer_type
@@ -242,6 +244,8 @@ public:
void close() { this->_set_state(this->_close(), this, this); }
+ bool is_open() { return this->_is_open(); }
+
internal_buffer_type* rdbuf() const { return this->buf_; }
~basic_ofstream() @KWSYS_NAMESPACE@_FStream_NOEXCEPT { close(); }
diff --git a/Source/kwsys/Glob.cxx b/Source/kwsys/Glob.cxx
index 34bb0d0..fad6ee1 100644
--- a/Source/kwsys/Glob.cxx
+++ b/Source/kwsys/Glob.cxx
@@ -23,9 +23,9 @@
#include <string>
#include <vector>
-#include <ctype.h>
-#include <stdio.h>
-#include <string.h>
+#include <cctype>
+#include <cstdio>
+#include <cstring>
namespace KWSYS_NAMESPACE {
#if defined(_WIN32) || defined(__APPLE__) || defined(__CYGWIN__)
// On Windows and Apple, no difference between lower and upper case
@@ -385,10 +385,9 @@ bool Glob::FindFiles(const std::string& inexpr, GlobMessages* messages)
}
if (skip > 0) {
- expr = expr.substr(skip);
+ expr.erase(0, skip);
}
- cexpr = "";
for (cc = 0; cc < expr.size(); cc++) {
int ch = expr[cc];
if (ch == '/') {
@@ -415,8 +414,7 @@ bool Glob::FindFiles(const std::string& inexpr, GlobMessages* messages)
void Glob::AddExpression(const std::string& expr)
{
- this->Internals->Expressions.push_back(
- kwsys::RegularExpression(this->PatternToRegex(expr)));
+ this->Internals->Expressions.emplace_back(this->PatternToRegex(expr));
}
void Glob::SetRelative(const char* dir)
diff --git a/Source/kwsys/MD5.c b/Source/kwsys/MD5.c
index 97cf9ba..fb18a5b 100644
--- a/Source/kwsys/MD5.c
+++ b/Source/kwsys/MD5.c
@@ -171,8 +171,10 @@ typedef struct md5_state_s
static void md5_process(md5_state_t* pms, const md5_byte_t* data /*[64]*/)
{
- md5_word_t a = pms->abcd[0], b = pms->abcd[1], c = pms->abcd[2],
- d = pms->abcd[3];
+ md5_word_t a = pms->abcd[0];
+ md5_word_t b = pms->abcd[1];
+ md5_word_t c = pms->abcd[2];
+ md5_word_t d = pms->abcd[3];
md5_word_t t;
#if BYTE_ORDER > 0
/* Define storage only for big-endian CPUs. */
@@ -227,9 +229,10 @@ static void md5_process(md5_state_t* pms, const md5_byte_t* data /*[64]*/)
# else
# define xbuf X /* (static only) */
# endif
- for (i = 0; i < 16; ++i, xp += 4)
+ for (i = 0; i < 16; ++i, xp += 4) {
xbuf[i] =
(md5_word_t)(xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24));
+ }
}
#endif
}
@@ -367,34 +370,39 @@ static void md5_append(md5_state_t* pms, const md5_byte_t* data, size_t nbytes)
size_t offset = (pms->count[0] >> 3) & 63;
md5_word_t nbits = (md5_word_t)(nbytes << 3);
- if (nbytes <= 0)
+ if (nbytes <= 0) {
return;
+ }
/* Update the message length. */
pms->count[1] += (md5_word_t)(nbytes >> 29);
pms->count[0] += nbits;
- if (pms->count[0] < nbits)
+ if (pms->count[0] < nbits) {
pms->count[1]++;
+ }
/* Process an initial partial block. */
if (offset) {
size_t copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
memcpy(pms->buf + offset, p, copy);
- if (offset + copy < 64)
+ if (offset + copy < 64) {
return;
+ }
p += copy;
left -= copy;
md5_process(pms, pms->buf);
}
/* Process full blocks. */
- for (; left >= 64; p += 64, left -= 64)
+ for (; left >= 64; p += 64, left -= 64) {
md5_process(pms, p);
+ }
/* Process a final partial block. */
- if (left)
+ if (left) {
memcpy(pms->buf, p, left);
+ }
}
/* Finish the message and return the digest. */
@@ -409,14 +417,16 @@ static void md5_finish(md5_state_t* pms, md5_byte_t digest[16])
int i;
/* Save the length before padding. */
- for (i = 0; i < 8; ++i)
+ for (i = 0; i < 8; ++i) {
data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
+ }
/* Pad to 56 bytes mod 64. */
md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
/* Append the length. */
md5_append(pms, data, 8);
- for (i = 0; i < 16; ++i)
+ for (i = 0; i < 16; ++i) {
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
+ }
}
#if defined(__clang__) && !defined(__INTEL_COMPILER)
diff --git a/Source/kwsys/Process.h.in b/Source/kwsys/Process.h.in
index 73ea9db..9f2162b 100644
--- a/Source/kwsys/Process.h.in
+++ b/Source/kwsys/Process.h.in
@@ -180,8 +180,8 @@ kwsysEXPORT void kwsysProcess_SetPipeShared(kwsysProcess* cp, int pipe,
* write end of the pipe will be closed in the parent process and the
* read end will be closed in the child process.
*/
-kwsysEXPORT void kwsysProcess_SetPipeNative(kwsysProcess* cp, int pipe,
- kwsysProcess_Pipe_Handle p[2]);
+kwsysEXPORT void kwsysProcess_SetPipeNative(
+ kwsysProcess* cp, int pipe, const kwsysProcess_Pipe_Handle p[2]);
/**
* Get/Set a possibly platform-specific option. Possible options are:
diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c
index f65690b..cc45529 100644
--- a/Source/kwsys/ProcessUNIX.c
+++ b/Source/kwsys/ProcessUNIX.c
@@ -152,10 +152,11 @@ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
static void kwsysProcessDestroy(kwsysProcess* cp);
static int kwsysProcessSetupOutputPipeFile(int* p, const char* name);
static int kwsysProcessSetupOutputPipeNative(int* p, int des[2]);
-static int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout,
+static int kwsysProcessGetTimeoutTime(kwsysProcess* cp,
+ const double* userTimeout,
kwsysProcessTime* timeoutTime);
static int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime,
- double* userTimeout,
+ const double* userTimeout,
kwsysProcessTimeNative* timeoutLength,
int zeroIsExpired);
static kwsysProcessTime kwsysProcessTimeGetCurrent(void);
@@ -431,8 +432,8 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command)
char const* const* c = command;
kwsysProcess_ptrdiff_t n = 0;
kwsysProcess_ptrdiff_t i = 0;
- while (*c++)
- ;
+ while (*c++) {
+ }
n = c - command - 1;
newCommands[cp->NumberOfCommands] =
(char**)malloc((size_t)(n + 1) * sizeof(char*));
@@ -571,7 +572,7 @@ void kwsysProcess_SetPipeShared(kwsysProcess* cp, int prPipe, int shared)
}
}
-void kwsysProcess_SetPipeNative(kwsysProcess* cp, int prPipe, int p[2])
+void kwsysProcess_SetPipeNative(kwsysProcess* cp, int prPipe, const int p[2])
{
int* pPipeNative = 0;
@@ -684,7 +685,8 @@ const char* kwsysProcess_GetErrorString(kwsysProcess* cp)
{
if (!cp) {
return "Process management structure could not be allocated";
- } else if (cp->State == kwsysProcess_State_Error) {
+ }
+ if (cp->State == kwsysProcess_State_Error) {
return cp->ErrorMessage;
}
return "Success";
@@ -694,7 +696,8 @@ const char* kwsysProcess_GetExceptionString(kwsysProcess* cp)
{
if (!(cp && cp->ProcessResults && (cp->NumberOfCommands > 0))) {
return "GetExceptionString called with NULL process management structure";
- } else if (cp->State == kwsysProcess_State_Exception) {
+ }
+ if (cp->State == kwsysProcess_State_Exception) {
return cp->ProcessResults[cp->NumberOfCommands - 1].ExitExceptionString;
}
return "No exception";
@@ -786,8 +789,8 @@ void kwsysProcess_Execute(kwsysProcess* cp)
/* Some platforms specify that the chdir call may be
interrupted. Repeat the call until it finishes. */
- while (((r = chdir(cp->WorkingDirectory)) < 0) && (errno == EINTR))
- ;
+ while (((r = chdir(cp->WorkingDirectory)) < 0) && (errno == EINTR)) {
+ }
if (r < 0) {
kwsysProcessCleanup(cp, 1);
return;
@@ -1013,8 +1016,8 @@ void kwsysProcess_Execute(kwsysProcess* cp)
if (cp->RealWorkingDirectory) {
/* Some platforms specify that the chdir call may be
interrupted. Repeat the call until it finishes. */
- while ((chdir(cp->RealWorkingDirectory) < 0) && (errno == EINTR))
- ;
+ while ((chdir(cp->RealWorkingDirectory) < 0) && (errno == EINTR)) {
+ }
free(cp->RealWorkingDirectory);
cp->RealWorkingDirectory = 0;
}
@@ -1099,22 +1102,22 @@ int kwsysProcess_WaitForData(kwsysProcess* cp, char** data, int* length,
if (wd.PipeId) {
/* Data are ready on a pipe. */
return wd.PipeId;
- } else if (wd.Expired) {
+ }
+ if (wd.Expired) {
/* A timeout has expired. */
if (wd.User) {
/* The user timeout has expired. It has no time left. */
return kwsysProcess_Pipe_Timeout;
- } else {
- /* The process timeout has expired. Kill the children now. */
- kwsysProcess_Kill(cp);
- cp->Killed = 0;
- cp->TimeoutExpired = 1;
- return kwsysProcess_Pipe_None;
}
- } else {
- /* No pipes are left open. */
+
+ /* The process timeout has expired. Kill the children now. */
+ kwsysProcess_Kill(cp);
+ cp->Killed = 0;
+ cp->TimeoutExpired = 1;
return kwsysProcess_Pipe_None;
}
+ /* No pipes are left open. */
+ return kwsysProcess_Pipe_None;
}
static int kwsysProcessWaitForPipe(kwsysProcess* cp, char** data, int* length,
@@ -1144,8 +1147,8 @@ static int kwsysProcessWaitForPipe(kwsysProcess* cp, char** data, int* length,
read until the operation is not interrupted. */
while (((n = read(cp->PipeReadEnds[i], cp->PipeBuffer,
KWSYSPE_PIPE_BUFFER_SIZE)) < 0) &&
- (errno == EINTR))
- ;
+ (errno == EINTR)) {
+ }
if (n > 0) {
/* We have data on this pipe. */
if (i == KWSYSPE_PIPE_SIGNAL) {
@@ -1183,7 +1186,7 @@ static int kwsysProcessWaitForPipe(kwsysProcess* cp, char** data, int* length,
/* Make sure the set is empty (it should always be empty here
anyway). */
- FD_ZERO(&cp->PipeSet);
+ FD_ZERO(&cp->PipeSet); // NOLINT(readability-isolate-declaration)
/* Setup a timeout if required. */
if (wd->TimeoutTime.tv_sec < 0) {
@@ -1218,15 +1221,16 @@ static int kwsysProcessWaitForPipe(kwsysProcess* cp, char** data, int* length,
/* Run select to block until data are available. Repeat call
until it is not interrupted. */
while (((numReady = select(max + 1, &cp->PipeSet, 0, 0, timeout)) < 0) &&
- (errno == EINTR))
- ;
+ (errno == EINTR)) {
+ }
/* Check result of select. */
if (numReady == 0) {
/* Select's timeout expired. */
wd->Expired = 1;
return 1;
- } else if (numReady < 0) {
+ }
+ if (numReady < 0) {
/* Select returned an error. Leave the error description in the
pipe buffer. */
strncpy(cp->ErrorMessage, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE);
@@ -1366,11 +1370,13 @@ int kwsysProcess_WaitForExit(kwsysProcess* cp, double* userTimeout)
cp->ProcessResults[prPipe].State = kwsysProcess_StateByIndex_Exited;
cp->ProcessResults[prPipe].ExitException = kwsysProcess_Exception_None;
cp->ProcessResults[prPipe].ExitValue =
+ // NOLINTNEXTLINE(google-readability-casting)
(int)WEXITSTATUS(cp->ProcessResults[prPipe].ExitCode);
} else if (WIFSIGNALED(cp->ProcessResults[prPipe].ExitCode)) {
/* The child received an unhandled signal. */
cp->ProcessResults[prPipe].State = kwsysProcess_State_Exception;
kwsysProcessSetExitExceptionByIndex(
+ // NOLINTNEXTLINE(google-readability-casting)
cp, (int)WTERMSIG(cp->ProcessResults[prPipe].ExitCode), prPipe);
} else {
/* Error getting the child return code. */
@@ -1449,8 +1455,8 @@ void kwsysProcess_Kill(kwsysProcess* cp)
/* Reap the child. Keep trying until the call is not
interrupted. */
- while ((waitpid(cp->ForkPIDs[i], &status, 0) < 0) && (errno == EINTR))
- ;
+ while ((waitpid(cp->ForkPIDs[i], &status, 0) < 0) && (errno == EINTR)) {
+ }
}
}
@@ -1501,7 +1507,7 @@ static int kwsysProcessInitialize(kwsysProcess* cp)
cp->PipesLeft = 0;
cp->CommandsLeft = 0;
#if KWSYSPE_USE_SELECT
- FD_ZERO(&cp->PipeSet);
+ FD_ZERO(&cp->PipeSet); // NOLINT(readability-isolate-declaration)
#endif
cp->State = kwsysProcess_State_Starting;
cp->Killed = 0;
@@ -1590,16 +1596,16 @@ static void kwsysProcessCleanup(kwsysProcess* cp, int error)
/* Reap the child. Keep trying until the call is not
interrupted. */
while ((waitpid(cp->ForkPIDs[i], &status, 0) < 0) &&
- (errno == EINTR))
- ;
+ (errno == EINTR)) {
+ }
}
}
}
/* Restore the working directory. */
if (cp->RealWorkingDirectory) {
- while ((chdir(cp->RealWorkingDirectory) < 0) && (errno == EINTR))
- ;
+ while ((chdir(cp->RealWorkingDirectory) < 0) && (errno == EINTR)) {
+ }
}
}
@@ -1635,8 +1641,8 @@ static void kwsysProcessCleanupDescriptor(int* pfd)
if (pfd && *pfd > 2) {
/* Keep trying to close until it is not interrupted by a
* signal. */
- while ((close(*pfd) < 0) && (errno == EINTR))
- ;
+ while ((close(*pfd) < 0) && (errno == EINTR)) {
+ }
*pfd = -1;
}
}
@@ -1661,8 +1667,8 @@ static void kwsysProcessClosePipes(kwsysProcess* cp)
read until the operation is not interrupted. */
while ((read(cp->PipeReadEnds[i], cp->PipeBuffer,
KWSYSPE_PIPE_BUFFER_SIZE) < 0) &&
- (errno == EINTR))
- ;
+ (errno == EINTR)) {
+ }
}
#endif
@@ -1689,7 +1695,8 @@ int decc$set_child_standard_streams(int fd1, int fd2, int fd3);
static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
kwsysProcessCreateInformation* si)
{
- sigset_t mask, old_mask;
+ sigset_t mask;
+ sigset_t old_mask;
int pgidPipe[2];
char tmp;
ssize_t readRes;
@@ -1817,8 +1824,8 @@ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
/* Make sure the child is in the process group before we proceed. This
avoids race conditions with calls to the kill function that we make for
signalling process groups. */
- while ((readRes = read(pgidPipe[0], &tmp, 1)) > 0)
- ;
+ while ((readRes = read(pgidPipe[0], &tmp, 1)) > 0) {
+ }
if (readRes < 0) {
sigprocmask(SIG_SETMASK, &old_mask, 0);
kwsysProcessCleanupDescriptor(&si->ErrorPipe[0]);
@@ -1846,8 +1853,8 @@ static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
/* Keep trying to read until the operation is not interrupted. */
while (((n = read(si->ErrorPipe[0], cp->ErrorMessage + total,
(size_t)(KWSYSPE_PIPE_BUFFER_SIZE - total))) < 0) &&
- (errno == EINTR))
- ;
+ (errno == EINTR)) {
+ }
if (n > 0) {
total += n;
}
@@ -1872,7 +1879,8 @@ static void kwsysProcessDestroy(kwsysProcess* cp)
int i;
/* Temporarily disable signals that access ForkPIDs. We don't want them to
read a reaped PID, and writes to ForkPIDs are not atomic. */
- sigset_t mask, old_mask;
+ sigset_t mask;
+ sigset_t old_mask;
sigemptyset(&mask);
sigaddset(&mask, SIGINT);
sigaddset(&mask, SIGTERM);
@@ -1885,8 +1893,8 @@ static void kwsysProcessDestroy(kwsysProcess* cp)
int result;
while (((result = waitpid(cp->ForkPIDs[i], &cp->CommandExitCodes[i],
WNOHANG)) < 0) &&
- (errno == EINTR))
- ;
+ (errno == EINTR)) {
+ }
if (result > 0) {
/* This child has termianted. */
cp->ForkPIDs[i] = 0;
@@ -1959,7 +1967,8 @@ static int kwsysProcessSetupOutputPipeNative(int* p, int des[2])
/* Get the time at which either the process or user timeout will
expire. Returns 1 if the user timeout is first, and 0 otherwise. */
-static int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout,
+static int kwsysProcessGetTimeoutTime(kwsysProcess* cp,
+ const double* userTimeout,
kwsysProcessTime* timeoutTime)
{
/* The first time this is called, we need to calculate the time at
@@ -1991,35 +2000,33 @@ static int kwsysProcessGetTimeoutTime(kwsysProcess* cp, double* userTimeout,
/* Get the length of time before the given timeout time arrives.
Returns 1 if the time has already arrived, and 0 otherwise. */
static int kwsysProcessGetTimeoutLeft(kwsysProcessTime* timeoutTime,
- double* userTimeout,
+ const double* userTimeout,
kwsysProcessTimeNative* timeoutLength,
int zeroIsExpired)
{
if (timeoutTime->tv_sec < 0) {
/* No timeout time has been requested. */
return 0;
- } else {
- /* Calculate the remaining time. */
- kwsysProcessTime currentTime = kwsysProcessTimeGetCurrent();
- kwsysProcessTime timeLeft =
- kwsysProcessTimeSubtract(*timeoutTime, currentTime);
- if (timeLeft.tv_sec < 0 && userTimeout && *userTimeout <= 0) {
- /* Caller has explicitly requested a zero timeout. */
- timeLeft.tv_sec = 0;
- timeLeft.tv_usec = 0;
- }
+ }
+ /* Calculate the remaining time. */
+ kwsysProcessTime currentTime = kwsysProcessTimeGetCurrent();
+ kwsysProcessTime timeLeft =
+ kwsysProcessTimeSubtract(*timeoutTime, currentTime);
+ if (timeLeft.tv_sec < 0 && userTimeout && *userTimeout <= 0) {
+ /* Caller has explicitly requested a zero timeout. */
+ timeLeft.tv_sec = 0;
+ timeLeft.tv_usec = 0;
+ }
- if (timeLeft.tv_sec < 0 ||
- (timeLeft.tv_sec == 0 && timeLeft.tv_usec == 0 && zeroIsExpired)) {
- /* Timeout has already expired. */
- return 1;
- } else {
- /* There is some time left. */
- timeoutLength->tv_sec = timeLeft.tv_sec;
- timeoutLength->tv_usec = timeLeft.tv_usec;
- return 0;
- }
+ if (timeLeft.tv_sec < 0 ||
+ (timeLeft.tv_sec == 0 && timeLeft.tv_usec == 0 && zeroIsExpired)) {
+ /* Timeout has already expired. */
+ return 1;
}
+ /* There is some time left. */
+ timeoutLength->tv_sec = timeLeft.tv_sec;
+ timeoutLength->tv_usec = timeLeft.tv_usec;
+ return 0;
}
static kwsysProcessTime kwsysProcessTimeGetCurrent(void)
@@ -2424,41 +2431,39 @@ static pid_t kwsysProcessFork(kwsysProcess* cp,
if (middle_pid < 0) {
/* Fork failed. Return as if we were not detaching. */
return middle_pid;
- } else if (middle_pid == 0) {
+ }
+ if (middle_pid == 0) {
/* This is the intermediate process. Create the real child. */
pid_t child_pid = fork();
if (child_pid == 0) {
/* This is the real child process. There is nothing to do here. */
return 0;
- } else {
- /* Use the error pipe to report the pid to the real parent. */
- while ((write(si->ErrorPipe[1], &child_pid, sizeof(child_pid)) < 0) &&
- (errno == EINTR))
- ;
-
- /* Exit without cleanup. The parent holds all resources. */
- kwsysProcessExit();
- return 0; /* Never reached, but avoids SunCC warning. */
}
- } else {
- /* This is the original parent process. The intermediate
- process will use the error pipe to report the pid of the
- detached child. */
- pid_t child_pid;
- int status;
- while ((read(si->ErrorPipe[0], &child_pid, sizeof(child_pid)) < 0) &&
- (errno == EINTR))
- ;
+ /* Use the error pipe to report the pid to the real parent. */
+ while ((write(si->ErrorPipe[1], &child_pid, sizeof(child_pid)) < 0) &&
+ (errno == EINTR)) {
+ }
- /* Wait for the intermediate process to exit and clean it up. */
- while ((waitpid(middle_pid, &status, 0) < 0) && (errno == EINTR))
- ;
- return child_pid;
+ /* Exit without cleanup. The parent holds all resources. */
+ kwsysProcessExit();
+ return 0; /* Never reached, but avoids SunCC warning. */
}
- } else {
- /* Not creating a detached process. Use normal fork. */
- return fork();
+ /* This is the original parent process. The intermediate
+ process will use the error pipe to report the pid of the
+ detached child. */
+ pid_t child_pid;
+ int status;
+ while ((read(si->ErrorPipe[0], &child_pid, sizeof(child_pid)) < 0) &&
+ (errno == EINTR)) {
+ }
+
+ /* Wait for the intermediate process to exit and clean it up. */
+ while ((waitpid(middle_pid, &status, 0) < 0) && (errno == EINTR)) {
+ }
+ return child_pid;
}
+ /* Not creating a detached process. Use normal fork. */
+ return fork();
}
#endif
@@ -2563,7 +2568,8 @@ static void kwsysProcessKill(pid_t process_id)
/* Make sure the process started and provided a valid header. */
if (ps && fscanf(ps, "%*[^\n]\n") != EOF) {
/* Look for processes whose parent is the process being killed. */
- int pid, ppid;
+ int pid;
+ int ppid;
while (fscanf(ps, KWSYSPE_PS_FORMAT, &pid, &ppid) == 2) {
if (ppid == process_id) {
/* Recursively kill this child and its children. */
@@ -2725,8 +2731,8 @@ static int kwsysProcessesAdd(kwsysProcess* cp)
sigemptyset(&newSigAction.sa_mask);
while ((sigaction(SIGCHLD, &newSigAction,
&kwsysProcessesOldSigChldAction) < 0) &&
- (errno == EINTR))
- ;
+ (errno == EINTR)) {
+ }
/* Install our handler for SIGINT / SIGTERM. Repeat call until
it is not interrupted. */
@@ -2734,15 +2740,15 @@ static int kwsysProcessesAdd(kwsysProcess* cp)
sigaddset(&newSigAction.sa_mask, SIGTERM);
while ((sigaction(SIGINT, &newSigAction,
&kwsysProcessesOldSigIntAction) < 0) &&
- (errno == EINTR))
- ;
+ (errno == EINTR)) {
+ }
sigemptyset(&newSigAction.sa_mask);
sigaddset(&newSigAction.sa_mask, SIGINT);
while ((sigaction(SIGTERM, &newSigAction,
&kwsysProcessesOldSigIntAction) < 0) &&
- (errno == EINTR))
- ;
+ (errno == EINTR)) {
+ }
}
}
@@ -2773,14 +2779,14 @@ static void kwsysProcessesRemove(kwsysProcess* cp)
/* Restore the signal handlers. Repeat call until it is not
interrupted. */
while ((sigaction(SIGCHLD, &kwsysProcessesOldSigChldAction, 0) < 0) &&
- (errno == EINTR))
- ;
+ (errno == EINTR)) {
+ }
while ((sigaction(SIGINT, &kwsysProcessesOldSigIntAction, 0) < 0) &&
- (errno == EINTR))
- ;
+ (errno == EINTR)) {
+ }
while ((sigaction(SIGTERM, &kwsysProcessesOldSigTermAction, 0) < 0) &&
- (errno == EINTR))
- ;
+ (errno == EINTR)) {
+ }
/* Free the table of process pointers since it is now empty.
This is safe because the signal handler has been removed. */
@@ -2806,7 +2812,10 @@ static void kwsysProcessesSignalHandler(int signum
#endif
)
{
- int i, j, procStatus, old_errno = errno;
+ int i;
+ int j;
+ int procStatus;
+ int old_errno = errno;
#if KWSYSPE_USE_SIGINFO
(void)info;
(void)ucontext;
@@ -2863,8 +2872,8 @@ static void kwsysProcessesSignalHandler(int signum
memset(&defSigAction, 0, sizeof(defSigAction));
defSigAction.sa_handler = SIG_DFL;
sigemptyset(&defSigAction.sa_mask);
- while ((sigaction(signum, &defSigAction, 0) < 0) && (errno == EINTR))
- ;
+ while ((sigaction(signum, &defSigAction, 0) < 0) && (errno == EINTR)) {
+ }
/* Unmask the signal. */
sigemptyset(&unblockSet);
sigaddset(&unblockSet, signum);
diff --git a/Source/kwsys/ProcessWin32.c b/Source/kwsys/ProcessWin32.c
index 68c5218..56bbd20 100644
--- a/Source/kwsys/ProcessWin32.c
+++ b/Source/kwsys/ProcessWin32.c
@@ -761,7 +761,7 @@ void kwsysProcess_SetPipeShared(kwsysProcess* cp, int pipe, int shared)
}
}
-void kwsysProcess_SetPipeNative(kwsysProcess* cp, int pipe, HANDLE p[2])
+void kwsysProcess_SetPipeNative(kwsysProcess* cp, int pipe, const HANDLE p[2])
{
HANDLE* pPipeNative = 0;
diff --git a/Source/kwsys/RegularExpression.cxx b/Source/kwsys/RegularExpression.cxx
index 5e6f8da..4f74eba 100644
--- a/Source/kwsys/RegularExpression.cxx
+++ b/Source/kwsys/RegularExpression.cxx
@@ -28,8 +28,8 @@
# include "RegularExpression.hxx.in"
#endif
-#include <stdio.h>
-#include <string.h>
+#include <cstdio>
+#include <cstring>
namespace KWSYS_NAMESPACE {
@@ -367,8 +367,7 @@ bool RegularExpression::compile(const char* exp)
// Allocate space.
//#ifndef _WIN32
- if (this->program != nullptr)
- delete[] this->program;
+ delete[] this->program;
//#endif
this->program = new char[comp.regsize];
this->progsize = static_cast<int>(comp.regsize);
diff --git a/Source/kwsys/RegularExpression.hxx.in b/Source/kwsys/RegularExpression.hxx.in
index df7eb45..d11db88 100644
--- a/Source/kwsys/RegularExpression.hxx.in
+++ b/Source/kwsys/RegularExpression.hxx.in
@@ -66,16 +66,27 @@ private:
const char* searchstring;
};
+#ifdef _MSC_VER
+# pragma warning(push)
+# if _MSC_VER < 1900
+# pragma warning(disable : 4351) /* new behavior */
+# endif
+#endif
+
/**
* \brief Creates an invalid match object
*/
inline RegularExpressionMatch::RegularExpressionMatch()
+ : startp{}
+ , endp{}
+ , searchstring{}
{
- startp[0] = nullptr;
- endp[0] = nullptr;
- searchstring = nullptr;
}
+#ifdef _MSC_VER
+# pragma warning(pop)
+#endif
+
/**
* \brief Returns true if the match pointers are valid
*/
diff --git a/Source/kwsys/System.c b/Source/kwsys/System.c
index d43cc6f..dbfd2fd 100644
--- a/Source/kwsys/System.c
+++ b/Source/kwsys/System.c
@@ -22,7 +22,7 @@ typedef ptrdiff_t kwsysSystem_ptrdiff_t;
typedef int kwsysSystem_ptrdiff_t;
#endif
-static int kwsysSystem__AppendByte(char* local, char** begin, char** end,
+static int kwsysSystem__AppendByte(const char* local, char** begin, char** end,
int* size, char c)
{
/* Allocate space for the character. */
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx
index 6ec6e48..c565823 100644
--- a/Source/kwsys/SystemInformation.cxx
+++ b/Source/kwsys/SystemInformation.cxx
@@ -64,9 +64,9 @@ typedef int siginfo_t;
#else
# include <sys/types.h>
-# include <errno.h> // extern int errno;
+# include <cerrno> // extern int errno;
+# include <csignal>
# include <fcntl.h>
-# include <signal.h>
# include <sys/resource.h> // getrlimit
# include <sys/time.h>
# include <sys/utsname.h> // int uname(struct utsname *buf);
@@ -132,7 +132,7 @@ typedef int siginfo_t;
# endif
# endif
# if defined(KWSYS_CXX_HAS_RLIMIT64)
-typedef struct rlimit64 ResourceLimitType;
+using ResourceLimitType = struct rlimit64;
# define GetResourceLimit getrlimit64
# else
typedef struct rlimit ResourceLimitType;
@@ -163,11 +163,11 @@ typedef struct rlimit ResourceLimitType;
# undef KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP
#endif
-#include <ctype.h> // int isdigit(int c);
+#include <cctype> // int isdigit(int c);
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
#include <memory.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#if defined(KWSYS_USE_LONG_LONG)
# if defined(KWSYS_IOS_HAS_OSTREAM_LONG_LONG)
@@ -204,7 +204,8 @@ typedef struct rlimit ResourceLimitType;
# define USE_ASM_INSTRUCTIONS 0
#endif
-#if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__clang__)
+#if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__clang__) && \
+ !defined(_M_ARM64)
# include <intrin.h>
# define USE_CPUID_INTRINSICS 1
#else
@@ -303,34 +304,34 @@ T min(T a, T b)
}
extern "C" {
-typedef void (*SigAction)(int, siginfo_t*, void*);
+using SigAction = void (*)(int, siginfo_t*, void*);
}
// Define SystemInformationImplementation class
-typedef void (*DELAY_FUNC)(unsigned int uiMS);
+using DELAY_FUNC = void (*)(unsigned int);
class SystemInformationImplementation
{
public:
- typedef SystemInformation::LongLong LongLong;
+ using LongLong = SystemInformation::LongLong;
SystemInformationImplementation();
- ~SystemInformationImplementation();
+ ~SystemInformationImplementation() = default;
- const char* GetVendorString();
+ const char* GetVendorString() const;
const char* GetVendorID();
- std::string GetTypeID();
- std::string GetFamilyID();
- std::string GetModelID();
- std::string GetModelName();
- std::string GetSteppingCode();
- const char* GetExtendedProcessorName();
- const char* GetProcessorSerialNumber();
- int GetProcessorCacheSize();
- unsigned int GetLogicalProcessorsPerPhysical();
- float GetProcessorClockFrequency();
- int GetProcessorAPICID();
- int GetProcessorCacheXSize(long int);
- bool DoesCPUSupportFeature(long int);
+ std::string GetTypeID() const;
+ std::string GetFamilyID() const;
+ std::string GetModelID() const;
+ std::string GetModelName() const;
+ std::string GetSteppingCode() const;
+ const char* GetExtendedProcessorName() const;
+ const char* GetProcessorSerialNumber() const;
+ int GetProcessorCacheSize() const;
+ unsigned int GetLogicalProcessorsPerPhysical() const;
+ float GetProcessorClockFrequency() const;
+ int GetProcessorAPICID() const;
+ int GetProcessorCacheXSize(long int) const;
+ bool DoesCPUSupportFeature(long int) const;
const char* GetOSName();
const char* GetHostname();
@@ -339,24 +340,24 @@ public:
const char* GetOSVersion();
const char* GetOSPlatform();
- bool Is64Bits();
+ bool Is64Bits() const;
- unsigned int GetNumberOfLogicalCPU(); // per physical cpu
- unsigned int GetNumberOfPhysicalCPU();
+ unsigned int GetNumberOfLogicalCPU() const; // per physical cpu
+ unsigned int GetNumberOfPhysicalCPU() const;
bool DoesCPUSupportCPUID();
// Retrieve memory information in MiB.
- size_t GetTotalVirtualMemory();
- size_t GetAvailableVirtualMemory();
- size_t GetTotalPhysicalMemory();
- size_t GetAvailablePhysicalMemory();
+ size_t GetTotalVirtualMemory() const;
+ size_t GetAvailableVirtualMemory() const;
+ size_t GetTotalPhysicalMemory() const;
+ size_t GetAvailablePhysicalMemory() const;
LongLong GetProcessId();
// Retrieve memory information in KiB.
LongLong GetHostMemoryTotal();
- LongLong GetHostMemoryAvailable(const char* envVarName);
+ LongLong GetHostMemoryAvailable(const char* hostLimitEnvVarName);
LongLong GetHostMemoryUsed();
LongLong GetProcMemoryAvailable(const char* hostLimitEnvVarName,
@@ -377,60 +378,103 @@ public:
void RunMemoryCheck();
public:
- typedef struct tagID
+ using ID = struct tagID
+
{
+
int Type;
+
int Family;
+
int Model;
+
int Revision;
+
int ExtendedFamily;
+
int ExtendedModel;
+
std::string ProcessorName;
+
std::string Vendor;
+
std::string SerialNumber;
+
std::string ModelName;
- } ID;
+ };
+
+ using CPUPowerManagement = struct tagCPUPowerManagement
- typedef struct tagCPUPowerManagement
{
+
bool HasVoltageID;
+
bool HasFrequencyID;
+
bool HasTempSenseDiode;
- } CPUPowerManagement;
+ };
+
+ using CPUExtendedFeatures = struct tagCPUExtendedFeatures
- typedef struct tagCPUExtendedFeatures
{
+
bool Has3DNow;
+
bool Has3DNowPlus;
+
bool SupportsMP;
+
bool HasMMXPlus;
+
bool HasSSEMMX;
+
unsigned int LogicalProcessorsPerPhysical;
+
int APIC_ID;
+
CPUPowerManagement PowerManagement;
- } CPUExtendedFeatures;
+ };
+
+ using CPUFeatures = struct CPUtagFeatures
- typedef struct CPUtagFeatures
{
+
bool HasFPU;
+
bool HasTSC;
+
bool HasMMX;
+
bool HasSSE;
+
bool HasSSEFP;
+
bool HasSSE2;
+
bool HasIA64;
+
bool HasAPIC;
+
bool HasCMOV;
+
bool HasMTRR;
+
bool HasACPI;
+
bool HasSerial;
+
bool HasThermal;
+
int CPUSpeed;
+
int L1CacheSize;
+
int L2CacheSize;
+
int L3CacheSize;
+
CPUExtendedFeatures ExtendedFeatures;
- } CPUFeatures;
+ };
enum Manufacturer
{
@@ -476,7 +520,7 @@ protected:
void CPUCountWindows(); // For windows
unsigned char GetAPICId(); // For windows
- bool IsSMTSupported();
+ bool IsSMTSupported() const;
static LongLong GetCyclesDifference(DELAY_FUNC, unsigned int); // For windows
// For Linux and Cygwin, /proc/cpuinfo formats are slightly different
@@ -885,7 +929,7 @@ int LoadLines(FILE* file, std::vector<std::string>& lines)
*pBuf = '\0';
pBuf += 1;
}
- lines.push_back(buf);
+ lines.emplace_back(buf);
++nRead;
}
if (ferror(file)) {
@@ -899,7 +943,7 @@ int LoadLines(FILE* file, std::vector<std::string>& lines)
int LoadLines(const char* fileName, std::vector<std::string>& lines)
{
FILE* file = fopen(fileName, "r");
- if (file == 0) {
+ if (file == nullptr) {
return 0;
}
int nRead = LoadLines(file, lines);
@@ -1322,9 +1366,9 @@ std::string SymbolProperties::GetFileName(const std::string& path) const
{
std::string file(path);
if (!this->ReportPath) {
- size_t at = file.rfind("/");
+ size_t at = file.rfind('/');
if (at != std::string::npos) {
- file = file.substr(at + 1);
+ file.erase(0, at + 1);
}
}
return file;
@@ -1464,10 +1508,6 @@ SystemInformationImplementation::SystemInformationImplementation()
this->OSIs64Bit = (sizeof(void*) == 8);
}
-SystemInformationImplementation::~SystemInformationImplementation()
-{
-}
-
void SystemInformationImplementation::RunCPUCheck()
{
#ifdef _WIN32
@@ -1564,7 +1604,7 @@ void SystemInformationImplementation::RunMemoryCheck()
}
/** Get the vendor string */
-const char* SystemInformationImplementation::GetVendorString()
+const char* SystemInformationImplementation::GetVendorString() const
{
return this->ChipID.Vendor.c_str();
}
@@ -1760,7 +1800,7 @@ const char* SystemInformationImplementation::GetVendorID()
}
/** Return the type ID of the CPU */
-std::string SystemInformationImplementation::GetTypeID()
+std::string SystemInformationImplementation::GetTypeID() const
{
std::ostringstream str;
str << this->ChipID.Type;
@@ -1768,7 +1808,7 @@ std::string SystemInformationImplementation::GetTypeID()
}
/** Return the family of the CPU present */
-std::string SystemInformationImplementation::GetFamilyID()
+std::string SystemInformationImplementation::GetFamilyID() const
{
std::ostringstream str;
str << this->ChipID.Family;
@@ -1776,7 +1816,7 @@ std::string SystemInformationImplementation::GetFamilyID()
}
// Return the model of CPU present */
-std::string SystemInformationImplementation::GetModelID()
+std::string SystemInformationImplementation::GetModelID() const
{
std::ostringstream str;
str << this->ChipID.Model;
@@ -1784,13 +1824,13 @@ std::string SystemInformationImplementation::GetModelID()
}
// Return the model name of CPU present */
-std::string SystemInformationImplementation::GetModelName()
+std::string SystemInformationImplementation::GetModelName() const
{
return this->ChipID.ModelName;
}
/** Return the stepping code of the CPU present. */
-std::string SystemInformationImplementation::GetSteppingCode()
+std::string SystemInformationImplementation::GetSteppingCode() const
{
std::ostringstream str;
str << this->ChipID.Revision;
@@ -1798,44 +1838,46 @@ std::string SystemInformationImplementation::GetSteppingCode()
}
/** Return the stepping code of the CPU present. */
-const char* SystemInformationImplementation::GetExtendedProcessorName()
+const char* SystemInformationImplementation::GetExtendedProcessorName() const
{
return this->ChipID.ProcessorName.c_str();
}
/** Return the serial number of the processor
* in hexadecimal: xxxx-xxxx-xxxx-xxxx-xxxx-xxxx. */
-const char* SystemInformationImplementation::GetProcessorSerialNumber()
+const char* SystemInformationImplementation::GetProcessorSerialNumber() const
{
return this->ChipID.SerialNumber.c_str();
}
/** Return the logical processors per physical */
unsigned int SystemInformationImplementation::GetLogicalProcessorsPerPhysical()
+ const
{
return this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical;
}
/** Return the processor clock frequency. */
-float SystemInformationImplementation::GetProcessorClockFrequency()
+float SystemInformationImplementation::GetProcessorClockFrequency() const
{
return this->CPUSpeedInMHz;
}
/** Return the APIC ID. */
-int SystemInformationImplementation::GetProcessorAPICID()
+int SystemInformationImplementation::GetProcessorAPICID() const
{
return this->Features.ExtendedFeatures.APIC_ID;
}
/** Return the L1 cache size. */
-int SystemInformationImplementation::GetProcessorCacheSize()
+int SystemInformationImplementation::GetProcessorCacheSize() const
{
return this->Features.L1CacheSize;
}
/** Return the chosen cache size. */
-int SystemInformationImplementation::GetProcessorCacheXSize(long int dwCacheID)
+int SystemInformationImplementation::GetProcessorCacheXSize(
+ long int dwCacheID) const
{
switch (dwCacheID) {
case SystemInformation::CPU_FEATURE_L1CACHE:
@@ -1848,7 +1890,8 @@ int SystemInformationImplementation::GetProcessorCacheXSize(long int dwCacheID)
return -1;
}
-bool SystemInformationImplementation::DoesCPUSupportFeature(long int dwFeature)
+bool SystemInformationImplementation::DoesCPUSupportFeature(
+ long int dwFeature) const
{
bool bHasFeature = false;
@@ -2128,7 +2171,7 @@ void SystemInformationImplementation::FindManufacturer(
this->ChipManufacturer = HP; // Hewlett-Packard
else if (this->ChipID.Vendor == "Motorola")
this->ChipManufacturer = Motorola; // Motorola Microelectronics
- else if (family.substr(0, 7) == "PA-RISC")
+ else if (family.compare(0, 7, "PA-RISC") == 0)
this->ChipManufacturer = HP; // Hewlett-Packard
else
this->ChipManufacturer = UnknownManufacturer; // Unknown manufacturer
@@ -2843,7 +2886,7 @@ static void SystemInformationStripLeadingSpace(std::string& str)
// post-process the name.
std::string::size_type pos = str.find_first_not_of(" ");
if (pos != std::string::npos) {
- str = str.substr(pos);
+ str.erase(0, pos);
}
}
#endif
@@ -3344,8 +3387,8 @@ std::string SystemInformationImplementation::ExtractValueFromCpuInfoFile(
size_t pos = buffer.find(word, init);
if (pos != std::string::npos) {
this->CurrentPositionInFile = pos;
- pos = buffer.find(":", pos);
- size_t pos2 = buffer.find("\n", pos);
+ pos = buffer.find(':', pos);
+ size_t pos2 = buffer.find('\n', pos);
if (pos != std::string::npos && pos2 != std::string::npos) {
// It may happen that the beginning matches, but this is still not the
// requested key.
@@ -3358,7 +3401,9 @@ std::string SystemInformationImplementation::ExtractValueFromCpuInfoFile(
return this->ExtractValueFromCpuInfoFile(buffer, word, pos2);
}
}
- return buffer.substr(pos + 2, pos2 - pos - 2);
+ buffer.erase(0, pos + 2);
+ buffer.resize(pos2 - pos - 2);
+ return buffer;
}
}
this->CurrentPositionInFile = std::string::npos;
@@ -3409,7 +3454,7 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
// We want to record the total number of cores in this->NumberOfPhysicalCPU
// (checking only the first proc)
std::string Cores = this->ExtractValueFromCpuInfoFile(buffer, "cpu cores");
- unsigned int NumberOfCoresPerSocket = (unsigned int)atoi(Cores.c_str());
+ auto NumberOfCoresPerSocket = (unsigned int)atoi(Cores.c_str());
NumberOfCoresPerSocket = std::max(NumberOfCoresPerSocket, 1u);
this->NumberOfPhysicalCPU =
NumberOfCoresPerSocket * (unsigned int)NumberOfSockets;
@@ -3441,7 +3486,7 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
// Linux Sparc: CPU speed is in Hz and encoded in hexadecimal
CPUSpeed = this->ExtractValueFromCpuInfoFile(buffer, "Cpu0ClkTck");
this->CPUSpeedInMHz =
- static_cast<float>(strtoull(CPUSpeed.c_str(), 0, 16)) / 1000000.0f;
+ static_cast<float>(strtoull(CPUSpeed.c_str(), nullptr, 16)) / 1000000.0f;
}
#endif
@@ -3502,13 +3547,12 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
cachename.push_back("D-cache"); // e.g. PA-RISC
this->Features.L1CacheSize = 0;
- for (size_t index = 0; index < cachename.size(); index++) {
- std::string cacheSize =
- this->ExtractValueFromCpuInfoFile(buffer, cachename[index]);
+ for (auto& index : cachename) {
+ std::string cacheSize = this->ExtractValueFromCpuInfoFile(buffer, index);
if (!cacheSize.empty()) {
pos = cacheSize.find(" KB");
if (pos != std::string::npos) {
- cacheSize = cacheSize.substr(0, pos);
+ cacheSize.resize(pos);
}
this->Features.L1CacheSize += atoi(cacheSize.c_str());
}
@@ -3893,7 +3937,7 @@ std::string SystemInformationImplementation::GetProgramStack(int firstFrame,
int wholePath)
{
std::ostringstream oss;
- std::string programStack = "";
+ std::string programStack;
#ifdef KWSYS_SYSTEMINFORMATION_HAS_DBGHELP
(void)wholePath;
@@ -4249,24 +4293,24 @@ bool SystemInformationImplementation::QueryMemory()
}
/** */
-size_t SystemInformationImplementation::GetTotalVirtualMemory()
+size_t SystemInformationImplementation::GetTotalVirtualMemory() const
{
return this->TotalVirtualMemory;
}
/** */
-size_t SystemInformationImplementation::GetAvailableVirtualMemory()
+size_t SystemInformationImplementation::GetAvailableVirtualMemory() const
{
return this->AvailableVirtualMemory;
}
-size_t SystemInformationImplementation::GetTotalPhysicalMemory()
+size_t SystemInformationImplementation::GetTotalPhysicalMemory() const
{
return this->TotalPhysicalMemory;
}
/** */
-size_t SystemInformationImplementation::GetAvailablePhysicalMemory()
+size_t SystemInformationImplementation::GetAvailablePhysicalMemory() const
{
return this->AvailablePhysicalMemory;
}
@@ -4279,9 +4323,15 @@ SystemInformationImplementation::GetCyclesDifference(DELAY_FUNC DelayFunction,
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
unsigned __int64 stamp1, stamp2;
+# ifdef _M_ARM64
+ stamp1 = _ReadStatusReg(ARM64_PMCCNTR_EL0);
+ DelayFunction(uiParameter);
+ stamp2 = _ReadStatusReg(ARM64_PMCCNTR_EL0);
+# else
stamp1 = __rdtsc();
DelayFunction(uiParameter);
stamp2 = __rdtsc();
+# endif
return stamp2 - stamp1;
#elif USE_ASM_INSTRUCTIONS
@@ -4350,7 +4400,7 @@ void SystemInformationImplementation::DelayOverhead(unsigned int uiMS)
}
/** Works only for windows */
-bool SystemInformationImplementation::IsSMTSupported()
+bool SystemInformationImplementation::IsSMTSupported() const
{
return this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical > 1;
}
@@ -4432,13 +4482,13 @@ void SystemInformationImplementation::CPUCountWindows()
}
/** Return the number of logical CPUs on the system */
-unsigned int SystemInformationImplementation::GetNumberOfLogicalCPU()
+unsigned int SystemInformationImplementation::GetNumberOfLogicalCPU() const
{
return this->NumberOfLogicalCPU;
}
/** Return the number of physical CPUs on the system */
-unsigned int SystemInformationImplementation::GetNumberOfPhysicalCPU()
+unsigned int SystemInformationImplementation::GetNumberOfPhysicalCPU() const
{
return this->NumberOfPhysicalCPU;
}
@@ -4638,7 +4688,7 @@ std::string SystemInformationImplementation::ExtractValueFromSysCtl(
size_t pos = this->SysCtlBuffer.find(word);
if (pos != std::string::npos) {
pos = this->SysCtlBuffer.find(": ", pos);
- size_t pos2 = this->SysCtlBuffer.find("\n", pos);
+ size_t pos2 = this->SysCtlBuffer.find('\n', pos);
if (pos != std::string::npos && pos2 != std::string::npos) {
return this->SysCtlBuffer.substr(pos + 2, pos2 - pos - 2);
}
@@ -4733,14 +4783,15 @@ std::string SystemInformationImplementation::ParseValueFromKStat(
}
pos = command.find(' ', pos + 1);
}
- args_string.push_back(command.substr(start + 1, command.size() - start - 1));
+ command.erase(0, start + 1);
+ args_string.push_back(command);
std::vector<const char*> args;
args.reserve(3 + args_string.size());
args.push_back("kstat");
args.push_back("-p");
- for (size_t i = 0; i < args_string.size(); ++i) {
- args.push_back(args_string[i].c_str());
+ for (auto& i : args_string) {
+ args.push_back(i.c_str());
}
args.push_back(nullptr);
@@ -4922,7 +4973,9 @@ bool SystemInformationImplementation::QueryQNXMemory()
while (buffer[pos] == ' ')
pos++;
- this->TotalPhysicalMemory = atoi(buffer.substr(pos, pos2 - pos).c_str());
+ buffer.erase(0, pos);
+ buffer.resize(pos2);
+ this->TotalPhysicalMemory = atoi(buffer.c_str());
return true;
#endif
return false;
@@ -5447,19 +5500,19 @@ void SystemInformationImplementation::TrimNewline(std::string& output)
{
// remove \r
std::string::size_type pos = 0;
- while ((pos = output.find("\r", pos)) != std::string::npos) {
+ while ((pos = output.find('\r', pos)) != std::string::npos) {
output.erase(pos);
}
// remove \n
pos = 0;
- while ((pos = output.find("\n", pos)) != std::string::npos) {
+ while ((pos = output.find('\n', pos)) != std::string::npos) {
output.erase(pos);
}
}
/** Return true if the machine is 64 bits */
-bool SystemInformationImplementation::Is64Bits()
+bool SystemInformationImplementation::Is64Bits() const
{
return this->OSIs64Bit;
}
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index ce4d6ef..a6d210f 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -24,6 +24,7 @@
#include KWSYS_HEADER(Encoding.h)
#include KWSYS_HEADER(Encoding.hxx)
+#include <algorithm>
#include <fstream>
#include <iostream>
#include <set>
@@ -49,15 +50,15 @@
# pragma set woff 1375 /* base class destructor not virtual */
#endif
-#include <ctype.h>
-#include <errno.h>
+#include <cctype>
+#include <cerrno>
#ifdef __QNX__
# include <malloc.h> /* for malloc/free on QNX */
#endif
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
#if defined(_WIN32) && !defined(_MSC_VER) && defined(__GNUC__)
# include <strings.h> /* for strcasecmp */
@@ -69,7 +70,7 @@
// support for realpath call
#ifndef _WIN32
-# include <limits.h>
+# include <climits>
# include <pwd.h>
# include <sys/ioctl.h>
# include <sys/time.h>
@@ -80,7 +81,7 @@
# include <sys/param.h>
# include <termios.h>
# endif
-# include <signal.h> /* sigprocmask */
+# include <csignal> /* sigprocmask */
#endif
#ifdef __linux
@@ -123,9 +124,9 @@ extern char** environ;
#define VTK_URL_PROTOCOL_REGEX "([a-zA-Z0-9]*)://(.*)"
#define VTK_URL_REGEX \
- "([a-zA-Z0-9]*)://(([A-Za-z0-9]+)(:([^:@]+))?@)?([^:@/]+)(:([0-9]+))?/" \
+ "([a-zA-Z0-9]*)://(([A-Za-z0-9]+)(:([^:@]+))?@)?([^:@/]*)(:([0-9]+))?/" \
"(.+)?"
-
+#define VTK_URL_BYTE_REGEX "%[0-9a-fA-F][0-9a-fA-F]"
#ifdef _MSC_VER
# include <sys/utime.h>
#else
@@ -221,11 +222,17 @@ static time_t windows_filetime_to_posix_time(const FILETIME& ft)
#ifdef KWSYS_WINDOWS_DIRS
# include <wctype.h>
+# ifdef _MSC_VER
+typedef KWSYS_NAMESPACE::SystemTools::mode_t mode_t;
+# endif
-inline int Mkdir(const std::string& dir)
+inline int Mkdir(const std::string& dir, const mode_t* mode)
{
- return _wmkdir(
- KWSYS_NAMESPACE::Encoding::ToWindowsExtendedPath(dir).c_str());
+ int ret =
+ _wmkdir(KWSYS_NAMESPACE::Encoding::ToWindowsExtendedPath(dir).c_str());
+ if (ret == 0 && mode)
+ KWSYS_NAMESPACE::SystemTools::SetPermissions(dir, *mode);
+ return ret;
}
inline int Rmdir(const std::string& dir)
{
@@ -295,9 +302,9 @@ inline void Realpath(const std::string& path, std::string& resolved_path,
# include <fcntl.h>
# include <unistd.h>
-inline int Mkdir(const std::string& dir)
+inline int Mkdir(const std::string& dir, const mode_t* mode)
{
- return mkdir(dir.c_str(), 00777);
+ return mkdir(dir.c_str(), mode ? *mode : 00777);
}
inline int Rmdir(const std::string& dir)
{
@@ -350,7 +357,7 @@ extern int putenv(char* __string) __THROW;
namespace KWSYS_NAMESPACE {
-double SystemTools::GetTime(void)
+double SystemTools::GetTime()
{
#if defined(_WIN32) && !defined(__CYGWIN__)
FILETIME ft;
@@ -368,7 +375,7 @@ double SystemTools::GetTime(void)
#if defined(_WIN32)
typedef wchar_t envchar;
#else
-typedef char envchar;
+using envchar = char;
#endif
/* Order by environment key only (VAR from VAR=VALUE). */
@@ -421,7 +428,7 @@ public:
const envchar* Release(const envchar* env)
{
const envchar* old = nullptr;
- iterator i = this->find(env);
+ auto i = this->find(env);
if (i != this->end()) {
old = *i;
this->erase(i);
@@ -452,7 +459,7 @@ struct SystemToolsPathCaseCmp
class SystemToolsStatic
{
public:
- typedef std::map<std::string, std::string> StringMap;
+ using StringMap = std::map<std::string, std::string>;
#if KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP
/**
* Path translation table from dir to refdir
@@ -488,10 +495,13 @@ public:
*/
static std::string FindName(
const std::string& name,
- const std::vector<std::string>& path = std::vector<std::string>(),
+ const std::vector<std::string>& userPaths = std::vector<std::string>(),
bool no_system_path = false);
};
+// Do NOT initialize. Default initialization to zero is necessary.
+static SystemToolsStatic* SystemToolsStatics;
+
#ifdef _WIN32
std::string SystemToolsStatic::GetCasePathName(std::string const& pathIn)
{
@@ -566,7 +576,7 @@ 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 = SystemTools::Statics->PathCaseMap;
+ auto& pcm = SystemToolsStatics->PathCaseMap;
{
auto itr = pcm.find(p);
if (itr != pcm.end()) {
@@ -613,8 +623,7 @@ void SystemTools::GetPath(std::vector<std::string>& path, const char* env)
done = true;
}
}
- for (std::vector<std::string>::iterator i = path.begin() + old_size;
- i != path.end(); ++i) {
+ for (auto i = path.begin() + old_size; i != path.end(); ++i) {
SystemTools::ConvertToUnixSlashes(*i);
}
}
@@ -624,7 +633,7 @@ const char* SystemToolsStatic::GetEnvBuffered(const char* key)
{
std::string env;
if (SystemTools::GetEnv(key, env)) {
- std::string& menv = SystemTools::Statics->EnvMap[key];
+ std::string& menv = SystemToolsStatics->EnvMap[key];
if (menv != env) {
menv = std::move(env);
}
@@ -884,8 +893,12 @@ const char* SystemTools::GetExecutableExtension()
FILE* SystemTools::Fopen(const std::string& file, const char* mode)
{
#ifdef _WIN32
+ // Remove any 'e', which is supported on UNIX, but not Windows.
+ std::wstring trimmedMode = Encoding::ToWide(mode);
+ trimmedMode.erase(std::remove(trimmedMode.begin(), trimmedMode.end(), L'e'),
+ trimmedMode.end());
return _wfopen(Encoding::ToWindowsExtendedPath(file).c_str(),
- Encoding::ToWide(mode).c_str());
+ trimmedMode.c_str());
#else
return fopen(file.c_str(), mode);
#endif
@@ -913,16 +926,17 @@ bool SystemTools::MakeDirectory(const std::string& path, const mode_t* mode)
std::string::size_type pos = 0;
std::string topdir;
while ((pos = dir.find('/', pos)) != std::string::npos) {
- topdir = dir.substr(0, pos);
+ // all underlying functions use C strings, so temporarily
+ // end the string here
+ dir[pos] = '\0';
- if (Mkdir(topdir) == 0 && mode != nullptr) {
- SystemTools::SetPermissions(topdir, *mode);
- }
+ Mkdir(dir, mode);
+ dir[pos] = '/';
++pos;
}
topdir = dir;
- if (Mkdir(topdir) != 0) {
+ if (Mkdir(topdir, mode) != 0) {
// There is a bug in the Borland Run time library which makes MKDIR
// return EACCES when it should return EEXISTS
// if it is some other error besides directory exists
@@ -934,8 +948,6 @@ bool SystemTools::MakeDirectory(const std::string& path, const mode_t* mode)
) {
return false;
}
- } else if (mode != nullptr) {
- SystemTools::SetPermissions(topdir, *mode);
}
return true;
@@ -1011,38 +1023,40 @@ void SystemToolsStatic::ReplaceString(std::string& source, const char* replace,
# define KWSYS_ST_KEY_WOW64_64KEY 0x0100
# endif
-static bool SystemToolsParseRegistryKey(const std::string& key,
- HKEY& primaryKey, std::string& second,
- std::string& valuename)
+static bool hasPrefix(const std::string& s, const char* pattern,
+ std::string::size_type spos)
{
- std::string primary = key;
+ size_t plen = strlen(pattern);
+ if (spos != plen)
+ return false;
+ return s.compare(0, plen, pattern) == 0;
+}
- size_t start = primary.find('\\');
+static bool SystemToolsParseRegistryKey(const std::string& key,
+ HKEY& primaryKey, std::wstring& second,
+ std::string* valuename)
+{
+ size_t start = key.find('\\');
if (start == std::string::npos) {
return false;
}
- size_t valuenamepos = primary.find(';');
- if (valuenamepos != std::string::npos) {
- valuename = primary.substr(valuenamepos + 1);
+ size_t valuenamepos = key.find(';');
+ if (valuenamepos != std::string::npos && valuename) {
+ *valuename = key.substr(valuenamepos + 1);
}
- second = primary.substr(start + 1, valuenamepos - start - 1);
- primary = primary.substr(0, start);
+ second = Encoding::ToWide(key.substr(start + 1, valuenamepos - start - 1));
- if (primary == "HKEY_CURRENT_USER") {
+ if (hasPrefix(key, "HKEY_CURRENT_USER", start)) {
primaryKey = HKEY_CURRENT_USER;
- }
- if (primary == "HKEY_CURRENT_CONFIG") {
+ } else if (hasPrefix(key, "HKEY_CURRENT_CONFIG", start)) {
primaryKey = HKEY_CURRENT_CONFIG;
- }
- if (primary == "HKEY_CLASSES_ROOT") {
+ } else if (hasPrefix(key, "HKEY_CLASSES_ROOT", start)) {
primaryKey = HKEY_CLASSES_ROOT;
- }
- if (primary == "HKEY_LOCAL_MACHINE") {
+ } else if (hasPrefix(key, "HKEY_LOCAL_MACHINE", start)) {
primaryKey = HKEY_LOCAL_MACHINE;
- }
- if (primary == "HKEY_USERS") {
+ } else if (hasPrefix(key, "HKEY_USERS", start)) {
primaryKey = HKEY_USERS;
}
@@ -1074,14 +1088,13 @@ bool SystemTools::GetRegistrySubKeys(const std::string& key,
KeyWOW64 view)
{
HKEY primaryKey = HKEY_CURRENT_USER;
- std::string second;
- std::string valuename;
- if (!SystemToolsParseRegistryKey(key, primaryKey, second, valuename)) {
+ std::wstring second;
+ if (!SystemToolsParseRegistryKey(key, primaryKey, second, nullptr)) {
return false;
}
HKEY hKey;
- if (RegOpenKeyExW(primaryKey, Encoding::ToWide(second).c_str(), 0,
+ if (RegOpenKeyExW(primaryKey, second.c_str(), 0,
SystemToolsMakeRegistryMode(KEY_READ, view),
&hKey) != ERROR_SUCCESS) {
return false;
@@ -1121,14 +1134,14 @@ bool SystemTools::ReadRegistryValue(const std::string& key, std::string& value,
{
bool valueset = false;
HKEY primaryKey = HKEY_CURRENT_USER;
- std::string second;
+ std::wstring second;
std::string valuename;
- if (!SystemToolsParseRegistryKey(key, primaryKey, second, valuename)) {
+ if (!SystemToolsParseRegistryKey(key, primaryKey, second, &valuename)) {
return false;
}
HKEY hKey;
- if (RegOpenKeyExW(primaryKey, Encoding::ToWide(second).c_str(), 0,
+ if (RegOpenKeyExW(primaryKey, second.c_str(), 0,
SystemToolsMakeRegistryMode(KEY_READ, view),
&hKey) != ERROR_SUCCESS) {
return false;
@@ -1175,16 +1188,16 @@ bool SystemTools::WriteRegistryValue(const std::string& key,
const std::string& value, KeyWOW64 view)
{
HKEY primaryKey = HKEY_CURRENT_USER;
- std::string second;
+ std::wstring second;
std::string valuename;
- if (!SystemToolsParseRegistryKey(key, primaryKey, second, valuename)) {
+ if (!SystemToolsParseRegistryKey(key, primaryKey, second, &valuename)) {
return false;
}
HKEY hKey;
DWORD dwDummy;
wchar_t lpClass[] = L"";
- if (RegCreateKeyExW(primaryKey, Encoding::ToWide(second).c_str(), 0, lpClass,
+ if (RegCreateKeyExW(primaryKey, second.c_str(), 0, lpClass,
REG_OPTION_NON_VOLATILE,
SystemToolsMakeRegistryMode(KEY_WRITE, view), nullptr,
&hKey, &dwDummy) != ERROR_SUCCESS) {
@@ -1219,14 +1232,14 @@ bool SystemTools::WriteRegistryValue(const std::string&, const std::string&,
bool SystemTools::DeleteRegistryValue(const std::string& key, KeyWOW64 view)
{
HKEY primaryKey = HKEY_CURRENT_USER;
- std::string second;
+ std::wstring second;
std::string valuename;
- if (!SystemToolsParseRegistryKey(key, primaryKey, second, valuename)) {
+ if (!SystemToolsParseRegistryKey(key, primaryKey, second, &valuename)) {
return false;
}
HKEY hKey;
- if (RegOpenKeyExW(primaryKey, Encoding::ToWide(second).c_str(), 0,
+ if (RegOpenKeyExW(primaryKey, second.c_str(), 0,
SystemToolsMakeRegistryMode(KEY_WRITE, view),
&hKey) != ERROR_SUCCESS) {
return false;
@@ -1448,15 +1461,15 @@ int SystemTools::Stat(const std::string& path, SystemTools::Stat_t* buf)
#ifdef __CYGWIN__
bool SystemTools::PathCygwinToWin32(const char* path, char* win32_path)
{
- auto itr = SystemTools::Statics->Cyg2Win32Map.find(path);
- if (itr != SystemTools::Statics->Cyg2Win32Map.end()) {
+ auto itr = SystemToolsStatics->Cyg2Win32Map.find(path);
+ if (itr != SystemToolsStatics->Cyg2Win32Map.end()) {
strncpy(win32_path, itr->second.c_str(), MAX_PATH);
} else {
if (cygwin_conv_path(CCP_POSIX_TO_WIN_A, path, win32_path, MAX_PATH) !=
0) {
win32_path[0] = 0;
}
- SystemTools::Statics->Cyg2Win32Map.insert(
+ SystemToolsStatics->Cyg2Win32Map.insert(
SystemToolsStatic::StringMap::value_type(path, win32_path));
}
return win32_path[0] != 0;
@@ -1858,7 +1871,7 @@ char* SystemTools::DuplicateString(const char* str)
// Return a cropped string
std::string SystemTools::CropString(const std::string& s, size_t max_len)
{
- if (!s.size() || max_len == 0 || max_len >= s.size()) {
+ if (s.empty() || max_len == 0 || max_len >= s.size()) {
return s;
}
@@ -1867,7 +1880,7 @@ std::string SystemTools::CropString(const std::string& s, size_t max_len)
size_t middle = max_len / 2;
- n += s.substr(0, middle);
+ n.assign(s, 0, middle);
n += s.substr(s.size() - (max_len - middle));
if (max_len > 2) {
@@ -1893,10 +1906,10 @@ std::vector<std::string> SystemTools::SplitString(const std::string& p,
}
if (isPath && path[0] == '/') {
path.erase(path.begin());
- paths.push_back("/");
+ paths.emplace_back("/");
}
std::string::size_type pos1 = 0;
- std::string::size_type pos2 = path.find(sep, pos1 + 1);
+ std::string::size_type pos2 = path.find(sep, pos1);
while (pos2 != std::string::npos) {
paths.push_back(path.substr(pos1, pos2 - pos1));
pos1 = pos2 + 1;
@@ -2065,8 +2078,10 @@ void SystemTools::ConvertToUnixSlashes(std::string& path)
#ifdef HAVE_GETPWNAM
else if (pathCString[0] == '~') {
std::string::size_type idx = path.find_first_of("/\0");
- std::string user = path.substr(1, idx - 1);
- passwd* pw = getpwnam(user.c_str());
+ char oldch = path[idx];
+ path[idx] = '\0';
+ passwd* pw = getpwnam(path.c_str() + 1);
+ path[idx] = oldch;
if (pw) {
path.replace(0, idx, pw->pw_dir);
}
@@ -2103,7 +2118,7 @@ std::string SystemTools::ConvertToUnixOutputPath(const std::string& path)
ret.erase(pos, 1);
}
// escape spaces and () in the path
- if (ret.find_first_of(" ") != std::string::npos) {
+ if (ret.find_first_of(' ') != std::string::npos) {
std::string result;
char lastch = 1;
for (const char* ch = ret.c_str(); *ch != '\0'; ++ch) {
@@ -2186,12 +2201,15 @@ bool SystemTools::CopyFileIfDifferent(const std::string& source,
// FilesDiffer does not handle file to directory compare
if (SystemTools::FileIsDirectory(destination)) {
const std::string new_destination = FileInDir(source, destination);
- return SystemTools::CopyFileIfDifferent(source, new_destination);
- }
- // source and destination are files so do a copy if they
- // are different
- if (SystemTools::FilesDiffer(source, destination)) {
- return SystemTools::CopyFileAlways(source, destination);
+ if (!SystemTools::ComparePath(new_destination, destination)) {
+ return SystemTools::CopyFileIfDifferent(source, new_destination);
+ }
+ } else {
+ // source and destination are files so do a copy if they
+ // are different
+ if (SystemTools::FilesDiffer(source, destination)) {
+ return SystemTools::CopyFileAlways(source, destination);
+ }
}
// at this point the files must be the same so return true
return true;
@@ -2326,14 +2344,8 @@ bool SystemTools::TextFilesDiffer(const std::string& path1,
static bool CopyFileContentBlockwise(const std::string& source,
const std::string& destination)
{
-// Open files
-#if defined(_WIN32)
- kwsys::ifstream fin(
- Encoding::ToNarrow(Encoding::ToWindowsExtendedPath(source)).c_str(),
- std::ios::in | std::ios::binary);
-#else
+ // Open files
kwsys::ifstream fin(source.c_str(), std::ios::in | std::ios::binary);
-#endif
if (!fin) {
return false;
}
@@ -2344,14 +2356,8 @@ static bool CopyFileContentBlockwise(const std::string& source,
// that do not allow file removal can be modified.
SystemTools::RemoveFile(destination);
-#if defined(_WIN32)
- kwsys::ofstream fout(
- Encoding::ToNarrow(Encoding::ToWindowsExtendedPath(destination)).c_str(),
- std::ios::out | std::ios::trunc | std::ios::binary);
-#else
kwsys::ofstream fout(destination.c_str(),
std::ios::out | std::ios::trunc | std::ios::binary);
-#endif
if (!fout) {
return false;
}
@@ -2510,8 +2516,8 @@ bool SystemTools::CopyADirectory(const std::string& source,
return false;
}
for (fileNum = 0; fileNum < dir.GetNumberOfFiles(); ++fileNum) {
- if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), ".") &&
- strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), "..")) {
+ if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), ".") != 0 &&
+ strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), "..") != 0) {
std::string fullPath = source;
fullPath += "/";
fullPath += dir.GetFile(static_cast<unsigned long>(fileNum));
@@ -2673,8 +2679,8 @@ bool SystemTools::RemoveADirectory(const std::string& source)
dir.Load(source);
size_t fileNum;
for (fileNum = 0; fileNum < dir.GetNumberOfFiles(); ++fileNum) {
- if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), ".") &&
- strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), "..")) {
+ if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), ".") != 0 &&
+ strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)), "..") != 0) {
std::string fullPath = source;
fullPath += "/";
fullPath += dir.GetFile(static_cast<unsigned long>(fileNum));
@@ -2806,7 +2812,7 @@ std::string SystemTools::FindProgram(const std::string& name,
for (std::string const& ext : extensions) {
tryPath = name;
tryPath += ext;
- if (SystemTools::FileExists(tryPath, true)) {
+ if (SystemTools::FileIsExecutable(tryPath)) {
return SystemTools::CollapseFullPath(tryPath);
}
}
@@ -2814,7 +2820,7 @@ std::string SystemTools::FindProgram(const std::string& name,
#endif
// now try just the name
- if (SystemTools::FileExists(name, true)) {
+ if (SystemTools::FileIsExecutable(name)) {
return SystemTools::CollapseFullPath(name);
}
// now construct the path
@@ -2844,7 +2850,7 @@ std::string SystemTools::FindProgram(const std::string& name,
tryPath = p;
tryPath += name;
tryPath += ext;
- if (SystemTools::FileExists(tryPath, true)) {
+ if (SystemTools::FileIsExecutable(tryPath)) {
return SystemTools::CollapseFullPath(tryPath);
}
}
@@ -2852,7 +2858,7 @@ std::string SystemTools::FindProgram(const std::string& name,
// now try it without them
tryPath = p;
tryPath += name;
- if (SystemTools::FileExists(tryPath, true)) {
+ if (SystemTools::FileIsExecutable(tryPath)) {
return SystemTools::CollapseFullPath(tryPath);
}
}
@@ -3007,6 +3013,15 @@ bool SystemTools::FileIsDirectory(const std::string& inName)
}
}
+bool SystemTools::FileIsExecutable(const std::string& name)
+{
+#if defined(_WIN32)
+ return SystemTools::FileExists(name, true);
+#else
+ return !FileIsDirectory(name) && TestFileAccess(name, TEST_FILE_EXECUTE);
+#endif
+}
+
bool SystemTools::FileIsSymlink(const std::string& name)
{
#if defined(_WIN32)
@@ -3116,16 +3131,14 @@ int SystemTools::ChangeDirectory(const std::string& dir)
return Chdir(dir);
}
-std::string SystemTools::GetCurrentWorkingDirectory(bool collapse)
+std::string SystemTools::GetCurrentWorkingDirectory()
{
char buf[2048];
const char* cwd = Getcwd(buf, 2048);
std::string path;
if (cwd) {
path = cwd;
- }
- if (collapse) {
- return SystemTools::CollapseFullPath(path);
+ SystemTools::ConvertToUnixSlashes(path);
}
return path;
}
@@ -3141,17 +3154,17 @@ bool SystemTools::SplitProgramPath(const std::string& in_name,
std::string& dir, std::string& file, bool)
{
dir = in_name;
- file = "";
+ file.clear();
SystemTools::ConvertToUnixSlashes(dir);
if (!SystemTools::FileIsDirectory(dir)) {
- std::string::size_type slashPos = dir.rfind("/");
+ std::string::size_type slashPos = dir.rfind('/');
if (slashPos != std::string::npos) {
file = dir.substr(slashPos + 1);
- dir = dir.substr(0, slashPos);
+ dir.resize(slashPos);
} else {
file = dir;
- dir = "";
+ dir.clear();
}
}
if (!(dir.empty()) && !SystemTools::FileIsDirectory(dir)) {
@@ -3173,7 +3186,7 @@ bool SystemTools::FindProgramPath(const char* argv0, std::string& pathOut,
failures.push_back(self);
SystemTools::ConvertToUnixSlashes(self);
self = SystemTools::FindProgram(self);
- if (!SystemTools::FileExists(self)) {
+ if (!SystemTools::FileIsExecutable(self)) {
if (buildDir) {
std::string intdir = ".";
#ifdef CMAKE_INTDIR
@@ -3188,14 +3201,14 @@ bool SystemTools::FindProgramPath(const char* argv0, std::string& pathOut,
}
}
if (installPrefix) {
- if (!SystemTools::FileExists(self)) {
+ if (!SystemTools::FileIsExecutable(self)) {
failures.push_back(self);
self = installPrefix;
self += "/bin/";
self += exeName;
}
}
- if (!SystemTools::FileExists(self)) {
+ if (!SystemTools::FileIsExecutable(self)) {
failures.push_back(self);
std::ostringstream msg;
msg << "Can not find the command line program ";
@@ -3217,11 +3230,6 @@ bool SystemTools::FindProgramPath(const char* argv0, std::string& pathOut,
return true;
}
-std::string SystemTools::CollapseFullPath(const std::string& in_relative)
-{
- return SystemTools::CollapseFullPath(in_relative, nullptr);
-}
-
#if KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP
void SystemTools::AddTranslationPath(const std::string& a,
const std::string& b)
@@ -3246,7 +3254,7 @@ void SystemTools::AddTranslationPath(const std::string& a,
path_b += '/';
}
if (!(path_a == path_b)) {
- SystemTools::Statics->TranslationMap.insert(
+ SystemToolsStatics->TranslationMap.insert(
SystemToolsStatic::StringMap::value_type(std::move(path_a),
std::move(path_b)));
}
@@ -3276,9 +3284,9 @@ void SystemTools::CheckTranslationPath(std::string& path)
// In case a file was specified we still have to go through this:
// Now convert any path found in the table back to the one desired:
- for (auto const& pair : SystemTools::Statics->TranslationMap) {
+ for (auto const& pair : SystemToolsStatics->TranslationMap) {
// We need to check of the path is a substring of the other path
- if (path.find(pair.first) == 0) {
+ if (path.compare(0, pair.first.size(), pair.first) == 0) {
path = path.replace(0, pair.first.size(), pair.second);
}
}
@@ -3311,25 +3319,10 @@ static void SystemToolsAppendComponents(
}
}
-std::string SystemTools::CollapseFullPath(const std::string& in_path,
- const char* in_base)
-{
- // Use the current working directory as a base path.
- char buf[2048];
- const char* res_in_base = in_base;
- if (!res_in_base) {
- if (const char* cwd = Getcwd(buf, 2048)) {
- res_in_base = cwd;
- } else {
- res_in_base = "";
- }
- }
-
- return SystemTools::CollapseFullPath(in_path, std::string(res_in_base));
-}
+namespace {
-std::string SystemTools::CollapseFullPath(const std::string& in_path,
- const std::string& in_base)
+std::string CollapseFullPathImpl(std::string const& in_path,
+ std::string const* in_base)
{
// Collect the output path components.
std::vector<std::string> out_components;
@@ -3342,8 +3335,15 @@ std::string SystemTools::CollapseFullPath(const std::string& in_path,
// If the input path is relative, start with a base path.
if (path_components[0].empty()) {
std::vector<std::string> base_components;
- // Use the given base path.
- SystemTools::SplitPath(in_base, base_components);
+
+ if (in_base) {
+ // Use the given base path.
+ SystemTools::SplitPath(*in_base, base_components);
+ } else {
+ // Use the current working directory as a base path.
+ std::string cwd = SystemTools::GetCurrentWorkingDirectory();
+ SystemTools::SplitPath(cwd, base_components);
+ }
// Append base path components to the output path.
out_components.push_back(base_components[0]);
@@ -3376,12 +3376,34 @@ std::string SystemTools::CollapseFullPath(const std::string& in_path,
SystemTools::CheckTranslationPath(newPath);
#endif
#ifdef _WIN32
- newPath = SystemTools::Statics->GetActualCaseForPathCached(newPath);
+ newPath = SystemToolsStatics->GetActualCaseForPathCached(newPath);
SystemTools::ConvertToUnixSlashes(newPath);
#endif
// Return the reconstructed path.
return newPath;
}
+}
+
+std::string SystemTools::CollapseFullPath(std::string const& in_path)
+{
+ return CollapseFullPathImpl(in_path, nullptr);
+}
+
+std::string SystemTools::CollapseFullPath(std::string const& in_path,
+ const char* in_base)
+{
+ if (!in_base) {
+ return CollapseFullPathImpl(in_path, nullptr);
+ }
+ std::string tmp_base = in_base;
+ return CollapseFullPathImpl(in_path, &tmp_base);
+}
+
+std::string SystemTools::CollapseFullPath(std::string const& in_path,
+ std::string const& in_base)
+{
+ return CollapseFullPathImpl(in_path, &in_base);
+}
// compute the relative path from here to there
std::string SystemTools::RelativePath(const std::string& local,
@@ -3550,7 +3572,7 @@ void SystemTools::SplitPath(const std::string& p,
// Expand home directory references if requested.
if (expand_home_dir && !root.empty() && root[0] == '~') {
std::string homedir;
- root = root.substr(0, root.size() - 1);
+ root.resize(root.size() - 1);
if (root.size() == 1) {
#if defined(_WIN32) && !defined(__CYGWIN__)
if (!SystemTools::GetEnv("USERPROFILE", homedir))
@@ -3580,14 +3602,14 @@ void SystemTools::SplitPath(const std::string& p,
for (; *last; ++last) {
if (*last == '/' || *last == '\\') {
// End of a component. Save it.
- components.push_back(std::string(first, last));
+ components.emplace_back(first, last);
first = last + 1;
}
}
// Save the last component unless there were no components.
if (last != c) {
- components.push_back(std::string(first, last));
+ components.emplace_back(first, last);
}
}
@@ -3603,7 +3625,7 @@ std::string SystemTools::JoinPath(
// Construct result in a single string.
std::string result;
size_t len = 0;
- for (std::vector<std::string>::const_iterator i = first; i != last; ++i) {
+ for (auto i = first; i != last; ++i) {
len += 1 + i->size();
}
result.reserve(len);
@@ -3694,19 +3716,20 @@ std::string SystemTools::GetFilenamePath(const std::string& filename)
std::string fn = filename;
SystemTools::ConvertToUnixSlashes(fn);
- std::string::size_type slash_pos = fn.rfind("/");
- if (slash_pos != std::string::npos) {
- std::string ret = fn.substr(0, slash_pos);
- if (ret.size() == 2 && ret[1] == ':') {
- return ret + '/';
- }
- if (ret.empty()) {
- return "/";
- }
- return ret;
- } else {
+ std::string::size_type slash_pos = fn.rfind('/');
+ if (slash_pos == 0) {
+ return "/";
+ }
+ if (slash_pos == 2 && fn[1] == ':') {
+ // keep the / after a drive letter
+ fn.resize(3);
+ return fn;
+ }
+ if (slash_pos == std::string::npos) {
return "";
}
+ fn.resize(slash_pos);
+ return fn;
}
/**
@@ -3736,7 +3759,8 @@ std::string SystemTools::GetFilenameExtension(const std::string& filename)
std::string name = SystemTools::GetFilenameName(filename);
std::string::size_type dot_pos = name.find('.');
if (dot_pos != std::string::npos) {
- return name.substr(dot_pos);
+ name.erase(0, dot_pos);
+ return name;
} else {
return "";
}
@@ -3751,7 +3775,8 @@ std::string SystemTools::GetFilenameLastExtension(const std::string& filename)
std::string name = SystemTools::GetFilenameName(filename);
std::string::size_type dot_pos = name.rfind('.');
if (dot_pos != std::string::npos) {
- return name.substr(dot_pos);
+ name.erase(0, dot_pos);
+ return name;
} else {
return "";
}
@@ -3767,10 +3792,9 @@ std::string SystemTools::GetFilenameWithoutExtension(
std::string name = SystemTools::GetFilenameName(filename);
std::string::size_type dot_pos = name.find('.');
if (dot_pos != std::string::npos) {
- return name.substr(0, dot_pos);
- } else {
- return name;
+ name.resize(dot_pos);
}
+ return name;
}
/**
@@ -3784,10 +3808,9 @@ std::string SystemTools::GetFilenameWithoutLastExtension(
std::string name = SystemTools::GetFilenameName(filename);
std::string::size_type dot_pos = name.rfind('.');
if (dot_pos != std::string::npos) {
- return name.substr(0, dot_pos);
- } else {
- return name;
+ name.resize(dot_pos);
}
+ return name;
}
bool SystemTools::FileHasSignature(const char* filename, const char* signature,
@@ -3837,7 +3860,7 @@ SystemTools::FileTypeEnum SystemTools::DetectFileType(const char* filename,
// Allocate buffer and read bytes
- unsigned char* buffer = new unsigned char[length];
+ auto* buffer = new unsigned char[length];
size_t read_length = fread(buffer, 1, length, fp);
fclose(fp);
if (read_length == 0) {
@@ -4009,7 +4032,8 @@ bool SystemTools::GetShortPath(const std::string& path, std::string& shortPath)
// if the path passed in has quotes around it, first remove the quotes
if (!path.empty() && path[0] == '"' && path.back() == '"') {
- tempPath = path.substr(1, path.length() - 2);
+ tempPath.resize(path.length() - 1);
+ tempPath.erase(0, 1);
}
std::wstring wtempPath = Encoding::ToWide(tempPath);
@@ -4228,8 +4252,8 @@ bool SystemTools::IsSubDirectory(const std::string& cSubdir,
if (subdir[expectedSlashPosition] != '/') {
return false;
}
- std::string s = subdir.substr(0, dir.size());
- return SystemTools::ComparePath(s, dir);
+ subdir.resize(dir.size());
+ return SystemTools::ComparePath(subdir, dir);
}
void SystemTools::Delay(unsigned int msec)
@@ -4525,7 +4549,7 @@ std::string SystemTools::GetOperatingSystemNameAndVersion()
bool SystemTools::ParseURLProtocol(const std::string& URL,
std::string& protocol,
- std::string& dataglom)
+ std::string& dataglom, bool decode)
{
// match 0 entire url
// match 1 protocol
@@ -4538,13 +4562,17 @@ bool SystemTools::ParseURLProtocol(const std::string& URL,
protocol = urlRe.match(1);
dataglom = urlRe.match(2);
+ if (decode) {
+ dataglom = DecodeURL(dataglom);
+ }
+
return true;
}
bool SystemTools::ParseURL(const std::string& URL, std::string& protocol,
std::string& username, std::string& password,
std::string& hostname, std::string& dataport,
- std::string& database)
+ std::string& database, bool decode)
{
kwsys::RegularExpression urlRe(VTK_URL_REGEX);
if (!urlRe.find(URL))
@@ -4568,13 +4596,37 @@ bool SystemTools::ParseURL(const std::string& URL, std::string& protocol,
dataport = urlRe.match(8);
database = urlRe.match(9);
+ if (decode) {
+ username = DecodeURL(username);
+ password = DecodeURL(password);
+ hostname = DecodeURL(hostname);
+ dataport = DecodeURL(dataport);
+ database = DecodeURL(database);
+ }
+
return true;
}
-// These must NOT be initialized. Default initialization to zero is
-// necessary.
+// ----------------------------------------------------------------------
+std::string SystemTools::DecodeURL(const std::string& url)
+{
+ kwsys::RegularExpression urlByteRe(VTK_URL_BYTE_REGEX);
+ std::string ret;
+ for (size_t i = 0; i < url.length(); i++) {
+ if (urlByteRe.find(url.substr(i, 3))) {
+ char bytes[] = { url[i + 1], url[i + 2], '\0' };
+ ret += static_cast<char>(strtoul(bytes, nullptr, 16));
+ i += 2;
+ } else {
+ ret += url[i];
+ }
+ }
+ return ret;
+}
+
+// ----------------------------------------------------------------------
+// Do NOT initialize. Default initialization to zero is necessary.
static unsigned int SystemToolsManagerCount;
-SystemToolsStatic* SystemTools::Statics;
// SystemToolsManager manages the SystemTools singleton.
// SystemToolsManager should be included in any translation unit
@@ -4617,7 +4669,7 @@ void SystemTools::ClassInitialize()
#endif
// Create statics singleton instance
- SystemTools::Statics = new SystemToolsStatic;
+ SystemToolsStatics = new SystemToolsStatic;
#if KWSYS_SYSTEMTOOLS_USE_TRANSLATION_MAP
// Add some special translation paths for unix. These are not added
@@ -4667,7 +4719,7 @@ void SystemTools::ClassInitialize()
void SystemTools::ClassFinalize()
{
- delete SystemTools::Statics;
+ delete SystemToolsStatics;
}
} // namespace KWSYS_NAMESPACE
@@ -4678,8 +4730,12 @@ void SystemTools::ClassFinalize()
# include <stdlib.h>
namespace KWSYS_NAMESPACE {
-static int SystemToolsDebugReport(int, char* message, int*)
+static int SystemToolsDebugReport(int, char* message, int* ret)
{
+ if (ret) {
+ // Pretend user clicked on Retry button in popup.
+ *ret = 1;
+ }
fprintf(stderr, "%s", message);
fflush(stderr);
return 1; // no further reporting required
diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in
index c4ab9d4..ae08e57 100644
--- a/Source/kwsys/SystemTools.hxx.in
+++ b/Source/kwsys/SystemTools.hxx.in
@@ -411,11 +411,11 @@ public:
* (which defaults to the current working directory). The full path
* is returned.
*/
- static std::string CollapseFullPath(const std::string& in_relative);
- static std::string CollapseFullPath(const std::string& in_relative,
+ static std::string CollapseFullPath(std::string const& in_path);
+ static std::string CollapseFullPath(std::string const& in_path,
const char* in_base);
- static std::string CollapseFullPath(const std::string& in_relative,
- const std::string& in_base);
+ static std::string CollapseFullPath(std::string const& in_path,
+ std::string const& in_base);
/**
* Get the real path for a given path, removing all symlinks. In
@@ -549,7 +549,8 @@ public:
*/
/**
- * Open a file considering unicode.
+ * Open a file considering unicode. On Windows, if 'e' is present in
+ * mode it is first discarded.
*/
static FILE* Fopen(const std::string& file, const char* mode);
@@ -677,6 +678,11 @@ public:
static bool FileIsDirectory(const std::string& name);
/**
+ * Return true if the file is an executable
+ */
+ static bool FileIsExecutable(const std::string& name);
+
+ /**
* Return true if the file is a symlink
*/
static bool FileIsSymlink(const std::string& name);
@@ -869,7 +875,7 @@ public:
/**
* Get current working directory CWD
*/
- static std::string GetCurrentWorkingDirectory(bool collapse = true);
+ static std::string GetCurrentWorkingDirectory();
/**
* Change directory to the directory specified
@@ -935,22 +941,32 @@ public:
* Parse a character string :
* protocol://dataglom
* and fill protocol as appropriate.
+ * decode the dataglom using DecodeURL if set to true.
* Return false if the URL does not have the required form, true otherwise.
*/
static bool ParseURLProtocol(const std::string& URL, std::string& protocol,
- std::string& dataglom);
+ std::string& dataglom, bool decode = false);
/**
* Parse a string (a URL without protocol prefix) with the form:
* protocol://[[username[':'password]'@']hostname[':'dataport]]'/'[datapath]
* and fill protocol, username, password, hostname, dataport, and datapath
* when values are found.
+ * decode all string except the protocol using DecodeUrl if set to true.
* Return true if the string matches the format; false otherwise.
*/
static bool ParseURL(const std::string& URL, std::string& protocol,
std::string& username, std::string& password,
std::string& hostname, std::string& dataport,
- std::string& datapath);
+ std::string& datapath, bool decode = false);
+
+ /**
+ * Decode the percent-encoded string from an URL or an URI
+ * into their correct char values.
+ * Does not perform any other sort of validation.
+ * Return the decoded string
+ */
+ static std::string DecodeURL(const std::string& url);
private:
/**
@@ -971,7 +987,6 @@ private:
return &SystemToolsManagerInstance;
}
- static SystemToolsStatic* Statics;
friend class SystemToolsStatic;
friend class SystemToolsManager;
};
diff --git a/Source/kwsys/Terminal.c b/Source/kwsys/Terminal.c
index 4dd2461..4d1b46c 100644
--- a/Source/kwsys/Terminal.c
+++ b/Source/kwsys/Terminal.c
@@ -146,6 +146,7 @@ static const char* kwsysTerminalVT100Names[] = { "Eterm",
"screen-bce",
"screen-w",
"screen.linux",
+ "st-256color",
"tmux",
"tmux-256color",
"vt100",
@@ -172,6 +173,14 @@ static int kwsysTerminalStreamIsVT100(FILE* stream, int default_vt100,
}
}
+ /* GNU make 4.1+ may tell us that its output is destined for a TTY. */
+ {
+ const char* termout = getenv("MAKE_TERMOUT");
+ if (termout && *termout != '\0') {
+ return 1;
+ }
+ }
+
/* If running inside emacs the terminal is not VT100. Some emacs
seem to claim the TERM is xterm even though they do not support
VT100 escapes. */
diff --git a/Source/kwsys/kwsysPlatformTests.cmake b/Source/kwsys/kwsysPlatformTests.cmake
index 28d3f68..89be4b8 100644
--- a/Source/kwsys/kwsysPlatformTests.cmake
+++ b/Source/kwsys/kwsysPlatformTests.cmake
@@ -1,185 +1,185 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing#kwsys for details.
-SET(KWSYS_PLATFORM_TEST_FILE_C kwsysPlatformTestsC.c)
-SET(KWSYS_PLATFORM_TEST_FILE_CXX kwsysPlatformTestsCXX.cxx)
+set(KWSYS_PLATFORM_TEST_FILE_C kwsysPlatformTestsC.c)
+set(KWSYS_PLATFORM_TEST_FILE_CXX kwsysPlatformTestsCXX.cxx)
-MACRO(KWSYS_PLATFORM_TEST lang var description invert)
- IF(NOT DEFINED ${var}_COMPILED)
- MESSAGE(STATUS "${description}")
+macro(KWSYS_PLATFORM_TEST lang var description invert)
+ if(NOT DEFINED ${var}_COMPILED)
+ message(STATUS "${description}")
set(maybe_cxx_standard "")
if(CMAKE_VERSION VERSION_LESS 3.8 AND CMAKE_CXX_STANDARD)
set(maybe_cxx_standard "-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}")
endif()
- TRY_COMPILE(${var}_COMPILED
+ try_compile(${var}_COMPILED
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/${KWSYS_PLATFORM_TEST_FILE_${lang}}
COMPILE_DEFINITIONS -DTEST_${var} ${KWSYS_PLATFORM_TEST_DEFINES} ${KWSYS_PLATFORM_TEST_EXTRA_FLAGS}
CMAKE_FLAGS "-DLINK_LIBRARIES:STRING=${KWSYS_PLATFORM_TEST_LINK_LIBRARIES}"
${maybe_cxx_standard}
OUTPUT_VARIABLE OUTPUT)
- IF(${var}_COMPILED)
- FILE(APPEND
+ if(${var}_COMPILED)
+ file(APPEND
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"${description} compiled with the following output:\n${OUTPUT}\n\n")
- ELSE()
- FILE(APPEND
+ else()
+ file(APPEND
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"${description} failed to compile with the following output:\n${OUTPUT}\n\n")
- ENDIF()
- IF(${invert} MATCHES INVERT)
- IF(${var}_COMPILED)
- MESSAGE(STATUS "${description} - no")
- ELSE()
- MESSAGE(STATUS "${description} - yes")
- ENDIF()
- ELSE()
- IF(${var}_COMPILED)
- MESSAGE(STATUS "${description} - yes")
- ELSE()
- MESSAGE(STATUS "${description} - no")
- ENDIF()
- ENDIF()
- ENDIF()
- IF(${invert} MATCHES INVERT)
- IF(${var}_COMPILED)
- SET(${var} 0)
- ELSE()
- SET(${var} 1)
- ENDIF()
- ELSE()
- IF(${var}_COMPILED)
- SET(${var} 1)
- ELSE()
- SET(${var} 0)
- ENDIF()
- ENDIF()
-ENDMACRO()
+ endif()
+ if(${invert} MATCHES INVERT)
+ if(${var}_COMPILED)
+ message(STATUS "${description} - no")
+ else()
+ message(STATUS "${description} - yes")
+ endif()
+ else()
+ if(${var}_COMPILED)
+ message(STATUS "${description} - yes")
+ else()
+ message(STATUS "${description} - no")
+ endif()
+ endif()
+ endif()
+ if(${invert} MATCHES INVERT)
+ if(${var}_COMPILED)
+ set(${var} 0)
+ else()
+ set(${var} 1)
+ endif()
+ else()
+ if(${var}_COMPILED)
+ set(${var} 1)
+ else()
+ set(${var} 0)
+ endif()
+ endif()
+endmacro()
-MACRO(KWSYS_PLATFORM_TEST_RUN lang var description invert)
- IF(NOT DEFINED ${var})
- MESSAGE(STATUS "${description}")
- TRY_RUN(${var} ${var}_COMPILED
+macro(KWSYS_PLATFORM_TEST_RUN lang var description invert)
+ if(NOT DEFINED ${var})
+ message(STATUS "${description}")
+ try_run(${var} ${var}_COMPILED
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/${KWSYS_PLATFORM_TEST_FILE_${lang}}
COMPILE_DEFINITIONS -DTEST_${var} ${KWSYS_PLATFORM_TEST_DEFINES} ${KWSYS_PLATFORM_TEST_EXTRA_FLAGS}
OUTPUT_VARIABLE OUTPUT)
# Note that ${var} will be a 0 return value on success.
- IF(${var}_COMPILED)
- IF(${var})
- FILE(APPEND
+ if(${var}_COMPILED)
+ if(${var})
+ file(APPEND
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"${description} compiled but failed to run with the following output:\n${OUTPUT}\n\n")
- ELSE()
- FILE(APPEND
+ else()
+ file(APPEND
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"${description} compiled and ran with the following output:\n${OUTPUT}\n\n")
- ENDIF()
- ELSE()
- FILE(APPEND
+ endif()
+ else()
+ file(APPEND
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"${description} failed to compile with the following output:\n${OUTPUT}\n\n")
- SET(${var} -1 CACHE INTERNAL "${description} failed to compile.")
- ENDIF()
+ set(${var} -1 CACHE INTERNAL "${description} failed to compile.")
+ endif()
- IF(${invert} MATCHES INVERT)
- IF(${var}_COMPILED)
- IF(${var})
- MESSAGE(STATUS "${description} - yes")
- ELSE()
- MESSAGE(STATUS "${description} - no")
- ENDIF()
- ELSE()
- MESSAGE(STATUS "${description} - failed to compile")
- ENDIF()
- ELSE()
- IF(${var}_COMPILED)
- IF(${var})
- MESSAGE(STATUS "${description} - no")
- ELSE()
- MESSAGE(STATUS "${description} - yes")
- ENDIF()
- ELSE()
- MESSAGE(STATUS "${description} - failed to compile")
- ENDIF()
- ENDIF()
- ENDIF()
+ if(${invert} MATCHES INVERT)
+ if(${var}_COMPILED)
+ if(${var})
+ message(STATUS "${description} - yes")
+ else()
+ message(STATUS "${description} - no")
+ endif()
+ else()
+ message(STATUS "${description} - failed to compile")
+ endif()
+ else()
+ if(${var}_COMPILED)
+ if(${var})
+ message(STATUS "${description} - no")
+ else()
+ message(STATUS "${description} - yes")
+ endif()
+ else()
+ message(STATUS "${description} - failed to compile")
+ endif()
+ endif()
+ endif()
- IF(${invert} MATCHES INVERT)
- IF(${var}_COMPILED)
- IF(${var})
- SET(${var} 1)
- ELSE()
- SET(${var} 0)
- ENDIF()
- ELSE()
- SET(${var} 1)
- ENDIF()
- ELSE()
- IF(${var}_COMPILED)
- IF(${var})
- SET(${var} 0)
- ELSE()
- SET(${var} 1)
- ENDIF()
- ELSE()
- SET(${var} 0)
- ENDIF()
- ENDIF()
-ENDMACRO()
+ if(${invert} MATCHES INVERT)
+ if(${var}_COMPILED)
+ if(${var})
+ set(${var} 1)
+ else()
+ set(${var} 0)
+ endif()
+ else()
+ set(${var} 1)
+ endif()
+ else()
+ if(${var}_COMPILED)
+ if(${var})
+ set(${var} 0)
+ else()
+ set(${var} 1)
+ endif()
+ else()
+ set(${var} 0)
+ endif()
+ endif()
+endmacro()
-MACRO(KWSYS_PLATFORM_C_TEST var description invert)
- SET(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_C_TEST_DEFINES})
- SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_C_TEST_EXTRA_FLAGS})
+macro(KWSYS_PLATFORM_C_TEST var description invert)
+ set(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_C_TEST_DEFINES})
+ set(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_C_TEST_EXTRA_FLAGS})
KWSYS_PLATFORM_TEST(C "${var}" "${description}" "${invert}")
- SET(KWSYS_PLATFORM_TEST_DEFINES)
- SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
-ENDMACRO()
+ set(KWSYS_PLATFORM_TEST_DEFINES)
+ set(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
+endmacro()
-MACRO(KWSYS_PLATFORM_C_TEST_RUN var description invert)
- SET(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_C_TEST_DEFINES})
- SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_C_TEST_EXTRA_FLAGS})
+macro(KWSYS_PLATFORM_C_TEST_RUN var description invert)
+ set(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_C_TEST_DEFINES})
+ set(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_C_TEST_EXTRA_FLAGS})
KWSYS_PLATFORM_TEST_RUN(C "${var}" "${description}" "${invert}")
- SET(KWSYS_PLATFORM_TEST_DEFINES)
- SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
-ENDMACRO()
+ set(KWSYS_PLATFORM_TEST_DEFINES)
+ set(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
+endmacro()
-MACRO(KWSYS_PLATFORM_CXX_TEST var description invert)
- SET(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_CXX_TEST_DEFINES})
- SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_CXX_TEST_EXTRA_FLAGS})
- SET(KWSYS_PLATFORM_TEST_LINK_LIBRARIES ${KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES})
+macro(KWSYS_PLATFORM_CXX_TEST var description invert)
+ set(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_CXX_TEST_DEFINES})
+ set(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_CXX_TEST_EXTRA_FLAGS})
+ set(KWSYS_PLATFORM_TEST_LINK_LIBRARIES ${KWSYS_PLATFORM_CXX_TEST_LINK_LIBRARIES})
KWSYS_PLATFORM_TEST(CXX "${var}" "${description}" "${invert}")
- SET(KWSYS_PLATFORM_TEST_DEFINES)
- SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
- SET(KWSYS_PLATFORM_TEST_LINK_LIBRARIES)
-ENDMACRO()
+ set(KWSYS_PLATFORM_TEST_DEFINES)
+ set(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
+ set(KWSYS_PLATFORM_TEST_LINK_LIBRARIES)
+endmacro()
-MACRO(KWSYS_PLATFORM_CXX_TEST_RUN var description invert)
- SET(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_CXX_TEST_DEFINES})
- SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_CXX_TEST_EXTRA_FLAGS})
+macro(KWSYS_PLATFORM_CXX_TEST_RUN var description invert)
+ set(KWSYS_PLATFORM_TEST_DEFINES ${KWSYS_PLATFORM_CXX_TEST_DEFINES})
+ set(KWSYS_PLATFORM_TEST_EXTRA_FLAGS ${KWSYS_PLATFORM_CXX_TEST_EXTRA_FLAGS})
KWSYS_PLATFORM_TEST_RUN(CXX "${var}" "${description}" "${invert}")
- SET(KWSYS_PLATFORM_TEST_DEFINES)
- SET(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
-ENDMACRO()
+ set(KWSYS_PLATFORM_TEST_DEFINES)
+ set(KWSYS_PLATFORM_TEST_EXTRA_FLAGS)
+endmacro()
#-----------------------------------------------------------------------------
# KWSYS_PLATFORM_INFO_TEST(lang var description)
#
# Compile test named by ${var} and store INFO strings extracted from binary.
-MACRO(KWSYS_PLATFORM_INFO_TEST lang var description)
+macro(KWSYS_PLATFORM_INFO_TEST lang var description)
# We can implement this macro on CMake 2.6 and above.
- IF("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.6)
- SET(${var} "")
- ELSE()
+ if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.6)
+ set(${var} "")
+ else()
# Choose a location for the result binary.
- SET(KWSYS_PLATFORM_INFO_FILE
+ set(KWSYS_PLATFORM_INFO_FILE
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/${var}.bin)
# Compile the test binary.
- IF(NOT EXISTS ${KWSYS_PLATFORM_INFO_FILE})
- MESSAGE(STATUS "${description}")
- TRY_COMPILE(${var}_COMPILED
+ if(NOT EXISTS ${KWSYS_PLATFORM_INFO_FILE})
+ message(STATUS "${description}")
+ try_compile(${var}_COMPILED
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/${KWSYS_PLATFORM_TEST_FILE_${lang}}
COMPILE_DEFINITIONS -DTEST_${var}
@@ -188,29 +188,29 @@ MACRO(KWSYS_PLATFORM_INFO_TEST lang var description)
OUTPUT_VARIABLE OUTPUT
COPY_FILE ${KWSYS_PLATFORM_INFO_FILE}
)
- IF(${var}_COMPILED)
- FILE(APPEND
+ if(${var}_COMPILED)
+ file(APPEND
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"${description} compiled with the following output:\n${OUTPUT}\n\n")
- ELSE()
- FILE(APPEND
+ else()
+ file(APPEND
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"${description} failed to compile with the following output:\n${OUTPUT}\n\n")
- ENDIF()
- IF(${var}_COMPILED)
- MESSAGE(STATUS "${description} - compiled")
- ELSE()
- MESSAGE(STATUS "${description} - failed")
- ENDIF()
- ENDIF()
+ endif()
+ if(${var}_COMPILED)
+ message(STATUS "${description} - compiled")
+ else()
+ message(STATUS "${description} - failed")
+ endif()
+ endif()
# Parse info strings out of the compiled binary.
- IF(${var}_COMPILED)
- FILE(STRINGS ${KWSYS_PLATFORM_INFO_FILE} ${var} REGEX "INFO:[A-Za-z0-9]+\\[[^]]*\\]")
- ELSE()
- SET(${var} "")
- ENDIF()
+ if(${var}_COMPILED)
+ file(STRINGS ${KWSYS_PLATFORM_INFO_FILE} ${var} REGEX "INFO:[A-Za-z0-9]+\\[[^]]*\\]")
+ else()
+ set(${var} "")
+ endif()
- SET(KWSYS_PLATFORM_INFO_FILE)
- ENDIF()
-ENDMACRO()
+ set(KWSYS_PLATFORM_INFO_FILE)
+ endif()
+endmacro()
diff --git a/Source/kwsys/testCommandLineArguments.cxx b/Source/kwsys/testCommandLineArguments.cxx
index 1778a9b..0786751 100644
--- a/Source/kwsys/testCommandLineArguments.cxx
+++ b/Source/kwsys/testCommandLineArguments.cxx
@@ -12,8 +12,8 @@
#include <iostream>
#include <vector>
-#include <stddef.h> /* size_t */
-#include <string.h> /* strcmp */
+#include <cstddef> /* size_t */
+#include <cstring> /* strcmp */
static void* random_ptr = reinterpret_cast<void*>(0x123);
@@ -98,7 +98,7 @@ int testCommandLineArguments(int argc, char* argv[])
std::vector<std::string> stl_strings_argument;
std::string valid_stl_strings[] = { "ken", "brad", "bill", "andy" };
- typedef kwsys::CommandLineArguments argT;
+ using argT = kwsys::CommandLineArguments;
arg.AddArgument("--some-int-variable", argT::SPACE_ARGUMENT,
&some_int_variable, "Set some random int variable");
diff --git a/Source/kwsys/testCommandLineArguments1.cxx b/Source/kwsys/testCommandLineArguments1.cxx
index 64561b1..2f6b735 100644
--- a/Source/kwsys/testCommandLineArguments1.cxx
+++ b/Source/kwsys/testCommandLineArguments1.cxx
@@ -12,8 +12,8 @@
#include <iostream>
#include <vector>
-#include <assert.h> /* assert */
-#include <string.h> /* strcmp */
+#include <cassert> /* assert */
+#include <cstring> /* strcmp */
int testCommandLineArguments1(int argc, char* argv[])
{
@@ -25,7 +25,7 @@ int testCommandLineArguments1(int argc, char* argv[])
std::string p;
int res = 0;
- typedef kwsys::CommandLineArguments argT;
+ using argT = kwsys::CommandLineArguments;
arg.AddArgument("-n", argT::SPACE_ARGUMENT, &n, "Argument N");
arg.AddArgument("-m", argT::EQUAL_ARGUMENT, &m, "Argument M");
arg.AddBooleanArgument("-p", &p, "Argument P");
@@ -51,9 +51,7 @@ int testCommandLineArguments1(int argc, char* argv[])
std::cout << "Value of N: " << n << std::endl;
std::cout << "Value of M: " << m << std::endl;
std::cout << "Value of P: " << p << std::endl;
- if (m) {
- delete[] m;
- }
+ delete[] m;
char** newArgv = nullptr;
int newArgc = 0;
diff --git a/Source/kwsys/testDynamicLoader.cxx b/Source/kwsys/testDynamicLoader.cxx
index 2421ac0..703ad4d 100644
--- a/Source/kwsys/testDynamicLoader.cxx
+++ b/Source/kwsys/testDynamicLoader.cxx
@@ -25,7 +25,7 @@ static std::string GetLibName(const char* lname, const char* subdir = nullptr)
{
// Construct proper name of lib
std::string slname;
- slname = EXECUTABLE_OUTPUT_PATH;
+ slname = RUNTIME_OUTPUT_DIRECTORY;
if (subdir) {
slname += "/";
slname += subdir;
diff --git a/Source/kwsys/testDynload.c b/Source/kwsys/testDynload.c
index c49f747..33a431e 100644
--- a/Source/kwsys/testDynload.c
+++ b/Source/kwsys/testDynload.c
@@ -8,6 +8,6 @@
DL_EXPORT int TestDynamicLoaderData = 0;
-DL_EXPORT void TestDynamicLoaderSymbolPointer()
+DL_EXPORT void TestDynamicLoaderSymbolPointer(void)
{
}
diff --git a/Source/kwsys/testEncoding.cxx b/Source/kwsys/testEncoding.cxx
index 988697b..ee93e8d 100644
--- a/Source/kwsys/testEncoding.cxx
+++ b/Source/kwsys/testEncoding.cxx
@@ -10,10 +10,10 @@
#include KWSYS_HEADER(Encoding.h)
#include <algorithm>
+#include <clocale>
+#include <cstdlib>
+#include <cstring>
#include <iostream>
-#include <locale.h>
-#include <stdlib.h>
-#include <string.h>
// Work-around CMake dependency scanning limitation. This must
// duplicate the above list of headers.
@@ -59,7 +59,7 @@ static int testHelloWorldEncoding()
std::string str2 = kwsys::Encoding::ToNarrow(wstr);
wchar_t* c_wstr = kwsysEncoding_DupToWide(str.c_str());
char* c_str2 = kwsysEncoding_DupToNarrow(c_wstr);
- if (!wstr.empty() && (str != str2 || strcmp(c_str2, str.c_str()))) {
+ if (!wstr.empty() && (str != str2 || strcmp(c_str2, str.c_str()) != 0)) {
std::cout << "converted string was different: " << str2 << std::endl;
std::cout << "converted string was different: " << c_str2 << std::endl;
ret++;
@@ -85,7 +85,7 @@ static int testRobustEncoding()
std::wstring wstr = kwsys::Encoding::ToWide(cstr);
wstr = kwsys::Encoding::ToWide(nullptr);
- if (wstr != L"") {
+ if (!wstr.empty()) {
const wchar_t* wcstr = wstr.c_str();
std::cout << "ToWide(NULL) returned";
for (size_t i = 0; i < wstr.size(); i++) {
@@ -95,7 +95,7 @@ static int testRobustEncoding()
ret++;
}
wstr = kwsys::Encoding::ToWide("");
- if (wstr != L"") {
+ if (!wstr.empty()) {
const wchar_t* wcstr = wstr.c_str();
std::cout << "ToWide(\"\") returned";
for (size_t i = 0; i < wstr.size(); i++) {
@@ -113,13 +113,13 @@ static int testRobustEncoding()
#endif
std::string str = kwsys::Encoding::ToNarrow(nullptr);
- if (str != "") {
+ if (!str.empty()) {
std::cout << "ToNarrow(NULL) returned " << str << std::endl;
ret++;
}
str = kwsys::Encoding::ToNarrow(L"");
- if (wstr != L"") {
+ if (!wstr.empty()) {
std::cout << "ToNarrow(\"\") returned " << str << std::endl;
ret++;
}
@@ -140,14 +140,13 @@ static int testWithNulls()
strings.push_back(std::string("k") + '\0' + '\0');
strings.push_back(std::string("\0\0\0\0", 4) + "lmn" +
std::string("\0\0\0\0", 4));
- for (std::vector<std::string>::iterator it = strings.begin();
- it != strings.end(); ++it) {
- std::wstring wstr = kwsys::Encoding::ToWide(*it);
+ for (auto& string : strings) {
+ std::wstring wstr = kwsys::Encoding::ToWide(string);
std::string str = kwsys::Encoding::ToNarrow(wstr);
- std::string s(*it);
+ std::string s(string);
std::replace(s.begin(), s.end(), '\0', ' ');
- std::cout << "'" << s << "' (" << it->size() << ")" << std::endl;
- if (str != *it) {
+ std::cout << "'" << s << "' (" << string.size() << ")" << std::endl;
+ if (str != string) {
std::replace(str.begin(), str.end(), '\0', ' ');
std::cout << "string with null was different: '" << str << "' ("
<< str.size() << ")" << std::endl;
diff --git a/Source/kwsys/testFStream.cxx b/Source/kwsys/testFStream.cxx
index 5009e98..5762378 100644
--- a/Source/kwsys/testFStream.cxx
+++ b/Source/kwsys/testFStream.cxx
@@ -7,7 +7,7 @@
#endif
#include KWSYS_HEADER(FStream.hxx)
-#include <string.h>
+#include <cstring>
#ifdef __BORLANDC__
# include <mem.h> /* memcmp */
#endif
diff --git a/Source/kwsys/testHashSTL.cxx b/Source/kwsys/testHashSTL.cxx
index 4ed2f89..18cae7f 100644
--- a/Source/kwsys/testHashSTL.cxx
+++ b/Source/kwsys/testHashSTL.cxx
@@ -27,30 +27,30 @@ template class kwsys::hash_set<int>;
static bool test_hash_map()
{
- typedef kwsys::hash_map<const char*, int> mtype;
+ using mtype = kwsys::hash_map<const char*, int>;
mtype m;
const char* keys[] = { "hello", "world" };
m[keys[0]] = 1;
m.insert(mtype::value_type(keys[1], 2));
int sum = 0;
- for (mtype::iterator mi = m.begin(); mi != m.end(); ++mi) {
- std::cout << "Found entry [" << mi->first << "," << mi->second << "]"
+ for (auto& mi : m) {
+ std::cout << "Found entry [" << mi.first << "," << mi.second << "]"
<< std::endl;
- sum += mi->second;
+ sum += mi.second;
}
return sum == 3;
}
static bool test_hash_set()
{
- typedef kwsys::hash_set<int> stype;
+ using stype = kwsys::hash_set<int>;
stype s;
s.insert(1);
s.insert(2);
int sum = 0;
- for (stype::iterator si = s.begin(); si != s.end(); ++si) {
- std::cout << "Found entry [" << *si << "]" << std::endl;
- sum += *si;
+ for (int si : s) {
+ std::cout << "Found entry [" << si << "]" << std::endl;
+ sum += si;
}
return sum == 3;
}
diff --git a/Source/kwsys/testProcess.c b/Source/kwsys/testProcess.c
index 39aaa23..5507dfb 100644
--- a/Source/kwsys/testProcess.c
+++ b/Source/kwsys/testProcess.c
@@ -631,7 +631,8 @@ int main(int argc, const char* argv[])
}
fprintf(stderr, "Invalid test number %d.\n", n);
return 1;
- } else if (n >= 1 && n <= 10) {
+ }
+ if (n >= 1 && n <= 10) {
/* This is the parent process for a requested test number. */
int states[10] = {
kwsysProcess_State_Exited, kwsysProcess_State_Exited,
@@ -709,7 +710,8 @@ int main(int argc, const char* argv[])
free(argv0);
#endif
return r;
- } else if (argc > 2 && strcmp(argv[1], "0") == 0) {
+ }
+ if (argc > 2 && strcmp(argv[1], "0") == 0) {
/* This is the special debugging test to run a given command
line. */
const char** cmd = argv + 2;
@@ -720,9 +722,8 @@ int main(int argc, const char* argv[])
int r =
runChild(cmd, state, exception, value, 0, 1, 0, timeout, 0, 1, 0, 0, 0);
return r;
- } else {
- /* Improper usage. */
- fprintf(stdout, "Usage: %s <test number>\n", argv[0]);
- return 1;
}
+ /* Improper usage. */
+ fprintf(stdout, "Usage: %s <test number>\n", argv[0]);
+ return 1;
}
diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx
index 1f3a15b..ff8e2b2 100644
--- a/Source/kwsys/testSystemTools.cxx
+++ b/Source/kwsys/testSystemTools.cxx
@@ -20,10 +20,10 @@
// left on disk.
#include <testSystemTools.h>
+#include <cstdlib> /* free */
+#include <cstring> /* strcmp */
#include <iostream>
#include <sstream>
-#include <stdlib.h> /* free */
-#include <string.h> /* strcmp */
#if defined(_WIN32) && !defined(__CYGWIN__)
# include <io.h> /* _umask (MSVC) / umask (Borland) */
# ifdef _MSC_VER
@@ -328,7 +328,14 @@ static bool CheckFileOperations()
}
// While we're at it, check proper TestFileAccess functionality.
- if (kwsys::SystemTools::TestFileAccess(testNewFile,
+ bool do_write_test = true;
+#if defined(__linux__)
+ // If we are running as root on linux ignore this check, as
+ // root can always write to files
+ do_write_test = (getuid() != 0);
+#endif
+ if (do_write_test &&
+ kwsys::SystemTools::TestFileAccess(testNewFile,
kwsys::TEST_FILE_WRITE)) {
std::cerr
<< "TestFileAccess incorrectly indicated that this is a writable file:"
@@ -500,7 +507,7 @@ static bool CheckStringOperations()
char* cres =
kwsys::SystemTools::AppendStrings("Mary Had A", " Little Lamb.");
- if (strcmp(cres, "Mary Had A Little Lamb.")) {
+ if (strcmp(cres, "Mary Had A Little Lamb.") != 0) {
std::cerr << "Problem with AppendStrings "
<< "\"Mary Had A\" \" Little Lamb.\"" << std::endl;
res = false;
@@ -508,7 +515,7 @@ static bool CheckStringOperations()
delete[] cres;
cres = kwsys::SystemTools::AppendStrings("Mary Had", " A ", "Little Lamb.");
- if (strcmp(cres, "Mary Had A Little Lamb.")) {
+ if (strcmp(cres, "Mary Had A Little Lamb.") != 0) {
std::cerr << "Problem with AppendStrings "
<< "\"Mary Had\" \" A \" \"Little Lamb.\"" << std::endl;
res = false;
@@ -522,7 +529,7 @@ static bool CheckStringOperations()
}
cres = kwsys::SystemTools::RemoveChars("Mary Had A Little Lamb.", "aeiou");
- if (strcmp(cres, "Mry Hd A Lttl Lmb.")) {
+ if (strcmp(cres, "Mry Hd A Lttl Lmb.") != 0) {
std::cerr << "Problem with RemoveChars "
<< "\"Mary Had A Little Lamb.\"" << std::endl;
res = false;
@@ -530,7 +537,7 @@ static bool CheckStringOperations()
delete[] cres;
cres = kwsys::SystemTools::RemoveCharsButUpperHex("Mary Had A Little Lamb.");
- if (strcmp(cres, "A")) {
+ if (strcmp(cres, "A") != 0) {
std::cerr << "Problem with RemoveCharsButUpperHex "
<< "\"Mary Had A Little Lamb.\"" << std::endl;
res = false;
@@ -539,7 +546,7 @@ static bool CheckStringOperations()
char* cres2 = strdup("Mary Had A Little Lamb.");
kwsys::SystemTools::ReplaceChars(cres2, "aeiou", 'X');
- if (strcmp(cres2, "MXry HXd A LXttlX LXmb.")) {
+ if (strcmp(cres2, "MXry HXd A LXttlX LXmb.") != 0) {
std::cerr << "Problem with ReplaceChars "
<< "\"Mary Had A Little Lamb.\"" << std::endl;
res = false;
@@ -561,7 +568,7 @@ static bool CheckStringOperations()
}
cres = kwsys::SystemTools::DuplicateString("Mary Had A Little Lamb.");
- if (strcmp(cres, "Mary Had A Little Lamb.")) {
+ if (strcmp(cres, "Mary Had A Little Lamb.") != 0) {
std::cerr << "Problem with DuplicateString "
<< "\"Mary Had A Little Lamb.\"" << std::endl;
res = false;
@@ -721,8 +728,7 @@ static std::string StringVectorToString(const std::vector<std::string>& vec)
{
std::stringstream ss;
ss << "vector(";
- for (std::vector<std::string>::const_iterator i = vec.begin();
- i != vec.end(); ++i) {
+ for (auto i = vec.begin(); i != vec.end(); ++i) {
if (i != vec.begin()) {
ss << ", ";
}
@@ -743,16 +749,16 @@ static bool CheckGetPath()
const char* registryPath = "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MyApp; MyKey]";
std::vector<std::string> originalPaths;
- originalPaths.push_back(registryPath);
+ originalPaths.emplace_back(registryPath);
std::vector<std::string> expectedPaths;
- expectedPaths.push_back(registryPath);
+ expectedPaths.emplace_back(registryPath);
#ifdef _WIN32
expectedPaths.push_back("C:/Somewhere/something");
expectedPaths.push_back("D:/Temp");
#else
- expectedPaths.push_back("/Somewhere/something");
- expectedPaths.push_back("/tmp");
+ expectedPaths.emplace_back("/Somewhere/something");
+ expectedPaths.emplace_back("/tmp");
#endif
bool res = true;
@@ -817,7 +823,7 @@ static bool CheckFind()
}
std::vector<std::string> searchPaths;
- searchPaths.push_back(TEST_SYSTEMTOOLS_BINARY_DIR);
+ searchPaths.emplace_back(TEST_SYSTEMTOOLS_BINARY_DIR);
if (kwsys::SystemTools::FindFile(testFindFileName, searchPaths, true)
.empty()) {
std::cerr << "Problem with FindFile without system paths for: "
@@ -1074,6 +1080,79 @@ static bool CheckCopyFileIfDifferent()
}
}
+ if (!kwsys::SystemTools::MakeDirectory("dir_a") ||
+ !kwsys::SystemTools::MakeDirectory("dir_b")) {
+ return false;
+ }
+
+ if (!kwsys::SystemTools::CopyFileIfDifferent("dir_a/", "dir_b")) {
+ ret = false;
+ }
+
+ return ret;
+}
+
+static bool CheckURLParsing()
+{
+ bool ret = true;
+ std::string url = "http://user:pw@hostname:42/full/url.com";
+
+ std::string protocol, username, password, hostname, dataport, database;
+ kwsys::SystemTools::ParseURL(url, protocol, username, password, hostname,
+ dataport, database);
+ if (protocol != "http" || username != "user" || password != "pw" ||
+ hostname != "hostname" || dataport != "42" ||
+ database != "full/url.com") {
+ std::cerr << "Incorrect URL parsing" << std::endl;
+ ret = false;
+ }
+
+ std::string uri =
+ "file://hostname/path/to/"
+ "a%20file%20with%20str%C3%A0ng%C3%A8%20ch%40r%20and%20s%C2%B5aces";
+ kwsys::SystemTools::ParseURL(uri, protocol, username, password, hostname,
+ dataport, database, true);
+ if (protocol != "file" || hostname != "hostname" ||
+ database != "path/to/a file with stràngè ch@r and sµaces") {
+ std::cerr << "Incorrect URL parsing or decoding" << std::endl;
+ ret = false;
+ }
+ return ret;
+}
+
+static bool CheckSplitString()
+{
+ bool ret = true;
+
+ auto check_split = [](std::string const& input,
+ std::initializer_list<const char*> expected) -> bool {
+ auto const components = kwsys::SystemTools::SplitString(input, '/');
+ if (components.size() != expected.size()) {
+ std::cerr << "Incorrect split count for " << input << ": "
+ << components.size() << std::endl;
+ return false;
+ }
+ size_t i = 0;
+ for (auto& part : expected) {
+ if (components[i] != part) {
+ std::cerr << "Incorrect split component " << i << " for " << input
+ << ": " << components[i] << std::endl;
+ return false;
+ }
+ ++i;
+ }
+ return true;
+ };
+
+ // No separators
+ ret &= check_split("nosep", { "nosep" });
+ // Simple
+ ret &= check_split("first/second", { "first", "second" });
+ // Separator at beginning
+ ret &= check_split("/starts/sep", { "", "starts", "sep" });
+ // Separator at end
+ ret &= check_split("ends/sep/", { "ends", "sep", "" });
+
return ret;
}
@@ -1124,5 +1203,9 @@ int testSystemTools(int, char* [])
res &= CheckCopyFileIfDifferent();
+ res &= CheckURLParsing();
+
+ res &= CheckSplitString();
+
return res ? 0 : 1;
}
diff --git a/Source/kwsys/testSystemTools.h.in b/Source/kwsys/testSystemTools.h.in
index 022e36e..e4b89a7 100644
--- a/Source/kwsys/testSystemTools.h.in
+++ b/Source/kwsys/testSystemTools.h.in
@@ -3,7 +3,7 @@
#ifndef @KWSYS_NAMESPACE@_testSystemtools_h
#define @KWSYS_NAMESPACE@_testSystemtools_h
-#define EXECUTABLE_OUTPUT_PATH "@CMAKE_CURRENT_BINARY_DIR@"
+#define RUNTIME_OUTPUT_DIRECTORY "@CMAKE_CURRENT_BINARY_DIR@"
#define TEST_SYSTEMTOOLS_SOURCE_DIR "@TEST_SYSTEMTOOLS_SOURCE_DIR@"
#define TEST_SYSTEMTOOLS_BINARY_DIR "@TEST_SYSTEMTOOLS_BINARY_DIR@"
diff --git a/Templates/MSBuild/FlagTables/v10_Cuda.json b/Templates/MSBuild/FlagTables/v10_Cuda.json
index 1831b8a..b3230ac 100644
--- a/Templates/MSBuild/FlagTables/v10_Cuda.json
+++ b/Templates/MSBuild/FlagTables/v10_Cuda.json
@@ -20,6 +20,26 @@
]
},
{
+ "name": "AdditionalCompilerOptions",
+ "switch": "-compiler-options=",
+ "comment": "Host compiler options",
+ "value": "",
+ "flags": [
+ "UserValue",
+ "SpaceAppendable"
+ ]
+ },
+ {
+ "name": "AdditionalCompilerOptions",
+ "switch": "-compiler-options",
+ "comment": "Host compiler options",
+ "value": "",
+ "flags": [
+ "UserFollowing",
+ "SpaceAppendable"
+ ]
+ },
+ {
"name": "CudaRuntime",
"switch": "cudart=none",
"comment": "No CUDA runtime library",
diff --git a/Templates/TestDriver.cxx.in b/Templates/TestDriver.cxx.in
index 846a828..053f1ee 100644
--- a/Templates/TestDriver.cxx.in
+++ b/Templates/TestDriver.cxx.in
@@ -45,7 +45,8 @@ static const int NumTests = CM_CAST(int,
(note that it has to be free'd manually) */
static char* lowercase(const char* string)
{
- char *new_string, *p;
+ char *new_string;
+ char *p;
size_t stringSize;
stringSize = CM_CAST(size_t, strlen(string) + 1);
@@ -63,7 +64,9 @@ static char* lowercase(const char* string)
int main(int ac, char* av[])
{
- int i, testNum = 0, partial_match;
+ int i;
+ int testNum = 0;
+ int partial_match;
char *arg;
int testToRun = -1;
diff --git a/Tests/Assembler/CMakeLists.txt b/Tests/Assembler/CMakeLists.txt
index 21b265c..a3c9946 100644
--- a/Tests/Assembler/CMakeLists.txt
+++ b/Tests/Assembler/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required (VERSION 2.6)
+cmake_minimum_required (VERSION 3.8)
project(Assembler C)
message("CTEST_FULL_OUTPUT ")
set(CMAKE_VERBOSE_MAKEFILE 1)
@@ -22,7 +22,11 @@ if("${CMAKE_GENERATOR}" MATCHES "Makefile|Xcode|Ninja" AND
set(SRCS main.s)
add_custom_command(
OUTPUT main.s
- COMMAND ${CMAKE_C_COMPILER} ${C_FLAGS} -S ${CMAKE_CURRENT_SOURCE_DIR}/main.c -o main.s
+ COMMAND ${CMAKE_C_COMPILER} ${C_FLAGS}
+ "$<$<CONFIG:Debug>:${CMAKE_C_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL}>"
+ "$<$<NOT:$<CONFIG:Debug>>:${CMAKE_C_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL}>"
+ -S ${CMAKE_CURRENT_SOURCE_DIR}/main.c -o main.s
+ COMMAND_EXPAND_LISTS
DEPENDS main.c
VERBATIM
)
diff --git a/Tests/BuildDepends/CMakeLists.txt b/Tests/BuildDepends/CMakeLists.txt
index c1ad17c..5ddae83 100644
--- a/Tests/BuildDepends/CMakeLists.txt
+++ b/Tests/BuildDepends/CMakeLists.txt
@@ -368,6 +368,28 @@ is not newer than dependency
${TEST_LINK_DEPENDS}
")
endif()
+
+ set(linkdep3 ${BuildDepends_BINARY_DIR}/Project/linkdep3${CMAKE_EXECUTABLE_SUFFIX})
+ if(${linkdep3} IS_NEWER_THAN ${TEST_LINK_DEPENDS})
+ message("$<LINK_LANGUAGE> in LINK_DEPENDS worked")
+ else()
+ message(SEND_ERROR "$<LINK_LANGUAGE> in LINK_DEPENDS failed. Executable
+ ${linkdep3}
+is not newer than dependency
+ ${TEST_LINK_DEPENDS}
+")
+ endif()
+
+ set(linkdep4 ${BuildDepends_BINARY_DIR}/Project/linkdep4${CMAKE_EXECUTABLE_SUFFIX})
+ if(${linkdep4} IS_NEWER_THAN ${TEST_LINK_DEPENDS})
+ message("$<LINK_LANGUAGE> in INTERFACE_LINK_DEPENDS worked")
+ else()
+ message(SEND_ERROR "$<LINK_LANGUAGE> in INTERFACE_LINK_DEPENDS failed. Executable
+ ${linkdep4}
+is not newer than dependency
+ ${TEST_LINK_DEPENDS}
+")
+ endif()
endif()
if(EXISTS "${link_depends_no_shared_check_txt}")
diff --git a/Tests/BuildDepends/Project/CMakeLists.txt b/Tests/BuildDepends/Project/CMakeLists.txt
index 8338800..83583c9 100644
--- a/Tests/BuildDepends/Project/CMakeLists.txt
+++ b/Tests/BuildDepends/Project/CMakeLists.txt
@@ -118,6 +118,14 @@ if(TEST_LINK_DEPENDS)
set_property(TARGET foo_interface PROPERTY INTERFACE_LINK_DEPENDS $<1:${TEST_LINK_DEPENDS}>)
add_executable(linkdep2 linkdep.cxx)
target_link_libraries(linkdep2 PRIVATE foo_interface)
+
+ add_executable(linkdep3 linkdep.cxx)
+ set_property(TARGET linkdep3 PROPERTY LINK_DEPENDS $<$<LINK_LANGUAGE:CXX>:${TEST_LINK_DEPENDS}>)
+
+ add_library(foo_interface2 INTERFACE)
+ set_property(TARGET foo_interface2 PROPERTY INTERFACE_LINK_DEPENDS $<$<LINK_LANGUAGE:CXX>:${TEST_LINK_DEPENDS}>)
+ add_executable(linkdep4 linkdep.cxx)
+ target_link_libraries(linkdep4 PRIVATE foo_interface2)
endif()
add_library(link_depends_no_shared_lib SHARED link_depends_no_shared_lib.c
diff --git a/Tests/CFBundleTest/VerifyResult.cmake b/Tests/CFBundleTest/VerifyResult.cmake
index e637bb1..ac14e5d 100644
--- a/Tests/CFBundleTest/VerifyResult.cmake
+++ b/Tests/CFBundleTest/VerifyResult.cmake
@@ -14,7 +14,7 @@ message(STATUS "CTEST_CONFIGURATION_TYPE='${CTEST_CONFIGURATION_TYPE}'")
message(STATUS "dir='${dir}'")
message(STATUS "gen='${gen}'")
-if(gen STREQUAL "Xcode")
+if(gen MATCHES "^(Xcode$|Ninja Multi-Config$)")
set(expected_filename "${dir}/${CTEST_CONFIGURATION_TYPE}/CFBundleTest.plugin/Contents/MacOS/CFBundleTest")
else()
set(expected_filename "${dir}/CFBundleTest.plugin/Contents/MacOS/CFBundleTest")
diff --git a/Tests/CMakeCommands/target_link_libraries/SubDirB/CMakeLists.txt b/Tests/CMakeCommands/target_link_libraries/SubDirB/CMakeLists.txt
index 7c918e6..06d1111 100644
--- a/Tests/CMakeCommands/target_link_libraries/SubDirB/CMakeLists.txt
+++ b/Tests/CMakeCommands/target_link_libraries/SubDirB/CMakeLists.txt
@@ -2,7 +2,11 @@ add_executable(SubDirB SubDirB.c)
# Link to a target imported in this directory that would not normally
# be visible to the directory in which TopDir is defined.
-target_link_libraries(TopDir PUBLIC SameNameImported)
+target_link_libraries(TopDir PUBLIC debug SameNameImported optimized SameNameImported)
+
+# Link to a list of targets imported in this directory that would not
+# normally be visible to the directory in which TopDir is defined.
+target_link_libraries(TopDir PUBLIC "$<1:SameNameImported;SameNameImported>")
# Link SubDirA to a target imported in this directory that has the same
# name as a target imported in SubDirA's directory. We verify when
diff --git a/Tests/CMakeLib/CMakeLists.txt b/Tests/CMakeLib/CMakeLists.txt
index 840afc1..bb50d76 100644
--- a/Tests/CMakeLib/CMakeLists.txt
+++ b/Tests/CMakeLib/CMakeLists.txt
@@ -11,6 +11,7 @@ set(CMakeLib_TESTS
testCTestResourceAllocator.cxx
testCTestResourceSpec.cxx
testCTestResourceGroups.cxx
+ testGccDepfileReader.cxx
testGeneratedFileStream.cxx
testRST.cxx
testRange.cxx
@@ -25,6 +26,8 @@ set(CMakeLib_TESTS
testUVProcessChain.cxx
testUVRAII.cxx
testUVStreambuf.cxx
+ testCMExtMemory.cxx
+ testCMExtAlgorithm.cxx
)
add_executable(testUVProcessChainHelper testUVProcessChainHelper.cxx)
@@ -33,6 +36,7 @@ set(testRST_ARGS ${CMAKE_CURRENT_SOURCE_DIR})
set(testUVProcessChain_ARGS $<TARGET_FILE:testUVProcessChainHelper>)
set(testUVStreambuf_ARGS $<TARGET_FILE:cmake>)
set(testCTestResourceSpec_ARGS ${CMAKE_CURRENT_SOURCE_DIR})
+set(testGccDepfileReader_ARGS ${CMAKE_CURRENT_SOURCE_DIR})
if(WIN32)
list(APPEND CMakeLib_TESTS
diff --git a/Tests/CMakeLib/testArgumentParser.cxx b/Tests/CMakeLib/testArgumentParser.cxx
index 20f98c2..965690c 100644
--- a/Tests/CMakeLib/testArgumentParser.cxx
+++ b/Tests/CMakeLib/testArgumentParser.cxx
@@ -7,8 +7,7 @@
#include <vector>
#include <cm/string_view>
-
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
#include "cmArgumentParser.h"
diff --git a/Tests/CMakeLib/testCMExtAlgorithm.cxx b/Tests/CMakeLib/testCMExtAlgorithm.cxx
new file mode 100644
index 0000000..b8319c3
--- /dev/null
+++ b/Tests/CMakeLib/testCMExtAlgorithm.cxx
@@ -0,0 +1,118 @@
+#include <iostream>
+#include <memory>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+#include <cmext/algorithm>
+
+namespace {
+
+int failed = 0;
+
+void testAppend()
+{
+ std::cout << "testAppend()" << std::endl;
+
+ // ----------------------------------------------------
+ // cm::append(Vector, Iterator, Iterator)
+ {
+ std::vector<int> v1{ 1, 2, 3 };
+ std::vector<int> v1_ref{ 1, 2, 3, 4, 5, 6 };
+ std::vector<int> v2{ 4, 5, 6 };
+ std::vector<int> v2_ref{ 4, 5, 6 };
+
+ cm::append(v1, v2.begin(), v2.end());
+
+ if (v1 != v1_ref || v2 != v2_ref) {
+ ++failed;
+ }
+ }
+
+ // ----------------------------------------------------
+ // cm::append(Vector, Range)
+ {
+ std::vector<int> v1{ 1, 2, 3 };
+ std::vector<int> v1_ref{ 1, 2, 3, 4, 5, 6 };
+ std::vector<int> v2{ 4, 5, 6 };
+ std::vector<int> v2_ref{ 4, 5, 6 };
+
+ cm::append(v1, v2);
+
+ if (v1 != v1_ref || v2 != v2_ref) {
+ ++failed;
+ }
+ }
+
+ // ----------------------------------------------------
+ // cm::append(Vector<*>, Vector<unique_ptr>)
+ {
+ std::vector<int*> v1{ new int(1), new int(2), new int(3) };
+ std::vector<int*> v1_ref = v1;
+ std::vector<std::unique_ptr<int>> v2;
+
+ v2.emplace_back(new int(4));
+ v2.emplace_back(new int(5));
+ v2.emplace_back(new int(6));
+
+ cm::append(v1, v2);
+
+ if (v1.size() == 6 && v2.size() == 3) {
+ for (int i = 0; i < 3; i++) {
+ if (v1[i] != v1_ref[i]) {
+ ++failed;
+ break;
+ }
+ }
+ for (int i = 0; i < 3; i++) {
+ if (v1[i + 3] != v2[i].get()) {
+ ++failed;
+ break;
+ }
+ }
+ } else {
+ ++failed;
+ }
+
+ // free memory to please memory sanitizer
+ delete v1[0];
+ delete v1[1];
+ delete v1[2];
+ }
+
+ // ----------------------------------------------------
+ // cm::append(Vector<unique_ptr>, Vector<unique_ptr>)
+ {
+ std::vector<std::unique_ptr<int>> v1;
+ std::vector<std::unique_ptr<int>> v2;
+
+ v1.emplace_back(new int(1));
+ v1.emplace_back(new int(2));
+ v1.emplace_back(new int(3));
+
+ v2.emplace_back(new int(4));
+ v2.emplace_back(new int(5));
+ v2.emplace_back(new int(6));
+
+ cm::append(v1, std::move(v2));
+
+ if (v1.size() == 6 && v2.empty()) {
+ for (int i = 0; i < 6; i++) {
+ if (*v1[i] != i + 1) {
+ ++failed;
+ break;
+ }
+ }
+ } else {
+ ++failed;
+ }
+ }
+}
+}
+
+int testCMExtAlgorithm(int /*unused*/, char* /*unused*/ [])
+{
+ testAppend();
+
+ return failed;
+}
diff --git a/Tests/CMakeLib/testCMExtMemory.cxx b/Tests/CMakeLib/testCMExtMemory.cxx
new file mode 100644
index 0000000..6663c17
--- /dev/null
+++ b/Tests/CMakeLib/testCMExtMemory.cxx
@@ -0,0 +1,65 @@
+#include <iostream>
+#include <memory>
+
+#include <cmext/memory>
+
+namespace {
+class Base
+{
+public:
+ virtual ~Base() = default;
+};
+
+class Derived : public Base
+{
+public:
+ ~Derived() = default;
+
+ void method() {}
+};
+
+template <typename T>
+class Wrapper
+{
+public:
+ Wrapper(T* v)
+ : value(v)
+ {
+ }
+ ~Wrapper() { delete value; }
+
+ T* get() const { return value; }
+
+private:
+ T* value;
+};
+
+bool testReferenceCast()
+{
+ std::cout << "testReferenceCast()" << std::endl;
+
+ std::unique_ptr<Base> u(new Derived);
+ cm::static_reference_cast<Derived>(u).method();
+ cm::dynamic_reference_cast<Derived>(u).method();
+
+ std::shared_ptr<Base> s(new Derived);
+ cm::static_reference_cast<Derived>(s).method();
+ cm::dynamic_reference_cast<Derived>(s).method();
+
+ // can also be used with custom wrappers
+ Wrapper<Base> w(new Derived);
+ cm::static_reference_cast<Derived>(w).method();
+ cm::dynamic_reference_cast<Derived>(w).method();
+
+ return true;
+}
+}
+
+int testCMExtMemory(int /*unused*/, char* /*unused*/ [])
+{
+ if (!testReferenceCast()) {
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/Tests/CMakeLib/testCTestBinPacker.cxx b/Tests/CMakeLib/testCTestBinPacker.cxx
index 6f09af2..abdbefb 100644
--- a/Tests/CMakeLib/testCTestBinPacker.cxx
+++ b/Tests/CMakeLib/testCTestBinPacker.cxx
@@ -1,4 +1,4 @@
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
#include <iostream>
#include <map>
#include <string>
diff --git a/Tests/CMakeLib/testGccDepfileReader.cxx b/Tests/CMakeLib/testGccDepfileReader.cxx
new file mode 100644
index 0000000..e79f047
--- /dev/null
+++ b/Tests/CMakeLib/testGccDepfileReader.cxx
@@ -0,0 +1,131 @@
+#include <cstddef> // IWYU pragma: keep
+#include <iostream>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "cmsys/FStream.hxx"
+
+#include "cmGccDepfileReader.h"
+#include "cmGccDepfileReaderTypes.h" // for cmGccDepfileContent, cmGccStyle...
+#include "cmSystemTools.h"
+
+namespace {
+
+cmGccDepfileContent readPlainDepfile(const char* filePath)
+{
+ cmGccDepfileContent result;
+ cmsys::ifstream is(filePath);
+ if (!is.is_open())
+ return result;
+ std::string line;
+
+ cmGccStyleDependency dep;
+ bool readingRules = true;
+ while (cmSystemTools::GetLineFromStream(is, line)) {
+ if (line == "--RULES--") {
+ if (!dep.rules.empty()) {
+ result.push_back(std::move(dep));
+ dep = cmGccStyleDependency();
+ }
+ readingRules = true;
+ } else if (line == "--DEPENDENCIES--") {
+ readingRules = false;
+ } else {
+ std::vector<std::string>& dst = readingRules ? dep.rules : dep.paths;
+ dst.push_back(std::move(line));
+ line = std::string();
+ }
+ }
+
+ if (!dep.rules.empty()) {
+ result.push_back(std::move(dep));
+ }
+
+ return result;
+}
+
+bool compare(const std::vector<std::string>& actual,
+ const std::vector<std::string>& expected, const char* msg)
+{
+ if (actual.size() != expected.size()) {
+ std::cerr << msg << "expected " << expected.size() << " entries."
+ << std::endl
+ << "Actual number of entries: " << actual.size() << std::endl;
+ return false;
+ }
+ for (std::size_t i = 0; i < actual.size(); ++i) {
+ if (actual[i] != expected[i]) {
+ std::cerr << msg << std::endl
+ << "expected: " << expected[i] << std::endl
+ << "actual: " << actual[i] << std::endl;
+ return false;
+ }
+ }
+ return true;
+}
+
+bool compare(const cmGccDepfileContent& actual,
+ const cmGccDepfileContent& expected)
+{
+ if (actual.size() != expected.size()) {
+ std::cerr << "Expected " << expected.size() << " entries." << std::endl
+ << "Actual number of entries: " << actual.size() << std::endl;
+ return false;
+ }
+ for (std::size_t i = 0; i < actual.size(); ++i) {
+ if (!compare(actual[i].rules, expected[i].rules, "Rules differ: ") ||
+ !compare(actual[i].paths, expected[i].paths, "Paths differ: ")) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void dump(const char* label, const cmGccDepfileContent& dfc)
+{
+ std::cerr << label << std::endl;
+ for (const auto& entry : dfc) {
+ auto rit = entry.rules.cbegin();
+ if (rit != entry.rules.cend()) {
+ std::cerr << *rit;
+ for (++rit; rit != entry.rules.cend(); ++rit) {
+ std::cerr << " " << *rit;
+ }
+ std::cerr << ": " << std::endl;
+ }
+ for (const auto& path : entry.paths) {
+ std::cerr << " " << path << std::endl;
+ }
+ }
+}
+
+} // anonymous namespace
+
+int testGccDepfileReader(int argc, char* argv[])
+{
+ if (argc < 2) {
+ std::cout << "Invalid arguments.\n";
+ return -1;
+ }
+
+ std::string dataDirPath = argv[1];
+ dataDirPath += "/testGccDepfileReader_data";
+ const int numberOfTestFiles = 3;
+ for (int i = 1; i <= numberOfTestFiles; ++i) {
+ const std::string base = dataDirPath + "/deps" + std::to_string(i);
+ const std::string depfile = base + ".d";
+ const std::string plainDepfile = base + ".txt";
+ std::cout << "Comparing " << base << " with " << plainDepfile << std::endl;
+ const auto actual = cmReadGccDepfile(depfile.c_str());
+ const auto expected = readPlainDepfile(plainDepfile.c_str());
+ if (!compare(actual, expected)) {
+ dump("actual", actual);
+ dump("expected", expected);
+ return 1;
+ }
+ }
+
+ return 0;
+}
diff --git a/Tests/CMakeLib/testGccDepfileReader_data/deps1.d b/Tests/CMakeLib/testGccDepfileReader_data/deps1.d
new file mode 100644
index 0000000..9e34863
--- /dev/null
+++ b/Tests/CMakeLib/testGccDepfileReader_data/deps1.d
@@ -0,0 +1,20 @@
+main.o: main.cpp /usr/include/stdc-predef.h /usr/include/stdio.h \
+ /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \
+ /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \
+ /usr/include/x86_64-linux-gnu/bits/wordsize.h \
+ /usr/include/x86_64-linux-gnu/bits/long-double.h \
+ /usr/include/x86_64-linux-gnu/gnu/stubs.h \
+ /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \
+ /usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h \
+ /usr/lib/gcc/x86_64-linux-gnu/8/include/stdarg.h \
+ /usr/include/x86_64-linux-gnu/bits/types.h \
+ /usr/include/x86_64-linux-gnu/bits/typesizes.h \
+ /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \
+ /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \
+ /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \
+ /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \
+ /usr/include/x86_64-linux-gnu/bits/types/FILE.h \
+ /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \
+ /usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h \
+ /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \
+ /usr/include/x86_64-linux-gnu/bits/sys_errlist.h
diff --git a/Tests/CMakeLib/testGccDepfileReader_data/deps1.txt b/Tests/CMakeLib/testGccDepfileReader_data/deps1.txt
new file mode 100644
index 0000000..fd2679f
--- /dev/null
+++ b/Tests/CMakeLib/testGccDepfileReader_data/deps1.txt
@@ -0,0 +1,26 @@
+--RULES--
+main.o
+--DEPENDENCIES--
+main.cpp
+/usr/include/stdc-predef.h
+/usr/include/stdio.h
+/usr/include/x86_64-linux-gnu/bits/libc-header-start.h
+/usr/include/features.h
+/usr/include/x86_64-linux-gnu/sys/cdefs.h
+/usr/include/x86_64-linux-gnu/bits/wordsize.h
+/usr/include/x86_64-linux-gnu/bits/long-double.h
+/usr/include/x86_64-linux-gnu/gnu/stubs.h
+/usr/include/x86_64-linux-gnu/gnu/stubs-64.h
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stdarg.h
+/usr/include/x86_64-linux-gnu/bits/types.h
+/usr/include/x86_64-linux-gnu/bits/typesizes.h
+/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h
+/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h
+/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h
+/usr/include/x86_64-linux-gnu/bits/types/__FILE.h
+/usr/include/x86_64-linux-gnu/bits/types/FILE.h
+/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h
+/usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h
+/usr/include/x86_64-linux-gnu/bits/stdio_lim.h
+/usr/include/x86_64-linux-gnu/bits/sys_errlist.h
diff --git a/Tests/CMakeLib/testGccDepfileReader_data/deps2.d b/Tests/CMakeLib/testGccDepfileReader_data/deps2.d
new file mode 100644
index 0000000..25f0d78
--- /dev/null
+++ b/Tests/CMakeLib/testGccDepfileReader_data/deps2.d
@@ -0,0 +1 @@
+foo.o bar.o: foobar.c
diff --git a/Tests/CMakeLib/testGccDepfileReader_data/deps2.txt b/Tests/CMakeLib/testGccDepfileReader_data/deps2.txt
new file mode 100644
index 0000000..afaf78e
--- /dev/null
+++ b/Tests/CMakeLib/testGccDepfileReader_data/deps2.txt
@@ -0,0 +1,5 @@
+--RULES--
+foo.o
+bar.o
+--DEPENDENCIES--
+foobar.c
diff --git a/Tests/CMakeLib/testGccDepfileReader_data/deps3.d b/Tests/CMakeLib/testGccDepfileReader_data/deps3.d
new file mode 100644
index 0000000..d75ceed
--- /dev/null
+++ b/Tests/CMakeLib/testGccDepfileReader_data/deps3.d
@@ -0,0 +1,2 @@
+main.o: main.cpp foo\#bar.h foo\\#bar.h foo\ bar.h \
+ foo\\\ bar.h foo\\\\\ bar.h foo\\\\ foo$$bar.h
diff --git a/Tests/CMakeLib/testGccDepfileReader_data/deps3.txt b/Tests/CMakeLib/testGccDepfileReader_data/deps3.txt
new file mode 100644
index 0000000..448f69c
--- /dev/null
+++ b/Tests/CMakeLib/testGccDepfileReader_data/deps3.txt
@@ -0,0 +1,11 @@
+--RULES--
+main.o
+--DEPENDENCIES--
+main.cpp
+foo#bar.h
+foo\#bar.h
+foo bar.h
+foo\ bar.h
+foo\\ bar.h
+foo\\\\
+foo$bar.h
diff --git a/Tests/CMakeLib/testString.cxx b/Tests/CMakeLib/testString.cxx
index d7b3200..ad800cf 100644
--- a/Tests/CMakeLib/testString.cxx
+++ b/Tests/CMakeLib/testString.cxx
@@ -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. */
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
#include <cstring>
#include <iostream>
#include <iterator>
@@ -12,8 +12,7 @@
#include <utility>
#include <cm/string_view>
-
-#include "cm_static_string_view.hxx"
+#include <cmext/string_view>
#include "cmString.hxx"
@@ -191,7 +190,7 @@ static bool testConstructFromView()
{
std::cout << "testConstructFromView()\n";
cm::string_view view = cstr;
- return testFromCStr(view);
+ return testFromCStr(cm::String(view));
}
static bool testAssignFromView()
@@ -297,7 +296,7 @@ static bool testFromStaticStringView(cm::String str)
static bool testConstructFromStaticStringView()
{
std::cout << "testConstructFromStaticStringView()\n";
- return testFromStaticStringView(staticStringView);
+ return testFromStaticStringView(cm::String(staticStringView));
}
static bool testAssignFromStaticStringView()
@@ -796,7 +795,7 @@ static bool testMethod_substr_AtEnd(cm::String str)
static bool testMethod_substr_AtEndBorrowed()
{
std::cout << "testMethod_substr_AtEndBorrowed()\n";
- return testMethod_substr_AtEnd("abc"_s);
+ return testMethod_substr_AtEnd(cm::String("abc"_s));
}
static bool testMethod_substr_AtEndOwned()
@@ -855,7 +854,7 @@ static bool testMethod_substr_AtStart(cm::String str)
static bool testMethod_substr_AtStartBorrowed()
{
std::cout << "testMethod_substr_AtStartBorrowed()\n";
- return testMethod_substr_AtStart("abc"_s);
+ return testMethod_substr_AtStart(cm::String("abc"_s));
}
static bool testMethod_substr_AtStartOwned()
@@ -1146,7 +1145,7 @@ static bool testAddition()
static bool testStability()
{
std::cout << "testStability()\n";
- cm::String str = "abc"_s;
+ cm::String str("abc"_s);
ASSERT_TRUE(!str.is_stable());
ASSERT_TRUE(str.str_if_stable() == nullptr);
str.stabilize();
diff --git a/Tests/CMakeLib/testUTF8.cxx b/Tests/CMakeLib/testUTF8.cxx
index 986f595..1bf88cf 100644
--- a/Tests/CMakeLib/testUTF8.cxx
+++ b/Tests/CMakeLib/testUTF8.cxx
@@ -9,9 +9,11 @@ typedef char test_utf8_char[5];
static void test_utf8_char_print(test_utf8_char const c)
{
unsigned char const* d = reinterpret_cast<unsigned char const*>(c);
+#ifndef __clang_analyzer__ // somehow thinks arguments are not initialized
printf("[0x%02X,0x%02X,0x%02X,0x%02X]", static_cast<int>(d[0]),
static_cast<int>(d[1]), static_cast<int>(d[2]),
static_cast<int>(d[3]));
+#endif
}
static void byte_array_print(char const* s)
diff --git a/Tests/CMakeLib/testUVProcessChain.cxx b/Tests/CMakeLib/testUVProcessChain.cxx
index 71a1764..61a77cf 100644
--- a/Tests/CMakeLib/testUVProcessChain.cxx
+++ b/Tests/CMakeLib/testUVProcessChain.cxx
@@ -8,7 +8,7 @@
#include <cm/memory>
-#include "cm_uv.h"
+#include <cm3p/uv.h>
#include "cmGetPipes.h"
#include "cmUVHandlePtr.h"
diff --git a/Tests/CMakeLib/testUVRAII.cxx b/Tests/CMakeLib/testUVRAII.cxx
index cb05ace..0607f44 100644
--- a/Tests/CMakeLib/testUVRAII.cxx
+++ b/Tests/CMakeLib/testUVRAII.cxx
@@ -3,7 +3,7 @@
#include <thread>
#include <utility>
-#include "cm_uv.h"
+#include <cm3p/uv.h>
#include "cmUVHandlePtr.h"
diff --git a/Tests/CMakeLib/testUVStreambuf.cxx b/Tests/CMakeLib/testUVStreambuf.cxx
index cd9c9d4..b86ed76 100644
--- a/Tests/CMakeLib/testUVStreambuf.cxx
+++ b/Tests/CMakeLib/testUVStreambuf.cxx
@@ -3,10 +3,9 @@
#include <string>
#include <vector>
+#include <cm3p/uv.h>
#include <stdint.h>
-#include "cm_uv.h"
-
#include "cmGetPipes.h"
#include "cmUVHandlePtr.h"
#include "cmUVStreambuf.h"
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 57fa7fc..0c8a639 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -211,6 +211,13 @@ if(BUILD_TESTING)
#---------------------------------------------------------------------------
# Add tests below here.
+ if(NOT DEFINED CMake_TEST_Qt5)
+ set(CMake_TEST_Qt5 1)
+ endif()
+ if(CMake_TEST_Qt5)
+ find_package(Qt5Widgets QUIET NO_MODULE)
+ endif()
+
if(NOT CMake_TEST_EXTERNAL_CMAKE)
add_subdirectory(CMakeLib)
@@ -356,7 +363,10 @@ if(BUILD_TESTING)
add_test_macro(VSResourceNinjaForceRSP VSResourceNinjaForceRSP)
endif ()
endif()
- ADD_TEST_MACRO(MSManifest MSManifest)
+ if(_isMultiConfig)
+ set(MSManifest_CTEST_OPTIONS -C $<CONFIGURATION>)
+ endif()
+ ADD_TEST_MACRO(MSManifest ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>)
ADD_TEST_MACRO(Simple Simple)
ADD_TEST_MACRO(PreOrder PreOrder)
ADD_TEST_MACRO(MissingSourceFile MissingSourceFile)
@@ -436,7 +446,9 @@ if(BUILD_TESTING)
ADD_TEST_MACRO(Assembler HelloAsm)
ADD_TEST_MACRO(SourceGroups SourceGroups)
ADD_TEST_MACRO(Preprocess Preprocess)
- set(ExportImport_BUILD_OPTIONS -DCMake_TEST_NESTED_MAKE_PROGRAM:FILEPATH=${CMake_TEST_EXPLICIT_MAKE_PROGRAM})
+ set(ExportImport_BUILD_OPTIONS -DCMake_TEST_NESTED_MAKE_PROGRAM:FILEPATH=${CMake_TEST_EXPLICIT_MAKE_PROGRAM}
+ -DCMake_TEST_CUDA:BOOL=${CMake_TEST_CUDA}
+ )
ADD_TEST_MACRO(ExportImport ExportImport)
ADD_TEST_MACRO(Unset Unset)
ADD_TEST_MACRO(PolicyScope PolicyScope)
@@ -451,8 +463,12 @@ if(BUILD_TESTING)
ADD_TEST_MACRO(StagingPrefix StagingPrefix)
ADD_TEST_MACRO(ImportedSameName ImportedSameName)
ADD_TEST_MACRO(InterfaceLibrary InterfaceLibrary)
- if(NOT _isMultiConfig)
- set(ConfigSources_BUILD_OPTIONS -DCMAKE_BUILD_TYPE=$<CONFIGURATION>)
+ if(NOT CMAKE_GENERATOR STREQUAL "Xcode")
+ if(_isMultiConfig)
+ set(ConfigSources_CTEST_OPTIONS --build-config $<CONFIGURATION>)
+ else()
+ set(ConfigSources_BUILD_OPTIONS -DCMAKE_BUILD_TYPE=$<CONFIGURATION>)
+ endif()
ADD_TEST_MACRO(ConfigSources ConfigSources)
endif()
ADD_TEST_MACRO(SourcesProperty SourcesProperty)
@@ -774,13 +790,8 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
endif()
endmacro()
if(CMake_BUILD_NIGHTLY_RELEASES)
- ADD_NIGHTLY_BUILD_TEST(CMakeNightlyWin32
- win32_release.cmake)
- ADD_NIGHTLY_BUILD_TEST(CMakeNightlyWin64
- win64_release.cmake)
ADD_NIGHTLY_BUILD_TEST(CMakeNightlyOSX
osx_release.cmake)
- set_property(TEST CMakeNightlyWin64 PROPERTY DEPENDS CMakeNightlyWin32)
endif()
# add tests with more complex invocations
@@ -976,6 +987,27 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
endif()
endif()
+ # On Windows run the CPackNSISGenerator test
+ # if the nsis is available
+ if(WIN32 AND NSIS_MAKENSIS_EXECUTABLE)
+ add_test(CPackNSISGenerator ${CMAKE_CTEST_COMMAND}
+ -C \${CTEST_CONFIGURATION_TYPE}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/CPackNSISGenerator"
+ "${CMake_BINARY_DIR}/Tests/CPackNSISGenerator"
+ ${build_generator_args}
+ --build-project CPackNSISGenerator
+ --build-options
+ --test-command ${CMAKE_CMAKE_COMMAND}
+ "-DCPackNSISGenerator_BINARY_DIR:PATH=${CMake_BINARY_DIR}/Tests/CPackNSISGenerator"
+ "-Dconfig=\${CTEST_CONFIGURATION_TYPE}"
+ -P "${CMake_SOURCE_DIR}/Tests/CPackNSISGenerator/RunCPackVerifyResult.cmake")
+
+ set_property(TEST CPackNSISGenerator PROPERTY
+ ATTACHED_FILES_ON_FAIL
+ "${CMake_BINARY_DIR}/Tests/CPackNSISGenerator/_CPack_Packages/win32/NSIS/NSISOutput.log")
+ endif()
+
if(CTEST_TEST_CPACK)
add_test(CPackUseDefaultVersion ${CMAKE_CTEST_COMMAND}
--build-and-test
@@ -1128,8 +1160,8 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
foreach(CPackDEBConfiguration IN LISTS DEB_CONFIGURATIONS_TO_TEST)
set(CPackRun_CPackDEBConfiguration "-DCPackDEBConfiguration=${CPackDEBConfiguration}")
- add_test(${DEB_TEST_NAMES}-${CPackDEBConfiguration}
- ${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE}
+ add_test(NAME ${DEB_TEST_NAMES}-${CPackDEBConfiguration} COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIG>
--build-and-test
"${CMake_SOURCE_DIR}/Tests/${DEB_TEST_NAMES}"
"${CMake_BINARY_DIR}/Tests/${DEB_TEST_NAMES}/build${CPackGen}-${CPackDEBConfiguration}"
@@ -1146,6 +1178,7 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
"-D${DEB_TEST_NAMES}_BINARY_DIR:PATH=${CMake_BINARY_DIR}/Tests/${DEB_TEST_NAMES}/build${CPackGen}-${CPackDEBConfiguration}"
"${CPackRun_CPackGen}"
"${CPackRun_CPackDEBConfiguration}"
+ "-DCONFIG=$<CONFIG>"
-P "${CMake_SOURCE_DIR}/Tests/${DEB_TEST_NAMES}/RunCPackVerifyResult-${CPackDEBConfiguration}.cmake")
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/${DEB_TEST_NAMES}/build${CPackGen}-${CPackDEBConfiguration}")
endforeach()
@@ -1325,12 +1358,6 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/QtAutomocNoQt")
- if(NOT DEFINED CMake_TEST_Qt5)
- set(CMake_TEST_Qt5 1)
- endif()
- if(CMake_TEST_Qt5)
- find_package(Qt5Widgets QUIET NO_MODULE)
- endif()
if(CMake_TEST_Qt5 AND Qt5Widgets_FOUND)
add_subdirectory(Qt5Autogen)
endif()
@@ -1382,6 +1409,7 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
foreach(_mod IN ITEMS
ALSA
Boost
+ BLAS
BZip2
CURL
Cups
@@ -1401,11 +1429,14 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
ICU
JPEG
JsonCpp
+ LAPACK
+ LibArchive
LibLZMA
LibRHash
Libinput
LibUV
LibXml2
+ LibXslt
LTTngUST
ODBC
OpenACC
@@ -1440,7 +1471,8 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
add_subdirectory(GoogleTest)
endif()
- if(CMake_TEST_FindPython OR CMake_TEST_FindPython_NumPy)
+ if(CMake_TEST_FindPython OR CMake_TEST_FindPython_NumPy
+ OR CMake_TEST_FindPython_Conda OR CMake_TEST_FindPython_IronPython OR CMake_TEST_FindPython_PyPy)
add_subdirectory(FindPython)
endif()
@@ -1448,6 +1480,10 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
add_subdirectory(UseSWIG)
endif()
+ if(CMake_TEST_FindRuby)
+ add_subdirectory(FindRuby)
+ endif()
+
add_subdirectory(FindThreads)
# Matlab module
@@ -1575,7 +1611,7 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
DEPENDS ExternalProjectUpdateSetup )
# do each of the tutorial steps
- function(add_tutorial_test step_name use_mymath)
+ function(add_tutorial_test step_name use_mymath tutorial_arg pass_regex)
set(tutorial_test_name Tutorial${step_name})
set(tutorial_build_dir "${CMake_BINARY_DIR}/Tests/Tutorial/${step_name}")
if (use_mymath)
@@ -1586,25 +1622,35 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
set(tutorial_build_options -DUSE_MYMATH:BOOL=OFF)
endif()
add_test(${tutorial_test_name} ${CMAKE_CTEST_COMMAND}
+ -C "Release"
--build-and-test
"${CMake_SOURCE_DIR}/Help/guide/tutorial/${step_name}"
${tutorial_build_dir}_Build
${build_generator_args}
--build-project Tutorial
--build-options ${tutorial_build_options}
- --test-command Tutorial 25.0)
+ --test-command Tutorial ${tutorial_arg})
+ set_tests_properties(${tutorial_test_name} PROPERTIES
+ PASS_REGULAR_EXPRESSION ${pass_regex})
+
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/${tutorial_build_dir}_Build")
endfunction()
if(NOT CMake_TEST_EXTERNAL_CMAKE)
- foreach(STP RANGE 2 11)
- add_tutorial_test(Step${STP} TRUE)
+ foreach(STP RANGE 2 12)
+ if (STP EQUAL 6)
+ set(pass_regex ".*using log and exp")
+ else()
+ set(pass_regex "The square root of 25 is 5")
+ endif()
+ add_tutorial_test(Step${STP} TRUE 25 ${pass_regex})
endforeach()
- add_tutorial_test(Complete TRUE)
- foreach(STP RANGE 3 11)
- add_tutorial_test(Step${STP} FALSE)
+ set(pass_regex "The square root of 25 is 5")
+ add_tutorial_test(Complete TRUE 25 ${pass_regex})
+ foreach(STP RANGE 3 12)
+ add_tutorial_test(Step${STP} FALSE 25 ${pass_regex})
endforeach()
- add_tutorial_test(Complete FALSE)
+ add_tutorial_test(Complete FALSE 25 ${pass_regex})
endif()
add_test(testing ${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE}
@@ -1861,7 +1907,7 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
ADD_TEST_MACRO(CheckCompilerRelatedVariables CheckCompilerRelatedVariables)
if("${CMAKE_GENERATOR}" MATCHES "Makefile" OR
- "${CMAKE_GENERATOR}" MATCHES "Ninja")
+ "${CMAKE_GENERATOR}" MATCHES "^Ninja$")
add_test(MakeClean ${CMAKE_CTEST_COMMAND}
--build-and-test
"${CMake_SOURCE_DIR}/Tests/MakeClean"
@@ -2644,9 +2690,6 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
-S "${CMake_BINARY_DIR}/Tests/CTestCoverageCollectGCOV/test.cmake" -VV
--output-log "${CMake_BINARY_DIR}/Tests/CTestCoverageCollectGCOV/testOut.log"
)
- set_tests_properties(CTestCoverageCollectGCOV PROPERTIES
- PASS_REGULAR_EXPRESSION
- "PASSED with correct output.*Testing/CoverageInfo/main.cpp.gcov")
set_property(TEST CTestCoverageCollectGCOV PROPERTY ENVIRONMENT CTEST_PARALLEL_LEVEL=)
configure_file(
@@ -3392,17 +3435,6 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
set_tests_properties ( KDELibsAlpha1 PROPERTIES TIMEOUT 5400)
endif()
- # If this is not an in-source build, provide a target to wipe out
- # all the test build directories.
- if(NOT EXISTS "${CMake_BINARY_DIR}/CMakeLists.txt")
- configure_file(${CMake_SOURCE_DIR}/Tests/test_clean.cmake.in
- ${CMake_BINARY_DIR}/Tests/test_clean.cmake @ONLY)
- add_custom_target(test_clean
- COMMAND ${CMAKE_COMMAND} -P ${CMake_BINARY_DIR}/Tests/test_clean.cmake
- COMMENT "Removing test build directories."
- )
- endif()
-
# Define a set of "contract" tests, each activated by a cache entry
# named "CMake_TEST_CONTRACT_<project>". For each Contract test,
# the project should provide a directory with a CMakeLists.txt file
@@ -3444,6 +3476,8 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
--build-two-config
${build_generator_args}
--build-project IncludeDirectories
+ --build-options
+ -DMAKE_SUPPORTS_SPACES=${MAKE_SUPPORTS_SPACES}
--test-command IncludeDirectories)
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/IncludeDirectories")
@@ -3477,4 +3511,16 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
if(NOT CMake_TEST_EXTERNAL_CMAKE)
add_subdirectory(CMakeTests)
endif()
+
+ # If this is not an in-source build, provide a target to wipe out
+ # all the test build directories. This must come at the end after
+ # all the above logic has finished adding to TEST_BUILD_DIRS
+ if(NOT EXISTS "${CMake_BINARY_DIR}/CMakeLists.txt")
+ configure_file(${CMake_SOURCE_DIR}/Tests/test_clean.cmake.in
+ ${CMake_BINARY_DIR}/Tests/test_clean.cmake @ONLY)
+ add_custom_target(test_clean
+ COMMAND ${CMAKE_COMMAND} -P ${CMake_BINARY_DIR}/Tests/test_clean.cmake
+ COMMENT "Removing test build directories."
+ )
+ endif()
endif()
diff --git a/Tests/CMakeOnly/AllFindModules/CMakeLists.txt b/Tests/CMakeOnly/AllFindModules/CMakeLists.txt
index a53e441..49a4041 100644
--- a/Tests/CMakeOnly/AllFindModules/CMakeLists.txt
+++ b/Tests/CMakeOnly/AllFindModules/CMakeLists.txt
@@ -86,7 +86,7 @@ foreach(VTEST ALSA ARMADILLO BZIP2 CUPS CURL EXPAT FREETYPE GETTEXT GIT HG
endforeach()
foreach(VTEST BISON Boost CUDA DOXYGEN FLEX GIF GTK2
- HDF5 JPEG LibArchive OPENSCENEGRAPH RUBY SWIG Protobuf)
+ HDF5 JPEG LibArchive OPENSCENEGRAPH Ruby RUBY SWIG Protobuf)
check_version_string(${VTEST} ${VTEST}_VERSION)
endforeach()
diff --git a/Tests/CMakeOnly/CMakeLists.txt b/Tests/CMakeOnly/CMakeLists.txt
index 03babd2..361cf5f 100644
--- a/Tests/CMakeOnly/CMakeLists.txt
+++ b/Tests/CMakeOnly/CMakeLists.txt
@@ -31,12 +31,9 @@ add_CMakeOnly_test(CheckStructHasMember)
add_CMakeOnly_test(CompilerIdC)
add_CMakeOnly_test(CompilerIdCXX)
-if(CMAKE_OBJC_COMPILER)
+if (APPLE AND CMAKE_C_COMPILER_ID MATCHES "Clang|GNU")
add_CMakeOnly_test(CompilerIdOBJC)
add_CMakeOnly_test(CheckOBJCCompilerFlag)
-endif()
-
-if(CMAKE_OBJCXX_COMPILER)
add_CMakeOnly_test(CompilerIdOBJCXX)
add_CMakeOnly_test(CheckOBJCXXCompilerFlag)
endif()
@@ -75,6 +72,12 @@ add_test(CMakeOnly.ProjectIncludeAny ${CMAKE_CMAKE_COMMAND}
add_test(CMakeOnly.ProjectIncludeBefore ${CMAKE_CMAKE_COMMAND}
-DTEST=ProjectIncludeBefore
+ -DCMAKE_ARGS=-DCMAKE_PROJECT_ProjectInclude_INCLUDE_BEFORE=${CMAKE_CURRENT_SOURCE_DIR}/ProjectIncludeBefore/include.cmake
+ -P ${CMAKE_CURRENT_BINARY_DIR}/Test.cmake
+ )
+
+add_test(CMakeOnly.ProjectIncludeBeforeAny ${CMAKE_CMAKE_COMMAND}
+ -DTEST=ProjectIncludeBeforeAny
-DCMAKE_ARGS=-DCMAKE_PROJECT_INCLUDE_BEFORE=${CMAKE_CURRENT_SOURCE_DIR}/ProjectIncludeBefore/include.cmake
-P ${CMAKE_CURRENT_BINARY_DIR}/Test.cmake
)
diff --git a/Tests/CMakeOnly/CheckOBJCCompilerFlag/CMakeLists.txt b/Tests/CMakeOnly/CheckOBJCCompilerFlag/CMakeLists.txt
index a9a96ee..a714b73 100644
--- a/Tests/CMakeOnly/CheckOBJCCompilerFlag/CMakeLists.txt
+++ b/Tests/CMakeOnly/CheckOBJCCompilerFlag/CMakeLists.txt
@@ -1,17 +1,7 @@
-cmake_minimum_required(VERSION 2.8.12)
-
-project(CheckOBJCCompilerFlag)
-
+cmake_minimum_required(VERSION 3.16)
+project(CheckOBJCCompilerFlag OBJC)
include(CheckOBJCCompilerFlag)
-
-if(CMAKE_COMPILER_IS_GNUOBJC)
- set(COMPILER_FLAG -fobjc-direct-dispatch)
-else()
- set(COMPILER_FLAG -fobjc-gc)
-endif()
-
-CHECK_OBJC_COMPILER_FLAGS(${COMPILER_FLAG} HAS_COMPILER_FLAG)
-
+check_objc_compiler_flag(-DFOO HAS_COMPILER_FLAG)
if(NOT HAS_COMPILER_FLAG)
message(SEND_ERROR "Test fail: HAS_COMPILER_FLAG: ${COMPILER_FLAG}")
-endif
+endif()
diff --git a/Tests/CMakeOnly/CheckOBJCXXCompilerFlag/CMakeLists.txt b/Tests/CMakeOnly/CheckOBJCXXCompilerFlag/CMakeLists.txt
index f83b738..d09f0b9 100644
--- a/Tests/CMakeOnly/CheckOBJCXXCompilerFlag/CMakeLists.txt
+++ b/Tests/CMakeOnly/CheckOBJCXXCompilerFlag/CMakeLists.txt
@@ -1,17 +1,7 @@
-cmake_minimum_required(VERSION 2.8.12)
-
-project(CheckOBJCXXCompilerFlag)
-
+cmake_minimum_required(VERSION 3.16)
+project(CheckOBJCXXCompilerFlag OBJCXX)
include(CheckOBJCXXCompilerFlag)
-
-if(CMAKE_COMPILER_IS_GNUOBJCXX)
- set(COMPILER_FLAG -fobjc-direct-dispatch)
-else()
- set(COMPILER_FLAG -fobjc-gc)
-endif()
-
-CHECK_OBJCXX_COMPILER_FLAGS(${COMPILER_FLAG} HAS_COMPILER_FLAG)
-
+check_objcxx_compiler_flag(-DFOO HAS_COMPILER_FLAG)
if(NOT HAS_COMPILER_FLAG)
message(SEND_ERROR "Test fail: HAS_COMPILER_FLAG: ${COMPILER_FLAG}")
endif()
diff --git a/Tests/CMakeOnly/CheckStructHasMember/CMakeLists.txt b/Tests/CMakeOnly/CheckStructHasMember/CMakeLists.txt
index a584505..859ec41 100644
--- a/Tests/CMakeOnly/CheckStructHasMember/CMakeLists.txt
+++ b/Tests/CMakeOnly/CheckStructHasMember/CMakeLists.txt
@@ -6,7 +6,7 @@ set(CMAKE_REQUIRED_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}")
include(CheckStructHasMember)
-foreach(_config_type Release RelWithDebInfo MinSizeRel Debug)
+foreach(_config_type Release RelWithDebInfo Debug)
set(CMAKE_TRY_COMPILE_CONFIGURATION ${_config_type})
unset(CSHM_RESULT_S1_${_config_type} CACHE)
unset(CSHM_RESULT_S2_${_config_type} CACHE)
@@ -26,7 +26,7 @@ foreach(_config_type Release RelWithDebInfo MinSizeRel Debug)
endif()
endforeach()
-foreach(_config_type Release RelWithDebInfo MinSizeRel Debug)
+foreach(_config_type Release RelWithDebInfo Debug)
set(CMAKE_TRY_COMPILE_CONFIGURATION ${_config_type})
unset(CSHM_RESULT_S1_${_config_type}_C CACHE)
unset(CSHM_RESULT_S2_${_config_type}_C CACHE)
@@ -46,7 +46,7 @@ foreach(_config_type Release RelWithDebInfo MinSizeRel Debug)
endif()
endforeach()
-foreach(_config_type Release RelWithDebInfo MinSizeRel Debug)
+foreach(_config_type Release RelWithDebInfo Debug)
set(CMAKE_TRY_COMPILE_CONFIGURATION ${_config_type})
unset(CSHM_RESULT_S1_${_config_type}_CXX CACHE)
unset(CSHM_RESULT_S2_${_config_type}_CXX CACHE)
diff --git a/Tests/CMakeOnly/ProjectIncludeBeforeAny/CMakeLists.txt b/Tests/CMakeOnly/ProjectIncludeBeforeAny/CMakeLists.txt
new file mode 100644
index 0000000..5cd9cba
--- /dev/null
+++ b/Tests/CMakeOnly/ProjectIncludeBeforeAny/CMakeLists.txt
@@ -0,0 +1,5 @@
+set(FOO TRUE)
+project(ProjectInclude LANGUAGES NONE)
+if(NOT AUTO_INCLUDE)
+ message(FATAL_ERROR "include file not found")
+endif()
diff --git a/Tests/CMakeOnly/ProjectIncludeBeforeAny/include.cmake b/Tests/CMakeOnly/ProjectIncludeBeforeAny/include.cmake
new file mode 100644
index 0000000..0a4799d
--- /dev/null
+++ b/Tests/CMakeOnly/ProjectIncludeBeforeAny/include.cmake
@@ -0,0 +1,9 @@
+if(NOT FOO)
+ message(FATAL_ERROR "FOO is not set")
+endif()
+
+if(NOT "${PROJECT_NAME}" STREQUAL "")
+ message(FATAL_ERROR "PROJECT_NAME should be empty")
+endif()
+
+set(AUTO_INCLUDE TRUE)
diff --git a/Tests/CMakeOnly/Test.cmake.in b/Tests/CMakeOnly/Test.cmake.in
index 0ae8af1..c531e8b 100644
--- a/Tests/CMakeOnly/Test.cmake.in
+++ b/Tests/CMakeOnly/Test.cmake.in
@@ -7,6 +7,13 @@ if(make_program)
set(maybe_make_program "-DCMAKE_MAKE_PROGRAM=${make_program}")
endif()
+set(_isMultiConfig "@_isMultiConfig@")
+if(_isMultiConfig)
+ set(cfg_opts "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release\\;RelWithDebInfo")
+else()
+ set(cfg_opts)
+endif()
+
set(source_dir "@CMAKE_CURRENT_SOURCE_DIR@/${TEST_SOURCE}")
set(binary_dir "@CMAKE_CURRENT_BINARY_DIR@/${TEST}-build")
file(REMOVE_RECURSE "${binary_dir}")
@@ -16,6 +23,7 @@ execute_process(
"${source_dir}" -G "@CMAKE_GENERATOR@"
-A "@CMAKE_GENERATOR_PLATFORM@"
-T "@CMAKE_GENERATOR_TOOLSET@"
+ ${cfg_opts}
${maybe_make_program}
WORKING_DIRECTORY "${binary_dir}"
RESULT_VARIABLE result
diff --git a/Tests/CMakeTestMultipleConfigures/RunCMake.cmake b/Tests/CMakeTestMultipleConfigures/RunCMake.cmake
index 9632664..a79bfcb 100644
--- a/Tests/CMakeTestMultipleConfigures/RunCMake.cmake
+++ b/Tests/CMakeTestMultipleConfigures/RunCMake.cmake
@@ -21,11 +21,11 @@ set(N 7)
# First setup source and binary trees:
#
-execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory
+execute_process(COMMAND ${CMAKE_COMMAND} -E rm -rf
${dir}/Source
)
-execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory
+execute_process(COMMAND ${CMAKE_COMMAND} -E rm -rf
${dir}/Build
)
@@ -69,7 +69,7 @@ foreach(i RANGE 1 ${N})
# Save this iteration of the Build directory:
#
- execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory
+ execute_process(COMMAND ${CMAKE_COMMAND} -E rm -rf
${dir}/b${i}
)
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory
diff --git a/Tests/CMakeTests/CMakeLists.txt b/Tests/CMakeTests/CMakeLists.txt
index 1619081..e32d693 100644
--- a/Tests/CMakeTests/CMakeLists.txt
+++ b/Tests/CMakeTests/CMakeLists.txt
@@ -33,8 +33,9 @@ AddCMakeTest(While "")
AddCMakeTest(CMakeHostSystemInformation "")
AddCMakeTest(FileDownload "")
-set_property(TEST CMake.FileDownload PROPERTY
+set_tests_properties(CMake.FileDownload PROPERTIES
PASS_REGULAR_EXPRESSION "file already exists with expected MD5 sum"
+ FAIL_REGULAR_EXPRESSION "Unexpected status"
)
AddCMakeTest(FileDownloadBadHash "")
set_property(TEST CMake.FileDownloadBadHash PROPERTY
diff --git a/Tests/CMakeTests/FileDownloadTest.cmake.in b/Tests/CMakeTests/FileDownloadTest.cmake.in
index 3935449..76c0000 100644
--- a/Tests/CMakeTests/FileDownloadTest.cmake.in
+++ b/Tests/CMakeTests/FileDownloadTest.cmake.in
@@ -1,23 +1,50 @@
+# We do not contact any real URLs, but do try a bogus one.
+# Remove any proxy configuration that may change behavior.
+unset(ENV{http_proxy})
+unset(ENV{https_proxy})
+
+set(timeout 4)
+
if(NOT "@CMAKE_CURRENT_SOURCE_DIR@" MATCHES "^/")
set(slash /)
endif()
set(url "file://${slash}@CMAKE_CURRENT_SOURCE_DIR@/FileDownloadInput.png")
set(dir "@CMAKE_CURRENT_BINARY_DIR@/downloads")
+# Beware Windows asynchronous file/directory removal, rename and then
+# remove the renamed dir so we can be certain the dir isn't there when
+# we get to the file() commands below
+if(EXISTS "${dir}")
+ file(RENAME ${dir} "${dir}_beingRemoved")
+ file(REMOVE_RECURSE "${dir}_beingRemoved")
+endif()
+
+function(__reportIfWrongStatus statusPair expectedStatusCode)
+ list(GET statusPair 0 statusCode)
+ if(NOT statusCode EQUAL expectedStatusCode)
+ message(SEND_ERROR
+ "Unexpected status: ${statusCode}, expected: ${expectedStatusCode}")
+ endif()
+endfunction()
+
message(STATUS "FileDownload:1")
file(DOWNLOAD
${url}
${dir}/file1.png
- TIMEOUT 2
+ TIMEOUT ${timeout}
+ STATUS status
)
+__reportIfWrongStatus("${status}" 0)
message(STATUS "FileDownload:2")
file(DOWNLOAD
${url}
${dir}/file2.png
- TIMEOUT 2
+ TIMEOUT ${timeout}
+ STATUS status
SHOW_PROGRESS
)
+__reportIfWrongStatus("${status}" 0)
# Two calls in a row, exactly the same arguments.
# Since downloaded file should exist already for 2nd call,
@@ -31,82 +58,108 @@ message(STATUS "FileDownload:3")
file(DOWNLOAD
${url}
${dir}/file3.png
- TIMEOUT 2
+ TIMEOUT ${timeout}
+ STATUS status
EXPECTED_MD5 dbd330d52f4dbd60115d4191904ded92
)
+__reportIfWrongStatus("${status}" 0)
message(STATUS "FileDownload:4")
file(DOWNLOAD
${url}
${dir}/file3.png
- TIMEOUT 2
+ TIMEOUT ${timeout}
STATUS status
EXPECTED_HASH SHA1=67eee17f79d9ac557284fc0b8ad19f25723fb578
)
+__reportIfWrongStatus("${status}" 0)
message(STATUS "FileDownload:5")
file(DOWNLOAD
${url}
${dir}/file3.png
- TIMEOUT 2
+ TIMEOUT ${timeout}
STATUS status
EXPECTED_HASH SHA224=ba283726bbb602776818b463943189afd91836cb7ee5dd6e2c7b5ae4
)
+__reportIfWrongStatus("${status}" 0)
message(STATUS "FileDownload:6")
file(DOWNLOAD
${url}
${dir}/file3.png
- TIMEOUT 2
+ TIMEOUT ${timeout}
STATUS status
EXPECTED_HASH SHA256=cf3334b1275071e1da6e8c396ccb72cf1b2388d8c937526f3af26230affb9423
)
+__reportIfWrongStatus("${status}" 0)
message(STATUS "FileDownload:7")
file(DOWNLOAD
${url}
${dir}/file3.png
- TIMEOUT 2
+ TIMEOUT ${timeout}
STATUS status
EXPECTED_HASH SHA384=43a5d13978d97c660db44481aee0604cb4ff6ca0775cd5c2cd68cd8000e107e507c4caf6c228941231041e282ffb8950
)
+__reportIfWrongStatus("${status}" 0)
message(STATUS "FileDownload:8")
file(DOWNLOAD
${url}
${dir}/file3.png
- TIMEOUT 2
+ TIMEOUT ${timeout}
STATUS status
EXPECTED_HASH SHA512=6984e0909a1018030ccaa418e3be1654223cdccff0fe6adc745f9aea7e377f178be53b9fc7d54a6f81c2b62ef9ddcd38ba1978fedf4c5e7139baaf355eefad5b
)
+__reportIfWrongStatus("${status}" 0)
+
message(STATUS "FileDownload:9")
file(DOWNLOAD
${url}
${dir}/file3.png
- TIMEOUT 2
+ TIMEOUT ${timeout}
STATUS status
EXPECTED_HASH MD5=dbd330d52f4dbd60115d4191904ded92
)
+__reportIfWrongStatus("${status}" 0)
message(STATUS "FileDownload:10")
file(DOWNLOAD
${url}
${dir}/file3.png
- TIMEOUT 2
+ TIMEOUT ${timeout}
STATUS status
EXPECTED_MD5 dbd330d52f4dbd60115d4191904ded92
)
+__reportIfWrongStatus("${status}" 0)
+# Print status because we check its message too
message(STATUS "${status}")
message(STATUS "FileDownload:11")
file(DOWNLOAD
- badhostname.png
+ badhostname.invalid
${dir}/file11.png
- TIMEOUT 2
+ TIMEOUT 30
STATUS status
)
message(STATUS "${status}")
-list(GET status 0 status_code)
-if(NOT ${status_code} EQUAL 6)
- message(SEND_ERROR "error: expected status code 6 for bad host name, got: ${status_code}")
+__reportIfWrongStatus("${status}" 6) # 6 corresponds to an unresolvable host name
+
+message(STATUS "FileDownload:12")
+set(absFile "@CMAKE_CURRENT_BINARY_DIR@/file12.png")
+if(EXISTS "${absFile}")
+ file(RENAME ${absFile} "${absFile}_beingRemoved")
+ file(REMOVE "${absFile}_beingRemoved")
+endif()
+file(DOWNLOAD
+ ${url}
+ file12.png
+ TIMEOUT ${timeout}
+ EXPECTED_MD5 dbd330d52f4dbd60115d4191904ded92
+ STATUS status
+ )
+__reportIfWrongStatus("${status}" 0)
+if(NOT EXISTS file12.png)
+ message(SEND_ERROR "file12.png not downloaded: ${status}")
endif()
diff --git a/Tests/CMakeTests/FileTestScript.cmake b/Tests/CMakeTests/FileTestScript.cmake
index 9a43569..145f28a 100644
--- a/Tests/CMakeTests/FileTestScript.cmake
+++ b/Tests/CMakeTests/FileTestScript.cmake
@@ -183,7 +183,7 @@ elseif(testname STREQUAL to_native_path) # pass
elseif(testname STREQUAL download_wrong_number_of_args) # fail
file(DOWNLOAD zzzz://bogus/ffff)
-elseif(testname STREQUAL download_file_with_no_path) # fail
+elseif(testname STREQUAL download_file_with_no_path) # pass
file(DOWNLOAD zzzz://bogus/ffff ffff)
elseif(testname STREQUAL download_missing_time) # fail
diff --git a/Tests/CMakeTests/ListTest.cmake.in b/Tests/CMakeTests/ListTest.cmake.in
index f517e64..785f41d 100644
--- a/Tests/CMakeTests/ListTest.cmake.in
+++ b/Tests/CMakeTests/ListTest.cmake.in
@@ -85,6 +85,9 @@ set(result ken bill andy brad)
list(SORT result)
TEST("SORT result" "andy;bill;brad;ken")
+list(SORT result COMPARE NATURAL)
+TEST("SORT result COMPARE NATURAL" "andy;bill;brad;ken")
+
set(result andy bill brad ken)
list(REVERSE result)
TEST("REVERSE result" "ken;brad;bill;andy")
@@ -104,6 +107,26 @@ TEST("REVERSE empty result" "")
list(SORT result)
TEST("SORT empty result" "")
+list(SORT result COMPARE NATURAL)
+TEST("SORT result COMPARE NATURAL" "")
+
+set(result 1.1 10.0 11.0 12.0 12.1 2.0 2.1 3.0 3.1 3.2 8.0 9.0)
+
+list(SORT result COMPARE NATURAL)
+TEST("SORT result COMPARE NATURAL" "1.1;2.0;2.1;3.0;3.1;3.2;8.0;9.0;10.0;11.0;12.0;12.1")
+
+list(SORT result)
+TEST("SORT result" "1.1;10.0;11.0;12.0;12.1;2.0;2.1;3.0;3.1;3.2;8.0;9.0")
+
+list(SORT result COMPARE NATURAL ORDER DESCENDING)
+TEST("SORT result COMPARE NATURAL ORDER DESCENDING" "12.1;12.0;11.0;10.0;9.0;8.0;3.2;3.1;3.0;2.1;2.0;1.1")
+
+set(result b-1.1 a-10.0 c-2.0 d 1 00 0)
+
+list(SORT result COMPARE NATURAL)
+TEST("SORT result COMPARE NATURAL" "00;0;1;a-10.0;b-1.1;c-2.0;d")
+
+
# these trigger top-level condition
foreach(cmd IN ITEMS Append Find Get Insert Length Reverse Remove_At Remove_Duplicates Remove_Item Sort)
set(${cmd}-No-Arguments-RESULT 1)
diff --git a/Tests/CPackComponentsDEB/CMakeLists.txt b/Tests/CPackComponentsDEB/CMakeLists.txt
index bc5b6a9..4363f1b 100644
--- a/Tests/CPackComponentsDEB/CMakeLists.txt
+++ b/Tests/CPackComponentsDEB/CMakeLists.txt
@@ -104,7 +104,7 @@ install(FILES ${CPackComponentsDEB_BINARY_DIR}/symtest
COMPONENT applications)
if(EXISTS "./dirtest")
- execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory ./dirtest)
+ execute_process(COMMAND ${CMAKE_COMMAND} -E rm -rf ./dirtest)
endif()
# NOTE: directory left empty on purpose
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ./dirtest)
diff --git a/Tests/CPackComponentsDEB/RunCPackVerifyResult.cmake b/Tests/CPackComponentsDEB/RunCPackVerifyResult.cmake
index b172da2..3bc8d2a 100644
--- a/Tests/CPackComponentsDEB/RunCPackVerifyResult.cmake
+++ b/Tests/CPackComponentsDEB/RunCPackVerifyResult.cmake
@@ -45,7 +45,7 @@ function(run_cpack output_expected_file CPack_output_parent CPack_error_parent)
message("config_args = ${run_cpack_deb_CONFIG_ARGS}")
message("config_verbose = ${run_cpack_deb_CONFIG_VERBOSE}")
- execute_process(COMMAND ${CMAKE_CPACK_COMMAND} ${run_cpack_deb_CONFIG_VERBOSE} -G ${CPackGen} ${run_cpack_deb_CONFIG_ARGS}
+ execute_process(COMMAND ${CMAKE_CPACK_COMMAND} ${run_cpack_deb_CONFIG_VERBOSE} -G ${CPackGen} -C "${CONFIG}" ${run_cpack_deb_CONFIG_ARGS}
RESULT_VARIABLE CPack_result
OUTPUT_VARIABLE CPack_output
ERROR_VARIABLE CPack_error
diff --git a/Tests/CPackNSISGenerator/CMakeLists.txt b/Tests/CPackNSISGenerator/CMakeLists.txt
new file mode 100644
index 0000000..8ed4d59
--- /dev/null
+++ b/Tests/CPackNSISGenerator/CMakeLists.txt
@@ -0,0 +1,21 @@
+cmake_minimum_required(VERSION 3.16)
+
+project(CPackNSISGenerator)
+
+add_executable(hello main.cpp)
+
+install(TARGETS hello
+ ARCHIVE DESTINATION .
+ RUNTIME DESTINATION .
+ LIBRARY DESTINATION .
+ BUNDLE DESTINATION .)
+
+set(CPACK_NSIS_MUI_HEADERIMAGE "${PROJECT_SOURCE_DIR}\\\\header-image.bmp")
+set(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}\\\\header-icon.bmp")
+set(CPACK_NSIS_MUI_ICON "${PROJECT_SOURCE_DIR}\\\\install.ico")
+set(CPACK_NSIS_MUI_UNIICON "${PROJECT_SOURCE_DIR}\\\\uninstall.ico")
+set(CPACK_GENERATOR "NSIS")
+set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON)
+set(CPACK_NSIS_MANIFEST_DPI_AWARE ON)
+
+include(CPack)
diff --git a/Tests/CPackNSISGenerator/RunCPackVerifyResult.cmake b/Tests/CPackNSISGenerator/RunCPackVerifyResult.cmake
new file mode 100644
index 0000000..bfbcf9c
--- /dev/null
+++ b/Tests/CPackNSISGenerator/RunCPackVerifyResult.cmake
@@ -0,0 +1,54 @@
+message(STATUS "=============================================================")
+message(STATUS "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)")
+message(STATUS "")
+
+if(NOT CPackNSISGenerator_BINARY_DIR)
+ message(FATAL_ERROR "CPackNSISGenerator_BINARY_DIR not set")
+endif()
+
+message(STATUS "CMAKE_COMMAND: ${CMAKE_COMMAND}")
+message(STATUS "CMAKE_CPACK_COMMAND: ${CMAKE_CPACK_COMMAND}")
+message(STATUS "CPackNSISGenerator_BINARY_DIR: ${CPackNSISGenerator_BINARY_DIR}")
+
+if(config)
+ set(_C_config -C ${config})
+endif()
+
+execute_process(COMMAND "${CMAKE_CPACK_COMMAND}"
+ ${_C_config}
+ RESULT_VARIABLE CPack_result
+ OUTPUT_VARIABLE CPack_output
+ ERROR_VARIABLE CPack_error
+ WORKING_DIRECTORY "${CPackNSISGenerator_BINARY_DIR}")
+
+if(CPack_result)
+ message(FATAL_ERROR "CPack execution went wrong!, CPack_output=${CPack_output}, CPack_error=${CPack_error}")
+else ()
+ message(STATUS "CPack_output=${CPack_output}")
+endif()
+
+set(expected_file_mask "${CPackNSISGenerator_BINARY_DIR}/_CPack_Packages/*/NSIS/*.nsi")
+file(GLOB project_file "${expected_file_mask}")
+
+message(STATUS "project_file='${project_file}'")
+message(STATUS "expected_file_mask='${expected_file_mask}'")
+
+if(NOT project_file)
+ message(FATAL_ERROR "project_file does not exist.")
+endif()
+
+# should match !define MUI_HEADERIMAGE_BITMAP "${PROJECT_SOURCE_DIR}\header-image.bmp"
+file(STRINGS "${project_file}" line REGEX "^!define MUI_HEADERIMAGE_BITMAP")
+string(FIND "${line}" "header-image.bmp" output_index)
+message(STATUS "Found the bitmap at index ${output_index}")
+if("${output_index}" EQUAL "-1")
+ message(FATAL_ERROR "MUI_HEADERIMAGE_BITMAP not found in the project")
+endif()
+
+file(STRINGS "${project_file}" line REGEX "^ManifestDPIAware true")
+string(FIND "${line}" "true" output_index)
+if("${output_index}" EQUAL "-1")
+ message(FATAL_ERROR "ManifestDPIAware true not found in the project")
+else()
+ message(STATUS "Found DPI-aware")
+endif()
diff --git a/Tests/CPackNSISGenerator/header-icon.bmp b/Tests/CPackNSISGenerator/header-icon.bmp
new file mode 100644
index 0000000..ef6a656
--- /dev/null
+++ b/Tests/CPackNSISGenerator/header-icon.bmp
Binary files differ
diff --git a/Tests/CPackNSISGenerator/header-image.bmp b/Tests/CPackNSISGenerator/header-image.bmp
new file mode 100644
index 0000000..15b1730
--- /dev/null
+++ b/Tests/CPackNSISGenerator/header-image.bmp
Binary files differ
diff --git a/Tests/CPackNSISGenerator/install.ico b/Tests/CPackNSISGenerator/install.ico
new file mode 100644
index 0000000..3b1e480
--- /dev/null
+++ b/Tests/CPackNSISGenerator/install.ico
Binary files differ
diff --git a/Tests/CPackNSISGenerator/main.cpp b/Tests/CPackNSISGenerator/main.cpp
new file mode 100644
index 0000000..956f345
--- /dev/null
+++ b/Tests/CPackNSISGenerator/main.cpp
@@ -0,0 +1,4 @@
+int main()
+{
+ return 42;
+}
diff --git a/Tests/CPackNSISGenerator/uninstall.ico b/Tests/CPackNSISGenerator/uninstall.ico
new file mode 100644
index 0000000..c4f6316
--- /dev/null
+++ b/Tests/CPackNSISGenerator/uninstall.ico
Binary files differ
diff --git a/Tests/CPackWiXGenerator/myotherapp.cpp b/Tests/CPackWiXGenerator/myotherapp.cpp
index 0eefc1c..5047a34 100644
--- a/Tests/CPackWiXGenerator/myotherapp.cpp
+++ b/Tests/CPackWiXGenerator/myotherapp.cpp
@@ -1,3 +1,3 @@
int main()
{
-} \ No newline at end of file
+}
diff --git a/Tests/CSharpOnly/CMakeLists.txt b/Tests/CSharpOnly/CMakeLists.txt
index 82049c7..42cbe2e 100644
--- a/Tests/CSharpOnly/CMakeLists.txt
+++ b/Tests/CSharpOnly/CMakeLists.txt
@@ -2,7 +2,9 @@
project (CSharpOnly CSharp)
# C# does not make any difference between STATIC and SHARED libs
-add_library(lib1 STATIC lib1.cs)
+add_library(lib1 STATIC lib1.cs nested/lib1.cs)
+#without the source group this test will fail to compile
+source_group(nested FILES nested/lib1.cs)
add_library(lib2 SHARED lib2.cs)
add_executable(CSharpOnly csharponly.cs)
diff --git a/Tests/CSharpOnly/csharponly.cs b/Tests/CSharpOnly/csharponly.cs
index ad4641a..3890c82 100644
--- a/Tests/CSharpOnly/csharponly.cs
+++ b/Tests/CSharpOnly/csharponly.cs
@@ -5,10 +5,8 @@ namespace CSharpOnly
public static void Main(string[] args)
{
int val = Lib1.getResult();
-
Lib2 l = new Lib2();
- val = l.myVal;
-
+ val = val + l.myVal + nested.Lib1.getResult();
return;
}
}
diff --git a/Tests/CSharpOnly/nested/lib1.cs b/Tests/CSharpOnly/nested/lib1.cs
new file mode 100644
index 0000000..c2fde4b
--- /dev/null
+++ b/Tests/CSharpOnly/nested/lib1.cs
@@ -0,0 +1,13 @@
+namespace CSharpOnly
+{
+ namespace nested
+ {
+ public class Lib1
+ {
+ public static int getResult()
+ {
+ return 23;
+ }
+ }
+ }
+}
diff --git a/Tests/CTestConfig/dashboard.cmake.in b/Tests/CTestConfig/dashboard.cmake.in
index 4bb1262..34824e3 100644
--- a/Tests/CTestConfig/dashboard.cmake.in
+++ b/Tests/CTestConfig/dashboard.cmake.in
@@ -13,6 +13,8 @@ message("CMAKE_CTEST_COMMAND='${CMAKE_CTEST_COMMAND}'")
set(arg "")
if(NOT _isMultiConfig)
set(arg "-DCMAKE_BUILD_TYPE:STRING=@cfg@")
+else()
+ set(arg "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release\\;MinSizeRel\\;RelWithDebInfo")
endif()
message("cmake initial configure")
diff --git a/Tests/CTestConfig/script.cmake.in b/Tests/CTestConfig/script.cmake.in
index 973c7b8..59c585b 100644
--- a/Tests/CTestConfig/script.cmake.in
+++ b/Tests/CTestConfig/script.cmake.in
@@ -6,7 +6,14 @@ set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestConfig/@cfg@-script")
ctest_start(Experimental)
-ctest_configure(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE rv)
+set(_isMultiConfig "@_isMultiConfig@")
+if(_isMultiConfig)
+ set(cfg_opts "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release\\;MinSizeRel\\;RelWithDebInfo")
+else()
+ set(cfg_opts)
+endif()
+
+ctest_configure(BUILD "${CTEST_BINARY_DIRECTORY}" OPTIONS "${cfg_opts}" RETURN_VALUE rv)
if(NOT rv STREQUAL 0)
message(FATAL_ERROR "*** error in ctest_configure ***")
endif()
diff --git a/Tests/CTestCoverageCollectGCOV/test.cmake.in b/Tests/CTestCoverageCollectGCOV/test.cmake.in
index 2c98876..1818888 100644
--- a/Tests/CTestCoverageCollectGCOV/test.cmake.in
+++ b/Tests/CTestCoverageCollectGCOV/test.cmake.in
@@ -3,13 +3,15 @@ set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestCoverageCollectGCOV/Te
set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestCoverageCollectGCOV/TestProject")
set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")
-ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY})
-
ctest_start(Experimental)
ctest_configure()
ctest_build()
ctest_test()
+#------------------------------------------------------------------------------#
+# Common setup for all tests.
+#------------------------------------------------------------------------------#
+
list(APPEND CTEST_CUSTOM_COVERAGE_EXCLUDE
"/foo/something"
"/3rdparty/"
@@ -17,15 +19,118 @@ list(APPEND CTEST_CUSTOM_COVERAGE_EXCLUDE
"/CMakeFiles/"
)
list(APPEND CTEST_EXTRA_COVERAGE_GLOB "*.cpp")
-
include(CTestCoverageCollectGCOV)
+set(expected_out
+ CMakeFiles/myexecutable.dir/Labels.json
+ Testing/CoverageInfo/data.json
+ Testing/CoverageInfo/extra.cpp.gcov
+ Testing/CoverageInfo/main.cpp.gcov
+ uncovered/extra/uncovered1.cpp
+ uncovered/uncovered2.cpp
+)
+
+#------------------------------------------------------------------------------#
+# Test 1: with standard arguments
+#------------------------------------------------------------------------------#
+
+set(tar_file ${CTEST_BINARY_DIRECTORY}/gcov.tbz)
+ctest_coverage_collect_gcov(
+ TARBALL "${tar_file}"
+ SOURCE "${CTEST_SOURCE_DIRECTORY}"
+ BUILD "${CTEST_BINARY_DIRECTORY}"
+ GCOV_COMMAND "${CMAKE_COMMAND}"
+ GCOV_OPTIONS -P "@CMake_SOURCE_DIR@/Tests/CTestCoverageCollectGCOV/fakegcov.cmake")
+file(REMOVE_RECURSE "${CTEST_BINARY_DIRECTORY}/uncovered")
+
+execute_process(COMMAND
+ ${CMAKE_COMMAND} -E tar tf ${tar_file}
+ OUTPUT_VARIABLE out
+ WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+
+string(REPLACE "\n" ";" out "${out}")
+list(SORT out)
+
+if("${out}" STREQUAL "${expected_out}")
+ message("PASSED with correct output: ${out}")
+else()
+ message(FATAL_ERROR "FAILED: expected:\n${expected_out}\nGot:\n${out}")
+endif()
+
+#------------------------------------------------------------------------------#
+# Test 2: with optional argument: TARBALL_COMPRESSION "GZIP"
+#------------------------------------------------------------------------------#
+
+set(tar_file ${CTEST_BINARY_DIRECTORY}/gcov.tgz)
+ctest_coverage_collect_gcov(
+ TARBALL "${tar_file}"
+ TARBALL_COMPRESSION "GZIP"
+ SOURCE "${CTEST_SOURCE_DIRECTORY}"
+ BUILD "${CTEST_BINARY_DIRECTORY}"
+ GCOV_COMMAND "${CMAKE_COMMAND}"
+ GCOV_OPTIONS -P "@CMake_SOURCE_DIR@/Tests/CTestCoverageCollectGCOV/fakegcov.cmake")
+file(REMOVE_RECURSE "${CTEST_BINARY_DIRECTORY}/uncovered")
+
+execute_process(COMMAND
+ ${CMAKE_COMMAND} -E tar tf ${tar_file}
+ OUTPUT_VARIABLE out
+ WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+
+string(REPLACE "\n" ";" out "${out}")
+list(SORT out)
+
+if("${out}" STREQUAL "${expected_out}")
+ message("PASSED with correct output: ${out}")
+else()
+ message(FATAL_ERROR "FAILED: expected:\n${expected_out}\nGot:\n${out}")
+endif()
+
+#------------------------------------------------------------------------------#
+# Test 3: with optional argument: TARBALL_COMPRESSION "FROM_EXT"
+#------------------------------------------------------------------------------#
+
+set(tar_file ${CTEST_BINARY_DIRECTORY}/gcov.txz)
+ctest_coverage_collect_gcov(
+ TARBALL "${tar_file}"
+ TARBALL_COMPRESSION "FROM_EXT"
+ SOURCE "${CTEST_SOURCE_DIRECTORY}"
+ BUILD "${CTEST_BINARY_DIRECTORY}"
+ GCOV_COMMAND "${CMAKE_COMMAND}"
+ GCOV_OPTIONS -P "@CMake_SOURCE_DIR@/Tests/CTestCoverageCollectGCOV/fakegcov.cmake")
+file(REMOVE_RECURSE "${CTEST_BINARY_DIRECTORY}/uncovered")
+
+execute_process(COMMAND
+ ${CMAKE_COMMAND} -E tar tf ${tar_file}
+ OUTPUT_VARIABLE out
+ WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+
+string(REPLACE "\n" ";" out "${out}")
+list(SORT out)
+
+if("${out}" STREQUAL "${expected_out}")
+ message("PASSED with correct output: ${out}")
+else()
+ message(FATAL_ERROR "FAILED: expected:\n${expected_out}\nGot:\n${out}")
+endif()
+
+#------------------------------------------------------------------------------#
+# Test 4: with optional argument: TARBALL_COMPRESSION "FALSE"
+#------------------------------------------------------------------------------#
+
set(tar_file ${CTEST_BINARY_DIRECTORY}/gcov.tar)
ctest_coverage_collect_gcov(
TARBALL "${tar_file}"
+ TARBALL_COMPRESSION "FALSE"
SOURCE "${CTEST_SOURCE_DIRECTORY}"
BUILD "${CTEST_BINARY_DIRECTORY}"
GCOV_COMMAND "${CMAKE_COMMAND}"
GCOV_OPTIONS -P "@CMake_SOURCE_DIR@/Tests/CTestCoverageCollectGCOV/fakegcov.cmake")
+file(REMOVE_RECURSE "${CTEST_BINARY_DIRECTORY}/uncovered")
execute_process(COMMAND
${CMAKE_COMMAND} -E tar tf ${tar_file}
@@ -37,15 +142,36 @@ execute_process(COMMAND
string(REPLACE "\n" ";" out "${out}")
list(SORT out)
-set(expected_out
- CMakeFiles/myexecutable.dir/Labels.json
- Testing/CoverageInfo/data.json
- Testing/CoverageInfo/extra.cpp.gcov
- Testing/CoverageInfo/main.cpp.gcov
- uncovered/extra/uncovered1.cpp
- uncovered/uncovered2.cpp
+if("${out}" STREQUAL "${expected_out}")
+ message("PASSED with correct output: ${out}")
+else()
+ message(FATAL_ERROR "FAILED: expected:\n${expected_out}\nGot:\n${out}")
+endif()
+
+#------------------------------------------------------------------------------#
+# Test 5: with optional argument: TARBALL_COMPRESSION "ZSTD"
+#------------------------------------------------------------------------------#
+
+set(tar_file ${CTEST_BINARY_DIRECTORY}/gcov.zstd)
+ctest_coverage_collect_gcov(
+ TARBALL "${tar_file}"
+ TARBALL_COMPRESSION "ZSTD"
+ SOURCE "${CTEST_SOURCE_DIRECTORY}"
+ BUILD "${CTEST_BINARY_DIRECTORY}"
+ GCOV_COMMAND "${CMAKE_COMMAND}"
+ GCOV_OPTIONS -P "@CMake_SOURCE_DIR@/Tests/CTestCoverageCollectGCOV/fakegcov.cmake")
+file(REMOVE_RECURSE "${CTEST_BINARY_DIRECTORY}/uncovered")
+
+execute_process(COMMAND
+ ${CMAKE_COMMAND} -E tar tf ${tar_file}
+ OUTPUT_VARIABLE out
+ WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
+ OUTPUT_STRIP_TRAILING_WHITESPACE
)
+string(REPLACE "\n" ";" out "${out}")
+list(SORT out)
+
if("${out}" STREQUAL "${expected_out}")
message("PASSED with correct output: ${out}")
else()
diff --git a/Tests/Complex/CMakeLists.txt b/Tests/Complex/CMakeLists.txt
index 2e41754..9fd85be 100644
--- a/Tests/Complex/CMakeLists.txt
+++ b/Tests/Complex/CMakeLists.txt
@@ -324,7 +324,7 @@ if (WIN32)
${file}
"[${hkey}]" DOC "Registry_Test_Path")
exec_program(${CMAKE_COMMAND} ARGS "-E delete_regv \"${hkey}\"")
- exec_program(${CMAKE_COMMAND} ARGS "-E remove \"${dir}/${file}\"")
+ exec_program(${CMAKE_COMMAND} ARGS "-E rm -f \"${dir}/${file}\"")
endif ()
endif ()
diff --git a/Tests/Complex/Library/CMakeLists.txt b/Tests/Complex/Library/CMakeLists.txt
index 64f6dc8..df874ef 100644
--- a/Tests/Complex/Library/CMakeLists.txt
+++ b/Tests/Complex/Library/CMakeLists.txt
@@ -131,7 +131,7 @@ if("${CMAKE_GENERATOR}" MATCHES "Makefile" AND CMAKE_MAKE_PROGRAM)
# Custom target to try preprocessing invocation.
add_custom_target(test_preprocess ${MAYBE_ALL}
- COMMAND ${CMAKE_COMMAND} -E remove CMakeFiles/create_file.dir/create_file.i
+ COMMAND ${CMAKE_COMMAND} -E rm -f CMakeFiles/create_file.dir/create_file.i
COMMAND ${CMAKE_MAKE_PROGRAM} create_file.i
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/test_preprocess.cmake
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
diff --git a/Tests/ComplexOneConfig/CMakeLists.txt b/Tests/ComplexOneConfig/CMakeLists.txt
index 628cd4e..28b73af 100644
--- a/Tests/ComplexOneConfig/CMakeLists.txt
+++ b/Tests/ComplexOneConfig/CMakeLists.txt
@@ -281,7 +281,7 @@ if (WIN32)
${file}
"[${hkey}]" DOC "Registry_Test_Path")
exec_program(${CMAKE_COMMAND} ARGS "-E delete_regv \"${hkey}\"")
- exec_program(${CMAKE_COMMAND} ARGS "-E remove \"${dir}/${file}\"")
+ exec_program(${CMAKE_COMMAND} ARGS "-E rm -f \"${dir}/${file}\"")
endif ()
endif ()
diff --git a/Tests/ComplexOneConfig/Library/CMakeLists.txt b/Tests/ComplexOneConfig/Library/CMakeLists.txt
index 64f6dc8..df874ef 100644
--- a/Tests/ComplexOneConfig/Library/CMakeLists.txt
+++ b/Tests/ComplexOneConfig/Library/CMakeLists.txt
@@ -131,7 +131,7 @@ if("${CMAKE_GENERATOR}" MATCHES "Makefile" AND CMAKE_MAKE_PROGRAM)
# Custom target to try preprocessing invocation.
add_custom_target(test_preprocess ${MAYBE_ALL}
- COMMAND ${CMAKE_COMMAND} -E remove CMakeFiles/create_file.dir/create_file.i
+ COMMAND ${CMAKE_COMMAND} -E rm -f CMakeFiles/create_file.dir/create_file.i
COMMAND ${CMAKE_MAKE_PROGRAM} create_file.i
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/test_preprocess.cmake
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
diff --git a/Tests/ConfigSources/CMakeLists.txt b/Tests/ConfigSources/CMakeLists.txt
index f5dd276..21f923e 100644
--- a/Tests/ConfigSources/CMakeLists.txt
+++ b/Tests/ConfigSources/CMakeLists.txt
@@ -1,6 +1,7 @@
cmake_minimum_required(VERSION 3.0)
project(ConfigSources CXX)
+# Per-config sources via INTERFACE_SOURCES.
add_library(iface INTERFACE)
target_sources(iface INTERFACE
"${CMAKE_CURRENT_SOURCE_DIR}/iface_src.cpp"
@@ -12,10 +13,45 @@ target_compile_definitions(iface INTERFACE
"$<$<CONFIG:Debug>:CFG_DEBUG>"
"$<$<NOT:$<CONFIG:Debug>>:CFG_OTHER>"
)
-
add_executable(ConfigSources
$<$<CONFIG:Debug>:main_debug.cpp>
$<$<NOT:$<CONFIG:Debug>>:main_other.cpp>
$<$<CONFIG:NotAConfig>:does_not_exist.cpp>
)
target_link_libraries(ConfigSources iface)
+
+# Per-config sources via LINK_LIBRARIES.
+add_library(iface_debug INTERFACE)
+target_sources(iface_debug INTERFACE
+ "${CMAKE_CURRENT_SOURCE_DIR}/iface_src.cpp"
+ "${CMAKE_CURRENT_SOURCE_DIR}/iface_debug_src.cpp"
+ )
+add_library(iface_other INTERFACE)
+target_sources(iface_other INTERFACE
+ "${CMAKE_CURRENT_SOURCE_DIR}/iface_src.cpp"
+ "${CMAKE_CURRENT_SOURCE_DIR}/iface_other_src.cpp"
+ )
+add_executable(ConfigSourcesLink main.cpp)
+target_compile_definitions(ConfigSourcesLink PRIVATE
+ "$<$<CONFIG:Debug>:CFG_DEBUG>"
+ "$<$<NOT:$<CONFIG:Debug>>:CFG_OTHER>"
+ )
+target_link_libraries(ConfigSourcesLink PRIVATE
+ "$<$<CONFIG:Debug>:iface_debug>"
+ "$<$<NOT:$<CONFIG:Debug>>:iface_other>"
+ "$<$<CONFIG:NotAConfig>:iface_does_not_exist>"
+ )
+
+# Per-config sources via INTERFACE_LINK_LIBRARIES.
+add_library(ConfigSourcesIface INTERFACE)
+target_link_libraries(ConfigSourcesIface INTERFACE
+ "$<$<CONFIG:Debug>:iface_debug>"
+ "$<$<NOT:$<CONFIG:Debug>>:iface_other>"
+ "$<$<CONFIG:NotAConfig>:iface_does_not_exist>"
+ )
+add_executable(ConfigSourcesLinkIface main.cpp)
+target_compile_definitions(ConfigSourcesLinkIface PRIVATE
+ "$<$<CONFIG:Debug>:CFG_DEBUG>"
+ "$<$<NOT:$<CONFIG:Debug>>:CFG_OTHER>"
+ )
+target_link_libraries(ConfigSourcesLinkIface ConfigSourcesIface)
diff --git a/Tests/ConfigSources/main.cpp b/Tests/ConfigSources/main.cpp
new file mode 100644
index 0000000..c1cd3b2
--- /dev/null
+++ b/Tests/ConfigSources/main.cpp
@@ -0,0 +1,9 @@
+#if !defined(CFG_DEBUG) && !defined(CFG_OTHER)
+# error "Neither CFG_DEBUG or CFG_OTHER is defined."
+#endif
+#ifdef CFG_DEBUG
+# include "main_debug.cpp"
+#endif
+#ifdef CFG_OTHER
+# include "main_other.cpp"
+#endif
diff --git a/Tests/Contracts/VTK/CMakeLists.txt b/Tests/Contracts/VTK/CMakeLists.txt
index c946499..6ae2732 100644
--- a/Tests/Contracts/VTK/CMakeLists.txt
+++ b/Tests/Contracts/VTK/CMakeLists.txt
@@ -21,7 +21,7 @@ configure_file(
# build & test VTK's release branch
ExternalProject_Add(${PROJECT_NAME}
- GIT_REPOSITORY "git://vtk.org/VTK.git"
+ GIT_REPOSITORY "https://gitlab.kitware.com/vtk/vtk.git"
GIT_TAG "release"
PREFIX ${base_dir}
CONFIGURE_COMMAND ""
diff --git a/Tests/Contracts/VTK/Dashboard.cmake.in b/Tests/Contracts/VTK/Dashboard.cmake.in
index c3d10f4..ae760bc 100644
--- a/Tests/Contracts/VTK/Dashboard.cmake.in
+++ b/Tests/Contracts/VTK/Dashboard.cmake.in
@@ -24,8 +24,8 @@ set(CTEST_BUILD_COMMAND "@CMAKE_MAKE_PROGRAM@ -j9 -i")
ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY})
file(WRITE "${CTEST_BINARY_DIRECTORY}/CMakeCache.txt" "
- BUILD_EXAMPLES:BOOL=ON
- BUILD_TESTING:BOOL=ON
+ VTK_BUILD_EXAMPLES:BOOL=ON
+ VTK_BUILD_TESTING:STRING=WANT
VTK_WRAP_PYTHON:BOOL=ON
ExternalData_OBJECT_STORES:FILEPATH=@base_dir@/ExternalData
")
diff --git a/Tests/Cuda/CMakeLists.txt b/Tests/Cuda/CMakeLists.txt
index 44c6005..58b9b03 100644
--- a/Tests/Cuda/CMakeLists.txt
+++ b/Tests/Cuda/CMakeLists.txt
@@ -1,11 +1,25 @@
ADD_TEST_MACRO(Cuda.Complex CudaComplex)
ADD_TEST_MACRO(Cuda.ConsumeCompileFeatures CudaConsumeCompileFeatures)
+ADD_TEST_MACRO(Cuda.CXXStandardSetTwice CXXStandardSetTwice)
ADD_TEST_MACRO(Cuda.ObjectLibrary CudaObjectLibrary)
-ADD_TEST_MACRO(Cuda.MixedStandardLevels MixedStandardLevels)
+ADD_TEST_MACRO(Cuda.MixedStandardLevels1 MixedStandardLevels1)
+ADD_TEST_MACRO(Cuda.MixedStandardLevels2 MixedStandardLevels2)
+ADD_TEST_MACRO(Cuda.MixedStandardLevels3 MixedStandardLevels3)
+ADD_TEST_MACRO(Cuda.MixedStandardLevels4 MixedStandardLevels4)
+ADD_TEST_MACRO(Cuda.MixedStandardLevels5 MixedStandardLevels5)
ADD_TEST_MACRO(Cuda.NotEnabled CudaNotEnabled)
ADD_TEST_MACRO(Cuda.SeparableCompCXXOnly SeparableCompCXXOnly)
-ADD_TEST_MACRO(Cuda.ToolkitInclude CudaToolkitInclude)
+ADD_TEST_MACRO(Cuda.Toolkit Toolkit)
+ADD_TEST_MACRO(Cuda.IncludePathNoToolkit IncludePathNoToolkit)
ADD_TEST_MACRO(Cuda.ProperDeviceLibraries ProperDeviceLibraries)
ADD_TEST_MACRO(Cuda.ProperLinkFlags ProperLinkFlags)
+ADD_TEST_MACRO(Cuda.SharedRuntimePlusToolkit SharedRuntimePlusToolkit)
+
+# The CUDA only ships the shared version of the toolkit libraries
+# on windows
+if(NOT WIN32)
+ ADD_TEST_MACRO(Cuda.StaticRuntimePlusToolkit StaticRuntimePlusToolkit)
+endif()
+
ADD_TEST_MACRO(Cuda.WithC CudaWithC)
diff --git a/Tests/Cuda/CXXStandardSetTwice/CMakeLists.txt b/Tests/Cuda/CXXStandardSetTwice/CMakeLists.txt
new file mode 100644
index 0000000..f4ad83a
--- /dev/null
+++ b/Tests/Cuda/CXXStandardSetTwice/CMakeLists.txt
@@ -0,0 +1,13 @@
+cmake_minimum_required(VERSION 3.7)
+project(CXXStandardSetTwice CXX CUDA)
+
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CUDA_ARCHITECTURES 30)
+
+add_executable(CXXStandardSetTwice main.cu)
+target_compile_features(CXXStandardSetTwice PUBLIC cxx_std_11)
+
+if(APPLE)
+ # Help the static cuda runtime find the driver (libcuda.dyllib) at runtime.
+ set_property(TARGET CXXStandardSetTwice PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES})
+endif()
diff --git a/Tests/Cuda/MixedStandardLevels/main.cu b/Tests/Cuda/CXXStandardSetTwice/main.cu
index d57c05a..d57c05a 100644
--- a/Tests/Cuda/MixedStandardLevels/main.cu
+++ b/Tests/Cuda/CXXStandardSetTwice/main.cu
diff --git a/Tests/Cuda/Complex/CMakeLists.txt b/Tests/Cuda/Complex/CMakeLists.txt
index d3d4b7c..265bd85 100644
--- a/Tests/Cuda/Complex/CMakeLists.txt
+++ b/Tests/Cuda/Complex/CMakeLists.txt
@@ -15,25 +15,18 @@ project (Complex CXX CUDA)
#and also building cpp targets that need cuda implicit libraries
#verify that we can pass explicit cuda arch flags
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30")
+set(CMAKE_CUDA_ARCHITECTURES 30)
set(CMAKE_CUDA_STANDARD 11)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CUDA_STANDARD_REQUIRED TRUE)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
add_library(CudaComplexCppBase SHARED dynamic.cpp)
-add_library(CudaComplexSeperableLib STATIC file1.cu file2.cu file3.cu)
-set_target_properties(CudaComplexSeperableLib
- PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
-set_target_properties( CudaComplexSeperableLib
- PROPERTIES POSITION_INDEPENDENT_CODE ON)
-
add_library(CudaComplexSharedLib SHARED dynamic.cu)
target_link_libraries(CudaComplexSharedLib PUBLIC CudaComplexCppBase)
+add_library(CudaComplexSeperableLib STATIC file1.cu file2.cu file3.cu)
add_library(CudaComplexMixedLib SHARED mixed.cpp mixed.cu)
-set_target_properties(CudaComplexMixedLib
- PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
target_link_libraries(CudaComplexMixedLib
PUBLIC CudaComplexSharedLib
PRIVATE CudaComplexSeperableLib)
@@ -41,7 +34,27 @@ target_link_libraries(CudaComplexMixedLib
add_executable(CudaComplex main.cpp)
target_link_libraries(CudaComplex PUBLIC CudaComplexMixedLib)
+
+set_target_properties(CudaComplexMixedLib
+ CudaComplexSeperableLib
+ PROPERTIES
+ POSITION_INDEPENDENT_CODE ON
+ CUDA_SEPARABLE_COMPILATION ON
+ )
+set_target_properties(CudaComplexMixedLib
+ CudaComplexSharedLib
+ PROPERTIES
+ CUDA_RUNTIME_LIBRARY shared
+ )
+
+
if(APPLE)
# Help the static cuda runtime find the driver (libcuda.dyllib) at runtime.
set_property(TARGET CudaComplex PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES})
endif()
+
+if(UNIX)
+ # Help the shared cuda runtime find libcudart as it is not located
+ # in a default system searched location
+ set_property(TARGET CudaComplexMixedLib PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES})
+endif()
diff --git a/Tests/Cuda/Complex/dynamic.cu b/Tests/Cuda/Complex/dynamic.cu
index 9da8853..7f2f2b5 100644
--- a/Tests/Cuda/Complex/dynamic.cu
+++ b/Tests/Cuda/Complex/dynamic.cu
@@ -54,17 +54,20 @@ EXPORT int choose_cuda_device()
return 1;
}
-EXPORT void cuda_dynamic_lib_func()
+EXPORT bool cuda_dynamic_lib_func()
{
- DetermineIfValidCudaDevice<<<1, 1>>>();
cudaError_t err = cudaGetLastError();
if (err != cudaSuccess) {
- std::cerr << "DetermineIfValidCudaDevice [SYNC] failed: "
+ std::cerr << "DetermineIfValidCudaDevice [Per Launch] failed: "
<< cudaGetErrorString(err) << std::endl;
+ return false;
}
+ DetermineIfValidCudaDevice<<<1, 1>>>();
err = cudaDeviceSynchronize();
if (err != cudaSuccess) {
- std::cerr << "DetermineIfValidCudaDevice [ASYNC] failed: "
+ std::cerr << "DetermineIfValidCudaDevice [SYNC] failed: "
<< cudaGetErrorString(cudaGetLastError()) << std::endl;
+ return false;
}
+ return true;
}
diff --git a/Tests/Cuda/Complex/main.cpp b/Tests/Cuda/Complex/main.cpp
index 6ca5952..da09b44 100644
--- a/Tests/Cuda/Complex/main.cpp
+++ b/Tests/Cuda/Complex/main.cpp
@@ -22,5 +22,6 @@ int main(int argc, char** argv)
int r1 = call_cuda_seperable_code(42);
int r2 = mixed_launch_kernel(42);
+
return (r1 == 42 || r2 == 42) ? 1 : 0;
}
diff --git a/Tests/Cuda/Complex/mixed.cu b/Tests/Cuda/Complex/mixed.cu
index 5b85aec..76119ad 100644
--- a/Tests/Cuda/Complex/mixed.cu
+++ b/Tests/Cuda/Complex/mixed.cu
@@ -15,7 +15,7 @@
result_type __device__ file1_func(int x);
result_type_dynamic __device__ file2_func(int x);
-IMPORT void __host__ cuda_dynamic_lib_func();
+IMPORT bool __host__ cuda_dynamic_lib_func();
static __global__ void mixed_kernel(result_type* r, int x)
{
@@ -25,7 +25,9 @@ static __global__ void mixed_kernel(result_type* r, int x)
EXPORT int mixed_launch_kernel(int x)
{
- cuda_dynamic_lib_func();
+ if (!cuda_dynamic_lib_func()) {
+ return x;
+ }
result_type* r;
cudaError_t err = cudaMallocManaged(&r, sizeof(result_type));
diff --git a/Tests/Cuda/ToolkitInclude/CMakeLists.txt b/Tests/Cuda/IncludePathNoToolkit/CMakeLists.txt
index f246b54..7be1561 100644
--- a/Tests/Cuda/ToolkitInclude/CMakeLists.txt
+++ b/Tests/Cuda/IncludePathNoToolkit/CMakeLists.txt
@@ -1,11 +1,11 @@
cmake_minimum_required(VERSION 3.8)
-project (ToolkitInclude CXX CUDA)
+project (IncludePathNoToolkit CXX CUDA)
#Goal for this example:
# Validate that between the CXX implicit include directories and the
# CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES directories we can find
# the cuda runtime headers
-add_executable(CudaToolkitInclude main.cpp)
-target_include_directories(CudaToolkitInclude PRIVATE
+add_executable(IncludePathNoToolkit main.cpp)
+target_include_directories(IncludePathNoToolkit PRIVATE
${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES})
diff --git a/Tests/Cuda/ToolkitInclude/main.cpp b/Tests/Cuda/IncludePathNoToolkit/main.cpp
index c8d5c6b..c8d5c6b 100644
--- a/Tests/Cuda/ToolkitInclude/main.cpp
+++ b/Tests/Cuda/IncludePathNoToolkit/main.cpp
diff --git a/Tests/Cuda/MixedStandardLevels/CMakeLists.txt b/Tests/Cuda/MixedStandardLevels/CMakeLists.txt
deleted file mode 100644
index b399662..0000000
--- a/Tests/Cuda/MixedStandardLevels/CMakeLists.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-cmake_minimum_required(VERSION 3.7)
-project(MixedStandardLevels CXX CUDA)
-
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30")
-
-set(CMAKE_CXX_STANDARD 11)
-
-add_executable(MixedStandardLevels main.cu)
-target_compile_features(MixedStandardLevels PUBLIC cxx_std_11)
-
-if(APPLE)
- # Help the static cuda runtime find the driver (libcuda.dyllib) at runtime.
- set_property(TARGET MixedStandardLevels PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES})
-endif()
diff --git a/Tests/Cuda/MixedStandardLevels1/CMakeLists.txt b/Tests/Cuda/MixedStandardLevels1/CMakeLists.txt
new file mode 100644
index 0000000..e40ffa6
--- /dev/null
+++ b/Tests/Cuda/MixedStandardLevels1/CMakeLists.txt
@@ -0,0 +1,13 @@
+cmake_minimum_required(VERSION 3.7)
+project(MixedStandardLevels1 CXX CUDA)
+
+set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CUDA_STANDARD 11)
+set(CMAKE_CUDA_ARCHITECTURES 30)
+
+add_executable(MixedStandardLevels1 main.cu lib.cpp)
+
+if(APPLE)
+ # Help the static cuda runtime find the driver (libcuda.dyllib) at runtime.
+ set_property(TARGET MixedStandardLevels1 PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES})
+endif()
diff --git a/Tests/Cuda/MixedStandardLevels1/lib.cpp b/Tests/Cuda/MixedStandardLevels1/lib.cpp
new file mode 100644
index 0000000..cabbacb
--- /dev/null
+++ b/Tests/Cuda/MixedStandardLevels1/lib.cpp
@@ -0,0 +1,7 @@
+
+int func(int A, int B)
+{
+ // Verify that we have at least c++14
+ auto mult_func = [](auto a, auto b) { return a * b; };
+ return mult_func(A, B);
+}
diff --git a/Tests/Cuda/MixedStandardLevels1/main.cu b/Tests/Cuda/MixedStandardLevels1/main.cu
new file mode 100644
index 0000000..bc02c6d
--- /dev/null
+++ b/Tests/Cuda/MixedStandardLevels1/main.cu
@@ -0,0 +1,9 @@
+
+#include <type_traits>
+
+int main(int argc, char** argv)
+{
+ // Verify that we have at least c++11
+ using returnv = std::integral_constant<int, 0>;
+ return returnv::value;
+}
diff --git a/Tests/Cuda/MixedStandardLevels2/CMakeLists.txt b/Tests/Cuda/MixedStandardLevels2/CMakeLists.txt
new file mode 100644
index 0000000..7af8081
--- /dev/null
+++ b/Tests/Cuda/MixedStandardLevels2/CMakeLists.txt
@@ -0,0 +1,13 @@
+cmake_minimum_required(VERSION 3.7)
+project(MixedStandardLevels2 CXX CUDA)
+
+set(CMAKE_CXX_STANDARD 17) #this can decay
+set(CMAKE_CUDA_ARCHITECTURES 30)
+
+add_executable(MixedStandardLevels2 main.cu lib.cpp)
+target_compile_features(MixedStandardLevels2 PUBLIC cuda_std_11)
+
+if(APPLE)
+ # Help the static cuda runtime find the driver (libcuda.dyllib) at runtime.
+ set_property(TARGET MixedStandardLevels2 PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES})
+endif()
diff --git a/Tests/Cuda/MixedStandardLevels2/lib.cpp b/Tests/Cuda/MixedStandardLevels2/lib.cpp
new file mode 100644
index 0000000..cabbacb
--- /dev/null
+++ b/Tests/Cuda/MixedStandardLevels2/lib.cpp
@@ -0,0 +1,7 @@
+
+int func(int A, int B)
+{
+ // Verify that we have at least c++14
+ auto mult_func = [](auto a, auto b) { return a * b; };
+ return mult_func(A, B);
+}
diff --git a/Tests/Cuda/MixedStandardLevels2/main.cu b/Tests/Cuda/MixedStandardLevels2/main.cu
new file mode 100644
index 0000000..a97a41e
--- /dev/null
+++ b/Tests/Cuda/MixedStandardLevels2/main.cu
@@ -0,0 +1,11 @@
+
+#if __cplusplus < 201103L && !defined(_MSC_VER)
+# error "invalid standard value"
+#endif
+#include <type_traits>
+
+int main(int argc, char** argv)
+{
+ using returnv = std::integral_constant<int, 0>;
+ return returnv::value;
+}
diff --git a/Tests/Cuda/MixedStandardLevels3/CMakeLists.txt b/Tests/Cuda/MixedStandardLevels3/CMakeLists.txt
new file mode 100644
index 0000000..2c42003
--- /dev/null
+++ b/Tests/Cuda/MixedStandardLevels3/CMakeLists.txt
@@ -0,0 +1,12 @@
+cmake_minimum_required(VERSION 3.7)
+project(MixedStandardLevels3 CXX CUDA)
+
+set(CMAKE_CUDA_ARCHITECTURES 30)
+
+add_executable(MixedStandardLevels3 main.cu lib.cpp)
+target_compile_features(MixedStandardLevels3 PUBLIC cuda_std_03 cxx_std_14)
+
+if(APPLE)
+ # Help the static cuda runtime find the driver (libcuda.dyllib) at runtime.
+ set_property(TARGET MixedStandardLevels3 PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES})
+endif()
diff --git a/Tests/Cuda/MixedStandardLevels3/lib.cpp b/Tests/Cuda/MixedStandardLevels3/lib.cpp
new file mode 100644
index 0000000..cabbacb
--- /dev/null
+++ b/Tests/Cuda/MixedStandardLevels3/lib.cpp
@@ -0,0 +1,7 @@
+
+int func(int A, int B)
+{
+ // Verify that we have at least c++14
+ auto mult_func = [](auto a, auto b) { return a * b; };
+ return mult_func(A, B);
+}
diff --git a/Tests/Cuda/MixedStandardLevels3/main.cu b/Tests/Cuda/MixedStandardLevels3/main.cu
new file mode 100644
index 0000000..1c19e8d
--- /dev/null
+++ b/Tests/Cuda/MixedStandardLevels3/main.cu
@@ -0,0 +1,5 @@
+
+int main(int argc, char** argv)
+{
+ return 0;
+}
diff --git a/Tests/Cuda/MixedStandardLevels4/CMakeLists.txt b/Tests/Cuda/MixedStandardLevels4/CMakeLists.txt
new file mode 100644
index 0000000..230230d
--- /dev/null
+++ b/Tests/Cuda/MixedStandardLevels4/CMakeLists.txt
@@ -0,0 +1,13 @@
+cmake_minimum_required(VERSION 3.7)
+project(MixedStandardLevels4 CXX CUDA)
+
+set(CMAKE_CUDA_STANDARD 03)
+set(CMAKE_CUDA_ARCHITECTURES 30)
+
+add_executable(MixedStandardLevels4 main.cu lib.cpp)
+target_compile_features(MixedStandardLevels4 PUBLIC cxx_std_14)
+
+if(APPLE)
+ # Help the static cuda runtime find the driver (libcuda.dyllib) at runtime.
+ set_property(TARGET MixedStandardLevels4 PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES})
+endif()
diff --git a/Tests/Cuda/MixedStandardLevels4/lib.cpp b/Tests/Cuda/MixedStandardLevels4/lib.cpp
new file mode 100644
index 0000000..ef6fc20
--- /dev/null
+++ b/Tests/Cuda/MixedStandardLevels4/lib.cpp
@@ -0,0 +1,16 @@
+
+
+constexpr int func(int A, int B)
+{
+#if defined(_MSC_VER) && _MSC_VER < 1913
+ // no suppport for extended constexpr
+ return B * A;
+#else
+ // Verify that we have at least c++14
+ if (A < B) {
+ return A + B;
+ } else {
+ return B * A;
+ }
+#endif
+}
diff --git a/Tests/Cuda/MixedStandardLevels4/main.cu b/Tests/Cuda/MixedStandardLevels4/main.cu
new file mode 100644
index 0000000..1c19e8d
--- /dev/null
+++ b/Tests/Cuda/MixedStandardLevels4/main.cu
@@ -0,0 +1,5 @@
+
+int main(int argc, char** argv)
+{
+ return 0;
+}
diff --git a/Tests/Cuda/MixedStandardLevels5/CMakeLists.txt b/Tests/Cuda/MixedStandardLevels5/CMakeLists.txt
new file mode 100644
index 0000000..5f5ee06
--- /dev/null
+++ b/Tests/Cuda/MixedStandardLevels5/CMakeLists.txt
@@ -0,0 +1,12 @@
+cmake_minimum_required(VERSION 3.7)
+project(MixedStandardLevels5 CXX CUDA)
+
+set(CMAKE_CXX_STANDARD 98)
+set(CMAKE_CUDA_ARCHITECTURES 30)
+
+add_executable(MixedStandardLevels5 main.cu lib.cpp)
+
+if(APPLE)
+ # Help the static cuda runtime find the driver (libcuda.dyllib) at runtime.
+ set_property(TARGET MixedStandardLevels5 PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES})
+endif()
diff --git a/Tests/Cuda/MixedStandardLevels5/lib.cpp b/Tests/Cuda/MixedStandardLevels5/lib.cpp
new file mode 100644
index 0000000..dd7b31b
--- /dev/null
+++ b/Tests/Cuda/MixedStandardLevels5/lib.cpp
@@ -0,0 +1,13 @@
+
+#if __cplusplus >= 201103L
+# error "invalid standard value"
+#endif
+int func(int A, int B)
+{
+ // Verify that we have at least c++14
+ if (A < B) {
+ return A + B;
+ } else {
+ return B * A;
+ }
+}
diff --git a/Tests/Cuda/MixedStandardLevels5/main.cu b/Tests/Cuda/MixedStandardLevels5/main.cu
new file mode 100644
index 0000000..c79afd6
--- /dev/null
+++ b/Tests/Cuda/MixedStandardLevels5/main.cu
@@ -0,0 +1,8 @@
+
+#if __cplusplus >= 201103L
+# error "invalid standard value"
+#endif
+int main(int argc, char** argv)
+{
+ return 0;
+}
diff --git a/Tests/Cuda/ProperDeviceLibraries/CMakeLists.txt b/Tests/Cuda/ProperDeviceLibraries/CMakeLists.txt
index cb47b09..fe28c3e 100644
--- a/Tests/Cuda/ProperDeviceLibraries/CMakeLists.txt
+++ b/Tests/Cuda/ProperDeviceLibraries/CMakeLists.txt
@@ -1,8 +1,8 @@
cmake_minimum_required(VERSION 3.13)
project(ProperDeviceLibraries CXX CUDA)
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_35,code=compute_35 -gencode arch=compute_35,code=sm_35")
set(CMAKE_CUDA_STANDARD 11)
+set(CMAKE_CUDA_ARCHITECTURES 35)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads)
diff --git a/Tests/Cuda/SharedRuntimePlusToolkit/CMakeLists.txt b/Tests/Cuda/SharedRuntimePlusToolkit/CMakeLists.txt
new file mode 100644
index 0000000..48df558
--- /dev/null
+++ b/Tests/Cuda/SharedRuntimePlusToolkit/CMakeLists.txt
@@ -0,0 +1,35 @@
+cmake_minimum_required(VERSION 3.15)
+project(SharedRuntimePlusToolkit CXX)
+
+#Goal for this example:
+# Validate that with c++ we can use some components of the CUDA toolkit, and
+# specify the cuda runtime
+find_package(CUDAToolkit REQUIRED)
+
+add_library(Common OBJECT curand.cpp nppif.cpp)
+target_link_libraries(Common PRIVATE CUDA::toolkit)
+set_target_properties(Common PROPERTIES POSITION_INDEPENDENT_CODE ON)
+
+#shared runtime with shared toolkit libraries
+add_library(SharedToolkit SHARED shared.cpp)
+target_link_libraries(SharedToolkit PRIVATE Common PUBLIC CUDA::curand CUDA::nppif)
+target_link_libraries(SharedToolkit PUBLIC CUDA::cudart)
+
+# The CUDA only ships the shared version of the toolkit libraries
+# on windows
+if(NOT WIN32)
+ #shared runtime with static toolkit libraries
+ add_library(StaticToolkit SHARED static.cpp)
+ target_link_libraries(StaticToolkit PRIVATE Common CUDA::curand_static CUDA::nppif_static)
+ target_link_libraries(StaticToolkit PUBLIC CUDA::cudart)
+
+ #static runtime with mixed toolkit libraries
+ add_library(MixedToolkit SHARED mixed.cpp)
+ target_link_libraries(MixedToolkit PRIVATE Common CUDA::curand_static CUDA::nppif)
+ target_link_libraries(MixedToolkit PUBLIC CUDA::cudart)
+endif()
+
+add_executable(SharedRuntimePlusToolkit main.cpp)
+target_link_libraries(SharedRuntimePlusToolkit PRIVATE SharedToolkit
+ $<TARGET_NAME_IF_EXISTS:StaticToolkit>
+ $<TARGET_NAME_IF_EXISTS:MixedToolkit>)
diff --git a/Tests/Cuda/SharedRuntimePlusToolkit/curand.cpp b/Tests/Cuda/SharedRuntimePlusToolkit/curand.cpp
new file mode 100644
index 0000000..fdd7b53
--- /dev/null
+++ b/Tests/Cuda/SharedRuntimePlusToolkit/curand.cpp
@@ -0,0 +1,65 @@
+// Comes from:
+// https://docs.nvidia.com/cuda/curand/host-api-overview.html#host-api-example
+
+#ifdef _WIN32
+# define EXPORT __declspec(dllexport)
+#else
+# define EXPORT
+#endif
+
+/*
+ * This program uses the host CURAND API to generate 100
+ * pseudorandom floats.
+ */
+#include <cuda.h>
+#include <curand.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define CUDA_CALL(x) \
+ do { \
+ if ((x) != cudaSuccess) { \
+ printf("Error at %s:%d\n", __FILE__, __LINE__); \
+ return EXIT_FAILURE; \
+ } \
+ } while (0)
+#define CURAND_CALL(x) \
+ do { \
+ if ((x) != CURAND_STATUS_SUCCESS) { \
+ printf("Error at %s:%d\n", __FILE__, __LINE__); \
+ return EXIT_FAILURE; \
+ } \
+ } while (0)
+
+EXPORT int curand_main()
+{
+ size_t n = 100;
+ size_t i;
+ curandGenerator_t gen;
+ float *devData, *hostData;
+
+ /* Allocate n floats on host */
+ hostData = (float*)calloc(n, sizeof(float));
+
+ /* Allocate n floats on device */
+ CUDA_CALL(cudaMalloc((void**)&devData, n * sizeof(float)));
+
+ /* Create pseudo-random number generator */
+ CURAND_CALL(curandCreateGenerator(&gen, CURAND_RNG_PSEUDO_DEFAULT));
+
+ /* Set seed */
+ CURAND_CALL(curandSetPseudoRandomGeneratorSeed(gen, 1234ULL));
+
+ /* Generate n floats on device */
+ CURAND_CALL(curandGenerateUniform(gen, devData, n));
+
+ /* Copy device memory to host */
+ CUDA_CALL(
+ cudaMemcpy(hostData, devData, n * sizeof(float), cudaMemcpyDeviceToHost));
+
+ /* Cleanup */
+ CURAND_CALL(curandDestroyGenerator(gen));
+ CUDA_CALL(cudaFree(devData));
+ free(hostData);
+ return EXIT_SUCCESS;
+}
diff --git a/Tests/Cuda/SharedRuntimePlusToolkit/main.cpp b/Tests/Cuda/SharedRuntimePlusToolkit/main.cpp
new file mode 100644
index 0000000..2a4da22
--- /dev/null
+++ b/Tests/Cuda/SharedRuntimePlusToolkit/main.cpp
@@ -0,0 +1,23 @@
+
+#ifdef _WIN32
+# define IMPORT __declspec(dllimport)
+IMPORT int shared_version();
+int static_version()
+{
+ return 0;
+}
+int mixed_version()
+{
+ return 0;
+}
+#else
+int shared_version();
+int static_version();
+int mixed_version();
+#endif
+
+int main()
+{
+ return mixed_version() == 0 && shared_version() == 0 &&
+ static_version() == 0;
+}
diff --git a/Tests/Cuda/SharedRuntimePlusToolkit/mixed.cpp b/Tests/Cuda/SharedRuntimePlusToolkit/mixed.cpp
new file mode 100644
index 0000000..6de6886
--- /dev/null
+++ b/Tests/Cuda/SharedRuntimePlusToolkit/mixed.cpp
@@ -0,0 +1,16 @@
+
+#ifdef _WIN32
+# define IMPORT __declspec(dllimport)
+# define EXPORT __declspec(dllexport)
+#else
+# define IMPORT
+# define EXPORT
+#endif
+
+IMPORT int curand_main();
+IMPORT int nppif_main();
+
+EXPORT int mixed_version()
+{
+ return curand_main() == 0 && nppif_main() == 0;
+}
diff --git a/Tests/Cuda/SharedRuntimePlusToolkit/nppif.cpp b/Tests/Cuda/SharedRuntimePlusToolkit/nppif.cpp
new file mode 100644
index 0000000..ac5341c
--- /dev/null
+++ b/Tests/Cuda/SharedRuntimePlusToolkit/nppif.cpp
@@ -0,0 +1,92 @@
+// Comes from
+// https://devtalk.nvidia.com/default/topic/1037482/gpu-accelerated-libraries/help-me-help-you-with-modern-cmake-and-cuda-mwe-for-npp/post/5271066/#5271066
+
+#ifdef _WIN32
+# define EXPORT __declspec(dllexport)
+#else
+# define EXPORT
+#endif
+
+#include <cstdio>
+#include <iostream>
+
+#include <assert.h>
+#include <cuda_runtime_api.h>
+#include <nppi_filtering_functions.h>
+
+EXPORT int nppif_main()
+{
+ /**
+ * 8-bit unsigned single-channel 1D row convolution.
+ */
+ const int simgrows = 32;
+ const int simgcols = 32;
+ Npp8u *d_pSrc, *d_pDst;
+ const int nMaskSize = 3;
+ NppiSize oROI;
+ oROI.width = simgcols - nMaskSize;
+ oROI.height = simgrows;
+ const int simgsize = simgrows * simgcols * sizeof(d_pSrc[0]);
+ const int dimgsize = oROI.width * oROI.height * sizeof(d_pSrc[0]);
+ const int simgpix = simgrows * simgcols;
+ const int dimgpix = oROI.width * oROI.height;
+ const int nSrcStep = simgcols * sizeof(d_pSrc[0]);
+ const int nDstStep = oROI.width * sizeof(d_pDst[0]);
+ const int pixval = 1;
+ const int nDivisor = 1;
+ const Npp32s h_pKernel[nMaskSize] = { pixval, pixval, pixval };
+ Npp32s* d_pKernel;
+ const Npp32s nAnchor = 2;
+ cudaError_t err = cudaMalloc((void**)&d_pSrc, simgsize);
+ if (err != cudaSuccess) {
+ fprintf(stderr, "Cuda error %d\n", __LINE__);
+ return 1;
+ }
+ err = cudaMalloc((void**)&d_pDst, dimgsize);
+ if (err != cudaSuccess) {
+ fprintf(stderr, "Cuda error %d\n", __LINE__);
+ return 1;
+ }
+ err = cudaMalloc((void**)&d_pKernel, nMaskSize * sizeof(d_pKernel[0]));
+ if (err != cudaSuccess) {
+ fprintf(stderr, "Cuda error %d\n", __LINE__);
+ return 1;
+ }
+ // set image to pixval initially
+ err = cudaMemset(d_pSrc, pixval, simgsize);
+ if (err != cudaSuccess) {
+ fprintf(stderr, "Cuda error %d\n", __LINE__);
+ return 1;
+ }
+ err = cudaMemset(d_pDst, 0, dimgsize);
+ if (err != cudaSuccess) {
+ fprintf(stderr, "Cuda error %d\n", __LINE__);
+ return 1;
+ }
+ err = cudaMemcpy(d_pKernel, h_pKernel, nMaskSize * sizeof(d_pKernel[0]),
+ cudaMemcpyHostToDevice);
+ if (err != cudaSuccess) {
+ fprintf(stderr, "Cuda error %d\n", __LINE__);
+ return 1;
+ }
+ // copy src to dst
+ NppStatus ret =
+ nppiFilterRow_8u_C1R(d_pSrc, nSrcStep, d_pDst, nDstStep, oROI, d_pKernel,
+ nMaskSize, nAnchor, nDivisor);
+ assert(ret == NPP_NO_ERROR);
+ Npp8u* h_imgres = new Npp8u[dimgpix];
+ err = cudaMemcpy(h_imgres, d_pDst, dimgsize, cudaMemcpyDeviceToHost);
+ if (err != cudaSuccess) {
+ fprintf(stderr, "Cuda error %d\n", __LINE__);
+ return 1;
+ }
+ // test for filtering
+ for (int i = 0; i < dimgpix; i++) {
+ if (h_imgres[i] != (pixval * pixval * nMaskSize)) {
+ fprintf(stderr, "h_imgres at index %d failed to match\n", i);
+ return 1;
+ }
+ }
+
+ return 0;
+}
diff --git a/Tests/Cuda/SharedRuntimePlusToolkit/shared.cpp b/Tests/Cuda/SharedRuntimePlusToolkit/shared.cpp
new file mode 100644
index 0000000..f3c3dbc
--- /dev/null
+++ b/Tests/Cuda/SharedRuntimePlusToolkit/shared.cpp
@@ -0,0 +1,16 @@
+
+#ifdef _WIN32
+# define IMPORT __declspec(dllimport)
+# define EXPORT __declspec(dllexport)
+#else
+# define IMPORT
+# define EXPORT
+#endif
+
+int curand_main();
+int nppif_main();
+
+EXPORT int shared_version()
+{
+ return curand_main() == 0 && nppif_main() == 0;
+}
diff --git a/Tests/Cuda/SharedRuntimePlusToolkit/static.cpp b/Tests/Cuda/SharedRuntimePlusToolkit/static.cpp
new file mode 100644
index 0000000..6932fa3
--- /dev/null
+++ b/Tests/Cuda/SharedRuntimePlusToolkit/static.cpp
@@ -0,0 +1,16 @@
+
+#ifdef _WIN32
+# define IMPORT __declspec(dllimport)
+# define EXPORT __declspec(dllexport)
+#else
+# define IMPORT
+# define EXPORT
+#endif
+
+IMPORT int curand_main();
+IMPORT int nppif_main();
+
+EXPORT int static_version()
+{
+ return curand_main() == 0 && nppif_main() == 0;
+}
diff --git a/Tests/Cuda/StaticRuntimePlusToolkit/CMakeLists.txt b/Tests/Cuda/StaticRuntimePlusToolkit/CMakeLists.txt
new file mode 100644
index 0000000..df6c392
--- /dev/null
+++ b/Tests/Cuda/StaticRuntimePlusToolkit/CMakeLists.txt
@@ -0,0 +1,29 @@
+cmake_minimum_required(VERSION 3.15)
+project(StaticRuntimePlusToolkit CXX)
+
+#Goal for this example:
+# Validate that with c++ we can use some components of the CUDA toolkit, and
+# specify the cuda runtime
+find_package(CUDAToolkit REQUIRED)
+
+add_library(Common OBJECT curand.cpp nppif.cpp)
+target_link_libraries(Common PRIVATE CUDA::toolkit)
+set_target_properties(Common PROPERTIES POSITION_INDEPENDENT_CODE ON)
+
+#static runtime with shared toolkit libraries
+add_library(SharedToolkit SHARED shared.cpp)
+target_link_libraries(SharedToolkit PRIVATE Common PUBLIC CUDA::curand CUDA::nppif)
+target_link_libraries(SharedToolkit PUBLIC CUDA::cudart_static)
+
+#static runtime with static toolkit libraries
+add_library(StaticToolkit SHARED static.cpp)
+target_link_libraries(StaticToolkit PRIVATE Common CUDA::curand_static CUDA::nppif_static)
+target_link_libraries(StaticToolkit PUBLIC CUDA::cudart_static)
+
+#static runtime with mixed toolkit libraries
+add_library(MixedToolkit SHARED mixed.cpp)
+target_link_libraries(MixedToolkit PRIVATE Common CUDA::curand CUDA::nppif_static)
+target_link_libraries(MixedToolkit PUBLIC CUDA::cudart_static)
+
+add_executable(StaticRuntimePlusToolkit main.cpp)
+target_link_libraries(StaticRuntimePlusToolkit PRIVATE SharedToolkit StaticToolkit MixedToolkit)
diff --git a/Tests/Cuda/StaticRuntimePlusToolkit/curand.cpp b/Tests/Cuda/StaticRuntimePlusToolkit/curand.cpp
new file mode 100644
index 0000000..95872f0
--- /dev/null
+++ b/Tests/Cuda/StaticRuntimePlusToolkit/curand.cpp
@@ -0,0 +1,59 @@
+// Comes from:
+// https://docs.nvidia.com/cuda/curand/host-api-overview.html#host-api-example
+
+/*
+ * This program uses the host CURAND API to generate 100
+ * pseudorandom floats.
+ */
+#include <cuda.h>
+#include <curand.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define CUDA_CALL(x) \
+ do { \
+ if ((x) != cudaSuccess) { \
+ printf("Error at %s:%d\n", __FILE__, __LINE__); \
+ return EXIT_FAILURE; \
+ } \
+ } while (0)
+#define CURAND_CALL(x) \
+ do { \
+ if ((x) != CURAND_STATUS_SUCCESS) { \
+ printf("Error at %s:%d\n", __FILE__, __LINE__); \
+ return EXIT_FAILURE; \
+ } \
+ } while (0)
+
+int curand_main()
+{
+ size_t n = 100;
+ size_t i;
+ curandGenerator_t gen;
+ float *devData, *hostData;
+
+ /* Allocate n floats on host */
+ hostData = (float*)calloc(n, sizeof(float));
+
+ /* Allocate n floats on device */
+ CUDA_CALL(cudaMalloc((void**)&devData, n * sizeof(float)));
+
+ /* Create pseudo-random number generator */
+ CURAND_CALL(curandCreateGenerator(&gen, CURAND_RNG_PSEUDO_DEFAULT));
+
+ /* Set seed */
+ CURAND_CALL(curandSetPseudoRandomGeneratorSeed(gen, 1234ULL));
+
+ /* Generate n floats on device */
+ CURAND_CALL(curandGenerateUniform(gen, devData, n));
+
+ /* Copy device memory to host */
+ CUDA_CALL(
+ cudaMemcpy(hostData, devData, n * sizeof(float), cudaMemcpyDeviceToHost));
+
+ /* Cleanup */
+ CURAND_CALL(curandDestroyGenerator(gen));
+ CUDA_CALL(cudaFree(devData));
+ free(hostData);
+ return EXIT_SUCCESS;
+}
diff --git a/Tests/Cuda/StaticRuntimePlusToolkit/main.cpp b/Tests/Cuda/StaticRuntimePlusToolkit/main.cpp
new file mode 100644
index 0000000..5a09f8e
--- /dev/null
+++ b/Tests/Cuda/StaticRuntimePlusToolkit/main.cpp
@@ -0,0 +1,11 @@
+
+
+int shared_version();
+int static_version();
+int mixed_version();
+
+int main()
+{
+ return mixed_version() == 0 && shared_version() == 0 &&
+ static_version() == 0;
+}
diff --git a/Tests/Cuda/StaticRuntimePlusToolkit/mixed.cpp b/Tests/Cuda/StaticRuntimePlusToolkit/mixed.cpp
new file mode 100644
index 0000000..a05140d
--- /dev/null
+++ b/Tests/Cuda/StaticRuntimePlusToolkit/mixed.cpp
@@ -0,0 +1,8 @@
+
+int curand_main();
+int nppif_main();
+
+int mixed_version()
+{
+ return curand_main() == 0 && nppif_main() == 0;
+}
diff --git a/Tests/Cuda/StaticRuntimePlusToolkit/nppif.cpp b/Tests/Cuda/StaticRuntimePlusToolkit/nppif.cpp
new file mode 100644
index 0000000..2871090
--- /dev/null
+++ b/Tests/Cuda/StaticRuntimePlusToolkit/nppif.cpp
@@ -0,0 +1,86 @@
+// Comes from
+// https://devtalk.nvidia.com/default/topic/1037482/gpu-accelerated-libraries/help-me-help-you-with-modern-cmake-and-cuda-mwe-for-npp/post/5271066/#5271066
+
+#include <cstdio>
+#include <iostream>
+
+#include <assert.h>
+#include <cuda_runtime_api.h>
+#include <nppi_filtering_functions.h>
+
+int nppif_main()
+{
+ /**
+ * 8-bit unsigned single-channel 1D row convolution.
+ */
+ const int simgrows = 32;
+ const int simgcols = 32;
+ Npp8u *d_pSrc, *d_pDst;
+ const int nMaskSize = 3;
+ NppiSize oROI;
+ oROI.width = simgcols - nMaskSize;
+ oROI.height = simgrows;
+ const int simgsize = simgrows * simgcols * sizeof(d_pSrc[0]);
+ const int dimgsize = oROI.width * oROI.height * sizeof(d_pSrc[0]);
+ const int simgpix = simgrows * simgcols;
+ const int dimgpix = oROI.width * oROI.height;
+ const int nSrcStep = simgcols * sizeof(d_pSrc[0]);
+ const int nDstStep = oROI.width * sizeof(d_pDst[0]);
+ const int pixval = 1;
+ const int nDivisor = 1;
+ const Npp32s h_pKernel[nMaskSize] = { pixval, pixval, pixval };
+ Npp32s* d_pKernel;
+ const Npp32s nAnchor = 2;
+ cudaError_t err = cudaMalloc((void**)&d_pSrc, simgsize);
+ if (err != cudaSuccess) {
+ fprintf(stderr, "Cuda error %d\n", __LINE__);
+ return 1;
+ }
+ err = cudaMalloc((void**)&d_pDst, dimgsize);
+ if (err != cudaSuccess) {
+ fprintf(stderr, "Cuda error %d\n", __LINE__);
+ return 1;
+ }
+ err = cudaMalloc((void**)&d_pKernel, nMaskSize * sizeof(d_pKernel[0]));
+ if (err != cudaSuccess) {
+ fprintf(stderr, "Cuda error %d\n", __LINE__);
+ return 1;
+ }
+ // set image to pixval initially
+ err = cudaMemset(d_pSrc, pixval, simgsize);
+ if (err != cudaSuccess) {
+ fprintf(stderr, "Cuda error %d\n", __LINE__);
+ return 1;
+ }
+ err = cudaMemset(d_pDst, 0, dimgsize);
+ if (err != cudaSuccess) {
+ fprintf(stderr, "Cuda error %d\n", __LINE__);
+ return 1;
+ }
+ err = cudaMemcpy(d_pKernel, h_pKernel, nMaskSize * sizeof(d_pKernel[0]),
+ cudaMemcpyHostToDevice);
+ if (err != cudaSuccess) {
+ fprintf(stderr, "Cuda error %d\n", __LINE__);
+ return 1;
+ }
+ // copy src to dst
+ NppStatus ret =
+ nppiFilterRow_8u_C1R(d_pSrc, nSrcStep, d_pDst, nDstStep, oROI, d_pKernel,
+ nMaskSize, nAnchor, nDivisor);
+ assert(ret == NPP_NO_ERROR);
+ Npp8u* h_imgres = new Npp8u[dimgpix];
+ err = cudaMemcpy(h_imgres, d_pDst, dimgsize, cudaMemcpyDeviceToHost);
+ if (err != cudaSuccess) {
+ fprintf(stderr, "Cuda error %d\n", __LINE__);
+ return 1;
+ }
+ // test for filtering
+ for (int i = 0; i < dimgpix; i++) {
+ if (h_imgres[i] != (pixval * pixval * nMaskSize)) {
+ fprintf(stderr, "h_imgres at index %d failed to match\n", i);
+ return 1;
+ }
+ }
+
+ return 0;
+}
diff --git a/Tests/Cuda/StaticRuntimePlusToolkit/shared.cpp b/Tests/Cuda/StaticRuntimePlusToolkit/shared.cpp
new file mode 100644
index 0000000..9967b66
--- /dev/null
+++ b/Tests/Cuda/StaticRuntimePlusToolkit/shared.cpp
@@ -0,0 +1,8 @@
+
+int curand_main();
+int nppif_main();
+
+int shared_version()
+{
+ return curand_main() == 0 && nppif_main() == 0;
+}
diff --git a/Tests/Cuda/StaticRuntimePlusToolkit/static.cpp b/Tests/Cuda/StaticRuntimePlusToolkit/static.cpp
new file mode 100644
index 0000000..ca7eb4c
--- /dev/null
+++ b/Tests/Cuda/StaticRuntimePlusToolkit/static.cpp
@@ -0,0 +1,8 @@
+
+int curand_main();
+int nppif_main();
+
+int static_version()
+{
+ return curand_main() == 0 && nppif_main() == 0;
+}
diff --git a/Tests/Cuda/Toolkit/CMakeLists.txt b/Tests/Cuda/Toolkit/CMakeLists.txt
new file mode 100644
index 0000000..86b4652
--- /dev/null
+++ b/Tests/Cuda/Toolkit/CMakeLists.txt
@@ -0,0 +1,38 @@
+cmake_minimum_required(VERSION 3.15)
+project(Toolkit CXX)
+
+#Goal for this example:
+# Validate that we can use CUDAToolkit to find cuda include paths
+find_package(CUDAToolkit REQUIRED)
+
+message(STATUS "CUDAToolkit_VERSION: ${CUDAToolkit_VERSION}")
+message(STATUS "CUDAToolkit_VERSION_MAJOR: ${CUDAToolkit_VERSION_MAJOR}")
+message(STATUS "CUDAToolkit_VERSION_MINOR: ${CUDAToolkit_VERSION_MINOR}")
+message(STATUS "CUDAToolkit_VERSION_PATCH: ${CUDAToolkit_VERSION_PATCH}")
+message(STATUS "CUDAToolkit_BIN_DIR: ${CUDAToolkit_BIN_DIR}")
+message(STATUS "CUDAToolkit_INCLUDE_DIRS: ${CUDAToolkit_INCLUDE_DIRS}")
+message(STATUS "CUDAToolkit_LIBRARY_DIR: ${CUDAToolkit_LIBRARY_DIR}")
+message(STATUS "CUDAToolkit_NVCC_EXECUTABLE ${CUDAToolkit_NVCC_EXECUTABLE}")
+
+# Verify that all the CUDA:: targets exist even when the CUDA language isn't enabled
+
+foreach (cuda_lib cudart cuda_driver cublas cufft cufftw curand cusolver cusparse nvgraph)
+ if(NOT TARGET CUDA::${cuda_lib})
+ message(FATAL_ERROR "The CUDA::${cuda_lib} target was expected but couldn't be found")
+ endif()
+endforeach()
+
+foreach (cuda_lib nppc nppial nppicc nppidei nppif nppig nppim nppist nppitc npps nppicom nppisu)
+ if(NOT TARGET CUDA::${cuda_lib})
+ message(FATAL_ERROR "The CUDA::${cuda_lib} target was expected but couldn't be found")
+ endif()
+endforeach()
+
+foreach (cuda_lib nvrtc nvToolsExt OpenCL)
+ if(NOT TARGET CUDA::${cuda_lib})
+ message(FATAL_ERROR "The CUDA::${cuda_lib} target was expected but couldn't be found")
+ endif()
+endforeach()
+
+add_executable(Toolkit main.cpp)
+target_link_libraries(Toolkit PRIVATE CUDA::toolkit)
diff --git a/Tests/Cuda/Toolkit/main.cpp b/Tests/Cuda/Toolkit/main.cpp
new file mode 100644
index 0000000..c8d5c6b
--- /dev/null
+++ b/Tests/Cuda/Toolkit/main.cpp
@@ -0,0 +1,8 @@
+// Only thing we care about is that these headers are found
+#include <cuda.h>
+#include <cuda_runtime_api.h>
+
+int main()
+{
+ return 0;
+}
diff --git a/Tests/Cuda/WithC/CMakeLists.txt b/Tests/Cuda/WithC/CMakeLists.txt
index 69aa3f9..049cbce 100644
--- a/Tests/Cuda/WithC/CMakeLists.txt
+++ b/Tests/Cuda/WithC/CMakeLists.txt
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.7)
project(WithC CUDA C)
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30")
+set(CMAKE_CUDA_ARCHITECTURES 30)
add_executable(CudaWithC main.c cuda.cu)
diff --git a/Tests/CudaOnly/Architecture/CMakeLists.txt b/Tests/CudaOnly/Architecture/CMakeLists.txt
new file mode 100644
index 0000000..7270b56
--- /dev/null
+++ b/Tests/CudaOnly/Architecture/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.17)
+project(Architecture CUDA)
+
+set(CMAKE_CUDA_ARCHITECTURES 52)
+add_executable(Architecture main.cu)
diff --git a/Tests/CudaOnly/Architecture/main.cu b/Tests/CudaOnly/Architecture/main.cu
new file mode 100644
index 0000000..8c817d5
--- /dev/null
+++ b/Tests/CudaOnly/Architecture/main.cu
@@ -0,0 +1,9 @@
+#ifdef __CUDA_ARCH__
+# if __CUDA_ARCH__ != 520
+# error "Passed architecture 52, but got something else."
+# endif
+#endif
+
+int main()
+{
+}
diff --git a/Tests/CudaOnly/CMakeLists.txt b/Tests/CudaOnly/CMakeLists.txt
index f1fd344..d74e810 100644
--- a/Tests/CudaOnly/CMakeLists.txt
+++ b/Tests/CudaOnly/CMakeLists.txt
@@ -1,12 +1,27 @@
+ADD_TEST_MACRO(CudaOnly.Architecture Architecture)
ADD_TEST_MACRO(CudaOnly.CircularLinkLine CudaOnlyCircularLinkLine)
+ADD_TEST_MACRO(CudaOnly.CompileFlags CudaOnlyCompileFlags)
ADD_TEST_MACRO(CudaOnly.EnableStandard CudaOnlyEnableStandard)
ADD_TEST_MACRO(CudaOnly.ExportPTX CudaOnlyExportPTX)
ADD_TEST_MACRO(CudaOnly.GPUDebugFlag CudaOnlyGPUDebugFlag)
ADD_TEST_MACRO(CudaOnly.ResolveDeviceSymbols CudaOnlyResolveDeviceSymbols)
ADD_TEST_MACRO(CudaOnly.SeparateCompilation CudaOnlySeparateCompilation)
+ADD_TEST_MACRO(CudaOnly.SharedRuntimePlusToolkit CudaOnlySharedRuntimePlusToolkit)
+ADD_TEST_MACRO(CudaOnly.Standard98 CudaOnlyStandard98)
+ADD_TEST_MACRO(CudaOnly.Toolkit CudaOnlyToolkit)
ADD_TEST_MACRO(CudaOnly.WithDefs CudaOnlyWithDefs)
+# The CUDA only ships the shared version of the toolkit libraries
+# on windows
+if(NOT WIN32)
+ ADD_TEST_MACRO(Cuda.StaticRuntimePlusToolkit StaticRuntimePlusToolkit)
+endif()
+
+if(MSVC)
+ ADD_TEST_MACRO(CudaOnly.PDB CudaOnlyPDB)
+endif()
+
add_test(NAME CudaOnly.DontResolveDeviceSymbols COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
@@ -18,6 +33,14 @@ add_test(NAME CudaOnly.DontResolveDeviceSymbols COMMAND
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
-if(MSVC)
- ADD_TEST_MACRO(CudaOnly.PDB CudaOnlyPDB)
-endif()
+add_test(NAME CudaOnly.RuntimeControls COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMAKE_CURRENT_SOURCE_DIR}/RuntimeControls/"
+ "${CMAKE_CURRENT_BINARY_DIR}/RuntimeControls/"
+ --build-two-config
+ ${build_generator_args}
+ --build-project RuntimeControls
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
diff --git a/Tests/CudaOnly/CircularLinkLine/CMakeLists.txt b/Tests/CudaOnly/CircularLinkLine/CMakeLists.txt
index 5e6f7ab..e10a348 100644
--- a/Tests/CudaOnly/CircularLinkLine/CMakeLists.txt
+++ b/Tests/CudaOnly/CircularLinkLine/CMakeLists.txt
@@ -5,9 +5,9 @@ project (CircularLinkLine CUDA)
# Verify that we de-duplicate the device link line
# Verify that a de-duplicated link line still works with circular static libraries
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=[compute_30]")
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CUDA_STANDARD 11)
+set(CMAKE_CUDA_ARCHITECTURES 30)
add_library(CUDACircularDeviceLinking1 STATIC file1.cu)
add_library(CUDACircularDeviceLinking2 STATIC file2.cu)
diff --git a/Tests/CudaOnly/CompileFlags/CMakeLists.txt b/Tests/CudaOnly/CompileFlags/CMakeLists.txt
new file mode 100644
index 0000000..cbce7d6
--- /dev/null
+++ b/Tests/CudaOnly/CompileFlags/CMakeLists.txt
@@ -0,0 +1,16 @@
+cmake_minimum_required(VERSION 3.17)
+cmake_policy(SET CMP0104 OLD)
+project(CompileFlags CUDA)
+
+# Clear defaults.
+set(CMAKE_CUDA_ARCHITECTURES)
+
+add_executable(CudaOnlyCompileFlags main.cu)
+
+# Try passing CUDA architecture flags explicitly.
+if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
+ target_compile_options(CudaOnlyCompileFlags PRIVATE
+ -gencode arch=compute_50,code=compute_50
+ --compiler-options=-DHOST_DEFINE
+ )
+endif()
diff --git a/Tests/CudaOnly/CompileFlags/main.cu b/Tests/CudaOnly/CompileFlags/main.cu
new file mode 100644
index 0000000..573d230
--- /dev/null
+++ b/Tests/CudaOnly/CompileFlags/main.cu
@@ -0,0 +1,16 @@
+#ifdef __CUDA_ARCH__
+# if __CUDA_ARCH__ != 500
+# error "Passed architecture 50, but got something else."
+# endif
+#endif
+
+// Check HOST_DEFINE only for nvcc
+#ifndef __CUDA__
+# ifndef HOST_DEFINE
+# error "HOST_DEFINE not defined!"
+# endif
+#endif
+
+int main()
+{
+}
diff --git a/Tests/CudaOnly/DontResolveDeviceSymbols/CMakeLists.txt b/Tests/CudaOnly/DontResolveDeviceSymbols/CMakeLists.txt
index 6e3697f..1265660 100644
--- a/Tests/CudaOnly/DontResolveDeviceSymbols/CMakeLists.txt
+++ b/Tests/CudaOnly/DontResolveDeviceSymbols/CMakeLists.txt
@@ -24,9 +24,9 @@ endif()
# Don't resolve the device symbols in the static library
# Don't resolve the device symbols in the executable library
# Verify that we can't use those device symbols from anything
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=[compute_30] -gencode arch=compute_50,code=\\\"compute_50\\\"")
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CUDA_STANDARD 11)
+set(CMAKE_CUDA_ARCHITECTURES 30 50)
set(CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS OFF)
add_library(CUDANoDeviceResolve SHARED file1.cu)
diff --git a/Tests/CudaOnly/EnableStandard/CMakeLists.txt b/Tests/CudaOnly/EnableStandard/CMakeLists.txt
index 54e2c14..dfcb8da 100644
--- a/Tests/CudaOnly/EnableStandard/CMakeLists.txt
+++ b/Tests/CudaOnly/EnableStandard/CMakeLists.txt
@@ -11,8 +11,9 @@ add_library(CUDADynamic11 SHARED shared.cu)
add_executable(CudaOnlyEnableStandard main.cu)
target_link_libraries(CudaOnlyEnableStandard PRIVATE CUDAStatic11 CUDADynamic11)
-set_target_properties(CUDAStatic11 CUDADynamic11 PROPERTIES CUDA_STANDARD 11)
-set_target_properties(CUDAStatic11 CUDADynamic11 PROPERTIES CUDA_STANDARD_REQUIRED TRUE)
+target_compile_features(CUDADynamic11 PRIVATE cuda_std_11)
+set_target_properties(CUDAStatic11 PROPERTIES CUDA_STANDARD 11)
+set_target_properties(CUDAStatic11 PROPERTIES CUDA_STANDARD_REQUIRED TRUE)
#Verify CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES
foreach(dir ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES})
diff --git a/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt b/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt
index 64845c5..bd94ec8 100644
--- a/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt
+++ b/Tests/CudaOnly/ResolveDeviceSymbols/CMakeLists.txt
@@ -21,12 +21,12 @@ endif()
# confirming that the first static library is on the device link line
# 3. Verify that we can't use those device symbols from anything that links
# to the static library
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=[sm_30] -gencode arch=compute_50,code=\\\"compute_50\\\"")
-set(CMAKE_CXX_STANDARD 11)
-set(CMAKE_CUDA_STANDARD 11)
+set(CMAKE_CUDA_ARCHITECTURES 30 50)
add_library(CUDAResolveDeviceDepsA STATIC file1.cu)
add_library(CUDAResolveDeviceDepsB STATIC file2.cu)
+target_compile_features(CUDAResolveDeviceDepsA PUBLIC cuda_std_11)
+target_compile_features(CUDAResolveDeviceDepsB PUBLIC cuda_std_11)
set_target_properties(CUDAResolveDeviceDepsA CUDAResolveDeviceDepsB
PROPERTIES
CUDA_SEPARABLE_COMPILATION ON
diff --git a/Tests/CudaOnly/RuntimeControls/CMakeLists.txt b/Tests/CudaOnly/RuntimeControls/CMakeLists.txt
new file mode 100644
index 0000000..0da5739
--- /dev/null
+++ b/Tests/CudaOnly/RuntimeControls/CMakeLists.txt
@@ -0,0 +1,59 @@
+cmake_minimum_required(VERSION 3.7)
+project (RuntimeControls CUDA)
+
+# Find nm and dumpbin
+if(CMAKE_NM)
+ set(dump_command ${CMAKE_NM})
+ set(dump_args -g)
+else()
+ include(GetPrerequisites)
+ message(STATUS "calling list_prerequisites to find dumpbin")
+ list_prerequisites("${CMAKE_COMMAND}" 0 0 0)
+ if(gp_dumpbin)
+ set(dump_command ${gp_dumpbin})
+ set(dump_args /ARCHIVEMEMBERS)
+ endif()
+endif()
+
+set(CMAKE_CUDA_STANDARD 11)
+set(CMAKE_CUDA_ARCHITECTURES 30)
+set(CMAKE_CUDA_RUNTIME_LIBRARY static)
+
+if(NOT "x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC")
+ add_library(UsesNoCudaRT SHARED file1.cu)
+ set_target_properties(UsesNoCudaRT PROPERTIES CUDA_RUNTIME_LIBRARY none)
+endif()
+
+add_library(UsesStaticCudaRT SHARED file2.cu)
+
+add_executable(CudaOnlyRuntimeControls main.cu)
+set_target_properties(CudaOnlyRuntimeControls PROPERTIES CUDA_RUNTIME_LIBRARY shared)
+
+target_link_libraries(CudaOnlyRuntimeControls PRIVATE $<TARGET_NAME_IF_EXISTS:UsesNoCudaRT> UsesStaticCudaRT)
+
+
+if(dump_command)
+ if(TARGET UsesNoCudaRT)
+ add_custom_command(TARGET UsesNoCudaRT POST_BUILD
+ COMMAND ${CMAKE_COMMAND}
+ -DDUMP_COMMAND=${dump_command}
+ -DDUMP_ARGS=${dump_args}
+ -DTEST_LIBRARY_PATH=$<TARGET_FILE:UsesNoCudaRT>
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/no_runtime.cmake
+ )
+ endif()
+ add_custom_command(TARGET UsesStaticCudaRT POST_BUILD
+ COMMAND ${CMAKE_COMMAND}
+ -DDUMP_COMMAND=${dump_command}
+ -DDUMP_ARGS=${dump_args}
+ -DTEST_LIBRARY_PATH=$<TARGET_FILE:UsesStaticCudaRT>
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/uses_static_runtime.cmake
+ )
+ string(REPLACE ";" "|" dirs "${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}")
+ add_custom_command(TARGET CudaOnlyRuntimeControls POST_BUILD
+ COMMAND ${CMAKE_COMMAND}
+ -DEXEC_PATH=$<TARGET_FILE:CudaOnlyRuntimeControls>
+ -DEXTRA_LIB_DIRS="${dirs}"
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/verify_runtime.cmake
+ )
+endif()
diff --git a/Tests/CudaOnly/RuntimeControls/file1.cu b/Tests/CudaOnly/RuntimeControls/file1.cu
new file mode 100644
index 0000000..28beb5e
--- /dev/null
+++ b/Tests/CudaOnly/RuntimeControls/file1.cu
@@ -0,0 +1,18 @@
+
+#ifdef _WIN32
+# define EXPORT __declspec(dllexport)
+#else
+# define EXPORT
+#endif
+
+void __global__ file1_kernel(int x, int& r)
+{
+ r = -x;
+}
+
+EXPORT int file1_launch_kernel(int x)
+{
+ int r = 0;
+ file1_kernel<<<1, 1>>>(x, r);
+ return r;
+}
diff --git a/Tests/CudaOnly/RuntimeControls/file2.cu b/Tests/CudaOnly/RuntimeControls/file2.cu
new file mode 100644
index 0000000..ff68a70
--- /dev/null
+++ b/Tests/CudaOnly/RuntimeControls/file2.cu
@@ -0,0 +1,18 @@
+
+#ifdef _WIN32
+# define EXPORT __declspec(dllexport)
+#else
+# define EXPORT
+#endif
+
+void __global__ file2_kernel(int x, int& r)
+{
+ r = -x;
+}
+
+EXPORT int file2_launch_kernel(int x)
+{
+ int r = 0;
+ file2_kernel<<<1, 1>>>(x, r);
+ return r;
+}
diff --git a/Tests/CudaOnly/RuntimeControls/main.cu b/Tests/CudaOnly/RuntimeControls/main.cu
new file mode 100644
index 0000000..0be22af
--- /dev/null
+++ b/Tests/CudaOnly/RuntimeControls/main.cu
@@ -0,0 +1,81 @@
+
+#include <iostream>
+
+#include "cuda.h"
+
+#ifdef _WIN32
+# define IMPORT __declspec(dllimport)
+#else
+# define IMPORT
+#endif
+
+#ifndef _WIN32
+IMPORT int file1_launch_kernel(int x);
+#endif
+
+IMPORT int file2_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;
+ if (prop.major >= 3) {
+ 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 supporting compute >=3.0"
+ << std::endl;
+
+ return 1;
+}
+
+int main(int argc, char** argv)
+{
+ int ret = choose_cuda_device();
+ if (ret) {
+ return 0;
+ }
+
+ cudaError_t err;
+#ifndef _WIN32
+ file1_launch_kernel(1);
+ err = cudaGetLastError();
+ if (err != cudaSuccess) {
+ std::cerr << "file1_launch_kernel: kernel launch should have passed.\n "
+ "Error message: "
+ << cudaGetErrorString(err) << std::endl;
+ return 1;
+ }
+#endif
+
+ file2_launch_kernel(1);
+ err = cudaGetLastError();
+ if (err != cudaSuccess) {
+ std::cerr << "file2_launch_kernel: kernel launch should have passed.\n "
+ "Error message: "
+ << cudaGetErrorString(err) << std::endl;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/Tests/CudaOnly/RuntimeControls/no_runtime.cmake b/Tests/CudaOnly/RuntimeControls/no_runtime.cmake
new file mode 100644
index 0000000..55f28cc
--- /dev/null
+++ b/Tests/CudaOnly/RuntimeControls/no_runtime.cmake
@@ -0,0 +1,14 @@
+execute_process(COMMAND ${DUMP_COMMAND} ${DUMP_ARGS} ${TEST_LIBRARY_PATH}
+ RESULT_VARIABLE RESULT
+ OUTPUT_VARIABLE OUTPUT
+ ERROR_VARIABLE ERROR
+)
+
+if(NOT "${RESULT}" STREQUAL "0")
+ message(FATAL_ERROR "${DUMP_COMMAND} failed [${RESULT}] [${OUTPUT}] [${ERROR}]")
+endif()
+
+if(NOT "${OUTPUT}" MATCHES "(__cuda)")
+ message(FATAL_ERROR
+ "not missing cuda device symbols, static runtime linking was used.")
+endif()
diff --git a/Tests/CudaOnly/RuntimeControls/uses_static_runtime.cmake b/Tests/CudaOnly/RuntimeControls/uses_static_runtime.cmake
new file mode 100644
index 0000000..b372fea
--- /dev/null
+++ b/Tests/CudaOnly/RuntimeControls/uses_static_runtime.cmake
@@ -0,0 +1,14 @@
+execute_process(COMMAND ${DUMP_COMMAND} ${DUMP_ARGS} ${TEST_LIBRARY_PATH}
+ RESULT_VARIABLE RESULT
+ OUTPUT_VARIABLE OUTPUT
+ ERROR_VARIABLE ERROR
+)
+
+if(NOT "${RESULT}" STREQUAL "0")
+ message(FATAL_ERROR "${DUMP_COMMAND} failed [${RESULT}] [${OUTPUT}] [${ERROR}]")
+endif()
+
+if("${OUTPUT}" MATCHES "__cuda")
+ message(FATAL_ERROR
+ "missing cuda device symbols, static runtime linking was not used.")
+endif()
diff --git a/Tests/CudaOnly/RuntimeControls/verify_runtime.cmake b/Tests/CudaOnly/RuntimeControls/verify_runtime.cmake
new file mode 100644
index 0000000..b313dac
--- /dev/null
+++ b/Tests/CudaOnly/RuntimeControls/verify_runtime.cmake
@@ -0,0 +1,16 @@
+
+string(REPLACE "|" ";" dirs "${EXTRA_LIB_DIRS}")
+file(GET_RUNTIME_DEPENDENCIES
+ RESOLVED_DEPENDENCIES_VAR resolved_libs
+ UNRESOLVED_DEPENDENCIES_VAR unresolved_libs
+ DIRECTORIES ${dirs}
+ EXECUTABLES ${EXEC_PATH}
+ )
+
+list(FILTER resolved_libs INCLUDE REGEX ".*cudart.*")
+list(LENGTH resolved_libs has_cudart)
+
+if(has_cudart EQUAL 0)
+ message(FATAL_ERROR
+ "missing cudart shared library from runtime dependency output.")
+endif()
diff --git a/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt b/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt
index 1e574d6..586be81 100644
--- a/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt
+++ b/Tests/CudaOnly/SeparateCompilation/CMakeLists.txt
@@ -9,13 +9,10 @@ project (SeparateCompilation CUDA)
#and executables.
#We complicate the matter by also testing that multiple static libraries
#all containing cuda separable compilation code links properly
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=\\\"compute_30,sm_30,sm_35\\\"")
-string(APPEND CMAKE_CUDA_FLAGS " --generate-code=arch=compute_50,code=[compute_50,sm_50,sm_52]")
-set(CMAKE_CXX_STANDARD 11)
-set(CMAKE_CUDA_STANDARD 11)
-
+set(CMAKE_CUDA_ARCHITECTURES 30 35 50 52)
set(CMAKE_CUDA_SEPARABLE_COMPILATION ON)
add_library(CUDASeparateLibA STATIC file1.cu file2.cu file3.cu)
+target_compile_features(CUDASeparateLibA PRIVATE cuda_std_11)
get_property(sep_comp TARGET CUDASeparateLibA PROPERTY CUDA_SEPARABLE_COMPILATION)
if(NOT sep_comp)
message(FATAL_ERROR "CUDA_SEPARABLE_COMPILATION not initialized")
@@ -36,11 +33,14 @@ endif()
#cause a segv when trying to run the executable
#
add_library(CUDASeparateLibB STATIC file4.cu file5.cu)
+target_compile_features(CUDASeparateLibB PRIVATE cuda_std_11)
target_link_libraries(CUDASeparateLibB PRIVATE CUDASeparateLibA)
add_executable(CudaOnlySeparateCompilation main.cu)
target_link_libraries(CudaOnlySeparateCompilation
PRIVATE CUDASeparateLibB)
+set_target_properties(CudaOnlySeparateCompilation PROPERTIES CUDA_STANDARD 11)
+set_target_properties(CudaOnlySeparateCompilation PROPERTIES CUDA_STANDARD_REQUIRED TRUE)
set_target_properties(CUDASeparateLibA
CUDASeparateLibB
diff --git a/Tests/CudaOnly/SharedRuntimePlusToolkit/CMakeLists.txt b/Tests/CudaOnly/SharedRuntimePlusToolkit/CMakeLists.txt
new file mode 100644
index 0000000..03fba22
--- /dev/null
+++ b/Tests/CudaOnly/SharedRuntimePlusToolkit/CMakeLists.txt
@@ -0,0 +1,42 @@
+cmake_minimum_required(VERSION 3.15)
+project(SharedRuntimePlusToolkit CUDA)
+
+#Goal for this example:
+# Validate that with c++ we can use some components of the CUDA toolkit, and
+# specify the cuda runtime
+find_package(CUDAToolkit REQUIRED)
+
+add_library(Common OBJECT curand.cu nppif.cu)
+target_link_libraries(Common PRIVATE CUDA::toolkit)
+set_target_properties(Common PROPERTIES POSITION_INDEPENDENT_CODE ON)
+
+#shared runtime with shared toolkit libraries
+add_library(SharedToolkit SHARED shared.cu)
+target_link_libraries(SharedToolkit PRIVATE Common PUBLIC CUDA::curand CUDA::nppif)
+set_target_properties(SharedToolkit PROPERTIES CUDA_RUNTIME_LIBRARY none)
+target_link_libraries(SharedToolkit PUBLIC CUDA::cudart)
+
+# The CUDA only ships the shared version of the toolkit libraries
+# on windows
+if(NOT WIN32)
+ #shared runtime with static toolkit libraries
+ add_library(StaticToolkit SHARED static.cu)
+ target_link_libraries(StaticToolkit PRIVATE Common CUDA::curand_static CUDA::nppif_static)
+ set_target_properties(StaticToolkit PROPERTIES CUDA_RUNTIME_LIBRARY Shared)
+
+ #static runtime with mixed toolkit libraries
+ add_library(MixedToolkit SHARED mixed.cu)
+ target_link_libraries(MixedToolkit PRIVATE Common CUDA::curand_static CUDA::nppif)
+ set_target_properties(MixedToolkit PROPERTIES CUDA_RUNTIME_LIBRARY Shared)
+endif()
+
+add_executable(CudaOnlySharedRuntimePlusToolkit main.cu)
+target_link_libraries(CudaOnlySharedRuntimePlusToolkit PRIVATE SharedToolkit
+ $<TARGET_NAME_IF_EXISTS:StaticToolkit>
+ $<TARGET_NAME_IF_EXISTS:MixedToolkit>)
+
+if(UNIX)
+ # Help the shared cuda runtime find libcudart as it is not located
+ # in a default system searched location
+ set_property(TARGET CudaOnlySharedRuntimePlusToolkit PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES})
+endif()
diff --git a/Tests/CudaOnly/SharedRuntimePlusToolkit/curand.cu b/Tests/CudaOnly/SharedRuntimePlusToolkit/curand.cu
new file mode 100644
index 0000000..fdd7b53
--- /dev/null
+++ b/Tests/CudaOnly/SharedRuntimePlusToolkit/curand.cu
@@ -0,0 +1,65 @@
+// Comes from:
+// https://docs.nvidia.com/cuda/curand/host-api-overview.html#host-api-example
+
+#ifdef _WIN32
+# define EXPORT __declspec(dllexport)
+#else
+# define EXPORT
+#endif
+
+/*
+ * This program uses the host CURAND API to generate 100
+ * pseudorandom floats.
+ */
+#include <cuda.h>
+#include <curand.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define CUDA_CALL(x) \
+ do { \
+ if ((x) != cudaSuccess) { \
+ printf("Error at %s:%d\n", __FILE__, __LINE__); \
+ return EXIT_FAILURE; \
+ } \
+ } while (0)
+#define CURAND_CALL(x) \
+ do { \
+ if ((x) != CURAND_STATUS_SUCCESS) { \
+ printf("Error at %s:%d\n", __FILE__, __LINE__); \
+ return EXIT_FAILURE; \
+ } \
+ } while (0)
+
+EXPORT int curand_main()
+{
+ size_t n = 100;
+ size_t i;
+ curandGenerator_t gen;
+ float *devData, *hostData;
+
+ /* Allocate n floats on host */
+ hostData = (float*)calloc(n, sizeof(float));
+
+ /* Allocate n floats on device */
+ CUDA_CALL(cudaMalloc((void**)&devData, n * sizeof(float)));
+
+ /* Create pseudo-random number generator */
+ CURAND_CALL(curandCreateGenerator(&gen, CURAND_RNG_PSEUDO_DEFAULT));
+
+ /* Set seed */
+ CURAND_CALL(curandSetPseudoRandomGeneratorSeed(gen, 1234ULL));
+
+ /* Generate n floats on device */
+ CURAND_CALL(curandGenerateUniform(gen, devData, n));
+
+ /* Copy device memory to host */
+ CUDA_CALL(
+ cudaMemcpy(hostData, devData, n * sizeof(float), cudaMemcpyDeviceToHost));
+
+ /* Cleanup */
+ CURAND_CALL(curandDestroyGenerator(gen));
+ CUDA_CALL(cudaFree(devData));
+ free(hostData);
+ return EXIT_SUCCESS;
+}
diff --git a/Tests/CudaOnly/SharedRuntimePlusToolkit/main.cu b/Tests/CudaOnly/SharedRuntimePlusToolkit/main.cu
new file mode 100644
index 0000000..2a4da22
--- /dev/null
+++ b/Tests/CudaOnly/SharedRuntimePlusToolkit/main.cu
@@ -0,0 +1,23 @@
+
+#ifdef _WIN32
+# define IMPORT __declspec(dllimport)
+IMPORT int shared_version();
+int static_version()
+{
+ return 0;
+}
+int mixed_version()
+{
+ return 0;
+}
+#else
+int shared_version();
+int static_version();
+int mixed_version();
+#endif
+
+int main()
+{
+ return mixed_version() == 0 && shared_version() == 0 &&
+ static_version() == 0;
+}
diff --git a/Tests/CudaOnly/SharedRuntimePlusToolkit/mixed.cu b/Tests/CudaOnly/SharedRuntimePlusToolkit/mixed.cu
new file mode 100644
index 0000000..6de6886
--- /dev/null
+++ b/Tests/CudaOnly/SharedRuntimePlusToolkit/mixed.cu
@@ -0,0 +1,16 @@
+
+#ifdef _WIN32
+# define IMPORT __declspec(dllimport)
+# define EXPORT __declspec(dllexport)
+#else
+# define IMPORT
+# define EXPORT
+#endif
+
+IMPORT int curand_main();
+IMPORT int nppif_main();
+
+EXPORT int mixed_version()
+{
+ return curand_main() == 0 && nppif_main() == 0;
+}
diff --git a/Tests/CudaOnly/SharedRuntimePlusToolkit/nppif.cu b/Tests/CudaOnly/SharedRuntimePlusToolkit/nppif.cu
new file mode 100644
index 0000000..ac5341c
--- /dev/null
+++ b/Tests/CudaOnly/SharedRuntimePlusToolkit/nppif.cu
@@ -0,0 +1,92 @@
+// Comes from
+// https://devtalk.nvidia.com/default/topic/1037482/gpu-accelerated-libraries/help-me-help-you-with-modern-cmake-and-cuda-mwe-for-npp/post/5271066/#5271066
+
+#ifdef _WIN32
+# define EXPORT __declspec(dllexport)
+#else
+# define EXPORT
+#endif
+
+#include <cstdio>
+#include <iostream>
+
+#include <assert.h>
+#include <cuda_runtime_api.h>
+#include <nppi_filtering_functions.h>
+
+EXPORT int nppif_main()
+{
+ /**
+ * 8-bit unsigned single-channel 1D row convolution.
+ */
+ const int simgrows = 32;
+ const int simgcols = 32;
+ Npp8u *d_pSrc, *d_pDst;
+ const int nMaskSize = 3;
+ NppiSize oROI;
+ oROI.width = simgcols - nMaskSize;
+ oROI.height = simgrows;
+ const int simgsize = simgrows * simgcols * sizeof(d_pSrc[0]);
+ const int dimgsize = oROI.width * oROI.height * sizeof(d_pSrc[0]);
+ const int simgpix = simgrows * simgcols;
+ const int dimgpix = oROI.width * oROI.height;
+ const int nSrcStep = simgcols * sizeof(d_pSrc[0]);
+ const int nDstStep = oROI.width * sizeof(d_pDst[0]);
+ const int pixval = 1;
+ const int nDivisor = 1;
+ const Npp32s h_pKernel[nMaskSize] = { pixval, pixval, pixval };
+ Npp32s* d_pKernel;
+ const Npp32s nAnchor = 2;
+ cudaError_t err = cudaMalloc((void**)&d_pSrc, simgsize);
+ if (err != cudaSuccess) {
+ fprintf(stderr, "Cuda error %d\n", __LINE__);
+ return 1;
+ }
+ err = cudaMalloc((void**)&d_pDst, dimgsize);
+ if (err != cudaSuccess) {
+ fprintf(stderr, "Cuda error %d\n", __LINE__);
+ return 1;
+ }
+ err = cudaMalloc((void**)&d_pKernel, nMaskSize * sizeof(d_pKernel[0]));
+ if (err != cudaSuccess) {
+ fprintf(stderr, "Cuda error %d\n", __LINE__);
+ return 1;
+ }
+ // set image to pixval initially
+ err = cudaMemset(d_pSrc, pixval, simgsize);
+ if (err != cudaSuccess) {
+ fprintf(stderr, "Cuda error %d\n", __LINE__);
+ return 1;
+ }
+ err = cudaMemset(d_pDst, 0, dimgsize);
+ if (err != cudaSuccess) {
+ fprintf(stderr, "Cuda error %d\n", __LINE__);
+ return 1;
+ }
+ err = cudaMemcpy(d_pKernel, h_pKernel, nMaskSize * sizeof(d_pKernel[0]),
+ cudaMemcpyHostToDevice);
+ if (err != cudaSuccess) {
+ fprintf(stderr, "Cuda error %d\n", __LINE__);
+ return 1;
+ }
+ // copy src to dst
+ NppStatus ret =
+ nppiFilterRow_8u_C1R(d_pSrc, nSrcStep, d_pDst, nDstStep, oROI, d_pKernel,
+ nMaskSize, nAnchor, nDivisor);
+ assert(ret == NPP_NO_ERROR);
+ Npp8u* h_imgres = new Npp8u[dimgpix];
+ err = cudaMemcpy(h_imgres, d_pDst, dimgsize, cudaMemcpyDeviceToHost);
+ if (err != cudaSuccess) {
+ fprintf(stderr, "Cuda error %d\n", __LINE__);
+ return 1;
+ }
+ // test for filtering
+ for (int i = 0; i < dimgpix; i++) {
+ if (h_imgres[i] != (pixval * pixval * nMaskSize)) {
+ fprintf(stderr, "h_imgres at index %d failed to match\n", i);
+ return 1;
+ }
+ }
+
+ return 0;
+}
diff --git a/Tests/CudaOnly/SharedRuntimePlusToolkit/shared.cu b/Tests/CudaOnly/SharedRuntimePlusToolkit/shared.cu
new file mode 100644
index 0000000..f3c3dbc
--- /dev/null
+++ b/Tests/CudaOnly/SharedRuntimePlusToolkit/shared.cu
@@ -0,0 +1,16 @@
+
+#ifdef _WIN32
+# define IMPORT __declspec(dllimport)
+# define EXPORT __declspec(dllexport)
+#else
+# define IMPORT
+# define EXPORT
+#endif
+
+int curand_main();
+int nppif_main();
+
+EXPORT int shared_version()
+{
+ return curand_main() == 0 && nppif_main() == 0;
+}
diff --git a/Tests/CudaOnly/SharedRuntimePlusToolkit/static.cu b/Tests/CudaOnly/SharedRuntimePlusToolkit/static.cu
new file mode 100644
index 0000000..6932fa3
--- /dev/null
+++ b/Tests/CudaOnly/SharedRuntimePlusToolkit/static.cu
@@ -0,0 +1,16 @@
+
+#ifdef _WIN32
+# define IMPORT __declspec(dllimport)
+# define EXPORT __declspec(dllexport)
+#else
+# define IMPORT
+# define EXPORT
+#endif
+
+IMPORT int curand_main();
+IMPORT int nppif_main();
+
+EXPORT int static_version()
+{
+ return curand_main() == 0 && nppif_main() == 0;
+}
diff --git a/Tests/CudaOnly/Standard98/CMakeLists.txt b/Tests/CudaOnly/Standard98/CMakeLists.txt
new file mode 100644
index 0000000..3ba0360
--- /dev/null
+++ b/Tests/CudaOnly/Standard98/CMakeLists.txt
@@ -0,0 +1,15 @@
+cmake_minimum_required(VERSION 3.7)
+project(CudaOnlyStandard98 CUDA)
+
+set(CMAKE_CUDA_ARCHITECTURES 30)
+
+# Support setting CUDA Standard to 98 which internally gets transformed to
+# CUDA03
+set(CMAKE_CUDA_STANDARD 98)
+
+add_executable(CudaOnlyStandard98 main.cu)
+
+if(APPLE)
+ # Help the static cuda runtime find the driver (libcuda.dyllib) at runtime.
+ set_property(TARGET CudaOnlyStandard98 PROPERTY BUILD_RPATH ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES})
+endif()
diff --git a/Tests/CudaOnly/Standard98/main.cu b/Tests/CudaOnly/Standard98/main.cu
new file mode 100644
index 0000000..c79afd6
--- /dev/null
+++ b/Tests/CudaOnly/Standard98/main.cu
@@ -0,0 +1,8 @@
+
+#if __cplusplus >= 201103L
+# error "invalid standard value"
+#endif
+int main(int argc, char** argv)
+{
+ return 0;
+}
diff --git a/Tests/CudaOnly/StaticRuntimePlusToolkit/CMakeLists.txt b/Tests/CudaOnly/StaticRuntimePlusToolkit/CMakeLists.txt
new file mode 100644
index 0000000..97ac229
--- /dev/null
+++ b/Tests/CudaOnly/StaticRuntimePlusToolkit/CMakeLists.txt
@@ -0,0 +1,29 @@
+cmake_minimum_required(VERSION 3.15)
+project(StaticRuntimePlusToolkit CUDA)
+
+#Goal for this example:
+# Validate that with cuda we can use some components of the CUDA toolkit, and
+# specify the cuda runtime
+find_package(CUDAToolkit REQUIRED)
+
+add_library(Common OBJECT curand.cu nppif.cu)
+target_link_libraries(Common PRIVATE CUDA::toolkit)
+set_target_properties(Common PROPERTIES POSITION_INDEPENDENT_CODE ON)
+
+#static runtime with shared toolkit libraries
+add_library(SharedToolkit SHARED shared.cu)
+target_link_libraries(SharedToolkit PRIVATE Common CUDA::curand CUDA::nppif )
+set_target_properties(SharedToolkit PROPERTIES CUDA_RUNTIME_LIBRARY none)
+target_link_libraries(SharedToolkit PUBLIC CUDA::cudart_static)
+
+#static runtime with static toolkit libraries
+add_library(StaticToolkit SHARED static.cu)
+target_link_libraries(StaticToolkit PRIVATE Common CUDA::curand_static CUDA::nppif_static)
+
+#static runtime with mixed toolkit libraries
+add_library(MixedToolkit SHARED mixed.cu)
+target_link_libraries(MixedToolkit PRIVATE Common CUDA::curand CUDA::nppif_static)
+set_target_properties(MixedToolkit PROPERTIES CUDA_RUNTIME_LIBRARY Static)
+
+add_executable(CudaOnlyStaticRuntimePlusToolkit main.cu)
+target_link_libraries(CudaOnlyStaticRuntimePlusToolkit PRIVATE SharedToolkit StaticToolkit MixedToolkit)
diff --git a/Tests/CudaOnly/StaticRuntimePlusToolkit/curand.cu b/Tests/CudaOnly/StaticRuntimePlusToolkit/curand.cu
new file mode 100644
index 0000000..95872f0
--- /dev/null
+++ b/Tests/CudaOnly/StaticRuntimePlusToolkit/curand.cu
@@ -0,0 +1,59 @@
+// Comes from:
+// https://docs.nvidia.com/cuda/curand/host-api-overview.html#host-api-example
+
+/*
+ * This program uses the host CURAND API to generate 100
+ * pseudorandom floats.
+ */
+#include <cuda.h>
+#include <curand.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define CUDA_CALL(x) \
+ do { \
+ if ((x) != cudaSuccess) { \
+ printf("Error at %s:%d\n", __FILE__, __LINE__); \
+ return EXIT_FAILURE; \
+ } \
+ } while (0)
+#define CURAND_CALL(x) \
+ do { \
+ if ((x) != CURAND_STATUS_SUCCESS) { \
+ printf("Error at %s:%d\n", __FILE__, __LINE__); \
+ return EXIT_FAILURE; \
+ } \
+ } while (0)
+
+int curand_main()
+{
+ size_t n = 100;
+ size_t i;
+ curandGenerator_t gen;
+ float *devData, *hostData;
+
+ /* Allocate n floats on host */
+ hostData = (float*)calloc(n, sizeof(float));
+
+ /* Allocate n floats on device */
+ CUDA_CALL(cudaMalloc((void**)&devData, n * sizeof(float)));
+
+ /* Create pseudo-random number generator */
+ CURAND_CALL(curandCreateGenerator(&gen, CURAND_RNG_PSEUDO_DEFAULT));
+
+ /* Set seed */
+ CURAND_CALL(curandSetPseudoRandomGeneratorSeed(gen, 1234ULL));
+
+ /* Generate n floats on device */
+ CURAND_CALL(curandGenerateUniform(gen, devData, n));
+
+ /* Copy device memory to host */
+ CUDA_CALL(
+ cudaMemcpy(hostData, devData, n * sizeof(float), cudaMemcpyDeviceToHost));
+
+ /* Cleanup */
+ CURAND_CALL(curandDestroyGenerator(gen));
+ CUDA_CALL(cudaFree(devData));
+ free(hostData);
+ return EXIT_SUCCESS;
+}
diff --git a/Tests/CudaOnly/StaticRuntimePlusToolkit/main.cu b/Tests/CudaOnly/StaticRuntimePlusToolkit/main.cu
new file mode 100644
index 0000000..5a09f8e
--- /dev/null
+++ b/Tests/CudaOnly/StaticRuntimePlusToolkit/main.cu
@@ -0,0 +1,11 @@
+
+
+int shared_version();
+int static_version();
+int mixed_version();
+
+int main()
+{
+ return mixed_version() == 0 && shared_version() == 0 &&
+ static_version() == 0;
+}
diff --git a/Tests/CudaOnly/StaticRuntimePlusToolkit/mixed.cu b/Tests/CudaOnly/StaticRuntimePlusToolkit/mixed.cu
new file mode 100644
index 0000000..a05140d
--- /dev/null
+++ b/Tests/CudaOnly/StaticRuntimePlusToolkit/mixed.cu
@@ -0,0 +1,8 @@
+
+int curand_main();
+int nppif_main();
+
+int mixed_version()
+{
+ return curand_main() == 0 && nppif_main() == 0;
+}
diff --git a/Tests/CudaOnly/StaticRuntimePlusToolkit/nppif.cu b/Tests/CudaOnly/StaticRuntimePlusToolkit/nppif.cu
new file mode 100644
index 0000000..2871090
--- /dev/null
+++ b/Tests/CudaOnly/StaticRuntimePlusToolkit/nppif.cu
@@ -0,0 +1,86 @@
+// Comes from
+// https://devtalk.nvidia.com/default/topic/1037482/gpu-accelerated-libraries/help-me-help-you-with-modern-cmake-and-cuda-mwe-for-npp/post/5271066/#5271066
+
+#include <cstdio>
+#include <iostream>
+
+#include <assert.h>
+#include <cuda_runtime_api.h>
+#include <nppi_filtering_functions.h>
+
+int nppif_main()
+{
+ /**
+ * 8-bit unsigned single-channel 1D row convolution.
+ */
+ const int simgrows = 32;
+ const int simgcols = 32;
+ Npp8u *d_pSrc, *d_pDst;
+ const int nMaskSize = 3;
+ NppiSize oROI;
+ oROI.width = simgcols - nMaskSize;
+ oROI.height = simgrows;
+ const int simgsize = simgrows * simgcols * sizeof(d_pSrc[0]);
+ const int dimgsize = oROI.width * oROI.height * sizeof(d_pSrc[0]);
+ const int simgpix = simgrows * simgcols;
+ const int dimgpix = oROI.width * oROI.height;
+ const int nSrcStep = simgcols * sizeof(d_pSrc[0]);
+ const int nDstStep = oROI.width * sizeof(d_pDst[0]);
+ const int pixval = 1;
+ const int nDivisor = 1;
+ const Npp32s h_pKernel[nMaskSize] = { pixval, pixval, pixval };
+ Npp32s* d_pKernel;
+ const Npp32s nAnchor = 2;
+ cudaError_t err = cudaMalloc((void**)&d_pSrc, simgsize);
+ if (err != cudaSuccess) {
+ fprintf(stderr, "Cuda error %d\n", __LINE__);
+ return 1;
+ }
+ err = cudaMalloc((void**)&d_pDst, dimgsize);
+ if (err != cudaSuccess) {
+ fprintf(stderr, "Cuda error %d\n", __LINE__);
+ return 1;
+ }
+ err = cudaMalloc((void**)&d_pKernel, nMaskSize * sizeof(d_pKernel[0]));
+ if (err != cudaSuccess) {
+ fprintf(stderr, "Cuda error %d\n", __LINE__);
+ return 1;
+ }
+ // set image to pixval initially
+ err = cudaMemset(d_pSrc, pixval, simgsize);
+ if (err != cudaSuccess) {
+ fprintf(stderr, "Cuda error %d\n", __LINE__);
+ return 1;
+ }
+ err = cudaMemset(d_pDst, 0, dimgsize);
+ if (err != cudaSuccess) {
+ fprintf(stderr, "Cuda error %d\n", __LINE__);
+ return 1;
+ }
+ err = cudaMemcpy(d_pKernel, h_pKernel, nMaskSize * sizeof(d_pKernel[0]),
+ cudaMemcpyHostToDevice);
+ if (err != cudaSuccess) {
+ fprintf(stderr, "Cuda error %d\n", __LINE__);
+ return 1;
+ }
+ // copy src to dst
+ NppStatus ret =
+ nppiFilterRow_8u_C1R(d_pSrc, nSrcStep, d_pDst, nDstStep, oROI, d_pKernel,
+ nMaskSize, nAnchor, nDivisor);
+ assert(ret == NPP_NO_ERROR);
+ Npp8u* h_imgres = new Npp8u[dimgpix];
+ err = cudaMemcpy(h_imgres, d_pDst, dimgsize, cudaMemcpyDeviceToHost);
+ if (err != cudaSuccess) {
+ fprintf(stderr, "Cuda error %d\n", __LINE__);
+ return 1;
+ }
+ // test for filtering
+ for (int i = 0; i < dimgpix; i++) {
+ if (h_imgres[i] != (pixval * pixval * nMaskSize)) {
+ fprintf(stderr, "h_imgres at index %d failed to match\n", i);
+ return 1;
+ }
+ }
+
+ return 0;
+}
diff --git a/Tests/CudaOnly/StaticRuntimePlusToolkit/shared.cu b/Tests/CudaOnly/StaticRuntimePlusToolkit/shared.cu
new file mode 100644
index 0000000..9967b66
--- /dev/null
+++ b/Tests/CudaOnly/StaticRuntimePlusToolkit/shared.cu
@@ -0,0 +1,8 @@
+
+int curand_main();
+int nppif_main();
+
+int shared_version()
+{
+ return curand_main() == 0 && nppif_main() == 0;
+}
diff --git a/Tests/CudaOnly/StaticRuntimePlusToolkit/static.cu b/Tests/CudaOnly/StaticRuntimePlusToolkit/static.cu
new file mode 100644
index 0000000..ca7eb4c
--- /dev/null
+++ b/Tests/CudaOnly/StaticRuntimePlusToolkit/static.cu
@@ -0,0 +1,8 @@
+
+int curand_main();
+int nppif_main();
+
+int static_version()
+{
+ return curand_main() == 0 && nppif_main() == 0;
+}
diff --git a/Tests/CudaOnly/Toolkit/CMakeLists.txt b/Tests/CudaOnly/Toolkit/CMakeLists.txt
new file mode 100644
index 0000000..0d5d574
--- /dev/null
+++ b/Tests/CudaOnly/Toolkit/CMakeLists.txt
@@ -0,0 +1,44 @@
+cmake_minimum_required(VERSION 3.15)
+project(CudaOnlyToolkit CUDA)
+find_package(CUDAToolkit REQUIRED)
+
+message(STATUS "CUDAToolkit_VERSION: ${CUDAToolkit_VERSION}")
+message(STATUS "CUDAToolkit_VERSION_MAJOR: ${CUDAToolkit_VERSION_MAJOR}")
+message(STATUS "CUDAToolkit_VERSION_MINOR: ${CUDAToolkit_VERSION_MINOR}")
+message(STATUS "CUDAToolkit_VERSION_PATCH: ${CUDAToolkit_VERSION_PATCH}")
+message(STATUS "CUDAToolkit_BIN_DIR: ${CUDAToolkit_BIN_DIR}")
+message(STATUS "CUDAToolkit_INCLUDE_DIRS: ${CUDAToolkit_INCLUDE_DIRS}")
+message(STATUS "CUDAToolkit_LIBRARY_DIR: ${CUDAToolkit_LIBRARY_DIR}")
+message(STATUS "CUDAToolkit_NVCC_EXECUTABLE ${CUDAToolkit_NVCC_EXECUTABLE}")
+
+# Verify that all the CUDA:: targets and variables exist
+foreach (cuda_lib cudart cuda_driver cublas cufft cufftw curand cusolver cusparse nvgraph)
+ if(NOT CUDA_${cuda_lib}_LIBRARY)
+ message(FATAL_ERROR "expected CUDAToolkit variable CUDA_${cuda_lib}_LIBRARY not found")
+ endif()
+ if(NOT TARGET CUDA::${cuda_lib})
+ message(FATAL_ERROR "expected CUDAToolkit target CUDA::${cuda_lib} not found")
+ endif()
+endforeach()
+
+foreach (cuda_lib nppc nppial nppicc nppidei nppif nppig nppim nppist nppitc npps nppicom nppisu)
+ if(NOT CUDA_${cuda_lib}_LIBRARY)
+ message(FATAL_ERROR "expected CUDAToolkit variable CUDA_${cuda_lib}_LIBRARY not found")
+ endif()
+ if(NOT TARGET CUDA::${cuda_lib})
+ message(FATAL_ERROR "expected CUDAToolkit target CUDA::${cuda_lib} not found")
+ endif()
+endforeach()
+
+foreach (cuda_lib nvrtc nvToolsExt OpenCL)
+ if(NOT CUDA_${cuda_lib}_LIBRARY)
+ message(FATAL_ERROR "expected CUDAToolkit variable CUDA_${cuda_lib}_LIBRARY not found")
+ endif()
+
+ if(NOT TARGET CUDA::${cuda_lib})
+ message(FATAL_ERROR "expected CUDAToolkit target CUDA::${cuda_lib} not found")
+ endif()
+endforeach()
+
+add_executable(CudaOnlyToolkit main.cu)
+target_link_libraries(CudaOnlyToolkit PRIVATE CUDA::toolkit)
diff --git a/Tests/CudaOnly/Toolkit/main.cu b/Tests/CudaOnly/Toolkit/main.cu
new file mode 100644
index 0000000..0f3ccdc
--- /dev/null
+++ b/Tests/CudaOnly/Toolkit/main.cu
@@ -0,0 +1,8 @@
+// Only thing we care about is that these headers are found
+#include <cuda.h>
+#include <cuda_runtime_api.h>
+
+int main(int argc, char** argv)
+{
+ return 0;
+}
diff --git a/Tests/CudaOnly/WithDefs/CMakeLists.txt b/Tests/CudaOnly/WithDefs/CMakeLists.txt
index 00fd7d2..add8131 100644
--- a/Tests/CudaOnly/WithDefs/CMakeLists.txt
+++ b/Tests/CudaOnly/WithDefs/CMakeLists.txt
@@ -3,17 +3,7 @@ cmake_minimum_required(VERSION 3.7)
project (WithDefs CUDA)
#verify that we can pass explicit cuda arch flags
-string(APPEND CMAKE_CUDA_FLAGS " -gencode arch=compute_30,code=compute_30")
-if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 9)
- set(debug_compile_flags --generate-code arch=compute_32,code=sm_32)
-else()
- set(debug_compile_flags --generate-code arch=compute_20,code=sm_20)
-endif()
-if(CMAKE_CUDA_SIMULATE_ID STREQUAL "MSVC")
- list(APPEND debug_compile_flags -Xcompiler=-WX)
-else()
- list(APPEND debug_compile_flags -Xcompiler=-Werror)
-endif()
+set(CMAKE_CUDA_ARCHITECTURES 30)
set(release_compile_defs DEFREL)
#Goal for this example:
@@ -28,8 +18,7 @@ target_compile_options(CudaOnlyWithDefs
PRIVATE
-DFLAG_COMPILE_LANG_$<COMPILE_LANGUAGE>
-DFLAG_LANG_IS_CUDA=$<COMPILE_LANGUAGE:CUDA>
- -Xcompiler=-DHOST_DEFINE
- $<$<CONFIG:DEBUG>:$<BUILD_INTERFACE:${debug_compile_flags}>>
+ --compiler-options=-DHOST_DEFINE
)
target_compile_definitions(CudaOnlyWithDefs
diff --git a/Tests/CustComDepend/CMakeLists.txt b/Tests/CustComDepend/CMakeLists.txt
index 46276b2..777cdcc 100644
--- a/Tests/CustComDepend/CMakeLists.txt
+++ b/Tests/CustComDepend/CMakeLists.txt
@@ -6,9 +6,9 @@ set(EXECUTABLE_OUTPUT_PATH ${CustComDepend_BINARY_DIR}/bin)
add_executable(foo foo.cxx)
add_custom_command(
OUTPUT ${CustComDepend_BINARY_DIR}/bar.c
- COMMAND ${CustComDepend_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/foo
+ COMMAND $<TARGET_FILE:foo>
${CustComDepend_BINARY_DIR}/bar.c
- DEPENDS ${CustComDepend_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/foo
+ DEPENDS $<TARGET_FILE:foo>
)
add_library(bar SHARED ${CustComDepend_BINARY_DIR}/bar.c)
diff --git a/Tests/CustomCommand/CMakeLists.txt b/Tests/CustomCommand/CMakeLists.txt
index e9a9f52..53d56bf 100644
--- a/Tests/CustomCommand/CMakeLists.txt
+++ b/Tests/CustomCommand/CMakeLists.txt
@@ -70,7 +70,7 @@ add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/doc1.h APPEND
COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_BINARY_DIR}/doc1temp.h
${PROJECT_BINARY_DIR}/doc1.h
COMMAND ${CMAKE_COMMAND} -E echo " Removing doc1temp.h."
- COMMAND ${CMAKE_COMMAND} -E remove -f ${PROJECT_BINARY_DIR}/doc1temp.h
+ COMMAND ${CMAKE_COMMAND} -E rm -f ${PROJECT_BINARY_DIR}/doc1temp.h
)
# Add custom command to generate foo.h.
@@ -412,7 +412,7 @@ add_custom_target(do_check_command_line ALL
add_dependencies(do_check_command_line check_command_line)
add_custom_target(pre_check_command_line
- COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_CURRENT_BINARY_DIR}/check_mark.txt
+ COMMAND ${CMAKE_COMMAND} -E rm -f ${CMAKE_CURRENT_BINARY_DIR}/check_mark.txt
)
add_dependencies(do_check_command_line pre_check_command_line)
@@ -534,3 +534,43 @@ add_custom_command(
set_property(SOURCE "${gen_file}" PROPERTY SYMBOLIC ON)
add_custom_target(command_expand_lists ALL DEPENDS "${gen_file}")
set_property(TARGET command_expand_lists PROPERTY CMPARGS "${cmp_args}")
+
+# This also tests that `./` is squeezed out of the resulting path.
+set(depends_path "./depended_upon_path.txt")
+
+add_custom_command(
+ OUTPUT ${depends_path}
+ COMMAND ${CMAKE_COMMAND} -E touch ${depends_path}
+)
+
+add_custom_command(
+ OUTPUT "depends_on_path.txt"
+ COMMAND ${CMAKE_COMMAND} -E touch "depends_on_path.txt"
+ DEPENDS ${depends_path}
+)
+
+add_custom_target(depends_on_path ALL DEPENDS "depends_on_path.txt")
+
+add_custom_command(
+ OUTPUT "depends_on_in_source_path.txt"
+ COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/main.cxx" depends_on_in_source_path.txt
+ DEPENDS main.cxx
+)
+
+add_custom_target(depends_on_in_source_path ALL DEPENDS "depends_on_in_source_path.txt")
+
+add_custom_command(
+ OUTPUT "depends_on_in_rel_source_path.txt"
+ COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/main.cxx" depends_on_in_rel_source_path.txt
+ DEPENDS ./main.cxx
+)
+
+add_custom_target(depends_on_in_rel_source_path ALL DEPENDS "depends_on_in_rel_source_path.txt")
+
+add_library(mac_fw SHARED mac_fw.c)
+set_target_properties(mac_fw PROPERTIES
+ FRAMEWORK 1
+ LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib
+ )
+add_custom_command(OUTPUT mac_fw.txt COMMAND ${CMAKE_COMMAND} -E touch mac_fw.txt DEPENDS mac_fw)
+add_custom_target(drive_mac_fw ALL DEPENDS mac_fw.txt)
diff --git a/Tests/CustomCommand/mac_fw.c b/Tests/CustomCommand/mac_fw.c
new file mode 100644
index 0000000..cb35b44
--- /dev/null
+++ b/Tests/CustomCommand/mac_fw.c
@@ -0,0 +1,4 @@
+int mac_fw(void)
+{
+ return 0;
+}
diff --git a/Tests/EnforceConfig.cmake.in b/Tests/EnforceConfig.cmake.in
index b7587aa..7781ded 100644
--- a/Tests/EnforceConfig.cmake.in
+++ b/Tests/EnforceConfig.cmake.in
@@ -33,5 +33,6 @@ unset(ENV{CMAKE_GENERATOR})
unset(ENV{CMAKE_GENERATOR_INSTANCE})
unset(ENV{CMAKE_GENERATOR_PLATFORM})
unset(ENV{CMAKE_GENERATOR_TOOLSET})
+unset(ENV{CMAKE_EXPORT_COMPILE_COMMANDS})
@TEST_HOME_ENV_CODE@
diff --git a/Tests/ExportImport/CMakeLists.txt b/Tests/ExportImport/CMakeLists.txt
index dc621eb..d88eb11 100644
--- a/Tests/ExportImport/CMakeLists.txt
+++ b/Tests/ExportImport/CMakeLists.txt
@@ -7,7 +7,7 @@ endif()
# Wipe out the install tree to make sure the exporter works.
add_custom_command(
OUTPUT ${ExportImport_BINARY_DIR}/CleanupProject
- COMMAND ${CMAKE_COMMAND} -E remove_directory ${ExportImport_BINARY_DIR}/Root
+ COMMAND ${CMAKE_COMMAND} -E rm -rf ${ExportImport_BINARY_DIR}/Root
)
add_custom_target(CleanupTarget ALL DEPENDS ${ExportImport_BINARY_DIR}/CleanupProject)
set_property(
diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt
index 9d8a248..387fe6b 100644
--- a/Tests/ExportImport/Export/CMakeLists.txt
+++ b/Tests/ExportImport/Export/CMakeLists.txt
@@ -156,6 +156,7 @@ target_link_libraries(testLibDepends PRIVATE testStaticLibRequiredPrivate)
cmake_policy(POP)
cmake_policy(PUSH)
+cmake_policy(SET CMP0022 NEW)
cmake_policy(SET CMP0079 NEW)
add_library(TopDirLib STATIC testTopDirLib.c)
add_subdirectory(SubDirLinkA)
@@ -240,6 +241,10 @@ set_property(TARGET testLibRequired APPEND PROPERTY
)
include(GenerateExportHeader)
+# Test deprecation of imported library
+add_library(testLibDeprecation STATIC testLib1.c)
+set_property(TARGET testLibDeprecation PROPERTY DEPRECATION "Deprecated version. Please use latest version")
+
add_subdirectory(renamed)
add_library(testSharedLibRequired SHARED testSharedLibRequired.cpp)
@@ -515,6 +520,7 @@ install(
testExe2lib testLib4lib testLib4libdbg testLib4libopt
testLib6 testLib7 testLib8
testLib9
+ testLibDeprecation
testLibCycleA testLibCycleB
testLibNoSONAME
cmp0022NEW cmp0022OLD
@@ -585,6 +591,7 @@ export(TARGETS testExe1 testLib1 testLib2 testLib3
export(TARGETS testExe2 testLib4 testLib5 testLib6 testLib7 testExe3 testExe4 testExe2lib
testLib8
testLib9 testLib9ObjPub testLib9ObjPriv testLib9ObjIface
+ testLibDeprecation
testLib4lib testLib4libdbg testLib4libopt
testLibCycleA testLibCycleB
testLibNoSONAME
@@ -646,6 +653,18 @@ if(CMAKE_GENERATOR MATCHES "Make|Ninja")
export(TARGETS testLinkDepends NAMESPACE bld_ APPEND FILE ExportBuildTree.cmake)
endif()
+#------------------------------------------------------------------------------
+# test export of CUDA language
+if(CMake_TEST_CUDA)
+ enable_language(CUDA)
+ add_library(cudaInterfaceLib INTERFACE)
+ target_compile_features(cudaInterfaceLib INTERFACE $<BUILD_INTERFACE:cuda_std_11> $<INSTALL_INTERFACE:cuda_std_14>)
+
+ install(TARGETS cudaInterfaceLib
+ EXPORT RequiredExp DESTINATION lib)
+ export(TARGETS cudaInterfaceLib NAMESPACE bld_ APPEND FILE ExportBuildTree.cmake)
+endif()
+
# Test the presence of targets named the same as languages.
# IMPORTED_LINK_INTERFACE_LANGUAGES entries should not be targets.
add_library(C INTERFACE)
diff --git a/Tests/ExportImport/Export/SubDirLinkA/CMakeLists.txt b/Tests/ExportImport/Export/SubDirLinkA/CMakeLists.txt
index 1c3c9dc..1aa41d2 100644
--- a/Tests/ExportImport/Export/SubDirLinkA/CMakeLists.txt
+++ b/Tests/ExportImport/Export/SubDirLinkA/CMakeLists.txt
@@ -1,6 +1,6 @@
add_library(SubDirLinkAImported IMPORTED INTERFACE)
target_compile_definitions(SubDirLinkAImported INTERFACE DEF_SubDirLinkAImportedForExport)
-target_link_libraries(TopDirLib PUBLIC SubDirLinkAImported)
+target_link_libraries(TopDirLib PUBLIC debug "$<1:SubDirLinkAImported;SubDirLinkAImported>" optimized "$<1:SubDirLinkAImported;SubDirLinkAImported>")
add_library(SubDirLinkA STATIC SubDirLinkA.c)
diff --git a/Tests/ExportImport/Import/A/CMakeLists.txt b/Tests/ExportImport/Import/A/CMakeLists.txt
index b5df961..3cb3833 100644
--- a/Tests/ExportImport/Import/A/CMakeLists.txt
+++ b/Tests/ExportImport/Import/A/CMakeLists.txt
@@ -51,6 +51,12 @@ checkForProperty(bld_testLib4 "EXPORTED_PROPERTY2" "EXPORTING_TESTLIB4_1")
checkForProperty(exp_testLib4 "EXPORTED_PROPERTY2" "EXPORTING_TESTLIB4_1")
checkForProperty(bld_testLib4 "EXPORTED_PROPERTY3" "EXPORTING_TESTLIB4_2")
checkForProperty(exp_testLib4 "EXPORTED_PROPERTY3" "EXPORTING_TESTLIB4_2")
+checkForProperty(bld_testLibDeprecation "DEPRECATION" "Deprecated version. Please use latest version")
+checkForProperty(exp_testLibDeprecation "DEPRECATION" "Deprecated version. Please use latest version")
+
+# Try linking to a deprecated library
+target_link_libraries(imp_testExe1 exp_testLibDeprecation)
+
# Try linking to a library imported from the install tree.
target_link_libraries(imp_testExe1
@@ -499,3 +505,10 @@ if(CMAKE_GENERATOR MATCHES "Make|Ninja")
checkForProperty(bld_testLinkDepends "INTERFACE_LINK_DEPENDS" "BUILD_LINK_DEPENDS")
checkForProperty(Req::testLinkDepends "INTERFACE_LINK_DEPENDS" "${CMAKE_INSTALL_PREFIX}/INSTALL_LINK_DEPENDS")
endif()
+
+#------------------------------------------------------------------------------
+# test import of CUDA language level
+if(CMake_TEST_CUDA)
+ checkForProperty(bld_cudaInterfaceLib "INTERFACE_COMPILE_FEATURES" "cuda_std_11")
+ checkForProperty(Req::cudaInterfaceLib "INTERFACE_COMPILE_FEATURES" "cuda_std_14")
+endif()
diff --git a/Tests/ExportImport/InitialCache.cmake.in b/Tests/ExportImport/InitialCache.cmake.in
index f600d90..44cd179 100644
--- a/Tests/ExportImport/InitialCache.cmake.in
+++ b/Tests/ExportImport/InitialCache.cmake.in
@@ -14,3 +14,4 @@ set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "@CMAKE_CXX_FLAGS_RELWITHDEBINFO@" CACHE STRI
set(CMAKE_INSTALL_PREFIX "@ExportImport_BINARY_DIR@/Root" CACHE STRING "Installation Prefix")
set(CMAKE_SKIP_RPATH ON CACHE BOOL "No RPATH")
set(CMAKE_GNUtoMS "@ExportImport_GNUtoMS@" CACHE BOOL "CMAKE_GNUtoMS")
+set(CMake_TEST_CUDA "@CMake_TEST_CUDA@" CACHE BOOL "CMake_TEST_CUDA")
diff --git a/Tests/ExternalProject/CMakeLists.txt b/Tests/ExternalProject/CMakeLists.txt
index 093391e..c8850ea 100644
--- a/Tests/ExternalProject/CMakeLists.txt
+++ b/Tests/ExternalProject/CMakeLists.txt
@@ -100,6 +100,15 @@ ExternalProject_Add(${proj}
INSTALL_COMMAND ""
)
+set(proj NoExtractBool)
+ExternalProject_Add(${proj}
+ URL ${CMAKE_CURRENT_SOURCE_DIR}/gitrepo.tgz
+ DOWNLOAD_NO_EXTRACT 0
+ LOG_DOWNLOAD 1
+ BUILD_COMMAND ""
+ CONFIGURE_COMMAND ""
+ INSTALL_COMMAND ""
+)
# CVS-based tests:
#
@@ -380,7 +389,9 @@ if(do_git_tests)
set(proj TutorialStep1-GIT-config)
ExternalProject_Add(${proj}
GIT_REPOSITORY "${local_git_repo}"
- GIT_CONFIG core.eol=lf core.autocrlf=input
+ GIT_CONFIG core.eol=lf
+ core.autocrlf=input
+ "http.extraheader=AUTHORIZATION: bearer --unsupportedOption"
CMAKE_GENERATOR "${CMAKE_GENERATOR}"
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
INSTALL_COMMAND ""
@@ -482,6 +493,66 @@ if(do_git_tests)
)
set_property(TARGET ${proj} PROPERTY FOLDER "GIT")
+ # Unzip/untar the git repository in our source folder so that other
+ # projects below may use it to test git args of ExternalProject_Add
+ #
+ set(proj SetupLocalGITRepositoryWithRecursiveSubmodules)
+ ExternalProject_Add(${proj}
+ SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/LocalRepositories/GIT-with-recursive-submodules
+ URL ${CMAKE_CURRENT_SOURCE_DIR}/gitrepo-sub-rec.tgz
+ BUILD_COMMAND ""
+ CONFIGURE_COMMAND "${GIT_EXECUTABLE}" --version
+ INSTALL_COMMAND ""
+ )
+ set_property(TARGET ${proj}
+ PROPERTY FOLDER "SetupRepos/Local/Deeply/Nested/For/Testing")
+
+ set(local_git_repo "../../LocalRepositories/GIT-with-recursive-submodules")
+
+ set(proj TS1-GIT-RECURSIVE_SUBMODULES-default)
+ ExternalProject_Add(${proj}
+ GIT_REPOSITORY "${local_git_repo}"
+ CMAKE_GENERATOR "${CMAKE_GENERATOR}"
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+ -DWITH_RECURSIVE:BOOL=ON
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+ DEPENDS "SetupLocalGITRepository"
+ "SetupLocalGITRepositoryWithSubmodules"
+ "SetupLocalGITRepositoryWithRecursiveSubmodules"
+ )
+ set_property(TARGET ${proj} PROPERTY FOLDER "GIT")
+
+ set(proj TS1-GIT-RECURSIVE_SUBMODULES-exclusive)
+ ExternalProject_Add(${proj}
+ GIT_REPOSITORY "${local_git_repo}"
+ GIT_SUBMODULES_RECURSE TRUE
+ CMAKE_GENERATOR "${CMAKE_GENERATOR}"
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+ -DWITH_RECURSIVE:BOOL=ON
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+ DEPENDS "SetupLocalGITRepository"
+ "SetupLocalGITRepositoryWithSubmodules"
+ "SetupLocalGITRepositoryWithRecursiveSubmodules"
+ )
+ set_property(TARGET ${proj} PROPERTY FOLDER "GIT")
+
+ set(proj TS1-GIT-RECURSIVE_SUBMODULES-off)
+ ExternalProject_Add(${proj}
+ GIT_REPOSITORY "${local_git_repo}"
+ GIT_SUBMODULES_RECURSE FALSE
+ CMAKE_GENERATOR "${CMAKE_GENERATOR}"
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+ -DWITH_RECURSIVE:BOOL=OFF
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ""
+ DEPENDS "SetupLocalGITRepository"
+ "SetupLocalGITRepositoryWithSubmodules"
+ "SetupLocalGITRepositoryWithRecursiveSubmodules"
+ )
+ set_property(TARGET ${proj} PROPERTY FOLDER "GIT")
+
endif()
set(do_hg_tests 0)
@@ -601,11 +672,19 @@ if(do_git_tests)
add_test(TutorialStep1-GIT-bytag
"${binary_base}/TutorialStep1-GIT-bytag/Tutorial" 99)
+ add_test(TutorialStep1-GIT-bytag-withsubmodules
+ "${binary_base}/TutorialStep1-GIT-bytag-withsubmodules/Tutorial" 99)
+
add_test(TutorialStep1-GIT-shallow-master
"${binary_base}/TutorialStep1-GIT-shallow-master/Tutorial" 98)
add_test(TutorialStep1-GIT-master
"${binary_base}/TutorialStep1-GIT-master/Tutorial" 98)
+
+ if(NOT git_version VERSION_LESS 1.7.7)
+ add_test(TutorialStep1-GIT-config
+ "${binary_base}/TutorialStep1-GIT-config/Tutorial" 98)
+ endif()
endif()
diff --git a/Tests/ExternalProject/gitrepo-sub-rec.tgz b/Tests/ExternalProject/gitrepo-sub-rec.tgz
new file mode 100644
index 0000000..b0f3f18
--- /dev/null
+++ b/Tests/ExternalProject/gitrepo-sub-rec.tgz
Binary files differ
diff --git a/Tests/FindBLAS/CMakeLists.txt b/Tests/FindBLAS/CMakeLists.txt
new file mode 100644
index 0000000..667195d
--- /dev/null
+++ b/Tests/FindBLAS/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_test(NAME FindBLAS.Test COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindBLAS/Test"
+ "${CMake_BINARY_DIR}/Tests/FindBLAS/Test"
+ ${build_generator_args}
+ --build-project TestFindBLAS
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
diff --git a/Tests/FindBLAS/Test/CMakeLists.txt b/Tests/FindBLAS/Test/CMakeLists.txt
new file mode 100644
index 0000000..59418f3
--- /dev/null
+++ b/Tests/FindBLAS/Test/CMakeLists.txt
@@ -0,0 +1,13 @@
+cmake_minimum_required(VERSION 3.4)
+project(TestFindBLAS C)
+include(CTest)
+
+find_package(BLAS REQUIRED)
+
+add_executable(test_tgt main.c)
+target_link_libraries(test_tgt BLAS::BLAS)
+add_test(NAME test_tgt COMMAND test_tgt)
+
+add_executable(test_var main.c)
+target_link_libraries(test_var PRIVATE ${BLAS_LIBRARIES})
+add_test(NAME test_var COMMAND test_var)
diff --git a/Tests/FindBLAS/Test/main.c b/Tests/FindBLAS/Test/main.c
new file mode 100644
index 0000000..7360dee
--- /dev/null
+++ b/Tests/FindBLAS/Test/main.c
@@ -0,0 +1,14 @@
+#include <assert.h>
+#include <string.h>
+
+// declare what parts of the blas C-API we need
+void cblas_dswap(const int N, double* X, const int incX, double* Y,
+ const int incY);
+
+int main()
+{
+ double x[4] = { 1, 2, 3, 4 };
+ double y[4] = { 8, 7, 7, 6 };
+ cblas_dswap(4, x, 1, y, 1);
+ return 0;
+}
diff --git a/Tests/FindDoxygen/StampFile/CMakeLists.txt b/Tests/FindDoxygen/StampFile/CMakeLists.txt
index 2d06540..ed2bfbb 100644
--- a/Tests/FindDoxygen/StampFile/CMakeLists.txt
+++ b/Tests/FindDoxygen/StampFile/CMakeLists.txt
@@ -3,22 +3,41 @@ project(TestFindDoxygen VERSION 1.0 LANGUAGES NONE)
find_package(Doxygen REQUIRED)
+set(DOXYGEN_OUTPUT_DIRECTORY noFiles)
doxygen_add_docs(docsWithoutFilesWithStamp USE_STAMP_FILE)
if(NOT EXISTS "${PROJECT_BINARY_DIR}/Doxyfile.docsWithoutFilesWithStamp")
- message(FATAL_ERROR "Missing generated file: Doxyfile.docsWithoutFilesWithStamp")
+ message(FATAL_ERROR "Missing generated file: Doxyfile.docsWithoutFilesWithStamp")
endif()
if(NOT TARGET docsWithoutFilesWithStamp)
- message(FATAL_ERROR "Target docsWithoutFilesWithStamp not created")
+ message(FATAL_ERROR "Target docsWithoutFilesWithStamp not created")
endif()
+set(DOXYGEN_OUTPUT_DIRECTORY withFiles)
doxygen_add_docs(docsWithFilesWithStamp main.cpp main2.cpp USE_STAMP_FILE)
if(NOT EXISTS "${PROJECT_BINARY_DIR}/Doxyfile.docsWithFilesWithStamp")
- message(FATAL_ERROR "Missing generated file: Doxyfile.docsWithFilesWithStamp")
+ message(FATAL_ERROR "Missing generated file: Doxyfile.docsWithFilesWithStamp")
endif()
if(NOT TARGET docsWithFilesWithStamp)
- message(FATAL_ERROR "Target docsWithFilesWithStamp not created")
+ message(FATAL_ERROR "Target docsWithFilesWithStamp not created")
endif()
+# Confirm that doxygen_add_docs() doesn't cause a fatal error if given a
+# source file that is generated at build time
+file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/genDox.cpp)
+add_custom_command(OUTPUT genDox.cpp
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/main2.cpp genDox.cpp
+ DEPENDS main2.cpp
+)
+set(DOXYGEN_OUTPUT_DIRECTORY withGenFiles)
+doxygen_add_docs(docsWithGenFilesWithStamp
+ main.cpp
+ ${CMAKE_CURRENT_BINARY_DIR}/genDox.cpp
+ USE_STAMP_FILE
+)
add_custom_target(allDocTargets)
-add_dependencies(allDocTargets docsWithoutFilesWithStamp docsWithFilesWithStamp)
+add_dependencies(allDocTargets
+ docsWithoutFilesWithStamp
+ docsWithFilesWithStamp
+ docsWithGenFilesWithStamp
+)
diff --git a/Tests/FindGTest/Test/CMakeLists.txt b/Tests/FindGTest/Test/CMakeLists.txt
index b65b9d2..6537238 100644
--- a/Tests/FindGTest/Test/CMakeLists.txt
+++ b/Tests/FindGTest/Test/CMakeLists.txt
@@ -8,6 +8,10 @@ add_executable(test_gtest_tgt main.cxx)
target_link_libraries(test_gtest_tgt GTest::Main)
add_test(NAME test_gtest_tgt COMMAND test_gtest_tgt)
+add_executable(test_gtest_tgt_upstream main.cxx)
+target_link_libraries(test_gtest_tgt_upstream GTest::gtest_main)
+add_test(NAME test_gtest_tgt_upstream COMMAND test_gtest_tgt_upstream)
+
add_executable(test_gtest_var main.cxx)
target_include_directories(test_gtest_var PRIVATE ${GTEST_INCLUDE_DIRS})
target_link_libraries(test_gtest_var PRIVATE ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
diff --git a/Tests/FindLAPACK/CMakeLists.txt b/Tests/FindLAPACK/CMakeLists.txt
new file mode 100644
index 0000000..2081d59
--- /dev/null
+++ b/Tests/FindLAPACK/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_test(NAME FindLAPACK.Test COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindLAPACK/Test"
+ "${CMake_BINARY_DIR}/Tests/FindLAPACK/Test"
+ ${build_generator_args}
+ --build-project TestFindLAPACK
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
diff --git a/Tests/FindLAPACK/Test/CMakeLists.txt b/Tests/FindLAPACK/Test/CMakeLists.txt
new file mode 100644
index 0000000..8afa36a
--- /dev/null
+++ b/Tests/FindLAPACK/Test/CMakeLists.txt
@@ -0,0 +1,13 @@
+cmake_minimum_required(VERSION 3.4)
+project(TestFindLAPACK C)
+include(CTest)
+
+find_package(LAPACK REQUIRED)
+
+add_executable(test_tgt main.c)
+target_link_libraries(test_tgt LAPACK::LAPACK)
+add_test(NAME test_tgt COMMAND test_tgt)
+
+add_executable(test_var main.c)
+target_link_libraries(test_var PRIVATE ${LAPACK_LIBRARIES})
+add_test(NAME test_var COMMAND test_var)
diff --git a/Tests/FindLAPACK/Test/main.c b/Tests/FindLAPACK/Test/main.c
new file mode 100644
index 0000000..5873e7b
--- /dev/null
+++ b/Tests/FindLAPACK/Test/main.c
@@ -0,0 +1,20 @@
+#include <assert.h>
+#include <string.h>
+
+// declare what parts of the lapack C-API we need
+void dgesv_(int*, int*, double*, int*, int*, double*, int*, int*);
+
+int main()
+{
+ double A[8] = {
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ };
+ double B[2] = { 0, 5 };
+ int ipiv[2] = { 0, 0 };
+ int info = 0;
+
+ int dim = 2;
+ int numCols = 1;
+ dgesv_(&dim, &numCols, A, &dim, ipiv, B, &dim, &info);
+ return 0;
+}
diff --git a/Tests/FindLibArchive/CMakeLists.txt b/Tests/FindLibArchive/CMakeLists.txt
new file mode 100644
index 0000000..f532ef2
--- /dev/null
+++ b/Tests/FindLibArchive/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_test(NAME FindLibArchive.Test COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindLibArchive/Test"
+ "${CMake_BINARY_DIR}/Tests/FindLibArchive/Test"
+ ${build_generator_args}
+ --build-project TestFindLibArchive
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
diff --git a/Tests/FindLibArchive/Test/CMakeLists.txt b/Tests/FindLibArchive/Test/CMakeLists.txt
new file mode 100644
index 0000000..35843bb
--- /dev/null
+++ b/Tests/FindLibArchive/Test/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.12)
+project(TestFindLibArchive C)
+include(CTest)
+
+find_package(LibArchive REQUIRED)
+
+add_executable(test_libarchive_tgt main.c)
+target_link_libraries(test_libarchive_tgt LibArchive::LibArchive)
+add_test(NAME test_libarchive_tgt COMMAND test_libarchive_tgt)
+
+add_executable(test_libarchive_var main.c)
+target_include_directories(test_libarchive_var PRIVATE ${LibArchive_INCLUDE_DIRS})
+target_link_libraries(test_libarchive_var PRIVATE ${LibArchive_LIBRARIES})
+add_test(NAME test_libarchive_var COMMAND test_libarchive_var)
diff --git a/Tests/FindLibArchive/Test/main.c b/Tests/FindLibArchive/Test/main.c
new file mode 100644
index 0000000..03e7ece
--- /dev/null
+++ b/Tests/FindLibArchive/Test/main.c
@@ -0,0 +1,7 @@
+#include <archive.h>
+
+int main(void)
+{
+ archive_read_free(archive_read_new());
+ return 0;
+}
diff --git a/Tests/FindLibXml2/Test/CMakeLists.txt b/Tests/FindLibXml2/Test/CMakeLists.txt
index df5d8c3..041cc13 100644
--- a/Tests/FindLibXml2/Test/CMakeLists.txt
+++ b/Tests/FindLibXml2/Test/CMakeLists.txt
@@ -14,3 +14,7 @@ add_executable(test_var main.c)
target_include_directories(test_var PRIVATE ${LIBXML2_INCLUDE_DIRS})
target_link_libraries(test_var PRIVATE ${LIBXML2_LIBRARIES})
add_test(NAME test_var COMMAND test_var)
+
+add_test(NAME xmllint_tgt COMMAND LibXml2::xmllint --version)
+
+add_test(NAME xmllint_var COMMAND ${LIBXML2_XMLLINT_EXECUTABLE} --version)
diff --git a/Tests/FindLibXslt/CMakeLists.txt b/Tests/FindLibXslt/CMakeLists.txt
new file mode 100644
index 0000000..8a550b2
--- /dev/null
+++ b/Tests/FindLibXslt/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_test(NAME FindLibXslt.Test COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindLibXslt/Test"
+ "${CMake_BINARY_DIR}/Tests/FindLibXslt/Test"
+ ${build_generator_args}
+ --build-project TestFindLibXslt
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+)
diff --git a/Tests/FindLibXslt/Test/CMakeLists.txt b/Tests/FindLibXslt/Test/CMakeLists.txt
new file mode 100644
index 0000000..e932661
--- /dev/null
+++ b/Tests/FindLibXslt/Test/CMakeLists.txt
@@ -0,0 +1,45 @@
+cmake_minimum_required(VERSION 3.4)
+project(TestFindLibXslt C)
+include(CTest)
+
+find_package(Iconv)
+find_package(LibXml2 REQUIRED)
+find_package(LibXslt REQUIRED)
+
+add_definitions(-DCMAKE_EXPECTED_LibXslt_VERSION="${LIBXSLT_VERSION_STRING}")
+
+add_executable(libxslt_tgt libxslt.c)
+if(Iconv_FOUND)
+ target_link_libraries(libxslt_tgt Iconv::Iconv)
+endif()
+target_link_libraries(libxslt_tgt LibXml2::LibXml2 LibXslt::LibXslt)
+add_test(NAME libxslt_tgt COMMAND libxslt_tgt)
+
+add_executable(libxslt_var libxslt.c)
+if(Iconv_FOUND)
+ target_include_directories(libxslt_var PRIVATE ${Iconv_INCLUDE_DIRS})
+ target_link_libraries(libxslt_var PRIVATE ${Iconv_LIBRARIES})
+endif()
+target_include_directories(libxslt_var PRIVATE ${LIBXML2_INCLUDE_DIRS} ${LIBXSLT_INCLUDE_DIR})
+target_link_libraries(libxslt_var PRIVATE ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES})
+add_test(NAME libxslt_var COMMAND libxslt_var)
+
+add_executable(libexslt_tgt libexslt.c)
+if(Iconv_FOUND)
+ target_link_libraries(libexslt_tgt Iconv::Iconv)
+endif()
+target_link_libraries(libexslt_tgt LibXml2::LibXml2 LibXslt::LibXslt LibXslt::LibExslt)
+add_test(NAME libexslt_tgt COMMAND libexslt_tgt)
+
+add_executable(libexslt_var libexslt.c)
+if(Iconv_FOUND)
+ target_include_directories(libexslt_var PRIVATE ${Iconv_INCLUDE_DIRS})
+ target_link_libraries(libexslt_var PRIVATE ${Iconv_LIBRARIES})
+endif()
+target_include_directories(libexslt_var PRIVATE ${LIBXML2_INCLUDE_DIRS} ${LIBXSLT_INCLUDE_DIR} ${LIBXSLT_EXSLT_INCLUDE_DIR})
+target_link_libraries(libexslt_var PRIVATE ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${LIBXSLT_EXSLT_LIBRARIES})
+add_test(NAME libexslt_var COMMAND libexslt_var)
+
+add_test(NAME xsltproc_tgt COMMAND LibXslt::xsltproc --version)
+
+add_test(NAME xsltproc_var COMMAND ${LIBXSLT_XSLTPROC_EXECUTABLE} --version)
diff --git a/Tests/FindLibXslt/Test/libexslt.c b/Tests/FindLibXslt/Test/libexslt.c
new file mode 100644
index 0000000..ea6eb3d
--- /dev/null
+++ b/Tests/FindLibXslt/Test/libexslt.c
@@ -0,0 +1,16 @@
+#include <libexslt/exslt.h>
+#include <libxslt/xslt.h>
+#include <libxslt/xsltInternals.h>
+
+int main()
+{
+ xsltInit();
+
+ xsltStylesheet* style = xsltNewStylesheet();
+ exsltRegisterAll();
+ xsltFreeStylesheet(style);
+
+ xsltCleanupGlobals();
+
+ return 0;
+}
diff --git a/Tests/FindLibXslt/Test/libxslt.c b/Tests/FindLibXslt/Test/libxslt.c
new file mode 100644
index 0000000..5b3d766
--- /dev/null
+++ b/Tests/FindLibXslt/Test/libxslt.c
@@ -0,0 +1,24 @@
+#include <libxslt/xslt.h>
+#include <libxslt/xsltInternals.h>
+#include <libxslt/xsltconfig.h>
+#include <stdio.h>
+#include <string.h>
+
+int main()
+{
+ xsltInit();
+
+ xsltStylesheet* style = xsltNewStylesheet();
+ xsltFreeStylesheet(style);
+
+ if (0 != strcmp(CMAKE_EXPECTED_LibXslt_VERSION, LIBXSLT_DOTTED_VERSION)) {
+ printf("CMAKE_EXPECTED_LibXslt_VERSION: '%s'\n",
+ CMAKE_EXPECTED_LibXslt_VERSION);
+ printf("LIBXSLT_DOTTED_VERSION: '%s'\n", LIBXSLT_DOTTED_VERSION);
+ return 1;
+ }
+
+ xsltCleanupGlobals();
+
+ return 0;
+}
diff --git a/Tests/FindPackageModeMakefileTest/CMakeLists.txt b/Tests/FindPackageModeMakefileTest/CMakeLists.txt
index 23832da..8a87a8c 100644
--- a/Tests/FindPackageModeMakefileTest/CMakeLists.txt
+++ b/Tests/FindPackageModeMakefileTest/CMakeLists.txt
@@ -19,6 +19,14 @@ if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Makefile" AND
# configure a FindFoo.cmake so it knows where the library can be found
configure_file(FindFoo.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/FindFoo.cmake @ONLY)
+ # Need the -isysroot flag on recentish macOS after command line tools
+ # no longer provide headers in /usr/include
+ if(APPLE AND CMAKE_OSX_SYSROOT)
+ set(__EXTRA_OSX_SYSROOT_FLAGS "-isysroot ${CMAKE_OSX_SYSROOT}")
+ else()
+ set(__EXTRA_OSX_SYSROOT_FLAGS "")
+ endif()
+
# now set up the test:
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/cmakeExecutable.mk"
CONTENT "CMAKE = \"$<TARGET_FILE:cmake>\"\n"
diff --git a/Tests/FindPackageModeMakefileTest/Makefile.in b/Tests/FindPackageModeMakefileTest/Makefile.in
index 8e7ff72..5ef67d0 100644
--- a/Tests/FindPackageModeMakefileTest/Makefile.in
+++ b/Tests/FindPackageModeMakefileTest/Makefile.in
@@ -5,6 +5,7 @@ CMAKE_CURRENT_BINARY_DIR = "@CMAKE_CURRENT_BINARY_DIR@"
CMAKE_CXX_COMPILER = "@CMAKE_CXX_COMPILER@"
CMAKE_CXX_COMPILER_ID = "@CMAKE_CXX_COMPILER_ID@"
CMAKE_CXX_FLAGS = @CMAKE_CXX_FLAGS@
+__EXTRA_OSX_SYSROOT_FLAGS = @__EXTRA_OSX_SYSROOT_FLAGS@
CMAKE_FOO = $(CMAKE) --find-package -DCMAKE_MODULE_PATH=$(CMAKE_CURRENT_BINARY_DIR) -DNAME=Foo -DLANGUAGE=CXX -DCOMPILER_ID=$(CMAKE_CXX_COMPILER_ID)
@@ -15,7 +16,7 @@ all: pngtest
main.o: clean main.cpp
@$(CMAKE_FOO) -DMODE=COMPILE >$(tmp)
@foo="`cat $(tmp)`"; \
- printf '"%s" %s %s -c main.cpp\n' $(CMAKE_CXX_COMPILER) "$(CMAKE_CXX_FLAGS)" "$$foo" >$(tmp)
+ printf '"%s" %s %s %s -c main.cpp\n' $(CMAKE_CXX_COMPILER) "$(CMAKE_CXX_FLAGS)" "$(__EXTRA_OSX_SYSROOT_FLAGS)" "$$foo" >$(tmp)
@cat $(tmp)
@sh $(tmp)
@rm -f $(tmp)
diff --git a/Tests/FindPython/ArtifactsInteractive/CMakeLists.txt b/Tests/FindPython/ArtifactsInteractive/CMakeLists.txt
new file mode 100644
index 0000000..524be92
--- /dev/null
+++ b/Tests/FindPython/ArtifactsInteractive/CMakeLists.txt
@@ -0,0 +1,24 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestArtifactsInteractive LANGUAGES C)
+
+set (components Interpreter Development)
+if (CMake_TEST_FindPython_NumPy)
+ list (APPEND components NumPy)
+endif()
+
+find_package(Python3 REQUIRED COMPONENTS ${components})
+
+if (Python3_ARTIFACTS_INTERACTIVE)
+ if (NOT DEFINED CACHE{Python3_EXECUTABLE}
+ OR NOT DEFINED CACHE{Python3_LIBRARY} OR NOT DEFINED CACHE{Python3_INCLUDE_DIR}
+ OR (CMake_TEST_FindPython_NumPy AND NOT DEFINED CACHE{Python3_NumPy_INCLUDE_DIR}))
+ message (FATAL_ERROR "Python3_ARTIFACTS_INTERACTIVE=ON Failed.")
+ endif()
+else()
+ if (DEFINED CACHE{Python3_EXECUTABLE}
+ OR DEFINED CACHE{Python3_LIBRARY} OR DEFINED CACHE{Python3_INCLUDE_DIR}
+ OR (CMake_TEST_FindPython_NumPy AND DEFINED CACHE{Python3_NumPy_INCLUDE_DIR}))
+ message (FATAL_ERROR "Python3_ARTIFACTS_INTERACTIVE=OFF Failed.")
+ endif()
+endif()
diff --git a/Tests/FindPython/CMakeLists.txt b/Tests/FindPython/CMakeLists.txt
index 868cfe0..fdfa36e 100644
--- a/Tests/FindPython/CMakeLists.txt
+++ b/Tests/FindPython/CMakeLists.txt
@@ -20,6 +20,17 @@ if(CMake_TEST_FindPython)
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
+ add_test(NAME FindPython.Python2.Development.Module COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/Python2Module"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python2Module"
+ ${build_generator_args}
+ --build-project TestPython2Module
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+
add_test(NAME FindPython.Python2Fail COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
@@ -54,6 +65,17 @@ if(CMake_TEST_FindPython)
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
+ add_test(NAME FindPython.Python3.Development.Module COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/Python3Module"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python3Module"
+ ${build_generator_args}
+ --build-project TestPython3Module
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+
add_test(NAME FindPython.Python3Fail COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
@@ -67,14 +89,157 @@ if(CMake_TEST_FindPython)
set_tests_properties(FindPython.Python3Fail PROPERTIES
PASS_REGULAR_EXPRESSION "Could NOT find Python3 \\(missing: foobar\\)")
- add_test(NAME FindPython.Python COMMAND
+ add_test(NAME FindPython.Python.LOCATION COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
"${CMake_SOURCE_DIR}/Tests/FindPython/Python"
- "${CMake_BINARY_DIR}/Tests/FindPython/Python"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python.LOCATION"
${build_generator_args}
--build-project TestPython
- --build-options ${build_options}
+ --build-options ${build_options} -DPython_FIND_STRATEGY=LOCATION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.Python.VERSION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/Python"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python.VERSION"
+ ${build_generator_args}
+ --build-project TestPython
+ --build-options ${build_options} -DPython_FIND_STRATEGY=VERSION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.Python.V2.LOCATION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/Python"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python.V2.LOCATION"
+ ${build_generator_args}
+ --build-project TestPython
+ --build-options ${build_options} -DPython_REQUESTED_VERSION=2 -DPython_FIND_STRATEGY=LOCATION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.Python.V2.VERSION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/Python"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python.V2.VERSION"
+ ${build_generator_args}
+ --build-project TestPython
+ --build-options ${build_options} -DPython_REQUESTED_VERSION=2 -DPython_FIND_STRATEGY=VERSION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.Python.V3.LOCATION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/Python"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python.V3.LOCATION"
+ ${build_generator_args}
+ --build-project TestPython
+ --build-options ${build_options} -DPython_REQUESTED_VERSION=3 -DPython_FIND_STRATEGY=LOCATION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.Python.V3.VERSION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/Python"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python.V3.VERSION"
+ ${build_generator_args}
+ --build-project TestPython
+ --build-options ${build_options} -DPython_REQUESTED_VERSION=3 -DPython_FIND_STRATEGY=VERSION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+
+ add_test(NAME FindPython.Python2.ExactVersion.LOCATION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/ExactVersion"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python2.ExactVersion.LOCATION"
+ ${build_generator_args}
+ --build-project TestExactVersion
+ --build-options ${build_options} -DPython_MAJOR_VERSION=2
+ -DPython_REQUESTED_VERSION=2.1.2
+ -DPython2_FIND_STRATEGY=LOCATION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.Python2.ExactVersion.VERSION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/ExactVersion"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python2.ExactVersion.VERSION"
+ ${build_generator_args}
+ --build-project TestExactVersion
+ --build-options ${build_options} -DPython_MAJOR_VERSION=2
+ -DPython_REQUESTED_VERSION=2.1.2
+ -DPython2_FIND_STRATEGY=VERSION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.Python3.ExactVersion.LOCATION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/ExactVersion"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python3.ExactVersion.LOCATION"
+ ${build_generator_args}
+ --build-project TestExactVersion
+ --build-options ${build_options} -DPython_MAJOR_VERSION=3
+ -DPython_REQUESTED_VERSION=3.1.2
+ -DPython3_FIND_STRATEGY=LOCATION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.Python3.ExactVersion.VERSION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/ExactVersion"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python3.ExactVersion.VERSION"
+ ${build_generator_args}
+ --build-project TestExactVersion
+ --build-options ${build_options} -DPython_MAJOR_VERSION=3
+ -DPython_REQUESTED_VERSION=3.1.2
+ -DPython3_FIND_STRATEGY=VERSION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.Python.V2.ExactVersion.LOCATION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/ExactVersion"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python.V2.ExactVersion.LOCATION"
+ ${build_generator_args}
+ --build-project TestExactVersion
+ --build-options ${build_options} -DPython_REQUESTED_VERSION=2.1.2
+ -DPython_FIND_STRATEGY=LOCATION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.Python.V2.ExactVersion.VERSION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/ExactVersion"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python.V2.ExactVersion.VERSION"
+ ${build_generator_args}
+ --build-project TestExactVersion
+ --build-options ${build_options} -DPython_REQUESTED_VERSION=2.1.2
+ -DPython_FIND_STRATEGY=VERSION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.Python.V3.ExactVersion.LOCATION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/ExactVersion"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python.V3.ExactVersion.LOCATION"
+ ${build_generator_args}
+ --build-project TestExactVersion
+ --build-options ${build_options} -DPython_REQUESTED_VERSION=3.1.2
+ -DPython_FIND_STRATEGY=LOCATION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.Python.V3.ExactVersion.VERSION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/ExactVersion"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Python.V3.ExactVersion.VERSION"
+ ${build_generator_args}
+ --build-project TestExactVersion
+ --build-options ${build_options} -DPython_REQUESTED_VERSION=3.1.2
+ -DPython_FIND_STRATEGY=VERSION
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
@@ -134,6 +299,77 @@ if(CMake_TEST_FindPython)
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
+ add_test(NAME FindPython.ArtifactsInteractive.ON COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/ArtifactsInteractive"
+ "${CMake_BINARY_DIR}/Tests/FindPython/ArtifactsInteractive.ON"
+ ${build_generator_args}
+ --build-project TestArtifactsScope
+ --build-options ${build_options} "-Dbuild_generator_args=${build_generator_args}"
+ "-DCMake_SOURCE_DIR=${CMake_SOURCE_DIR}"
+ "-DCMake_BINARY_DIR=${CMake_BINARY_DIR}"
+ "-DCMake_TEST_FindPython_NumPy=${CMake_TEST_FindPython_NumPy}"
+ "-DPython3_ARTIFACTS_INTERACTIVE=ON"
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.ArtifactsInteractive.OFF COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/ArtifactsInteractive"
+ "${CMake_BINARY_DIR}/Tests/FindPython/ArtifactsInteractive.OFF"
+ ${build_generator_args}
+ --build-project TestArtifactsScope
+ --build-options ${build_options} "-Dbuild_generator_args=${build_generator_args}"
+ "-DCMake_SOURCE_DIR=${CMake_SOURCE_DIR}"
+ "-DCMake_BINARY_DIR=${CMake_BINARY_DIR}"
+ "-DCMake_TEST_FindPython_NumPy=${CMake_TEST_FindPython_NumPy}"
+ "-DPython3_ARTIFACTS_INTERACTIVE=OFF"
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+
+ add_test(NAME FindPython.CustomFailureMessage COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/CustomFailureMessage"
+ "${CMake_BINARY_DIR}/Tests/FindPython/CustomFailureMessage"
+ ${build_generator_args}
+ --build-project TestCustomFailureMessage
+ --build-options ${build_options} "-Dbuild_generator_args=${build_generator_args}"
+ "-DCMake_SOURCE_DIR=${CMake_SOURCE_DIR}"
+ "-DCMake_BINARY_DIR=${CMake_BINARY_DIR}"
+ "-DCMake_TEST_FindPython_NumPy=${CMake_TEST_FindPython_NumPy}"
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+
+ if (CMAKE_SYSTEM_NAME MATCHES "Linux|Darwin")
+ add_test(NAME FindPython.Interpreter.SOABI COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/SOABI"
+ "${CMake_BINARY_DIR}/Tests/FindPython/SOABI.Interpreter"
+ ${build_generator_args}
+ --build-project TestSOABI
+ --build-options ${build_options} "-Dbuild_generator_args=${build_generator_args}"
+ "-DCMake_SOURCE_DIR=${CMake_SOURCE_DIR}"
+ "-DCMake_BINARY_DIR=${CMake_BINARY_DIR}"
+ "-DCMake_TEST_FindPython_COMPONENT=Interpreter"
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.Development.SOABI COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/SOABI"
+ "${CMake_BINARY_DIR}/Tests/FindPython/SOABI.Development"
+ ${build_generator_args}
+ --build-project TestSOABI
+ --build-options ${build_options} "-Dbuild_generator_args=${build_generator_args}"
+ "-DCMake_SOURCE_DIR=${CMake_SOURCE_DIR}"
+ "-DCMake_BINARY_DIR=${CMake_BINARY_DIR}"
+ "-DCMake_TEST_FindPython_COMPONENT=Development"
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ endif()
endif()
if(CMake_TEST_FindPython_NumPy)
@@ -155,6 +391,210 @@ if(CMake_TEST_FindPython_NumPy)
${build_generator_args}
--build-project TestNumPyOnly
--build-options ${build_options}
- --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
- endif()
+endif()
+
+if(CMake_TEST_FindPython_Conda)
+ add_test(NAME FindPython.VirtualEnvConda COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/VirtualEnvConda"
+ "${CMake_BINARY_DIR}/Tests/FindPython/VirtualEnvConda"
+ ${build_generator_args}
+ --build-project TestVirtualEnvConda
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+endif()
+
+if (CMake_TEST_FindPython AND CMake_TEST_FindPython_IronPython)
+ add_test(NAME FindPython.Implementation.CPython COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/Implementation"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Implementation.CPython"
+ ${build_generator_args}
+ --build-project TestImplementationCPython
+ --build-options ${build_options} -DPython_REQUESTED_VERSION=2 -DPython_REQUESTED_IMPLEMENTATIONS=CPython
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.Implementation.IronPython COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/Implementation"
+ "${CMake_BINARY_DIR}/Tests/FindPython/Implementation.IronPython"
+ ${build_generator_args}
+ --build-project TestImplementationIronPython
+ --build-options ${build_options} -DPython_REQUESTED_VERSION=2 -DPython_REQUESTED_IMPLEMENTATION=IronPython
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+endif()
+
+if(CMake_TEST_FindPython_IronPython)
+ add_test(NAME FindPython.IronPython2.LOCATION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/IronPython2"
+ "${CMake_BINARY_DIR}/Tests/FindPython/IronPython2.LOCATION"
+ ${build_generator_args}
+ --build-project TestIronPython2
+ --build-options ${build_options} -DPython2_FIND_STRATEGY=LOCATION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.IronPython2.VERSION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/IronPython2"
+ "${CMake_BINARY_DIR}/Tests/FindPython/IronPython2.VERSION"
+ ${build_generator_args}
+ --build-project TestIronPython2
+ --build-options ${build_options} -DPython2_FIND_STRATEGY=VERSION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+
+ add_test(NAME FindPython.IronPython.LOCATION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/IronPython"
+ "${CMake_BINARY_DIR}/Tests/FindPython/IronPython.LOCATION"
+ ${build_generator_args}
+ --build-project TestIronPython
+ --build-options ${build_options} -DPython_FIND_STRATEGY=LOCATION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.IronPython.VERSION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/IronPython"
+ "${CMake_BINARY_DIR}/Tests/FindPython/IronPython.VERSION"
+ ${build_generator_args}
+ --build-project TestIronPython
+ --build-options ${build_options} -DPython_FIND_STRATEGY=VERSION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.IronPython.V2.LOCATION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/IronPython"
+ "${CMake_BINARY_DIR}/Tests/FindPython/IronPython.V2.LOCATION"
+ ${build_generator_args}
+ --build-project TestIronPython
+ --build-options ${build_options} -DPython_REQUESTED_VERSION=2 -DPython_FIND_STRATEGY=LOCATION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.IronPython.V2.VERSION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/IronPython"
+ "${CMake_BINARY_DIR}/Tests/FindPython/IronPython.V2.VERSION"
+ ${build_generator_args}
+ --build-project TestIronPython
+ --build-options ${build_options} -DPython_REQUESTED_VERSION=2 -DPython_FIND_STRATEGY=VERSION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+endif()
+
+if(CMake_TEST_FindPython_PyPy)
+ add_test(NAME FindPython.PyPy2.LOCATION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy2"
+ "${CMake_BINARY_DIR}/Tests/FindPython/PyPy2.LOCATION"
+ ${build_generator_args}
+ --build-project TestPyPy2
+ --build-options ${build_options} -DPython2_FIND_STRATEGY=LOCATION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.PyPy2.VERSION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy2"
+ "${CMake_BINARY_DIR}/Tests/FindPython/PyPy2.VERSION"
+ ${build_generator_args}
+ --build-project TestPyPy2
+ --build-options ${build_options} -DPython2_FIND_STRATEGY=VERSION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+
+ add_test(NAME FindPython.PyPy3.LOCATION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy3"
+ "${CMake_BINARY_DIR}/Tests/FindPython/PyPy3.LOCATION"
+ ${build_generator_args}
+ --build-project TestPyPy3
+ --build-options ${build_options} -DPython3_FIND_STRATEGY=LOCATION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.PyPy3.VERSION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy3"
+ "${CMake_BINARY_DIR}/Tests/FindPython/PyPy3.VERSION"
+ ${build_generator_args}
+ --build-project TestPyPy3
+ --build-options ${build_options} -DPython3_FIND_STRATEGY=VERSION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+
+ add_test(NAME FindPython.PyPy.LOCATION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy"
+ "${CMake_BINARY_DIR}/Tests/FindPython/PyPy.LOCATION"
+ ${build_generator_args}
+ --build-project TestPyPy
+ --build-options ${build_options} -DPython_FIND_STRATEGY=LOCATION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.PyPy.VERSION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy"
+ "${CMake_BINARY_DIR}/Tests/FindPython/PyPy.VERSION"
+ ${build_generator_args}
+ --build-project TestPyPy
+ --build-options ${build_options} -DPython_FIND_STRATEGY=VERSION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.PyPy.V2.LOCATION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy"
+ "${CMake_BINARY_DIR}/Tests/FindPython/PyPy.V2.LOCATION"
+ ${build_generator_args}
+ --build-project TestPyPy
+ --build-options ${build_options} -DPython_REQUESTED_VERSION=2 -DPython_FIND_STRATEGY=LOCATION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.PyPy.V2.VERSION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy"
+ "${CMake_BINARY_DIR}/Tests/FindPython/PyPy.V2.VERSION"
+ ${build_generator_args}
+ --build-project TestPyPy
+ --build-options ${build_options} -DPython_REQUESTED_VERSION=2 -DPython_FIND_STRATEGY=VERSION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.PyPy.V3.LOCATION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy"
+ "${CMake_BINARY_DIR}/Tests/FindPython/PyPy.V3.LOCATION"
+ ${build_generator_args}
+ --build-project TestPyPy
+ --build-options ${build_options} -DPython_REQUESTED_VERSION=3 -DPython_FIND_STRATEGY=LOCATION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ add_test(NAME FindPython.PyPy.V3.VERSION COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/PyPy"
+ "${CMake_BINARY_DIR}/Tests/FindPython/PyPy.V3.VERSION"
+ ${build_generator_args}
+ --build-project TestPyPy
+ --build-options ${build_options} -DPython_REQUESTED_VERSION=3 -DPython_FIND_STRATEGY=VERSION
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+endif()
diff --git a/Tests/FindPython/CustomFailureMessage/CMakeLists.txt b/Tests/FindPython/CustomFailureMessage/CMakeLists.txt
new file mode 100644
index 0000000..a0d8eb2
--- /dev/null
+++ b/Tests/FindPython/CustomFailureMessage/CMakeLists.txt
@@ -0,0 +1,79 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestCustomFailureMessage LANGUAGES NONE)
+
+include(CTest)
+
+add_test(NAME FindPython.CustomFailureMessage.Interpreter COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/CustomFailureMessage/Check"
+ "${CMake_BINARY_DIR}/Tests/FindPython/CustomFailureMessage/Interpreter"
+ ${build_generator_args}
+ --build-project TestCustomFailureMessage.Check
+ --build-options "-DCHECK_COMPONENTS=Interpreter"
+ "-DPython3_EXECUTABLE=/not/found/interpreter"
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+set_tests_properties(FindPython.CustomFailureMessage.Interpreter PROPERTIES
+ PASS_REGULAR_EXPRESSION "Reason given by package:.+Interpreter: Cannot run the interpreter")
+
+add_test(NAME FindPython.CustomFailureMessage.Library COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/CustomFailureMessage/Check"
+ "${CMake_BINARY_DIR}/Tests/FindPython/CustomFailureMessage/Library"
+ ${build_generator_args}
+ --build-project TestCustomFailureMessage.Check
+ --build-options "-DCHECK_COMPONENTS=Development"
+ "-DPython3_LIBRARY=/not/found/library"
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+set_tests_properties(FindPython.CustomFailureMessage.Library PROPERTIES
+ PASS_REGULAR_EXPRESSION "Reason given by package:.+Development: Cannot find the library")
+
+add_test(NAME FindPython.CustomFailureMessage.Include COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/CustomFailureMessage/Check"
+ "${CMake_BINARY_DIR}/Tests/FindPython/CustomFailureMessage/Include"
+ ${build_generator_args}
+ --build-project TestCustomFailureMessage.Check
+ --build-options "-DCHECK_COMPONENTS=Development"
+ "-DPython3_INCLUDE_DIR=/not/found/include"
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+set_tests_properties(FindPython.CustomFailureMessage.Include PROPERTIES
+ PASS_REGULAR_EXPRESSION "Reason given by package:.+Development: Cannot find the directory")
+
+add_test(NAME FindPython.CustomFailureMessage.Multiple COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/CustomFailureMessage/Check"
+ "${CMake_BINARY_DIR}/Tests/FindPython/CustomFailureMessage/Multiple"
+ ${build_generator_args}
+ --build-project TestCustomFailureMessage.Check
+ --build-options "-DCHECK_COMPONENTS=Interpreter;Development"
+ "-DPython3_EXECUTABLE=/not/found/interpreter"
+ "-DPython3_LIBRARY=/not/found/library"
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+set_tests_properties(FindPython.CustomFailureMessage.Multiple PROPERTIES
+ PASS_REGULAR_EXPRESSION "Reason given by package:.+Interpreter: Cannot run the interpreter.+Development: Cannot find the library")
+
+
+if (CMake_TEST_FindPython_NumPy)
+ add_test(NAME FindPython.CustomFailureMessage.NumPy COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindPython/CustomFailureMessage/Check"
+ "${CMake_BINARY_DIR}/Tests/FindPython/CustomFailureMessage/NumPy"
+ ${build_generator_args}
+ --build-project TestCustomFailureMessage.Check
+ --build-options "-DCHECK_COMPONENTS=Interpreter;Development;NumPy"
+ "-DPython3_NumPy_INCLUDE_DIR=/not/found/numpy/include"
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ set_tests_properties(FindPython.CustomFailureMessage.NumPy PROPERTIES
+ PASS_REGULAR_EXPRESSION "Reason given by package:.+NumPy: Cannot find the directory")
+endif()
diff --git a/Tests/FindPython/CustomFailureMessage/Check/CMakeLists.txt b/Tests/FindPython/CustomFailureMessage/Check/CMakeLists.txt
new file mode 100644
index 0000000..fed963e
--- /dev/null
+++ b/Tests/FindPython/CustomFailureMessage/Check/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestCustomFailureMessage.Check LANGUAGES C)
+
+find_package (Python3 REQUIRED COMPONENTS ${CHECK_COMPONENTS})
diff --git a/Tests/FindPython/ExactVersion/CMakeLists.txt b/Tests/FindPython/ExactVersion/CMakeLists.txt
new file mode 100644
index 0000000..e09f73a
--- /dev/null
+++ b/Tests/FindPython/ExactVersion/CMakeLists.txt
@@ -0,0 +1,56 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestExactVersion C)
+
+find_package(Python${Python_MAJOR_VERSION} ${Python_REQUESTED_VERSION} COMPONENTS Interpreter Development)
+if (NOT Python${Python_MAJOR_VERSION}_FOUND)
+ message (FATAL_ERROR "Fail to found Python ${Python_REQUESTED_VERSION}")
+endif()
+if (NOT Python${Python_MAJOR_VERSION}_Interpreter_FOUND)
+ message (FATAL_ERROR "Fail to found Python ${Python_REQUESTED_VERSION} Interpreter")
+endif()
+if (NOT Python${Python_MAJOR_VERSION}_Development_FOUND)
+ message (FATAL_ERROR "Fail to found Python ${Python_REQUESTED_VERSION} Development")
+endif()
+
+if(NOT TARGET Python${Python_MAJOR_VERSION}::Interpreter)
+ message(SEND_ERROR "Python${Python_MAJOR_VERSION}::Interpreter not found")
+endif()
+
+if(NOT TARGET Python${Python_MAJOR_VERSION}::Python)
+ message(SEND_ERROR "Python${Python_MAJOR_VERSION}::Python not found")
+endif()
+if(NOT TARGET Python${Python_MAJOR_VERSION}::Module)
+ message(SEND_ERROR "Python${Python_MAJOR_VERSION}::Module not found")
+endif()
+
+
+# reset artifacts and second search with exact version already founded
+unset (Python${Python_MAJOR_VERSION}_EXECUTABLE)
+unset (_Python${Python_MAJOR_VERSION}_EXECUTABLE CACHE)
+
+unset (_Python${Python_MAJOR_VERSION}_LIBRARY_RELEASE CACHE)
+unset (_Python${Python_MAJOR_VERSION}_INCLUDE_DIR CACHE)
+
+set (Python_REQUESTED_VERSION ${Python${Python_MAJOR_VERSION}_VERSION})
+find_package(Python${Python_MAJOR_VERSION} ${Python_REQUESTED_VERSION} EXACT COMPONENTS Interpreter Development)
+if (NOT Python${Python_MAJOR_VERSION}_FOUND)
+ message (FATAL_ERROR "Fail to found Python ${Python_REQUESTED_VERSION}")
+endif()
+if (NOT Python${Python_MAJOR_VERSION}_Interpreter_FOUND)
+ message (FATAL_ERROR "Fail to found Python ${Python_REQUESTED_VERSION} Interpreter")
+endif()
+if (NOT Python${Python_MAJOR_VERSION}_Development_FOUND)
+ message (FATAL_ERROR "Fail to found Python ${Python_REQUESTED_VERSION} Development")
+endif()
+
+if(NOT TARGET Python${Python_MAJOR_VERSION}::Interpreter)
+ message(SEND_ERROR "Python${Python_MAJOR_VERSION}::Interpreter not found")
+endif()
+
+if(NOT TARGET Python${Python_MAJOR_VERSION}::Python)
+ message(SEND_ERROR "Python${Python_MAJOR_VERSION}::Python not found")
+endif()
+if(NOT TARGET Python${Python_MAJOR_VERSION}::Module)
+ message(SEND_ERROR "Python${Python_MAJOR_VERSION}::Module not found")
+endif()
diff --git a/Tests/FindPython/Implementation/CMakeLists.txt b/Tests/FindPython/Implementation/CMakeLists.txt
new file mode 100644
index 0000000..d64fa1e
--- /dev/null
+++ b/Tests/FindPython/Implementation/CMakeLists.txt
@@ -0,0 +1,37 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestImplementation${Python_REQUESTED_IMPLEMENTATION} C)
+
+
+set (Python${Python_REQUESTED_VERSION}_FIND_IMPLEMENTATIONS ${Python_REQUESTED_IMPLEMENTATION})
+
+find_package(Python${Python_REQUESTED_VERSION} COMPONENTS Interpreter)
+if (NOT Python${Python_REQUESTED_VERSION}_FOUND OR NOT Python${Python_REQUESTED_VERSION}_Interpreter_FOUND)
+ message (FATAL_ERROR "Fail to found Python${Python_REQUESTED_VERSION}")
+endif()
+
+if (Python_REQUESTED_IMPLEMENTATION STREQUAL "IronPython"
+ AND NOT Python${Python_REQUESTED_VERSION}_INTERPRETER_ID STREQUAL "IronPython")
+ message (FATAL_ERROR "Erroneous interpreter ID (${Python${Python_REQUESTED_VERSION}_INTERPRETER_ID})")
+endif()
+if (Python_REQUESTED_IMPLEMENTATION STREQUAL "CPython"
+ AND Python${Python_REQUESTED_VERSION}_INTERPRETER_ID STREQUAL "IronPython")
+ message (FATAL_ERROR "Erroneous interpreter ID (${Python${Python_REQUESTED_VERSION}_INTERPRETER_ID})")
+endif()
+
+
+set (Python_FIND_IMPLEMENTATIONS ${Python_REQUESTED_IMPLEMENTATION})
+
+find_package(Python ${Python_REQUESTED_VERSION} REQUIRED COMPONENTS Interpreter)
+if (NOT Python_FOUND OR NOT Python_Interpreter_FOUND)
+ message (FATAL_ERROR "Fail to found Python ${Python_REQUESTED_VERSION}")
+endif()
+
+if (Python_REQUESTED_IMPLEMENTATION STREQUAL "IronPython"
+ AND NOT Python_INTERPRETER_ID STREQUAL "IronPython")
+ message (FATAL_ERROR "Erroneous interpreter ID (${Python_INTERPRETER_ID})")
+endif()
+if (Python_REQUESTED_IMPLEMENTATION STREQUAL "CPython"
+ AND Python_INTERPRETER_ID STREQUAL "IronPython")
+ message (FATAL_ERROR "Erroneous interpreter ID (${Python_INTERPRETER_ID})")
+endif()
diff --git a/Tests/FindPython/IronPython/CMakeLists.txt b/Tests/FindPython/IronPython/CMakeLists.txt
new file mode 100644
index 0000000..3493c29
--- /dev/null
+++ b/Tests/FindPython/IronPython/CMakeLists.txt
@@ -0,0 +1,31 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestIronPython C)
+
+set (Python_FIND_IMPLEMENTATIONS IronPython)
+
+find_package(Python ${Python_REQUESTED_VERSION} COMPONENTS Interpreter Compiler)
+if (NOT Python_FOUND)
+ message (FATAL_ERROR "Fail to found Python ${Python_REQUESTED_VERSION}")
+endif()
+
+if (NOT Python_Interpreter_FOUND)
+ message (FATAL_ERROR "Fail to found Python Interpreter")
+endif()
+if (NOT Python_INTERPRETER_ID STREQUAL "IronPython")
+ message (FATAL_ERROR "Erroneous interpreter ID (${Python_INTERPRETER_ID})")
+endif()
+
+if (NOT Python_Compiler_FOUND)
+ message (FATAL_ERROR "Fail to found Python Compiler")
+endif()
+if (NOT Python_COMPILER_ID STREQUAL "IronPython")
+ message (FATAL_ERROR "Erroneous compiler ID (${Python_COMPILER_ID})")
+endif()
+
+if(NOT TARGET Python::Interpreter)
+ message(SEND_ERROR "Python::Interpreter not found")
+endif()
+if(NOT TARGET Python::Compiler)
+ message(SEND_ERROR "Python::Interpreter not found")
+endif()
diff --git a/Tests/FindPython/IronPython2/CMakeLists.txt b/Tests/FindPython/IronPython2/CMakeLists.txt
new file mode 100644
index 0000000..1db798c
--- /dev/null
+++ b/Tests/FindPython/IronPython2/CMakeLists.txt
@@ -0,0 +1,31 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestIronPython2 C)
+
+set (Python2_FIND_IMPLEMENTATIONS "IronPython")
+
+find_package(Python2 COMPONENTS Interpreter Compiler)
+if (NOT Python2_FOUND)
+ message (FATAL_ERROR "Fail to found Python 2")
+endif()
+
+if (NOT Python2_Interpreter_FOUND)
+ message (FATAL_ERROR "Fail to found Python 2 Interpreter")
+endif()
+if (NOT Python2_INTERPRETER_ID STREQUAL "IronPython")
+ message (FATAL_ERROR "Erroneous interpreter ID (${Python2_INTERPRETER_ID})")
+endif()
+
+if (NOT Python2_Compiler_FOUND)
+ message (FATAL_ERROR "Fail to found Python 2 Compiler")
+endif()
+if (NOT Python2_COMPILER_ID STREQUAL "IronPython")
+ message (FATAL_ERROR "Erroneous compiler ID (${Python2_COMPILER_ID})")
+endif()
+
+if(NOT TARGET Python2::Interpreter)
+ message(SEND_ERROR "Python2::Interpreter not found")
+endif()
+if(NOT TARGET Python2::Compiler)
+ message(SEND_ERROR "Python2::Compiler not found")
+endif()
diff --git a/Tests/FindPython/PyPy/CMakeLists.txt b/Tests/FindPython/PyPy/CMakeLists.txt
new file mode 100644
index 0000000..b4ade8c
--- /dev/null
+++ b/Tests/FindPython/PyPy/CMakeLists.txt
@@ -0,0 +1,37 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestPyPy C)
+
+set (Python_FIND_IMPLEMENTATIONS PyPy)
+
+find_package(Python ${Python_REQUESTED_VERSION} COMPONENTS Interpreter Development)
+if (NOT Python_FOUND)
+ message (FATAL_ERROR "Fail to found Python PyPy ${Python_REQUESTED_VERSION}")
+endif()
+
+if (NOT Python_Interpreter_FOUND)
+ message (FATAL_ERROR "Fail to found Python PyPy Interpreter")
+endif()
+if (NOT Python_INTERPRETER_ID STREQUAL "PyPy")
+ message (FATAL_ERROR "Erroneous interpreter ID (${Python_INTERPRETER_ID})")
+endif()
+
+if (NOT Python_Development.Module_FOUND)
+ message (FATAL_ERROR "Fail to found Python PyPy ${Python_REQUESTED_VERSION} Development.Module")
+endif()
+if (NOT Python_Development.Embed_FOUND)
+ message (FATAL_ERROR "Fail to found Python PyPy ${Python_REQUESTED_VERSION} Development.Embed")
+endif()
+if (NOT Python_Development_FOUND)
+ message (FATAL_ERROR "Fail to found Python PyPy ${Python_REQUESTED_VERSION} Development")
+endif()
+
+if(NOT TARGET Python::Interpreter)
+ message(SEND_ERROR "Python::Interpreter not found")
+endif()
+if(NOT TARGET Python::Module)
+ message(SEND_ERROR "Python::Module not found")
+endif()
+if(NOT TARGET Python::Python)
+ message(SEND_ERROR "Python::Python not found")
+endif()
diff --git a/Tests/FindPython/PyPy2/CMakeLists.txt b/Tests/FindPython/PyPy2/CMakeLists.txt
new file mode 100644
index 0000000..2f0ddc9
--- /dev/null
+++ b/Tests/FindPython/PyPy2/CMakeLists.txt
@@ -0,0 +1,37 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestPyPy2 C)
+
+set (Python2_FIND_IMPLEMENTATIONS "PyPy")
+
+find_package(Python2 COMPONENTS Interpreter Development)
+if (NOT Python2_FOUND)
+ message (FATAL_ERROR "Fail to found Python PyPy 2")
+endif()
+
+if (NOT Python2_Interpreter_FOUND)
+ message (FATAL_ERROR "Fail to found Python PyPy 2 Interpreter")
+endif()
+if (NOT Python2_INTERPRETER_ID STREQUAL "PyPy")
+ message (FATAL_ERROR "Erroneous interpreter ID (${Python2_INTERPRETER_ID})")
+endif()
+
+if (NOT Python2_Development.Module_FOUND)
+ message (FATAL_ERROR "Fail to found Python PyPy 2 Development.Module")
+endif()
+if (NOT Python2_Development.Embed_FOUND)
+ message (FATAL_ERROR "Fail to found Python PyPy 2 Development.Embed")
+endif()
+if (NOT Python2_Development_FOUND)
+ message (FATAL_ERROR "Fail to found Python PyPy 2 Development")
+endif()
+
+if(NOT TARGET Python2::Interpreter)
+ message(SEND_ERROR "Python2::Interpreter not found")
+endif()
+if(NOT TARGET Python2::Module)
+ message(SEND_ERROR "Python2::Module not found")
+endif()
+if(NOT TARGET Python2::Python)
+ message(SEND_ERROR "Python2::Python not found")
+endif()
diff --git a/Tests/FindPython/PyPy3/CMakeLists.txt b/Tests/FindPython/PyPy3/CMakeLists.txt
new file mode 100644
index 0000000..5562d57
--- /dev/null
+++ b/Tests/FindPython/PyPy3/CMakeLists.txt
@@ -0,0 +1,37 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestPyPy3 C)
+
+set (Python3_FIND_IMPLEMENTATIONS "PyPy")
+
+find_package(Python3 COMPONENTS Interpreter Development)
+if (NOT Python3_FOUND)
+ message (FATAL_ERROR "Fail to found Python PyPy 3")
+endif()
+
+if (NOT Python3_Interpreter_FOUND)
+ message (FATAL_ERROR "Fail to found Python PyPy 3 Interpreter")
+endif()
+if (NOT Python3_INTERPRETER_ID STREQUAL "PyPy")
+ message (FATAL_ERROR "Erroneous interpreter ID (${Python3_INTERPRETER_ID})")
+endif()
+
+if (NOT Python3_Development.Module_FOUND)
+ message (FATAL_ERROR "Fail to found Python PyPy 3 Development.Module")
+endif()
+if (NOT Python3_Development.Embed_FOUND)
+ message (FATAL_ERROR "Fail to found Python PyPy 3 Development.Embed")
+endif()
+if (NOT Python3_Development_FOUND)
+ message (FATAL_ERROR "Fail to found Python PyPy 3 Development")
+endif()
+
+if(NOT TARGET Python3::Interpreter)
+ message(SEND_ERROR "Python3::Interpreter not found")
+endif()
+if(NOT TARGET Python3::Module)
+ message(SEND_ERROR "Python3::Module not found")
+endif()
+if(NOT TARGET Python3::Python)
+ message(SEND_ERROR "Python3::Python not found")
+endif()
diff --git a/Tests/FindPython/Python/CMakeLists.txt b/Tests/FindPython/Python/CMakeLists.txt
index 62c805e..e8828a2 100644
--- a/Tests/FindPython/Python/CMakeLists.txt
+++ b/Tests/FindPython/Python/CMakeLists.txt
@@ -4,9 +4,15 @@ project(TestPython C)
include(CTest)
-find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
+find_package(Python ${Python_REQUESTED_VERSION} REQUIRED COMPONENTS Interpreter Development)
if (NOT Python_FOUND)
- message (FATAL_ERROR "Fail to found Python 3")
+ message (FATAL_ERROR "Fail to found Python ${Python_REQUESTED_VERSION}")
+endif()
+if (NOT Python_Development.Module_FOUND)
+ message (FATAL_ERROR "Fail to found Python ${Python_REQUESTED_VERSION}, COMPONENT 'Development.Module'")
+endif()
+if (NOT Python_Development.Embed_FOUND)
+ message (FATAL_ERROR "Fail to found Python ${Python_REQUESTED_VERSION}, COMPOENENT 'Development.Embed'")
endif()
if(NOT TARGET Python::Interpreter)
@@ -20,13 +26,15 @@ if(NOT TARGET Python::Module)
message(SEND_ERROR "Python::Module not found")
endif()
-Python_add_library (spam3 MODULE ../spam.c)
-target_compile_definitions (spam3 PRIVATE PYTHON3)
-
-add_test (NAME python_spam3
- COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$<TARGET_FILE_DIR:spam3>"
- "${Python_EXECUTABLE}" -c "import spam3; spam3.system(\"cd\")")
-
-add_test(NAME findpython_script
- COMMAND "${CMAKE_COMMAND}" -DPYTHON_PACKAGE_NAME=Python
- -P "${CMAKE_CURRENT_LIST_DIR}/../FindPythonScript.cmake")
+if (Python_REQUESTED_VERSION)
+ Python_add_library (spam${Python_REQUESTED_VERSION} MODULE ../spam.c)
+ target_compile_definitions (spam${Python_REQUESTED_VERSION} PRIVATE PYTHON${Python_REQUESTED_VERSION})
+
+ add_test (NAME python_spam${Python_REQUESTED_VERSION}
+ COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$<TARGET_FILE_DIR:spam${Python_REQUESTED_VERSION}>"
+ "${Python_EXECUTABLE}" -c "import spam${Python_REQUESTED_VERSION}; spam${Python_REQUESTED_VERSION}.system(\"cd\")")
+else()
+ add_test(NAME findpython_script
+ COMMAND "${CMAKE_COMMAND}" -DPYTHON_PACKAGE_NAME=Python
+ -P "${CMAKE_CURRENT_LIST_DIR}/../FindPythonScript.cmake")
+endif()
diff --git a/Tests/FindPython/Python2/CMakeLists.txt b/Tests/FindPython/Python2/CMakeLists.txt
index cf77ca2..609d80f 100644
--- a/Tests/FindPython/Python2/CMakeLists.txt
+++ b/Tests/FindPython/Python2/CMakeLists.txt
@@ -13,6 +13,15 @@ find_package(Python2 REQUIRED COMPONENTS Interpreter Development)
if (NOT Python2_FOUND)
message (FATAL_ERROR "Fail to found Python 2")
endif()
+if (NOT Python2_Development_FOUND)
+ message (FATAL_ERROR "Fail to found Python 2 'Development' component")
+endif()
+if (NOT Python2_Development.Module_FOUND)
+ message (FATAL_ERROR "Fail to found Python 2 'Development.Module' component")
+endif()
+if (NOT Python2_Development.Embed_FOUND)
+ message (FATAL_ERROR "Fail to found Python 2 'Development.Embed' component")
+endif()
if(NOT TARGET Python2::Interpreter)
message(SEND_ERROR "Python2::Interpreter not found")
diff --git a/Tests/FindPython/Python2Embedded/CMakeLists.txt b/Tests/FindPython/Python2Embedded/CMakeLists.txt
index 0115dea..1cf6034 100644
--- a/Tests/FindPython/Python2Embedded/CMakeLists.txt
+++ b/Tests/FindPython/Python2Embedded/CMakeLists.txt
@@ -4,10 +4,23 @@ project(TestPython2Embedded C)
include(CTest)
-find_package(Python2 REQUIRED COMPONENTS Development)
+find_package(Python2 REQUIRED COMPONENTS Development.Embed)
if (NOT Python2_FOUND)
message (FATAL_ERROR "Fail to found Python 2")
endif()
+if (Python2_Development_FOUND)
+ message (FATAL_ERROR "Python 2, COMPONENT 'Development' unexpectedly found")
+endif()
+if (Python2_Development.Module_FOUND)
+ message (FATAL_ERROR "Python 2, COMPONENT 'Development.Module' unexpectedly found")
+endif()
+if (NOT Python2_Development.Embed_FOUND)
+ message (FATAL_ERROR "Python 2, COMPONENT 'Development.Embed' not found")
+endif()
+
+if(TARGET Python2::Module)
+ message(SEND_ERROR "Python2::Module unexpectedly found")
+endif()
if(NOT TARGET Python2::Python)
message(SEND_ERROR "Python2::Python not found")
diff --git a/Tests/FindPython/Python2Module/CMakeLists.txt b/Tests/FindPython/Python2Module/CMakeLists.txt
new file mode 100644
index 0000000..0bc3390
--- /dev/null
+++ b/Tests/FindPython/Python2Module/CMakeLists.txt
@@ -0,0 +1,37 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestPython2Module C)
+
+include(CTest)
+
+find_package(Python2 REQUIRED COMPONENTS Interpreter Development.Module)
+if (NOT Python2_FOUND)
+ message (FATAL_ERROR "Fail to found Python 2")
+endif()
+if (Python2_Development_FOUND)
+ message (FATAL_ERROR "Python 2, COMPONENT 'Development' unexpectedly found")
+endif()
+if (Python2_Development.Embed_FOUND)
+ message (FATAL_ERROR "Python 2, COMPONENT 'Development.Embed' unexpectedly found")
+endif()
+if (NOT Python2_Development.Module_FOUND)
+ message (FATAL_ERROR "Python 2, COMPONENT 'Development.Module' not found")
+endif()
+
+if(NOT TARGET Python2::Interpreter)
+ message(SEND_ERROR "Python2::Interpreter not found")
+endif()
+
+if(TARGET Python2::Python)
+ message(SEND_ERROR "Python2::Python unexpectedly found")
+endif()
+if(NOT TARGET Python2::Module)
+ message(SEND_ERROR "Python2::Module not found")
+endif()
+
+Python2_add_library (spam2 MODULE ../spam.c)
+target_compile_definitions (spam2 PRIVATE PYTHON2)
+
+add_test (NAME python2_spam2
+ COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$<TARGET_FILE_DIR:spam2>"
+ "${Python2_EXECUTABLE}" -c "import spam2; spam2.system(\"cd\")")
diff --git a/Tests/FindPython/Python3/CMakeLists.txt b/Tests/FindPython/Python3/CMakeLists.txt
index 6691a48..d6e5fdb 100644
--- a/Tests/FindPython/Python3/CMakeLists.txt
+++ b/Tests/FindPython/Python3/CMakeLists.txt
@@ -13,16 +13,25 @@ find_package(Python3 REQUIRED COMPONENTS Interpreter Development)
if (NOT Python3_FOUND)
message (FATAL_ERROR "Fail to found Python 3")
endif()
+if (NOT Python3_Development_FOUND)
+ message (FATAL_ERROR "Fail to found Python 3 'Development' component")
+endif()
+if (NOT Python3_Development.Module_FOUND)
+ message (FATAL_ERROR "Fail to found Python 3 'Development.Module' component")
+endif()
+if (NOT Python3_Development.Embed_FOUND)
+ message (FATAL_ERROR "Fail to found Python 3 'Development.Embed' component")
+endif()
if(NOT TARGET Python3::Interpreter)
- message(SEND_ERROR "Python2::Interpreter not found")
+ message(SEND_ERROR "Python3::Interpreter not found")
endif()
if(NOT TARGET Python3::Python)
- message(SEND_ERROR "Python2::Python not found")
+ message(SEND_ERROR "Python3::Python not found")
endif()
if(NOT TARGET Python3::Module)
- message(SEND_ERROR "Python2::Module not found")
+ message(SEND_ERROR "Python3::Module not found")
endif()
Python3_add_library (spam3 MODULE ../spam.c)
diff --git a/Tests/FindPython/Python3Embedded/CMakeLists.txt b/Tests/FindPython/Python3Embedded/CMakeLists.txt
index 4eb7ebc..184c0b4 100644
--- a/Tests/FindPython/Python3Embedded/CMakeLists.txt
+++ b/Tests/FindPython/Python3Embedded/CMakeLists.txt
@@ -4,10 +4,23 @@ project(TestPython3Embedded C)
include(CTest)
-find_package(Python3 REQUIRED COMPONENTS Development)
+find_package(Python3 REQUIRED COMPONENTS Development.Embed)
if (NOT Python3_FOUND)
message (FATAL_ERROR "Fail to found Python 3")
endif()
+if (Python3_Development_FOUND)
+ message (FATAL_ERROR "Python 3, COMPONENT 'Development' unexpectedly found")
+endif()
+if (Python3_Development.Module_FOUND)
+ message (FATAL_ERROR "Python 3, COMPONENT 'Development.Module' unexpectedly found")
+endif()
+if (NOT Python3_Development.Embed_FOUND)
+ message (FATAL_ERROR "Python 3, COMPONENT 'Development.Embed' not found")
+endif()
+
+if(TARGET Python3::Module)
+ message(SEND_ERROR "Python3::Module unexpectedly found")
+endif()
if(NOT TARGET Python3::Python)
message(SEND_ERROR "Python3::Python not found")
diff --git a/Tests/FindPython/Python3Module/CMakeLists.txt b/Tests/FindPython/Python3Module/CMakeLists.txt
new file mode 100644
index 0000000..676f4c8
--- /dev/null
+++ b/Tests/FindPython/Python3Module/CMakeLists.txt
@@ -0,0 +1,37 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestPython3Module C)
+
+include(CTest)
+
+find_package(Python3 REQUIRED COMPONENTS Interpreter Development.Module)
+if (NOT Python3_FOUND)
+ message (FATAL_ERROR "Fail to found Python 3")
+endif()
+if (Python3_Development_FOUND)
+ message (FATAL_ERROR "Python 3, COMPONENT 'Development' unexpectedly found")
+endif()
+if (Python3_Development.Embed_FOUND)
+ message (FATAL_ERROR "Python 3, COMPONENT 'Development.Embed' unexpectedly found")
+endif()
+if (NOT Python3_Development.Module_FOUND)
+ message (FATAL_ERROR "Python 3, COMPONENT 'Development.Module' not found")
+endif()
+
+if(NOT TARGET Python3::Interpreter)
+ message(SEND_ERROR "Python3::Interpreter not found")
+endif()
+
+if(TARGET Python3::Python)
+ message(SEND_ERROR "Python3::Python unexpectedly found")
+endif()
+if(NOT TARGET Python3::Module)
+ message(SEND_ERROR "Python3::Module not found")
+endif()
+
+Python3_add_library (spam3 MODULE ../spam.c)
+target_compile_definitions (spam3 PRIVATE PYTHON3)
+
+add_test (NAME python3_spam3
+ COMMAND "${CMAKE_COMMAND}" -E env "PYTHONPATH=$<TARGET_FILE_DIR:spam3>"
+ "${Python3_EXECUTABLE}" -c "import spam3; spam3.system(\"cd\")")
diff --git a/Tests/FindPython/SOABI/CMakeLists.txt b/Tests/FindPython/SOABI/CMakeLists.txt
new file mode 100644
index 0000000..4a6aea3
--- /dev/null
+++ b/Tests/FindPython/SOABI/CMakeLists.txt
@@ -0,0 +1,22 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestSOABI C)
+
+find_package(Python3 COMPONENTS ${CMake_TEST_FindPython_COMPONENT})
+if (NOT Python3_FOUND)
+ message (FATAL_ERROR "Fail to found Python 3")
+endif()
+
+if(NOT DEFINED Python3_SOABI)
+ message(FATAL_ERROR "Python3_SOABI for ${CMake_TEST_FindPython_COMPONENT} not found")
+endif()
+
+if (Python3_Development_FOUND AND Python3_SOABI)
+ Python3_add_library (spam3 MODULE WITH_SOABI ../spam.c)
+ target_compile_definitions (spam3 PRIVATE PYTHON3)
+
+ get_property (suffix TARGET spam3 PROPERTY SUFFIX)
+ if (NOT suffix MATCHES "^.${Python3_SOABI}")
+ message(FATAL_ERROR "Module suffix do not include Python3_SOABI")
+ endif()
+endif()
diff --git a/Tests/FindPython/VirtualEnv/CMakeLists.txt b/Tests/FindPython/VirtualEnv/CMakeLists.txt
index 64ba201..045a3f2 100644
--- a/Tests/FindPython/VirtualEnv/CMakeLists.txt
+++ b/Tests/FindPython/VirtualEnv/CMakeLists.txt
@@ -10,6 +10,7 @@ if (NOT Python3_FOUND)
endif()
set (Python3_VIRTUAL_ENV "${CMAKE_CURRENT_BINARY_DIR}/py3venv")
+file (REMOVE_RECURSE "${CMAKE_CURRENT_BINARY_DIR}/py3venv")
execute_process (COMMAND "${Python3_EXECUTABLE}" -m venv "${Python3_VIRTUAL_ENV}"
RESULT_VARIABLE result
@@ -21,22 +22,26 @@ endif()
add_test(NAME FindPython3.VirtualEnvDefault
COMMAND "${CMAKE_COMMAND}" -E env --unset=PYTHONHOME
+ --unset=CONDA_PREFIX
"VIRTUAL_ENV=${Python3_VIRTUAL_ENV}"
"${CMAKE_COMMAND}" "-DPYTHON3_VIRTUAL_ENV=${Python3_VIRTUAL_ENV}"
-P "${CMAKE_CURRENT_LIST_DIR}/VirtualEnvDefault.cmake")
add_test(NAME FindPython3.VirtualEnvOnly
COMMAND "${CMAKE_COMMAND}" -E env --unset=PYTHONHOME
+ --unset=CONDA_PREFIX
"VIRTUAL_ENV=${Python3_VIRTUAL_ENV}"
"${CMAKE_COMMAND}" "-DPYTHON3_VIRTUAL_ENV=${Python3_VIRTUAL_ENV}"
-P "${CMAKE_CURRENT_LIST_DIR}/VirtualEnvOnly.cmake")
add_test(NAME FindPython3.UnsetVirtualEnvOnly
COMMAND "${CMAKE_COMMAND}" -E env --unset=PYTHONHOME
--unset=VIRTUAL_ENV
+ --unset=CONDA_PREFIX
"${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_LIST_DIR}/VirtualEnvOnly.cmake")
add_test(NAME FindPython3.VirtualEnvStandard
COMMAND "${CMAKE_COMMAND}" -E env --unset=PYTHONHOME
+ --unset=CONDA_PREFIX
"VIRTUAL_ENV=${Python3_VIRTUAL_ENV}"
"${CMAKE_COMMAND}" "-DPYTHON3_VIRTUAL_ENV=${Python3_VIRTUAL_ENV}"
-P "${CMAKE_CURRENT_LIST_DIR}/VirtualEnvStandard.cmake")
diff --git a/Tests/FindPython/VirtualEnvConda/CMakeLists.txt b/Tests/FindPython/VirtualEnvConda/CMakeLists.txt
new file mode 100644
index 0000000..565095a
--- /dev/null
+++ b/Tests/FindPython/VirtualEnvConda/CMakeLists.txt
@@ -0,0 +1,46 @@
+cmake_minimum_required(VERSION 3.1)
+
+project(TestVirtualEnvConda LANGUAGES NONE)
+
+include(CTest)
+
+find_program(CONDA_EXECUTABLE conda)
+if (CONDA_EXECUTABLE EQUAL NOTFOUND)
+ message (FATAL_ERROR "Fail to found Conda")
+endif()
+
+set (Python3_VIRTUAL_ENV "${CMAKE_CURRENT_BINARY_DIR}/condaenv")
+
+execute_process (COMMAND "${CONDA_EXECUTABLE}" create --no-default-packages --prefix "${Python3_VIRTUAL_ENV}" --yes python=3
+ RESULT_VARIABLE result
+ OUTPUT_VARIABLE outputs
+ ERROR_VARIABLE outputs)
+if (result)
+ message (FATAL_ERROR "Fail to create virtual environment: ${outputs}")
+endif()
+
+add_test(NAME FindPython3.VirtualEnvDefaultConda
+ COMMAND "${CMAKE_COMMAND}" -E env --unset=PYTHONHOME
+ --unset=VIRTUAL_ENV
+ "CONDA_PREFIX=${Python3_VIRTUAL_ENV}"
+ "${CMAKE_COMMAND}" "-DPYTHON3_VIRTUAL_ENV=${Python3_VIRTUAL_ENV}"
+ -P "${CMAKE_CURRENT_LIST_DIR}/VirtualEnvDefault.cmake")
+
+add_test(NAME FindPython3.VirtualEnvOnlyConda
+ COMMAND "${CMAKE_COMMAND}" -E env --unset=PYTHONHOME
+ --unset=VIRTUAL_ENV
+ "CONDA_PREFIX=${Python3_VIRTUAL_ENV}"
+ "${CMAKE_COMMAND}" "-DPYTHON3_VIRTUAL_ENV=${Python3_VIRTUAL_ENV}"
+ -P "${CMAKE_CURRENT_LIST_DIR}/VirtualEnvOnly.cmake")
+add_test(NAME FindPython3.UnsetVirtualEnvOnlyConda
+ COMMAND "${CMAKE_COMMAND}" -E env --unset=PYTHONHOME
+ --unset=CONDA_PREFIX
+ --unset=VIRTUAL_ENV
+ "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_LIST_DIR}/VirtualEnvOnly.cmake")
+
+add_test(NAME FindPython3.VirtualEnvStandardConda
+ COMMAND "${CMAKE_COMMAND}" -E env --unset=PYTHONHOME
+ --unset=VIRTUAL_ENV
+ "CONDA_PREFIX=${Python3_VIRTUAL_ENV}"
+ "${CMAKE_COMMAND}" "-DPYTHON3_VIRTUAL_ENV=${Python3_VIRTUAL_ENV}"
+ -P "${CMAKE_CURRENT_LIST_DIR}/VirtualEnvStandard.cmake")
diff --git a/Tests/FindPython/VirtualEnvConda/VirtualEnvDefault.cmake b/Tests/FindPython/VirtualEnvConda/VirtualEnvDefault.cmake
new file mode 100644
index 0000000..020ecac
--- /dev/null
+++ b/Tests/FindPython/VirtualEnvConda/VirtualEnvDefault.cmake
@@ -0,0 +1,6 @@
+
+find_package (Python3 REQUIRED)
+
+if (NOT Python3_EXECUTABLE MATCHES "^${PYTHON3_VIRTUAL_ENV}/.+")
+ message (FATAL_ERROR "Fail to use virtual environment")
+endif()
diff --git a/Tests/FindPython/VirtualEnvConda/VirtualEnvOnly.cmake b/Tests/FindPython/VirtualEnvConda/VirtualEnvOnly.cmake
new file mode 100644
index 0000000..29a4924
--- /dev/null
+++ b/Tests/FindPython/VirtualEnvConda/VirtualEnvOnly.cmake
@@ -0,0 +1,16 @@
+
+#
+# Virtual environment is defined for python3
+# Trying to find a python2 using only virtual environment
+# It is expecting to fail if a virtual environment is active and to success otherwise.
+#
+set (Python2_FIND_VIRTUALENV ONLY)
+find_package (Python2 QUIET)
+
+if (PYTHON3_VIRTUAL_ENV AND Python2_FOUND)
+ message (FATAL_ERROR "Python2 unexpectedly found.")
+endif()
+
+if (NOT PYTHON3_VIRTUAL_ENV AND NOT Python2_FOUND)
+ message (FATAL_ERROR "Fail to find Python2.")
+endif()
diff --git a/Tests/FindPython/VirtualEnvConda/VirtualEnvStandard.cmake b/Tests/FindPython/VirtualEnvConda/VirtualEnvStandard.cmake
new file mode 100644
index 0000000..89f27d8
--- /dev/null
+++ b/Tests/FindPython/VirtualEnvConda/VirtualEnvStandard.cmake
@@ -0,0 +1,7 @@
+
+set (Python3_FIND_VIRTUALENV STANDARD)
+find_package (Python3 REQUIRED)
+
+if (Python3_EXECUTABLE MATCHES "^${PYTHON3_VIRTUAL_ENV}/.+")
+ message (FATAL_ERROR "Python3 virtual env unexpectedly found.")
+endif()
diff --git a/Tests/FindRuby/CMakeLists.txt b/Tests/FindRuby/CMakeLists.txt
new file mode 100644
index 0000000..3f4807c
--- /dev/null
+++ b/Tests/FindRuby/CMakeLists.txt
@@ -0,0 +1,57 @@
+if(CMake_TEST_FindRuby)
+
+ # Looks for ruby >=1.9.9, which is true on any Ubuntu (that installs it) or macOS (> 10.9)
+ add_test(NAME FindRuby.Test COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindRuby/Test"
+ "${CMake_BINARY_DIR}/Tests/FindRuby/Test"
+ ${build_generator_args}
+ --build-project TestRuby
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+
+ # Looks for ruby >= 50.1.0, which should logically fail
+ add_test(NAME FindRuby.Fail COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindRuby/Fail"
+ "${CMake_BINARY_DIR}/Tests/FindRuby/Fail"
+ ${build_generator_args}
+ --build-project TestRubyFail
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ set_tests_properties(FindRuby.Fail PROPERTIES
+ PASS_REGULAR_EXPRESSION "Could NOT find Ruby.*(Required is at least version \"[0-9]+\\.[0-9]+\\.[0-9]+\")")
+
+ # Looks for 1.9.9 EXACTLY, which unlike the "FindRuby" test above will fail on every machine
+ # since this version doesn't exist (ruby goes from 1.9.3 to 2.0.0)
+ add_test(NAME FindRuby.FailExact COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindRuby/FailExact"
+ "${CMake_BINARY_DIR}/Tests/FindRuby/FailExact"
+ ${build_generator_args}
+ --build-project TestRubyFailExact
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ set_tests_properties(FindRuby.FailExact PROPERTIES
+ PASS_REGULAR_EXPRESSION "Could NOT find Ruby: Found unsuitable version \".*\", but required is.*exact version \"[0-9]+\\.[0-9]+\\.[0-9]+\" \\(found .*\\)")
+
+ # RVM specific test
+ if(CMake_TEST_FindRuby_RVM)
+ add_test(NAME FindRuby.Rvm COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindRuby/Rvm"
+ "${CMake_BINARY_DIR}/Tests/FindRuby/Rvm"
+ ${build_generator_args}
+ --build-project TestRVM
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
+ endif()
+endif()
diff --git a/Tests/FindRuby/Fail/CMakeLists.txt b/Tests/FindRuby/Fail/CMakeLists.txt
new file mode 100644
index 0000000..9185ba5
--- /dev/null
+++ b/Tests/FindRuby/Fail/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.17)
+project(TestRubyFail LANGUAGES NONE)
+
+# Should always fail since there is NO ruby 50.1.0 yet.
+find_package(Ruby 50.1.0 REQUIRED)
diff --git a/Tests/FindRuby/FailExact/CMakeLists.txt b/Tests/FindRuby/FailExact/CMakeLists.txt
new file mode 100644
index 0000000..1ebc0ae
--- /dev/null
+++ b/Tests/FindRuby/FailExact/CMakeLists.txt
@@ -0,0 +1,8 @@
+cmake_minimum_required(VERSION 3.17)
+project(TestRubyFailExact LANGUAGES NONE)
+
+# Should always fail since there is NO ruby 1.9.9 (goes from 1.9.3 to 2.0.0)
+find_package(Ruby 1.9.9 EXACT REQUIRED)
+if (NOT Ruby_FOUND)
+ message (FATAL_ERROR "Failed to find Ruby 1.9.9")
+endif()
diff --git a/Tests/FindRuby/Rvm/CMakeLists.txt b/Tests/FindRuby/Rvm/CMakeLists.txt
new file mode 100644
index 0000000..545fc94
--- /dev/null
+++ b/Tests/FindRuby/Rvm/CMakeLists.txt
@@ -0,0 +1,75 @@
+cmake_minimum_required(VERSION 3.17)
+project(TestRVM LANGUAGES NONE)
+
+include(CTest)
+
+# To run this test, you need to have at least one RVM ruby installed
+# and to ensure that the env variable 'MY_RUBY_HOME' is set to a valid RVM ruby when you run the test
+# (which is the case if you have done `rvm use x.y.z`, but could be manually set too)
+
+# Properly using rvm would require sourcing a shell script, eg `source "$HOME/.rvm/scripts/rvm"`
+# Instead, I'll just rely on the env variable MY_RUBY_HOME
+set(MY_RUBY_HOME "$ENV{MY_RUBY_HOME}")
+if(NOT MY_RUBY_HOME)
+ message(FATAL_ERROR "Env variable MY_RUBY_HOME should be set to a valid RVM ruby location, or you should call `rvm use x.y.z` before")
+endif()
+execute_process (COMMAND "${MY_RUBY_HOME}/bin/ruby" -e "puts RUBY_VERSION"
+ RESULT_VARIABLE result
+ OUTPUT_VARIABLE RVM_RUBY_VERSION
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+if (result)
+ message (FATAL_ERROR "Unable to detect RVM ruby version from `${MY_RUBY_HOME}/bin/ruby`: ${RVM_RUBY_VERSION}")
+endif()
+
+execute_process(COMMAND "${CMAKE_COMMAND}" -E env --unset=MY_RUBY_HOME --unset=PATH
+ "which" "ruby"
+ RESULT_VARIABLE result
+ OUTPUT_VARIABLE SYSTEM_RUBY
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+if (SYSTEM_RUBY MATCHES "^${MY_RUBY_HOME}/.+")
+ message(FATAL_ERROR "Unable to find system ruby, found ${SYSTEM_RUBY} which is part of MY_RUBY_HOME=${MY_RUBY_HOME}")
+endif()
+
+# Check version of the system ruby executable.
+execute_process (COMMAND "${SYSTEM_RUBY}" -e "puts RUBY_VERSION"
+ RESULT_VARIABLE result
+ OUTPUT_VARIABLE SYSTEM_RUBY_VERSION
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+if (result)
+ message (FATAL_ERROR "Unable to detect system ruby version from '${SYSTEM_RUBY}': ${SYSTEM_RUBY_VERSION}")
+endif()
+
+if(SYSTEM_RUBY_VERSION VERSION_EQUAL RVM_RUBY_VERSION)
+ message(FATAL_ERROR "Your RVM Ruby Version and your System ruby version are the same (${RVM_RUBY_VERSION}).")
+endif()
+
+message("Found System Ruby (${SYSTEM_RUBY_VERSION}): ${SYSTEM_RUBY}")
+message("Found RVM Ruby (${RVM_RUBY_VERSION}): ${MY_RUBY_HOME}/bin/ruby")
+
+add_test(NAME FindRuby.RvmDefault
+ COMMAND "${CMAKE_COMMAND}" -E env "MY_RUBY_HOME=${MY_RUBY_HOME}"
+ "${CMAKE_COMMAND}" "-DRUBY_HOME=${MY_RUBY_HOME}"
+ -P "${CMAKE_CURRENT_LIST_DIR}/RvmDefault.cmake")
+
+add_test(NAME FindRuby.RvmOnly
+ COMMAND "${CMAKE_COMMAND}" -E env --unset=PATH
+ "MY_RUBY_HOME=${MY_RUBY_HOME}"
+ "${CMAKE_COMMAND}" "-DRUBY_HOME=${MY_RUBY_HOME}"
+ "-DRVM_RUBY_VERSION=${RVM_RUBY_VERSION}" "-DSYSTEM_RUBY_VERSION=${SYSTEM_RUBY_VERSION}"
+ -P "${CMAKE_CURRENT_LIST_DIR}/RvmOnly.cmake")
+add_test(NAME FindRuby.UnsetRvmOnly
+ COMMAND "${CMAKE_COMMAND}" -E env --unset=MY_RUBY_HOME "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin"
+ "${CMAKE_COMMAND}" "-DRVM_RUBY_VERSION=${RVM_RUBY_VERSION}" "-DSYSTEM_RUBY_VERSION=${SYSTEM_RUBY_VERSION}"
+ -P "${CMAKE_CURRENT_LIST_DIR}/RvmOnly.cmake")
+
+add_test(NAME FindRuby.RvmStandard
+ COMMAND "${CMAKE_COMMAND}" -E env "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin"
+ "MY_RUBY_HOME=${MY_RUBY_HOME}"
+ "${CMAKE_COMMAND}" "-DRUBY_HOME=${MY_RUBY_HOME}"
+ -P "${CMAKE_CURRENT_LIST_DIR}/RvmStandard.cmake")
diff --git a/Tests/FindRuby/Rvm/RvmDefault.cmake b/Tests/FindRuby/Rvm/RvmDefault.cmake
new file mode 100644
index 0000000..a66b911
--- /dev/null
+++ b/Tests/FindRuby/Rvm/RvmDefault.cmake
@@ -0,0 +1,17 @@
+set(CMAKE_FIND_LIBRARY_PREFIXES "")
+set(CMAKE_FIND_LIBRARY_SUFFIXES "")
+
+find_package (Ruby 2.1.1 REQUIRED)
+if (NOT RUBY_EXECUTABLE MATCHES "^${RUBY_HOME}/.+")
+ message (FATAL_ERROR "Failed to use RVM environment: ${RUBY_EXECUTABLE}, ${RUBY_HOME}")
+endif()
+
+find_package (Ruby 2.1 REQUIRED)
+if (NOT RUBY_EXECUTABLE MATCHES "^${RUBY_HOME}/.+")
+ message (FATAL_ERROR "Failed to use RVM environment: ${RUBY_EXECUTABLE}, ${RUBY_HOME}")
+endif()
+
+find_package (Ruby REQUIRED)
+if (NOT RUBY_EXECUTABLE MATCHES "^${RUBY_HOME}/.+")
+ message (FATAL_ERROR "Failed to use RVM environment: ${RUBY_EXECUTABLE}, ${RUBY_HOME}")
+endif()
diff --git a/Tests/FindRuby/Rvm/RvmOnly.cmake b/Tests/FindRuby/Rvm/RvmOnly.cmake
new file mode 100644
index 0000000..3851a7c
--- /dev/null
+++ b/Tests/FindRuby/Rvm/RvmOnly.cmake
@@ -0,0 +1,41 @@
+set(CMAKE_FIND_LIBRARY_PREFIXES "")
+set(CMAKE_FIND_LIBRARY_SUFFIXES "")
+
+set(Ruby_FIND_VIRTUALENV ONLY)
+
+# Test: FindRuby.RvmOnly
+if (RUBY_HOME)
+ # => Trying to find exactly system ruby using ONLY virtual environment should fail
+ find_package (Ruby ${SYSTEM_RUBY_VERSION} EXACT QUIET)
+ if(Ruby_FOUND)
+ message (FATAL_ERROR "Ruby unexpectedly found.")
+ endif()
+ # And should work to find the rvm version
+ find_package (Ruby ${RVM_RUBY_VERSION} EXACT QUIET)
+ if(Ruby_FOUND)
+ message (FATAL_ERROR "Ruby unexpectedly found.")
+ endif()
+endif()
+
+
+# Test: FindRuby.UnsetRvmOnly
+if (NOT RUBY_HOME)
+
+ # If ENV{MY_RUBY_HOME} isn't defined, it should default back to "STANDARD"
+ # At which point:
+
+ # It shouldn't find the RVM ruby
+ find_package (Ruby ${RVM_RUBY_VERSION} EXACT QUIET)
+ if(Ruby_FOUND)
+ message(FATAL_ERROR "Found RVM ruby when expecting system")
+ endif()
+
+ # it should find the system ruby
+ find_package (Ruby ${SYSTEM_RUBY_VERSION} EXACT QUIET)
+ if(NOT Ruby_FOUND)
+ message (FATAL_ERROR "Ruby not found.")
+ endif()
+ if (Ruby_FOUND MATCHES "^${RUBY_HOME}/.+")
+ message(FATAL_ERROR "Failed to find system ruby")
+ endif()
+endif()
diff --git a/Tests/FindRuby/Rvm/RvmStandard.cmake b/Tests/FindRuby/Rvm/RvmStandard.cmake
new file mode 100644
index 0000000..26befdb7
--- /dev/null
+++ b/Tests/FindRuby/Rvm/RvmStandard.cmake
@@ -0,0 +1,9 @@
+set(CMAKE_FIND_LIBRARY_PREFIXES "")
+set(CMAKE_FIND_LIBRARY_SUFFIXES "")
+
+set (Ruby_FIND_VIRTUALENV STANDARD)
+find_package (Ruby REQUIRED)
+
+if (RUBY_EXECUTABLE MATCHES "^${RUBY_HOME}/.+")
+ message (FATAL_ERROR "RVM ruby unexpectedly found at ${RUBY_EXECUTABLE}, matches ${RUBY_HOME}")
+endif()
diff --git a/Tests/FindRuby/Test/CMakeLists.txt b/Tests/FindRuby/Test/CMakeLists.txt
new file mode 100644
index 0000000..dcf3ec3
--- /dev/null
+++ b/Tests/FindRuby/Test/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.17)
+project(TestRuby LANGUAGES C)
+include(CTest)
+
+find_package(Ruby 1.9.9 REQUIRED)
+if (NOT Ruby_FOUND)
+ message (FATAL_ERROR "Failed to find Ruby >=1.9.9")
+endif()
+
+add_executable(ruby_version ruby_version.c)
+target_include_directories(ruby_version PRIVATE ${Ruby_INCLUDE_DIRS})
+target_link_libraries(ruby_version PRIVATE ${Ruby_LIBRARIES})
+
+add_test(NAME ruby_version COMMAND ruby_version)
diff --git a/Tests/FindRuby/Test/ruby_version.c b/Tests/FindRuby/Test/ruby_version.c
new file mode 100644
index 0000000..8800436
--- /dev/null
+++ b/Tests/FindRuby/Test/ruby_version.c
@@ -0,0 +1,7 @@
+#include "ruby.h"
+
+int main(void)
+{
+ ruby_show_version();
+ return 0;
+}
diff --git a/Tests/FindX11/Test/CMakeLists.txt b/Tests/FindX11/Test/CMakeLists.txt
index 769271f..b2adfb2 100644
--- a/Tests/FindX11/Test/CMakeLists.txt
+++ b/Tests/FindX11/Test/CMakeLists.txt
@@ -29,6 +29,10 @@ test_x11_component(x11_components SM)
set(X11_X11_FOUND ${X11_FOUND})
test_x11_component(x11_components X11)
test_x11_component(x11_components Xau)
+test_x11_component(x11_components xcb)
+test_x11_component(x11_components X11_xcb)
+test_x11_component(x11_components xcb_icccm)
+test_x11_component(x11_components xcb_xkb)
test_x11_component(x11_components Xcomposite)
test_x11_component(x11_components Xdamage)
test_x11_component(x11_components Xdmcp)
@@ -41,6 +45,8 @@ test_x11_component(x11_components Xfixes)
test_x11_component(x11_components_ignore Xft)
test_x11_component(x11_components Xi)
test_x11_component(x11_components Xinerama)
+test_x11_component(x11_components xkbcommon)
+test_x11_component(x11_components xkbcommon_X11)
test_x11_component(x11_components Xkb)
test_x11_component(x11_components xkbfile)
test_x11_component(x11_components Xmu)
@@ -61,6 +67,9 @@ target_link_libraries(test_var PRIVATE ${X11_LIBRARIES})
# Not included in X11_LIBRARIES.
foreach(lib
Xau
+ xcb
+ X11_xcb
+ xcb_icccm
Xcomposite
Xdamage
Xdmcp
@@ -69,6 +78,8 @@ foreach(lib
Xfixes
Xi
Xinerama
+ xkbcommon
+ xkbcommon_X11
Xkb
xkbfile
Xmu
diff --git a/Tests/FortranModules/CMakeLists.txt b/Tests/FortranModules/CMakeLists.txt
index d056b43..b7a6f68 100644
--- a/Tests/FortranModules/CMakeLists.txt
+++ b/Tests/FortranModules/CMakeLists.txt
@@ -21,7 +21,7 @@ end module parent
submodule ( parent ) child
contains
module procedure id
- f = x
+ id = x
end procedure id
end submodule child
program main
diff --git a/Tests/FortranModules/Executable/CMakeLists.txt b/Tests/FortranModules/Executable/CMakeLists.txt
index de08d86..f31a3e6 100644
--- a/Tests/FortranModules/Executable/CMakeLists.txt
+++ b/Tests/FortranModules/Executable/CMakeLists.txt
@@ -1,6 +1,6 @@
include_directories(${Library_MODDIR})
include_directories(${External_BINARY_DIR})
-link_directories(${External_BINARY_DIR})
+link_directories(${External_BINARY_DIR}/${CMAKE_CFG_INTDIR})
add_executable(subdir_exe2 main.f90)
target_link_libraries(subdir_exe2 subdir_mods subdir_mods2)
diff --git a/Tests/FortranOnly/CMakeLists.txt b/Tests/FortranOnly/CMakeLists.txt
index de887fa..4327c2f 100644
--- a/Tests/FortranOnly/CMakeLists.txt
+++ b/Tests/FortranOnly/CMakeLists.txt
@@ -51,40 +51,36 @@ add_custom_target(checksayhello ALL
)
add_dependencies(checksayhello sayhello)
-# Exclude this test on IBM XL for now because the check strangely
-# fails with 'ld: 0706-029 Use a number with the -H flag'.
-if(NOT CMAKE_Fortran_COMPILER_ID STREQUAL XL)
- set(err_log ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log)
- file(REMOVE "${err_log}")
- include(CheckFortranSourceCompiles)
- unset(HAVE_PRINT CACHE)
- CHECK_Fortran_SOURCE_COMPILES([[
+set(err_log ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log)
+file(REMOVE "${err_log}")
+include(CheckFortranSourceCompiles)
+unset(HAVE_PRINT CACHE)
+CHECK_Fortran_SOURCE_COMPILES([[
PROGRAM TEST_HAVE_PRINT
PRINT *, 'Hello'
END
]] HAVE_PRINT)
- if(NOT HAVE_PRINT)
- if(EXISTS "${err_log}")
- file(READ "${err_log}" err)
- endif()
- string(REPLACE "\n" "\n " err " ${err}")
- message(SEND_ERROR "CHECK_Fortran_SOURCE_COMPILES for HAVE_PRINT failed:\n"
- "${err}")
+if(NOT HAVE_PRINT)
+ if(EXISTS "${err_log}")
+ file(READ "${err_log}" err)
endif()
+ string(REPLACE "\n" "\n " err " ${err}")
+ message(SEND_ERROR "CHECK_Fortran_SOURCE_COMPILES for HAVE_PRINT failed:\n"
+ "${err}")
+endif()
- unset(Fortran_BOGUS_FLAG CACHE)
- include(CheckFortranCompilerFlag)
- CHECK_Fortran_COMPILER_FLAG(-_this_is_not_a_flag_ Fortran_BOGUS_FLAG)
- if (Fortran_BOGUS_FLAG)
- message(SEND_ERROR "CHECK_Fortran_COMPILER_FLAG() succeeded, but should have failed")
- endif()
+unset(Fortran_BOGUS_FLAG CACHE)
+include(CheckFortranCompilerFlag)
+CHECK_Fortran_COMPILER_FLAG(-_this_is_not_a_flag_ Fortran_BOGUS_FLAG)
+if (Fortran_BOGUS_FLAG)
+ message(SEND_ERROR "CHECK_Fortran_COMPILER_FLAG() succeeded, but should have failed")
+endif()
- unset(Fortran_RUN_FLAG CACHE)
- include(CheckFortranSourceRuns)
- check_fortran_source_runs("program a; end program" Fortran_RUN_FLAG SRC_EXT F90)
- if(NOT Fortran_RUN_FLAG)
- message(SEND_ERROR "CHECK_Fortran_SOURCE_RUNS() failed")
- endif()
+unset(Fortran_RUN_FLAG CACHE)
+include(CheckFortranSourceRuns)
+check_fortran_source_runs("program a; end program" Fortran_RUN_FLAG SRC_EXT F90)
+if(NOT Fortran_RUN_FLAG)
+ message(SEND_ERROR "CHECK_Fortran_SOURCE_RUNS() failed")
endif()
# Test generation of preprocessed sources.
@@ -103,11 +99,11 @@ if("${CMAKE_GENERATOR}" MATCHES "Makefile" AND CMAKE_MAKE_PROGRAM)
# Custom target to try preprocessing invocation.
add_custom_target(test_preprocess ${MAYBE_ALL}
- COMMAND ${CMAKE_COMMAND} -E remove CMakeFiles/preprocess.dir/preprocess.F.i
+ COMMAND ${CMAKE_COMMAND} -E rm -f CMakeFiles/preprocess.dir/preprocess.F.i
COMMAND ${CMAKE_MAKE_PROGRAM} preprocess.i
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/test_preprocess.cmake
# Remove bogus file some compilers leave behind.
- COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_CURRENT_SOURCE_DIR}/preprocess.s
+ COMMAND ${CMAKE_COMMAND} -E rm -f ${CMAKE_CURRENT_SOURCE_DIR}/preprocess.s
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
endif()
diff --git a/Tests/IncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/CMakeLists.txt
index 761c405..eb08676 100644
--- a/Tests/IncludeDirectories/CMakeLists.txt
+++ b/Tests/IncludeDirectories/CMakeLists.txt
@@ -65,6 +65,39 @@ else()
PROPERTIES COMPILE_FLAGS "-ITarProp")
endif()
+# Test escaping of special characters in include directory paths.
+set(special_chars "~@%&{}()!'")
+if(NOT CMAKE_GENERATOR STREQUAL "Watcom WMake")
+ # Watcom seems to have no way to encode these characters.
+ string(APPEND special_chars "#=[]")
+endif()
+if(NOT (MINGW AND CMAKE_GENERATOR MATCHES "(Unix|MSYS) Makefiles"))
+ # FIXME: Dependencies work but command-line generation does not handle '$'.
+ string(APPEND special_chars "$")
+endif()
+if(NOT CMAKE_GENERATOR MATCHES "(Borland|NMake) Makefiles")
+ # NMake and Borland seem to have no way to encode a single '^'.
+ string(APPEND special_chars "^")
+endif()
+if(NOT CMAKE_GENERATOR MATCHES "Visual Studio 9 2008|Watcom WMake")
+ # The vcproj format separates values with ','.
+ string(APPEND special_chars ",")
+endif()
+if(NOT WIN32 AND NOT CYGWIN)
+ string(APPEND special_chars "*?<>")
+endif()
+set(special_dir "${CMAKE_CURRENT_BINARY_DIR}/special-${special_chars}-include")
+file(WRITE "${special_dir}/SpecialDir.h" "#define SPECIAL_DIR_H\n")
+target_include_directories(IncludeDirectories PRIVATE "${special_dir}")
+target_compile_definitions(IncludeDirectories PRIVATE INCLUDE_SPECIAL_DIR)
+
+if(MAKE_SUPPORTS_SPACES)
+ set(special_space_dir "${CMAKE_CURRENT_BINARY_DIR}/special-space ${special_chars}-include")
+ file(WRITE "${special_space_dir}/SpecialSpaceDir.h" "#define SPECIAL_SPACE_DIR_H\n")
+ target_include_directories(IncludeDirectories PRIVATE "${special_space_dir}")
+ target_compile_definitions(IncludeDirectories PRIVATE INCLUDE_SPECIAL_SPACE_DIR)
+endif()
+
add_library(ordertest ordertest.cpp)
target_include_directories(ordertest SYSTEM PUBLIC SystemIncludeDirectories/systemlib)
target_include_directories(ordertest PUBLIC SystemIncludeDirectories/userlib)
@@ -94,6 +127,6 @@ if (NOT incs STREQUAL ";/one/two")
message(SEND_ERROR "Empty include_directories entry was not ignored.")
endif()
-if(NOT CMAKE_GENERATOR STREQUAL Xcode AND NOT CMAKE_GENERATOR STREQUAL Ninja)
+if(NOT CMAKE_GENERATOR STREQUAL "Xcode" AND NOT CMAKE_GENERATOR MATCHES "Ninja")
add_subdirectory(CMP0021)
endif()
diff --git a/Tests/IncludeDirectories/main.cpp b/Tests/IncludeDirectories/main.cpp
index a59d27c..6dc88e2 100644
--- a/Tests/IncludeDirectories/main.cpp
+++ b/Tests/IncludeDirectories/main.cpp
@@ -3,6 +3,20 @@
#include "SrcProp.h"
#include "TarProp.h"
+#ifdef INCLUDE_SPECIAL_DIR
+# include "SpecialDir.h"
+# ifndef SPECIAL_DIR_H
+# error "SPECIAL_DIR_H not defined"
+# endif
+#endif
+
+#ifdef INCLUDE_SPECIAL_SPACE_DIR
+# include "SpecialSpaceDir.h"
+# ifndef SPECIAL_SPACE_DIR_H
+# error "SPECIAL_SPACE_DIR_H not defined"
+# endif
+#endif
+
int main(int argc, char** argv)
{
return 0;
diff --git a/Tests/InterfaceLibrary/CMakeLists.txt b/Tests/InterfaceLibrary/CMakeLists.txt
index 954c02d..311ca2a 100644
--- a/Tests/InterfaceLibrary/CMakeLists.txt
+++ b/Tests/InterfaceLibrary/CMakeLists.txt
@@ -3,6 +3,12 @@ cmake_minimum_required(VERSION 2.8)
project(InterfaceLibrary)
+set(cfg_dir)
+get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+if(_isMultiConfig)
+ set(cfg_dir /$<CONFIG>)
+endif()
+
add_library(iface_nodepends INTERFACE)
target_compile_definitions(iface_nodepends INTERFACE IFACE_DEFINE)
@@ -32,7 +38,7 @@ add_library(item_iface INTERFACE IMPORTED)
set_property(TARGET item_iface PROPERTY IMPORTED_LIBNAME item_real)
add_dependencies(item_iface item_real)
get_property(item_iface_dependencies TARGET item_iface PROPERTY MANUALLY_ADDED_DEPENDENCIES)
-link_directories(${CMAKE_CURRENT_BINARY_DIR})
+link_directories(${CMAKE_CURRENT_BINARY_DIR}${cfg_dir})
add_executable(InterfaceLibrary definetestexe.cpp)
target_link_libraries(InterfaceLibrary
diff --git a/Tests/JavaExportImport/CMakeLists.txt b/Tests/JavaExportImport/CMakeLists.txt
index c70704a..7a2d020 100644
--- a/Tests/JavaExportImport/CMakeLists.txt
+++ b/Tests/JavaExportImport/CMakeLists.txt
@@ -9,7 +9,7 @@ find_package(Java COMPONENTS Development)
# Wipe out the install tree to make sure the exporter works.
add_custom_command(
OUTPUT ${JavaExportImport_BINARY_DIR}/CleanupProject
- COMMAND ${CMAKE_COMMAND} -E remove_directory ${JavaExportImport_BINARY_DIR}/Root
+ COMMAND ${CMAKE_COMMAND} -E rm -rf ${JavaExportImport_BINARY_DIR}/Root
)
add_custom_target(CleanupTarget ALL DEPENDS ${JavaExportImport_BINARY_DIR}/CleanupProject)
set_property(
diff --git a/Tests/LinkDirectory/CMakeLists.txt b/Tests/LinkDirectory/CMakeLists.txt
index c60de84..c7a2700 100644
--- a/Tests/LinkDirectory/CMakeLists.txt
+++ b/Tests/LinkDirectory/CMakeLists.txt
@@ -33,7 +33,7 @@ ExternalProject_Add(ExternalTarget
# directly because it does not know the full paths to the libraries.
# (The purpose of this test is to check that link_directories works.)
ExternalProject_Add_Step(ExternalTarget cleanup
- COMMAND ${CMAKE_COMMAND} -E remove_directory ${LinkDirectory_BINARY_DIR}/bin
+ COMMAND ${CMAKE_COMMAND} -E rm -rf ${LinkDirectory_BINARY_DIR}/bin
DEPENDEES download
DEPENDERS configure
DEPENDS mylibA mylibB
diff --git a/Tests/LinkDirectory/External/CMakeLists.txt b/Tests/LinkDirectory/External/CMakeLists.txt
index d2a1f9f..c877913 100644
--- a/Tests/LinkDirectory/External/CMakeLists.txt
+++ b/Tests/LinkDirectory/External/CMakeLists.txt
@@ -2,13 +2,19 @@ cmake_minimum_required(VERSION 2.8)
project(LinkDirectoryExternal C)
+set(cfg_dir)
+get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+if(_isMultiConfig)
+ set(cfg_dir /$<CONFIG>)
+endif()
+
add_executable(myexe2 myexe.c)
set_property(TARGET myexe2 PROPERTY OUTPUT_NAME LinkDirectory2)
-target_link_directories(myexe2 PRIVATE lib "${CMAKE_CURRENT_SOURCE_DIR}/../lib")
+target_link_directories(myexe2 PRIVATE lib${cfg_dir} "${CMAKE_CURRENT_SOURCE_DIR}/../lib${cfg_dir}")
target_link_libraries(myexe2 PRIVATE mylibA mylibB)
add_library (mylibs INTERFACE)
-target_link_directories(mylibs INTERFACE lib "${CMAKE_CURRENT_SOURCE_DIR}/../lib")
+target_link_directories(mylibs INTERFACE lib${cfg_dir} "${CMAKE_CURRENT_SOURCE_DIR}/../lib${cfg_dir}")
target_link_libraries(mylibs INTERFACE mylibA mylibB)
add_executable(myexe3 myexe.c)
set_property(TARGET myexe3 PROPERTY OUTPUT_NAME LinkDirectory3)
@@ -17,11 +23,11 @@ target_link_libraries(myexe3 PRIVATE mylibs)
# Test CMP0015 OLD behavior: -L../lib
cmake_policy(SET CMP0015 OLD)
-link_directories(../lib)
+link_directories(../lib${cfg_dir})
# Test CMP0015 NEW behavior: -L${CMAKE_CURRENT_SOURCE_DIR}/lib
cmake_policy(SET CMP0015 NEW)
-link_directories(lib)
+link_directories(lib${cfg_dir})
add_executable(myexe myexe.c)
set_property(TARGET myexe PROPERTY OUTPUT_NAME LinkDirectory)
diff --git a/Tests/MSManifest/CMakeLists.txt b/Tests/MSManifest/CMakeLists.txt
index 300cfa6..631c598 100644
--- a/Tests/MSManifest/CMakeLists.txt
+++ b/Tests/MSManifest/CMakeLists.txt
@@ -1,5 +1,8 @@
cmake_minimum_required(VERSION 3.3)
project(MSManifest C)
+include(CTest)
+
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
add_subdirectory(Subdir)
+add_subdirectory(Subdir2)
diff --git a/Tests/MSManifest/Subdir/CMakeLists.txt b/Tests/MSManifest/Subdir/CMakeLists.txt
index 11272bb..8664572 100644
--- a/Tests/MSManifest/Subdir/CMakeLists.txt
+++ b/Tests/MSManifest/Subdir/CMakeLists.txt
@@ -2,10 +2,9 @@ configure_file(test.manifest.in test.manifest)
add_executable(MSManifest main.c ${CMAKE_CURRENT_BINARY_DIR}/test.manifest)
if(MSVC AND NOT MSVC_VERSION LESS 1400)
- add_custom_command(TARGET MSManifest POST_BUILD VERBATIM
- COMMAND ${CMAKE_COMMAND} -Dexe=$<TARGET_FILE:MSManifest>
- -P ${CMAKE_CURRENT_SOURCE_DIR}/check.cmake
- )
+ add_test(NAME MSManifest.Single COMMAND
+ ${CMAKE_COMMAND} -Dexe=$<TARGET_FILE:MSManifest>
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/check.cmake)
add_executable(MSManifestNone main.c)
set_property(TARGET MSManifestNone PROPERTY LINK_FLAGS "/MANIFEST:NO")
endif()
diff --git a/Tests/MSManifest/Subdir2/CMakeLists.txt b/Tests/MSManifest/Subdir2/CMakeLists.txt
new file mode 100644
index 0000000..19d8de7
--- /dev/null
+++ b/Tests/MSManifest/Subdir2/CMakeLists.txt
@@ -0,0 +1,13 @@
+configure_file(test_manifest1.in test_manifest1.manifest)
+configure_file(test_manifest2.in test_manifest2.manifest)
+configure_file(test_manifest3.in test_manifest3.manifest)
+add_executable(MSMultipleManifest main.c
+ ${CMAKE_CURRENT_BINARY_DIR}/test_manifest1.manifest
+ ${CMAKE_CURRENT_BINARY_DIR}/test_manifest2.manifest
+ ${CMAKE_CURRENT_BINARY_DIR}/test_manifest3.manifest)
+
+if(MSVC AND NOT MSVC_VERSION LESS 1400)
+ add_test(NAME MSManifest.Multiple COMMAND
+ ${CMAKE_COMMAND} -Dexe=$<TARGET_FILE:MSMultipleManifest>
+ -P ${CMAKE_CURRENT_SOURCE_DIR}/check.cmake)
+endif()
diff --git a/Tests/MSManifest/Subdir2/check.cmake b/Tests/MSManifest/Subdir2/check.cmake
new file mode 100644
index 0000000..4a1705b
--- /dev/null
+++ b/Tests/MSManifest/Subdir2/check.cmake
@@ -0,0 +1,22 @@
+file(STRINGS "${exe}" manifest_content1 REGEX "name=\"Kitware.CMake.MSMultipleManifest\"")
+if(manifest_content1)
+ message(STATUS "Expected manifest content found:\n ${manifest_content1}")
+else()
+ message(FATAL_ERROR "Expected manifest content not found in\n ${exe}")
+endif()
+
+# Verify Second Manifest Content is inside Executable.
+file(STRINGS "${exe}" manifest_content2 REGEX "8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a")
+if(manifest_content2)
+ message(STATUS "Expected manifest content found:\n ${manifest_content2}")
+else()
+ message(FATAL_ERROR "Expected manifest content not found in\n ${exe}")
+endif()
+
+# Verify Third Manifest Content is inside Executable.
+file(STRINGS "${exe}" manifest_content3 REGEX "<dpiAware>true</dpiAware>")
+if(manifest_content3)
+ message(STATUS "Expected manifest content found:\n ${manifest_content3}")
+else()
+ message(FATAL_ERROR "Expected manifest content not found in\n ${exe}")
+endif()
diff --git a/Tests/MSManifest/Subdir2/main.c b/Tests/MSManifest/Subdir2/main.c
new file mode 100644
index 0000000..8488f4e
--- /dev/null
+++ b/Tests/MSManifest/Subdir2/main.c
@@ -0,0 +1,4 @@
+int main(void)
+{
+ return 0;
+}
diff --git a/Tests/MSManifest/Subdir2/test_manifest1.in b/Tests/MSManifest/Subdir2/test_manifest1.in
new file mode 100644
index 0000000..f36eead
--- /dev/null
+++ b/Tests/MSManifest/Subdir2/test_manifest1.in
@@ -0,0 +1,5 @@
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <assemblyIdentity type="win32" version="1.0.0.0"
+ name="Kitware.CMake.MSMultipleManifest"/>
+ <description>CMake Multiple Manifest Test Application</description>
+</assembly>
diff --git a/Tests/MSManifest/Subdir2/test_manifest2.in b/Tests/MSManifest/Subdir2/test_manifest2.in
new file mode 100644
index 0000000..ec96f11
--- /dev/null
+++ b/Tests/MSManifest/Subdir2/test_manifest2.in
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
+ <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+ <application>
+ <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"></supportedOS>
+ <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"></supportedOS>
+ <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"></supportedOS>
+ <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"></supportedOS>
+ <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"></supportedOS>
+ </application>
+ </compatibility>
+</assembly>
diff --git a/Tests/MSManifest/Subdir2/test_manifest3.in b/Tests/MSManifest/Subdir2/test_manifest3.in
new file mode 100644
index 0000000..0770e11
--- /dev/null
+++ b/Tests/MSManifest/Subdir2/test_manifest3.in
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
+ <asmv3:application>
+ <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
+ <dpiAware>true</dpiAware>
+ <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
+ </asmv3:windowsSettings>
+ </asmv3:application>
+</assembly>
diff --git a/Tests/MacRuntimePath/CMakeLists.txt b/Tests/MacRuntimePath/CMakeLists.txt
index a3c6fd9..9f1bf1a 100644
--- a/Tests/MacRuntimePath/CMakeLists.txt
+++ b/Tests/MacRuntimePath/CMakeLists.txt
@@ -7,7 +7,7 @@ endif()
# Wipe out the install tree to make sure the exporter works.
add_custom_command(
OUTPUT ${MacRuntimePath_BINARY_DIR}/CleanupProject
- COMMAND ${CMAKE_COMMAND} -E remove_directory ${MacRuntimePath_BINARY_DIR}/Root
+ COMMAND ${CMAKE_COMMAND} -E rm -rf ${MacRuntimePath_BINARY_DIR}/Root
)
add_custom_target(CleanupTarget ALL DEPENDS ${MacRuntimePath_BINARY_DIR}/CleanupProject)
set_property(
diff --git a/Tests/ObjectLibrary/CMakeLists.txt b/Tests/ObjectLibrary/CMakeLists.txt
index 7897ab9..fca5f41 100644
--- a/Tests/ObjectLibrary/CMakeLists.txt
+++ b/Tests/ObjectLibrary/CMakeLists.txt
@@ -73,3 +73,5 @@ add_executable(UseABstaticObjs $<TARGET_OBJECTS:UseABstatic>)
target_link_libraries(UseABstaticObjs ABstatic)
add_subdirectory(ExportLanguages)
+
+add_subdirectory(Transitive)
diff --git a/Tests/ObjectLibrary/Transitive/CMakeLists.txt b/Tests/ObjectLibrary/Transitive/CMakeLists.txt
new file mode 100644
index 0000000..d616cda
--- /dev/null
+++ b/Tests/ObjectLibrary/Transitive/CMakeLists.txt
@@ -0,0 +1,12 @@
+cmake_policy(SET CMP0022 NEW)
+add_library(FooStatic STATIC FooStatic.c)
+
+add_library(FooObject1 OBJECT FooObject.c)
+target_link_libraries(FooObject1 PRIVATE FooStatic)
+add_executable(Transitive1 Transitive.c)
+target_link_libraries(Transitive1 PRIVATE FooObject1)
+
+add_library(FooObject2 OBJECT FooObject.c)
+target_link_libraries(FooObject2 INTERFACE FooStatic)
+add_executable(Transitive2 Transitive.c)
+target_link_libraries(Transitive2 PRIVATE FooObject2)
diff --git a/Tests/ObjectLibrary/Transitive/FooObject.c b/Tests/ObjectLibrary/Transitive/FooObject.c
new file mode 100644
index 0000000..54c1f29
--- /dev/null
+++ b/Tests/ObjectLibrary/Transitive/FooObject.c
@@ -0,0 +1,4 @@
+int FooObject(void)
+{
+ return 0;
+}
diff --git a/Tests/ObjectLibrary/Transitive/FooStatic.c b/Tests/ObjectLibrary/Transitive/FooStatic.c
new file mode 100644
index 0000000..84649c7
--- /dev/null
+++ b/Tests/ObjectLibrary/Transitive/FooStatic.c
@@ -0,0 +1,4 @@
+int FooStatic(void)
+{
+ return 0;
+}
diff --git a/Tests/ObjectLibrary/Transitive/Transitive.c b/Tests/ObjectLibrary/Transitive/Transitive.c
new file mode 100644
index 0000000..43089b8
--- /dev/null
+++ b/Tests/ObjectLibrary/Transitive/Transitive.c
@@ -0,0 +1,7 @@
+extern int FooObject(void);
+extern int FooStatic(void);
+
+int main(void)
+{
+ return FooObject() + FooStatic();
+}
diff --git a/Tests/OutDir/CMakeLists.txt b/Tests/OutDir/CMakeLists.txt
index 823ab08..8afe036 100644
--- a/Tests/OutDir/CMakeLists.txt
+++ b/Tests/OutDir/CMakeLists.txt
@@ -20,7 +20,7 @@ set(top "${OutDir_BINARY_DIR}")
foreach(config ${configs})
foreach(type archive runtime library)
string(TOUPPER "${type}" TYPE)
- set(CMAKE_${TYPE}_OUTPUT_DIRECTORY_${config} "${top}/${type}")
+ set(CMAKE_${TYPE}_OUTPUT_DIRECTORY_${config} "${top}/${type}/$<CONFIG>")
file(REMOVE_RECURSE "${top}/${type}")
endforeach()
endforeach()
@@ -29,7 +29,7 @@ add_subdirectory(../COnly COnly)
add_custom_command(
OUTPUT OutDir.h
- COMMAND ${CMAKE_COMMAND} -Dtop=${top} -P ${OutDir_SOURCE_DIR}/OutDir.cmake
+ COMMAND ${CMAKE_COMMAND} -Dtop=${top} -Dcfg_dir=$<CONFIG> -P ${OutDir_SOURCE_DIR}/OutDir.cmake
DEPENDS COnly ${OutDir_SOURCE_DIR}/OutDir.cmake
)
include_directories(${top})
diff --git a/Tests/OutDir/OutDir.cmake b/Tests/OutDir/OutDir.cmake
index a1f13e7..2a003b8 100644
--- a/Tests/OutDir/OutDir.cmake
+++ b/Tests/OutDir/OutDir.cmake
@@ -3,17 +3,17 @@ set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib" ".a" ".so" ".sl" ".dylib" ".dll.a")
find_library(TESTC1_LIB
NAMES testc1 testc1_test_debug_postfix
- PATHS ${top}/archive
+ PATHS ${top}/archive/${cfg_dir}
NO_DEFAULT_PATH)
find_library(TESTC2_LIB
NAMES testc2 testc2_test_debug_postfix
- PATHS ${top}/archive ${top}/library
+ PATHS ${top}/archive/${cfg_dir} ${top}/library/${cfg_dir}
NO_DEFAULT_PATH)
find_program(CONLY_EXE
NAMES COnly
- PATHS ${top}/runtime
+ PATHS ${top}/runtime/${cfg_dir}
NO_DEFAULT_PATH)
file(RELATIVE_PATH TESTC1_LIB_FILE "${top}" "${TESTC1_LIB}")
diff --git a/Tests/Preprocess/preprocess.c b/Tests/Preprocess/preprocess.c
index 958c77e..b3117da 100644
--- a/Tests/Preprocess/preprocess.c
+++ b/Tests/Preprocess/preprocess.c
@@ -15,21 +15,21 @@ int check_defines_C(void)
result = 0;
}
if (strcmp(TARGET_STRING, STRING_VALUE) != 0) {
- fprintf(stderr, "TARGET_STRING has wrong value in C [%s]\n",
- TARGET_STRING);
+ fprintf(stderr, "TARGET_STRING has wrong value in C [%s] vs [%s]\n",
+ TARGET_STRING, STRING_VALUE);
result = 0;
}
{
int x = 2;
int y = 3;
if ((FILE_EXPR) != (EXPR)) {
- fprintf(stderr, "FILE_EXPR did not work in C [%s]\n",
- TO_STRING(FILE_EXPR));
+ fprintf(stderr, "FILE_EXPR did not work in C [%s] vs [%s]\n",
+ TO_STRING(FILE_EXPR), TO_STRING(EXPR));
result = 0;
}
if ((TARGET_EXPR) != (EXPR)) {
- fprintf(stderr, "TARGET_EXPR did not work in C [%s]\n",
- TO_STRING(FILE_EXPR));
+ fprintf(stderr, "TARGET_EXPR did not work in C [%s] vs [%s]\n",
+ TO_STRING(TARGET_EXPR), TO_STRING(EXPR));
result = 0;
}
}
diff --git a/Tests/Preprocess/preprocess.cxx b/Tests/Preprocess/preprocess.cxx
index 34a69c6..f2fffef 100644
--- a/Tests/Preprocess/preprocess.cxx
+++ b/Tests/Preprocess/preprocess.cxx
@@ -12,25 +12,26 @@ int check_defines_CXX()
{
int result = 1;
if (strcmp(FILE_STRING, STRING_VALUE) != 0) {
- fprintf(stderr, "FILE_STRING has wrong value in CXX [%s]\n", FILE_STRING);
+ fprintf(stderr, "FILE_STRING has wrong value in CXX [%s] vs [%s]\n",
+ FILE_STRING, STRING_VALUE);
result = 0;
}
if (strcmp(TARGET_STRING, STRING_VALUE) != 0) {
- fprintf(stderr, "TARGET_STRING has wrong value in CXX [%s]\n",
- TARGET_STRING);
+ fprintf(stderr, "TARGET_STRING has wrong value in CXX [%s] vs [%s]\n",
+ TARGET_STRING, STRING_VALUE);
result = 0;
}
{
int x = 2;
int y = 3;
if ((FILE_EXPR) != (EXPR)) {
- fprintf(stderr, "FILE_EXPR did not work in CXX [%s]\n",
- TO_STRING(FILE_EXPR));
+ fprintf(stderr, "FILE_EXPR did not work in CXX [%s] vs [%s]\n",
+ TO_STRING(FILE_EXPR), TO_STRING(EXPR));
result = 0;
}
if ((TARGET_EXPR) != (EXPR)) {
- fprintf(stderr, "TARGET_EXPR did not work in CXX [%s]\n",
- TO_STRING(FILE_EXPR));
+ fprintf(stderr, "TARGET_EXPR did not work in CXX [%s] vs [%s]\n",
+ TO_STRING(TARGET_EXPR), TO_STRING(EXPR));
result = 0;
}
}
diff --git a/Tests/Properties/CMakeLists.txt b/Tests/Properties/CMakeLists.txt
index a263061..f93f553 100644
--- a/Tests/Properties/CMakeLists.txt
+++ b/Tests/Properties/CMakeLists.txt
@@ -144,4 +144,143 @@ set_property(CACHE SOME_ENTRY PROPERTY ADVANCED "${expect_ADVANCED}")
set_property(CACHE SOME_ENTRY PROPERTY STRINGS "${expect_STRINGS}")
check_cache_props()
+function(generate_file_for_set_property_test i target_name)
+ set(src_path "${CMAKE_CURRENT_BINARY_DIR}/src${i}.cpp")
+ file(GENERATE OUTPUT "${src_path}" CONTENT
+ "#ifndef def${i}\n\
+ #error Expected def${i}\n\
+ #endif\n\
+ #ifdef _WIN32\n\
+ __declspec(dllexport)\n\
+ #endif\n\
+ void dummy_symbol${i}() {}\n")
+ target_sources(${target_name} PRIVATE "${src_path}")
+endfunction()
+
+add_library(maindirtest SHARED)
add_subdirectory(SubDir2)
+
+set(src_prefix "${CMAKE_CURRENT_BINARY_DIR}/SubDir2/")
+
+# Set property + target directory
+set_property(SOURCE "${src_prefix}/src1.cpp"
+ TARGET_DIRECTORY set_prop_lib_1
+ PROPERTY COMPILE_DEFINITIONS def1)
+
+# Append property + target directory
+set_property(SOURCE "${src_prefix}/src2.cpp"
+ TARGET_DIRECTORY set_prop_lib_1
+ APPEND PROPERTY COMPILE_DEFINITIONS def2)
+
+# Set property + relative directory path
+set_property(SOURCE "${src_prefix}/src3.cpp"
+ DIRECTORY SubDir2
+ PROPERTY COMPILE_DEFINITIONS def3)
+
+# Set property + absolute directory path
+set_property(SOURCE "${src_prefix}/src4.cpp"
+ DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/SubDir2"
+ PROPERTY COMPILE_DEFINITIONS def4)
+
+# Append property + relative directory path
+set_property(SOURCE "${src_prefix}/src5.cpp"
+ DIRECTORY SubDir2
+ APPEND PROPERTY COMPILE_DEFINITIONS def5)
+
+# Append property + absolute directory path
+set_property(SOURCE "${src_prefix}/src6.cpp"
+ DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/SubDir2"
+ APPEND PROPERTY COMPILE_DEFINITIONS def6)
+
+
+# Target directory
+set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src10.cpp"
+ TARGET_DIRECTORY set_prop_lib_1
+ PROPERTIES COMPILE_DEFINITIONS def10)
+
+# Relative directory path
+set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src11.cpp"
+ DIRECTORY SubDir2
+ PROPERTIES COMPILE_DEFINITIONS def11)
+
+# Absolute directory path
+set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src12.cpp"
+ DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/SubDir2"
+ PROPERTIES COMPILE_DEFINITIONS def12)
+
+
+# Multiple files + absolute directory path
+set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src20.cpp"
+ "${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src21.cpp"
+ DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/SubDir2"
+ PROPERTIES COMPILE_DEFINITIONS "def20;def21")
+
+# Multiple files + multiple target directories
+set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src22.cpp"
+ "${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src23.cpp"
+ TARGET_DIRECTORY set_prop_lib_2 set_prop_lib_3
+ PROPERTIES COMPILE_DEFINITIONS "def22;def23")
+
+
+# Multiple files in multiple relative directories
+generate_file_for_set_property_test(30 maindirtest)
+set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/src30.cpp"
+ "${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src31.cpp"
+ DIRECTORY . SubDir2
+ PROPERTIES COMPILE_DEFINITIONS "def30;def31")
+
+# Check that specifying files without any properties doesn't crash.
+set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/src30.cpp"
+ "${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src31.cpp")
+
+function(check_get_property_value expected)
+ if(NOT actual STREQUAL expected)
+ message(SEND_ERROR "Error: get_property returned unexpected value\n"
+ "actual: ${actual}\n"
+ "expected: ${expected}")
+ endif()
+endfunction()
+
+# Get property + target directory
+get_property(actual
+ SOURCE "${src_prefix}/src1.cpp"
+ TARGET_DIRECTORY set_prop_lib_1
+ PROPERTY COMPILE_DEFINITIONS)
+check_get_property_value("def1")
+
+# Get property + relative directory path
+get_property(actual
+ SOURCE "${src_prefix}/src3.cpp"
+ DIRECTORY SubDir2
+ PROPERTY COMPILE_DEFINITIONS)
+check_get_property_value("def3")
+
+# Get property + absolute directory path
+get_property(actual
+ SOURCE "${src_prefix}/src4.cpp"
+ DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/SubDir2"
+ PROPERTY COMPILE_DEFINITIONS)
+check_get_property_value("def4")
+
+
+# Get property + target directory
+unset(actual)
+get_source_file_property(actual
+ "${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src10.cpp"
+ TARGET_DIRECTORY set_prop_lib_1
+ COMPILE_DEFINITIONS)
+check_get_property_value("def10")
+
+# Get property + relative directory path
+get_source_file_property(actual
+ "${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src11.cpp"
+ DIRECTORY SubDir2
+ COMPILE_DEFINITIONS)
+check_get_property_value("def11")
+
+# Get property + absolute directory path
+get_source_file_property(actual
+ "${CMAKE_CURRENT_BINARY_DIR}/SubDir2/src12.cpp"
+ DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/SubDir2"
+ COMPILE_DEFINITIONS)
+check_get_property_value("def12")
diff --git a/Tests/Properties/SubDir2/CMakeLists.txt b/Tests/Properties/SubDir2/CMakeLists.txt
index 377dc83..9b2c79e 100644
--- a/Tests/Properties/SubDir2/CMakeLists.txt
+++ b/Tests/Properties/SubDir2/CMakeLists.txt
@@ -3,3 +3,28 @@ set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/../subdirtest.cxx"
PROPERTIES COMPILE_DEFINITIONS SUBDIR_TEST)
add_executable(subdirtest "${CMAKE_CURRENT_SOURCE_DIR}/../subdirtest.cxx")
+
+# For set_property
+add_library(set_prop_lib_1 SHARED)
+foreach(i RANGE 1 6)
+ generate_file_for_set_property_test(${i} set_prop_lib_1)
+endforeach()
+
+# For set_source_files_properties
+foreach(i RANGE 10 12)
+ generate_file_for_set_property_test(${i} set_prop_lib_1)
+endforeach()
+
+# For set_source_files_properties + multiple files + absolute directory path
+add_library(set_prop_lib_2 SHARED)
+foreach(i RANGE 20 21)
+ generate_file_for_set_property_test(${i} set_prop_lib_1)
+endforeach()
+
+# For set_source_files_properties + multiple files + multiple target directories
+add_library(set_prop_lib_3 SHARED)
+generate_file_for_set_property_test(22 set_prop_lib_2)
+generate_file_for_set_property_test(23 set_prop_lib_3)
+
+# For set_source_files_properties + multiple files in multiple directories
+generate_file_for_set_property_test(31 set_prop_lib_3)
diff --git a/Tests/Qt4Autogen/CMakeLists.txt b/Tests/Qt4Autogen/CMakeLists.txt
index 68b885b..e7f1ae3 100644
--- a/Tests/Qt4Autogen/CMakeLists.txt
+++ b/Tests/Qt4Autogen/CMakeLists.txt
@@ -7,3 +7,5 @@ ADD_AUTOGEN_TEST(DefinesTest)
# Common tests
include("../QtAutogen/Tests.cmake")
+
+set(TEST_BUILD_DIRS "${TEST_BUILD_DIRS}" PARENT_SCOPE)
diff --git a/Tests/Qt5Autogen/CMakeLists.txt b/Tests/Qt5Autogen/CMakeLists.txt
index 49d33cc..df4927a 100644
--- a/Tests/Qt5Autogen/CMakeLists.txt
+++ b/Tests/Qt5Autogen/CMakeLists.txt
@@ -4,3 +4,5 @@ include("../QtAutogen/TestMacros.cmake")
# Common tests
include("../QtAutogen/Tests.cmake")
+
+set(TEST_BUILD_DIRS "${TEST_BUILD_DIRS}" PARENT_SCOPE)
diff --git a/Tests/QtAutogen/MocCMP0100/CMakeLists.txt b/Tests/QtAutogen/MocCMP0100/CMakeLists.txt
new file mode 100644
index 0000000..559cffe
--- /dev/null
+++ b/Tests/QtAutogen/MocCMP0100/CMakeLists.txt
@@ -0,0 +1,9 @@
+cmake_minimum_required(VERSION 3.10)
+project(MocCMP0100)
+include("../AutogenCoreTest.cmake")
+
+set(CMAKE_AUTOMOC ON)
+set(CSD ${CMAKE_CURRENT_SOURCE_DIR})
+
+add_subdirectory(OLD)
+add_subdirectory(NEW)
diff --git a/Tests/QtAutogen/MocCMP0100/NEW/CMakeLists.txt b/Tests/QtAutogen/MocCMP0100/NEW/CMakeLists.txt
new file mode 100644
index 0000000..654b31e
--- /dev/null
+++ b/Tests/QtAutogen/MocCMP0100/NEW/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 3.16)
+cmake_policy(SET CMP0100 NEW)
+
+add_executable(mocCMP0100New
+ ${CSD}/main.cpp
+ ${CSD}/Obj.hh # Manually include Obj.hh
+ ${CSD}/Obj.cpp
+ ${CSD}/Obj2.cpp # Let AUTOMOC detect Obj2.hh
+)
+target_link_libraries(mocCMP0100New ${QT_LIBRARIES})
diff --git a/Tests/QtAutogen/MocCMP0100/OLD/CMakeLists.txt b/Tests/QtAutogen/MocCMP0100/OLD/CMakeLists.txt
new file mode 100644
index 0000000..2be0535
--- /dev/null
+++ b/Tests/QtAutogen/MocCMP0100/OLD/CMakeLists.txt
@@ -0,0 +1,31 @@
+cmake_minimum_required(VERSION 3.16)
+cmake_policy(SET CMP0100 OLD)
+
+# Generate moc files externally.
+# If AUTOMOC generates the header moc files as well
+# (it should not in OLD behavior), the test will fail with a
+# multiple definition error when linking the executable.
+qtx_wrap_cpp(mocCMP0100OldMoc ${CSD}/Obj.hh ${CSD}/Obj2.hh)
+qtx_generate_moc(${CBD}/Obj.cpp ${CMAKE_CURRENT_BINARY_DIR}/Obj.moc)
+qtx_generate_moc(${CBD}/Obj2.cpp ${CMAKE_CURRENT_BINARY_DIR}/Obj2.moc)
+
+# Make sure AUTOGEN file skipping is disabled
+set_source_files_properties(
+ ${CSD}/Obj.hh
+ ${CBD}/Obj.cpp
+ ${CSD}/Obj2.hh
+ ${CBD}/Obj2.cpp
+ PROPERTIES
+ SKIP_AUTOGEN OFF
+ SKIP_AUTOMOC OFF
+)
+
+add_executable(mocCMP0100Old
+ ${CSD}/main.cpp
+ ${CSD}/Obj.hh # Manually include Obj.hh
+ ${CSD}/Obj.cpp
+ ${CSD}/Obj2.cpp # Let AUTOMOC detect Obj2.hh
+ ${mocCMP0100OldMoc}
+)
+target_link_libraries(mocCMP0100Old ${QT_LIBRARIES})
+target_include_directories(mocCMP0100Old PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
diff --git a/Tests/QtAutogen/MocCMP0100/Obj.cpp b/Tests/QtAutogen/MocCMP0100/Obj.cpp
new file mode 100644
index 0000000..bb6d0a0
--- /dev/null
+++ b/Tests/QtAutogen/MocCMP0100/Obj.cpp
@@ -0,0 +1,31 @@
+#include "Obj.hh"
+
+#include <QObject>
+
+class ObjPrivate : public QObject
+{
+ Q_OBJECT
+public:
+ ObjPrivate();
+ ~ObjPrivate();
+};
+
+ObjPrivate::ObjPrivate()
+{
+}
+
+ObjPrivate::~ObjPrivate()
+{
+}
+
+Obj::Obj()
+ : d(new ObjPrivate)
+{
+}
+
+Obj::~Obj()
+{
+ delete d;
+}
+
+#include "Obj.moc"
diff --git a/Tests/QtAutogen/MocCMP0100/Obj.hh b/Tests/QtAutogen/MocCMP0100/Obj.hh
new file mode 100644
index 0000000..940bfc2
--- /dev/null
+++ b/Tests/QtAutogen/MocCMP0100/Obj.hh
@@ -0,0 +1,20 @@
+#ifndef OBJ_HH
+#define OBJ_HH
+
+#include <QObject>
+
+// Qt enabled private class
+class ObjPrivate;
+// Qt enabled class
+class Obj : public QObject
+{
+ Q_OBJECT
+public:
+ Obj();
+ ~Obj();
+
+private:
+ ObjPrivate* const d;
+};
+
+#endif
diff --git a/Tests/QtAutogen/MocCMP0100/Obj2.cpp b/Tests/QtAutogen/MocCMP0100/Obj2.cpp
new file mode 100644
index 0000000..8a359ad
--- /dev/null
+++ b/Tests/QtAutogen/MocCMP0100/Obj2.cpp
@@ -0,0 +1,31 @@
+#include "Obj2.hh"
+
+#include <QObject>
+
+class Obj2Private : public QObject
+{
+ Q_OBJECT
+public:
+ Obj2Private();
+ ~Obj2Private();
+};
+
+Obj2Private::Obj2Private()
+{
+}
+
+Obj2Private::~Obj2Private()
+{
+}
+
+Obj2::Obj2()
+ : d(new Obj2Private)
+{
+}
+
+Obj2::~Obj2()
+{
+ delete d;
+}
+
+#include "Obj2.moc"
diff --git a/Tests/QtAutogen/MocCMP0100/Obj2.hh b/Tests/QtAutogen/MocCMP0100/Obj2.hh
new file mode 100644
index 0000000..1c74cdd
--- /dev/null
+++ b/Tests/QtAutogen/MocCMP0100/Obj2.hh
@@ -0,0 +1,20 @@
+#ifndef OBJ2_HH
+#define OBJ2_HH
+
+#include <QObject>
+
+// Qt enabled private class
+class Obj2Private;
+// Qt enabled class
+class Obj2 : public QObject
+{
+ Q_OBJECT
+public:
+ Obj2();
+ ~Obj2();
+
+private:
+ Obj2Private* const d;
+};
+
+#endif
diff --git a/Tests/QtAutogen/MocCMP0100/main.cpp b/Tests/QtAutogen/MocCMP0100/main.cpp
new file mode 100644
index 0000000..17061da
--- /dev/null
+++ b/Tests/QtAutogen/MocCMP0100/main.cpp
@@ -0,0 +1,9 @@
+#include "Obj.hh"
+#include "Obj2.hh"
+
+int main(int argv, char** args)
+{
+ Obj obj;
+ Obj2 obj2;
+ return 0;
+}
diff --git a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleA.hpp b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleA.hpp
index e1fdf0b..198ae98 100644
--- a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleA.hpp
+++ b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleA.hpp
@@ -10,7 +10,7 @@ class StyleA : public QStylePlugin
Q_OBJECT
// Json file in source local directory
Q_PLUGIN_METADATA(IID "org.styles.A" FILE "StyleA.json")
- A_CUSTOM_MACRO(SomeArg, "StyleA_Custom.json", AnotherArg)
+ A_CUSTOM_MACRO(org.styles.A, "StyleA_Custom.json", AnotherArg)
public:
QStyle* create(const QString& key);
};
diff --git a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleB.hpp b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleB.hpp
index 7550d0c..8ce8d77 100644
--- a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleB.hpp
+++ b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleB.hpp
@@ -10,7 +10,7 @@ class StyleB : public QStylePlugin
Q_OBJECT
// Json file in source local subdirectory
Q_PLUGIN_METADATA(IID "org.styles.B" FILE "jsonIn/StyleB.json")
- A_CUSTOM_MACRO(SomeArg, "jsonIn/StyleB_Custom.json", AnotherArg)
+ A_CUSTOM_MACRO(org.styles.B, "jsonIn/StyleB_Custom.json", AnotherArg)
public:
QStyle* create(const QString& key);
};
diff --git a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleC.hpp b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleC.hpp
index ec71bec..53171e3 100644
--- a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleC.hpp
+++ b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleC.hpp
@@ -10,7 +10,7 @@ class StyleC : public QStylePlugin
Q_OBJECT
// Json file in global root directory
Q_PLUGIN_METADATA(IID "org.styles.C" FILE "StyleC.json")
- A_CUSTOM_MACRO(SomeArg, "StyleC_Custom.json", AnotherArg)
+ A_CUSTOM_MACRO(org.styles.C, "StyleC_Custom.json", AnotherArg)
public:
QStyle* create(const QString& key);
};
diff --git a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleD.hpp b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleD.hpp
index 3c093b9..29674f9 100644
--- a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleD.hpp
+++ b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleD.hpp
@@ -10,7 +10,7 @@ class StyleD : public QStylePlugin
Q_OBJECT
// Json file in global sub director
Q_PLUGIN_METADATA(IID "org.styles.D" FILE "sub/StyleD.json")
- A_CUSTOM_MACRO(SomeArg, "sub/StyleD_Custom.json", AnotherArg)
+ A_CUSTOM_MACRO(org.styles.D, "sub/StyleD_Custom.json", AnotherArg)
public:
QStyle* create(const QString& key);
};
diff --git a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleEInclude.hpp b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleEInclude.hpp
index 5f10fb4..7318220 100644
--- a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleEInclude.hpp
+++ b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/StyleEInclude.hpp
@@ -10,7 +10,7 @@ class StyleE : public QStylePlugin
Q_OBJECT
// Json files in global root directory
Q_PLUGIN_METADATA(IID "org.styles.E" FILE "StyleE.json")
- A_CUSTOM_MACRO(SomeArg, "StyleE_Custom.json", AnotherArg)
+ A_CUSTOM_MACRO(org.styles.E, "StyleE_Custom.json", AnotherArg)
public:
QStyle* create(const QString& key);
};
diff --git a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/UtilityMacros.hpp b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/UtilityMacros.hpp
index 53a4284..2f558a8 100644
--- a/Tests/QtAutogen/RerunMocPlugin/MocPlugin/UtilityMacros.hpp
+++ b/Tests/QtAutogen/RerunMocPlugin/MocPlugin/UtilityMacros.hpp
@@ -1,7 +1,7 @@
#ifndef UTILITYMACROS_HPP
#define UTILITYMACROS_HPP
-// Empty test macro definition
-#define A_CUSTOM_MACRO(name, jsonFile, pluginRegistrations)
+#define A_CUSTOM_MACRO(url, jsonFile, pluginRegistrations) \
+ Q_PLUGIN_METADATA(IID #url FILE jsonFile)
#endif
diff --git a/Tests/QtAutogen/SameName/CMakeLists.txt b/Tests/QtAutogen/SameName/CMakeLists.txt
index cd29a2a..4ce8dbd 100644
--- a/Tests/QtAutogen/SameName/CMakeLists.txt
+++ b/Tests/QtAutogen/SameName/CMakeLists.txt
@@ -1,7 +1,10 @@
-cmake_minimum_required(VERSION 3.10)
+cmake_minimum_required(VERSION 3.16.0)
project(SameName)
include("../AutogenGuiTest.cmake")
+# Process .hh headers in AUTOMOC
+cmake_policy(SET CMP0100 NEW)
+
# Test AUTOMOC and AUTORCC on source files with the same name
# but in different subdirectories
@@ -18,6 +21,7 @@ add_executable(sameName
ccc/data.qrc
item.cpp
object.h
+ object.hh
object.h++
object.hpp
object.hxx
diff --git a/Tests/QtAutogen/SameName/main.cpp b/Tests/QtAutogen/SameName/main.cpp
index 19a6f6d..725f4cd 100644
--- a/Tests/QtAutogen/SameName/main.cpp
+++ b/Tests/QtAutogen/SameName/main.cpp
@@ -6,6 +6,7 @@
#include "item.hpp"
#include "object.h"
#include "object.h++"
+#include "object.hh"
#include "object.hpp"
#include "object.hxx"
#include "object_upper_ext.H"
@@ -21,6 +22,7 @@ int main(int argv, char** args)
::ccc::Item ccc_item;
// Object instances
::Object_h obj_h;
+ ::Object_hh obj_hh;
::Object_hplpl obj_hplpl;
::Object_hpp obj_hpp;
::Object_hxx obj_hxx;
diff --git a/Tests/QtAutogen/SameName/object.hh b/Tests/QtAutogen/SameName/object.hh
new file mode 100644
index 0000000..3e16f83
--- /dev/null
+++ b/Tests/QtAutogen/SameName/object.hh
@@ -0,0 +1,13 @@
+#ifndef OBJECT_HH
+#define OBJECT_HH
+
+#include <QObject>
+
+class Object_hh : public QObject
+{
+ Q_OBJECT
+ Q_SLOT
+ void go(){};
+};
+
+#endif
diff --git a/Tests/QtAutogen/Tests.cmake b/Tests/QtAutogen/Tests.cmake
index 2b001d4..a19a9ae 100644
--- a/Tests/QtAutogen/Tests.cmake
+++ b/Tests/QtAutogen/Tests.cmake
@@ -32,6 +32,7 @@ ADD_AUTOGEN_TEST(UicSkipSource)
if(QT_TEST_ALLOW_QT_MACROS)
ADD_AUTOGEN_TEST(MocCMP0071)
+ ADD_AUTOGEN_TEST(MocCMP0100)
ADD_AUTOGEN_TEST(MocInclude)
ADD_AUTOGEN_TEST(MocIncludeSymlink)
ADD_AUTOGEN_TEST(MocSkipSource)
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-result.txt b/Tests/RunCMake/AutoExportDll/AIXExportExplicit-build-result.txt
index d197c91..d197c91 100644
--- a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-result.txt
+++ b/Tests/RunCMake/AutoExportDll/AIXExportExplicit-build-result.txt
diff --git a/Tests/RunCMake/AutoExportDll/AIXExportExplicit-build-stdout.txt b/Tests/RunCMake/AutoExportDll/AIXExportExplicit-build-stdout.txt
new file mode 100644
index 0000000..760ba3c
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/AIXExportExplicit-build-stdout.txt
@@ -0,0 +1 @@
+ERROR: Undefined symbol: .AIXNotExported
diff --git a/Tests/RunCMake/AutoExportDll/AIXExportExplicit.cmake b/Tests/RunCMake/AutoExportDll/AIXExportExplicit.cmake
new file mode 100644
index 0000000..d23b172
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/AIXExportExplicit.cmake
@@ -0,0 +1,7 @@
+enable_language(C)
+
+set(CMAKE_AIX_EXPORT_ALL_SYMBOLS OFF)
+add_library(AIXExportExplicitLib SHARED AIXExportExplicitLib.c)
+add_executable(AIXExportExplicitMain AIXExportExplicitMain.c)
+target_link_options(AIXExportExplicitLib PRIVATE LINKER:-bE:${CMAKE_CURRENT_SOURCE_DIR}/AIXExportExplicitLib.exp)
+target_link_libraries(AIXExportExplicitMain PRIVATE AIXExportExplicitLib)
diff --git a/Tests/RunCMake/AutoExportDll/AIXExportExplicitLib.c b/Tests/RunCMake/AutoExportDll/AIXExportExplicitLib.c
new file mode 100644
index 0000000..58fd5ac
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/AIXExportExplicitLib.c
@@ -0,0 +1,8 @@
+int AIXNotExported(void)
+{
+ return 0;
+}
+int AIXExportedSymbol(void)
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/AutoExportDll/AIXExportExplicitLib.exp b/Tests/RunCMake/AutoExportDll/AIXExportExplicitLib.exp
new file mode 100644
index 0000000..9eb7bf8
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/AIXExportExplicitLib.exp
@@ -0,0 +1 @@
+AIXExportedSymbol
diff --git a/Tests/RunCMake/AutoExportDll/AIXExportExplicitMain.c b/Tests/RunCMake/AutoExportDll/AIXExportExplicitMain.c
new file mode 100644
index 0000000..ad9c8ec
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/AIXExportExplicitMain.c
@@ -0,0 +1,7 @@
+extern int AIXNotExported(void);
+extern int AIXExportedSymbol(void);
+
+int main(void)
+{
+ return AIXNotExported() + AIXExportedSymbol();
+}
diff --git a/Tests/RunCMake/AutoExportDll/AutoExport.cmake b/Tests/RunCMake/AutoExportDll/AutoExport.cmake
index a550005..85eff7e 100644
--- a/Tests/RunCMake/AutoExportDll/AutoExport.cmake
+++ b/Tests/RunCMake/AutoExportDll/AutoExport.cmake
@@ -5,6 +5,10 @@ add_subdirectory(sub)
add_library(objlib OBJECT objlib.c)
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)
+ set_property(TARGET autoexport3 PROPERTY COMMON_LANGUAGE_RUNTIME "")
+endif()
add_executable(say say.cxx)
if(MSVC)
@@ -18,4 +22,4 @@ if(MSVC)
target_compile_definitions(say PRIVATE HAS_JUSTNOP)
endif()
endif()
-target_link_libraries(say autoexport autoexport2)
+target_link_libraries(say autoexport autoexport2 autoexport3)
diff --git a/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake b/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake
index 6c9be4b..75130f2 100644
--- a/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake
+++ b/Tests/RunCMake/AutoExportDll/RunCMakeTest.cmake
@@ -55,3 +55,14 @@ if(EXPORTS)
message(SEND_ERROR "\"${EXPORTS_DEF}\" has been updated.")
endif()
endif()
+
+function(run_AIXExportExplicit)
+ set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/AIXExpotExplicit-build")
+ run_cmake(AIXExportExplicit)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ set(RunCMake_TEST_OUTPUT_MERGE TRUE)
+ run_cmake_command(AIXExportExplicit-build ${CMAKE_COMMAND} --build . --config Debug)
+endfunction()
+if(CMAKE_SYSTEM_NAME STREQUAL "AIX")
+ run_AIXExportExplicit()
+endif()
diff --git a/Tests/RunCMake/AutoExportDll/cppCLI.cxx b/Tests/RunCMake/AutoExportDll/cppCLI.cxx
new file mode 100644
index 0000000..816bb6e
--- /dev/null
+++ b/Tests/RunCMake/AutoExportDll/cppCLI.cxx
@@ -0,0 +1,22 @@
+#include <stdio.h>
+
+#ifdef __cplusplus_cli
+# include <msclr\marshal_cppstd.h>
+
+void cliFunction()
+{
+ System::String ^ result = "cliFunction";
+ result = result->Trim();
+ printf(msclr::interop::marshal_as<std::string>(result).c_str());
+}
+#else
+void cliFunction()
+{
+ printf("cliFunction (but /cli was not passed to the compiler)");
+}
+#endif
+
+void nonCliFunction()
+{
+ printf("nonCliFunction");
+}
diff --git a/Tests/RunCMake/AutoExportDll/say.cxx b/Tests/RunCMake/AutoExportDll/say.cxx
index 654b5e0..8fc768a 100644
--- a/Tests/RunCMake/AutoExportDll/say.cxx
+++ b/Tests/RunCMake/AutoExportDll/say.cxx
@@ -17,9 +17,11 @@ void justnop();
}
// test c++ functions
-// forward declare hello and world
+// forward declare hello, world, cliFunction and nonCliFunction
void hello();
void world();
+void cliFunction();
+void nonCliFunction();
// test exports for executable target
extern "C" {
@@ -44,6 +46,10 @@ int main()
bar();
objlib();
printf("\n");
+ cliFunction();
+ printf("\n");
+ nonCliFunction();
+ printf("\n");
#ifdef HAS_JUSTNOP
justnop();
#endif
diff --git a/Tests/RunCMake/BuildDepends/ExternalProject/CMakeLists.txt b/Tests/RunCMake/BuildDepends/ExternalProject/CMakeLists.txt
new file mode 100644
index 0000000..57a0f6e
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/ExternalProject/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.12)
+project(External NONE)
+
+if (DEFINED cache_arg)
+ message("configured with: ${cache_arg}")
+else ()
+ message("cache_arg is undefined")
+endif ()
+
+if (DEFINED second_cache_arg)
+ message("configured again with: ${second_cache_arg}")
+else ()
+ message("second_cache_arg is undefined")
+endif ()
diff --git a/Tests/RunCMake/BuildDepends/ExternalProjectCacheArgs-build1-stdout.txt b/Tests/RunCMake/BuildDepends/ExternalProjectCacheArgs-build1-stdout.txt
new file mode 100644
index 0000000..fea7fd9
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/ExternalProjectCacheArgs-build1-stdout.txt
@@ -0,0 +1,2 @@
+.*configured with: first
+.*second_cache_arg is undefined
diff --git a/Tests/RunCMake/BuildDepends/ExternalProjectCacheArgs-build2-stdout.txt b/Tests/RunCMake/BuildDepends/ExternalProjectCacheArgs-build2-stdout.txt
new file mode 100644
index 0000000..e19e743
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/ExternalProjectCacheArgs-build2-stdout.txt
@@ -0,0 +1,2 @@
+.*configured with: first
+.*configured again with: second
diff --git a/Tests/RunCMake/BuildDepends/ExternalProjectCacheArgs.cmake b/Tests/RunCMake/BuildDepends/ExternalProjectCacheArgs.cmake
new file mode 100644
index 0000000..fe69426
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/ExternalProjectCacheArgs.cmake
@@ -0,0 +1,19 @@
+include("${CMAKE_CURRENT_BINARY_DIR}/data.cmake")
+
+include(ExternalProject)
+ExternalProject_add(external
+ SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/ExternalProject"
+ CMAKE_CACHE_ARGS
+ ${cache_args}
+ BUILD_COMMAND ""
+ INSTALL_COMMAND "")
+
+set(cache_args_path "<TMP_DIR>/external-cache-$<CONFIG>.cmake")
+set(cmake_cache_path "<BINARY_DIR>/CMakeCache.txt")
+_ep_replace_location_tags(external cache_args_path cmake_cache_path)
+
+file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/check-$<LOWER_CASE:$<CONFIG>>.cmake" CONTENT "
+set(check_pairs
+ \"${cmake_cache_path}|${cache_args_path}\"
+)
+")
diff --git a/Tests/RunCMake/BuildDepends/ExternalProjectCacheArgs.step1.cmake b/Tests/RunCMake/BuildDepends/ExternalProjectCacheArgs.step1.cmake
new file mode 100644
index 0000000..57c7ab7
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/ExternalProjectCacheArgs.step1.cmake
@@ -0,0 +1,3 @@
+file(WRITE "${RunCMake_TEST_BINARY_DIR}/data.cmake"
+ "set(cache_args -Dcache_arg:STRING=first)
+")
diff --git a/Tests/RunCMake/BuildDepends/ExternalProjectCacheArgs.step2.cmake b/Tests/RunCMake/BuildDepends/ExternalProjectCacheArgs.step2.cmake
new file mode 100644
index 0000000..cbb79e1
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/ExternalProjectCacheArgs.step2.cmake
@@ -0,0 +1,3 @@
+file(WRITE "${RunCMake_TEST_BINARY_DIR}/data.cmake"
+ "set(cache_args -Dsecond_cache_arg:STRING=second)
+")
diff --git a/Tests/RunCMake/BuildDepends/GNU-AS-stdout.txt b/Tests/RunCMake/BuildDepends/GNU-AS-stdout.txt
new file mode 100644
index 0000000..c4326ae
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/GNU-AS-stdout.txt
@@ -0,0 +1,4 @@
+-- The ASM compiler identification is GNU
+-- Found assembler: [^
+]*/as(\.exe)?
+-- CMAKE_ASM_COMPILER_ID_VENDOR_MATCH='GNU assembler'
diff --git a/Tests/RunCMake/BuildDepends/GNU-AS.cmake b/Tests/RunCMake/BuildDepends/GNU-AS.cmake
new file mode 100644
index 0000000..21921ef
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/GNU-AS.cmake
@@ -0,0 +1,13 @@
+enable_language(ASM)
+
+# Validate undocumented implementation detail.
+message(STATUS "CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_MATCH='${CMAKE_ASM${ASM_DIALECT}_COMPILER_ID_VENDOR_MATCH}'")
+
+add_library(gnu_as STATIC gnu_as.s)
+target_include_directories(gnu_as PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
+
+file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT "
+set(check_pairs
+ \"$<TARGET_FILE:gnu_as>|${CMAKE_CURRENT_BINARY_DIR}/gnu_as.inc\"
+ )
+")
diff --git a/Tests/RunCMake/BuildDepends/GNU-AS.step1.cmake b/Tests/RunCMake/BuildDepends/GNU-AS.step1.cmake
new file mode 100644
index 0000000..15a5e96
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/GNU-AS.step1.cmake
@@ -0,0 +1 @@
+file(WRITE "${RunCMake_TEST_BINARY_DIR}/gnu_as.inc" "")
diff --git a/Tests/RunCMake/BuildDepends/GNU-AS.step2.cmake b/Tests/RunCMake/BuildDepends/GNU-AS.step2.cmake
new file mode 100644
index 0000000..15a5e96
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/GNU-AS.step2.cmake
@@ -0,0 +1 @@
+file(WRITE "${RunCMake_TEST_BINARY_DIR}/gnu_as.inc" "")
diff --git a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
index 14ae243..7a68c4b 100644
--- a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
+++ b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
@@ -46,6 +46,11 @@ endif()
run_BuildDepends(Custom-Symbolic-and-Byproduct)
run_BuildDepends(Custom-Always)
+set(RunCMake_TEST_OUTPUT_MERGE_save "${RunCMake_TEST_OUTPUT_MERGE}")
+set(RunCMake_TEST_OUTPUT_MERGE 1)
+run_BuildDepends(ExternalProjectCacheArgs)
+set(RunCMake_TEST_OUTPUT_MERGE "${RunCMake_TEST_OUTPUT_MERGE_save}")
+
# Test header dependencies with a build tree underneath a source tree.
set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/BuildUnderSource")
set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/BuildUnderSource/build")
@@ -103,3 +108,8 @@ endfunction()
if(RunCMake_GENERATOR STREQUAL "Xcode")
run_ReGeneration(regenerate-project)
endif()
+
+if(CMake_TEST_BuildDepends_GNU_AS)
+ set(ENV{ASM} "${CMake_TEST_BuildDepends_GNU_AS}")
+ run_BuildDepends(GNU-AS)
+endif()
diff --git a/Tests/RunCMake/BuildDepends/gnu_as.s b/Tests/RunCMake/BuildDepends/gnu_as.s
new file mode 100644
index 0000000..a2e7dfb
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/gnu_as.s
@@ -0,0 +1 @@
+.include "gnu_as.inc"
diff --git a/Tests/RunCMake/CMP0037/RunCMakeTest.cmake b/Tests/RunCMake/CMP0037/RunCMakeTest.cmake
index 98274f0..5952279 100644
--- a/Tests/RunCMake/CMP0037/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CMP0037/RunCMakeTest.cmake
@@ -1,5 +1,24 @@
include(RunCMake)
+if(RunCMake_GENERATOR MATCHES "^Ninja")
+ # Detect ninja version so we know what tests can be supported.
+ execute_process(
+ COMMAND "${RunCMake_MAKE_PROGRAM}" --version
+ OUTPUT_VARIABLE ninja_out
+ ERROR_VARIABLE ninja_out
+ RESULT_VARIABLE ninja_res
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ if(ninja_res EQUAL 0 AND "x${ninja_out}" MATCHES "^x[0-9]+\\.[0-9]+")
+ set(ninja_version "${ninja_out}")
+ message(STATUS "ninja version: ${ninja_version}")
+ else()
+ message(FATAL_ERROR "'ninja --version' reported:\n${ninja_out}")
+ endif()
+else()
+ set(ninja_version "")
+endif()
+
run_cmake(CMP0037-OLD-space)
run_cmake(CMP0037-NEW-space)
run_cmake(CMP0037-WARN-space)
@@ -9,8 +28,10 @@ if(NOT (WIN32 AND "${RunCMake_GENERATOR}" MATCHES "Make"))
run_cmake(CMP0037-WARN-colon)
endif()
-run_cmake(CMP0037-WARN-reserved)
-run_cmake(CMP0037-OLD-reserved)
+if(NOT ninja_version VERSION_GREATER_EQUAL 1.10)
+ run_cmake(CMP0037-WARN-reserved)
+ run_cmake(CMP0037-OLD-reserved)
+endif()
run_cmake(CMP0037-NEW-reserved)
run_cmake(NEW-cond)
diff --git a/Tests/RunCMake/CMP0068/CMP0068-OLD-stderr.txt b/Tests/RunCMake/CMP0068/CMP0068-OLD-stderr.txt
new file mode 100644
index 0000000..a736129
--- /dev/null
+++ b/Tests/RunCMake/CMP0068/CMP0068-OLD-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at CMP0068-OLD.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0068 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/CMP0069/CMP0069-OLD-stderr.txt b/Tests/RunCMake/CMP0069/CMP0069-OLD-stderr.txt
new file mode 100644
index 0000000..f51a6f4
--- /dev/null
+++ b/Tests/RunCMake/CMP0069/CMP0069-OLD-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at CMP0069-OLD.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0069 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/CMP0102/CMP0102-Common.cmake b/Tests/RunCMake/CMP0102/CMP0102-Common.cmake
new file mode 100644
index 0000000..61fdad6
--- /dev/null
+++ b/Tests/RunCMake/CMP0102/CMP0102-Common.cmake
@@ -0,0 +1,2 @@
+
+mark_as_advanced(CMP0102_TEST_VARIABLE)
diff --git a/Tests/RunCMake/CMP0102/CMP0102-NEW.cmake b/Tests/RunCMake/CMP0102/CMP0102-NEW.cmake
new file mode 100644
index 0000000..bdf769f
--- /dev/null
+++ b/Tests/RunCMake/CMP0102/CMP0102-NEW.cmake
@@ -0,0 +1,13 @@
+
+cmake_policy(SET CMP0102 NEW)
+
+include (CMP0102-Common.cmake)
+get_property(is_type_set CACHE CMP0102_TEST_VARIABLE
+ PROPERTY TYPE SET)
+if (is_type_set)
+ get_property(type CACHE CMP0102_TEST_VARIABLE
+ PROPERTY TYPE)
+ message(FATAL_ERROR
+ "There is a cache entry for an undefined variable after "
+ "`mark_as_advanced`.")
+endif ()
diff --git a/Tests/RunCMake/CMP0102/CMP0102-OLD.cmake b/Tests/RunCMake/CMP0102/CMP0102-OLD.cmake
new file mode 100644
index 0000000..5c20dd3
--- /dev/null
+++ b/Tests/RunCMake/CMP0102/CMP0102-OLD.cmake
@@ -0,0 +1,18 @@
+
+cmake_policy(SET CMP0102 OLD)
+
+include (CMP0102-Common.cmake)
+get_property(is_type_set CACHE CMP0102_TEST_VARIABLE
+ PROPERTY TYPE SET)
+if (NOT is_type_set)
+ message(FATAL_ERROR
+ "There is a cache entry for an undefined variable after "
+ "`mark_as_advanced`.")
+endif ()
+get_property(type CACHE CMP0102_TEST_VARIABLE
+ PROPERTY TYPE)
+if (NOT type STREQUAL "UNINITIALIZED")
+ message(FATAL_ERROR
+ "The cache type for CMP0102_TEST_VARIABLE is not "
+ "UNINITIALIZED")
+endif ()
diff --git a/Tests/RunCMake/CMP0102/CMP0102-WARN-Default.cmake b/Tests/RunCMake/CMP0102/CMP0102-WARN-Default.cmake
new file mode 100644
index 0000000..d6ebe4d
--- /dev/null
+++ b/Tests/RunCMake/CMP0102/CMP0102-WARN-Default.cmake
@@ -0,0 +1,16 @@
+
+include (CMP0102-Common.cmake)
+get_property(is_type_set CACHE CMP0102_TEST_VARIABLE
+ PROPERTY TYPE SET)
+if (NOT is_type_set)
+ message(FATAL_ERROR
+ "There is a cache entry for an undefined variable after "
+ "`mark_as_advanced`.")
+endif ()
+get_property(type CACHE CMP0102_TEST_VARIABLE
+ PROPERTY TYPE)
+if (NOT type STREQUAL "UNINITIALIZED")
+ message(FATAL_ERROR
+ "The cache type for CMP0102_TEST_VARIABLE is not "
+ "UNINITIALIZED")
+endif ()
diff --git a/Tests/RunCMake/CMP0102/CMP0102-WARN-stderr.txt b/Tests/RunCMake/CMP0102/CMP0102-WARN-stderr.txt
new file mode 100644
index 0000000..bb56ec2
--- /dev/null
+++ b/Tests/RunCMake/CMP0102/CMP0102-WARN-stderr.txt
@@ -0,0 +1,10 @@
+CMake Warning \(dev\) at CMP0102-Common.cmake:2 \(mark_as_advanced\):
+ Policy CMP0102 is not set: The variable named "CMP0102_TEST_VARIABLE" is
+ not in the cache. This results in an empty cache entry which is no longer
+ created when policy CMP0102 is set to NEW. Run "cmake --help-policy
+ CMP0102" for policy details. Use the cmake_policy command to set the
+ policy and suppress this warning.
+Call Stack \(most recent call first\):
+ CMP0102-WARN.cmake:4 \(include\)
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0102/CMP0102-WARN.cmake b/Tests/RunCMake/CMP0102/CMP0102-WARN.cmake
new file mode 100644
index 0000000..e9a45f1
--- /dev/null
+++ b/Tests/RunCMake/CMP0102/CMP0102-WARN.cmake
@@ -0,0 +1,18 @@
+
+set(CMAKE_POLICY_WARNING_CMP0102 1)
+
+include (CMP0102-Common.cmake)
+get_property(is_type_set CACHE CMP0102_TEST_VARIABLE
+ PROPERTY TYPE SET)
+if (NOT is_type_set)
+ message(FATAL_ERROR
+ "There is a cache entry for an undefined variable after "
+ "`mark_as_advanced`.")
+endif ()
+get_property(type CACHE CMP0102_TEST_VARIABLE
+ PROPERTY TYPE)
+if (NOT type STREQUAL "UNINITIALIZED")
+ message(FATAL_ERROR
+ "The cache type for CMP0102_TEST_VARIABLE is not "
+ "UNINITIALIZED")
+endif ()
diff --git a/Tests/RunCMake/CMP0102/CMakeLists.txt b/Tests/RunCMake/CMP0102/CMakeLists.txt
new file mode 100644
index 0000000..ef2163c
--- /dev/null
+++ b/Tests/RunCMake/CMP0102/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.1)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0102/RunCMakeTest.cmake b/Tests/RunCMake/CMP0102/RunCMakeTest.cmake
new file mode 100644
index 0000000..9b5df74
--- /dev/null
+++ b/Tests/RunCMake/CMP0102/RunCMakeTest.cmake
@@ -0,0 +1,6 @@
+include(RunCMake)
+
+run_cmake(CMP0102-OLD)
+run_cmake(CMP0102-NEW)
+run_cmake(CMP0102-WARN)
+run_cmake(CMP0102-WARN-Default)
diff --git a/Tests/RunCMake/CMP0104/CMP0104-Common.cmake b/Tests/RunCMake/CMP0104/CMP0104-Common.cmake
new file mode 100644
index 0000000..b3568f1
--- /dev/null
+++ b/Tests/RunCMake/CMP0104/CMP0104-Common.cmake
@@ -0,0 +1,2 @@
+enable_language(CUDA)
+add_library(cuda main.cu)
diff --git a/Tests/RunCMake/CMP0104/CMP0104-NEW.cmake b/Tests/RunCMake/CMP0104/CMP0104-NEW.cmake
new file mode 100644
index 0000000..732ab77
--- /dev/null
+++ b/Tests/RunCMake/CMP0104/CMP0104-NEW.cmake
@@ -0,0 +1,6 @@
+cmake_policy(SET CMP0104 NEW)
+include(CMP0104-Common.cmake)
+
+if(NOT CMAKE_CUDA_ARCHITECTURES)
+ message(FATAL_ERROR "CMAKE_CUDA_ARCHITECTURES is empty with CMP0104 enabled.")
+endif()
diff --git a/Tests/RunCMake/CMP0104/CMP0104-OLD.cmake b/Tests/RunCMake/CMP0104/CMP0104-OLD.cmake
new file mode 100644
index 0000000..415eecc
--- /dev/null
+++ b/Tests/RunCMake/CMP0104/CMP0104-OLD.cmake
@@ -0,0 +1,12 @@
+cmake_policy(SET CMP0104 OLD)
+include(CMP0104-Common.cmake)
+
+if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
+ if(CMAKE_CUDA_ARCHITECTURES)
+ message(FATAL_ERROR "CMAKE_CUDA_ARCHITECTURES isn't empty for NVIDIA with CMP0104 OLD.")
+ endif()
+else(NOT CMAKE_CUDA_COMPILER_ID STREQUAL "Unknown")
+ if(NOT CMAKE_CUDA_ARCHITECTURES)
+ message(FATAL_ERROR "CMAKE_CUDA_ARCHITECTURES isn't non-empty for non-NVIDIA with CMP0104 OLD.")
+ endif()
+endif()
diff --git a/Tests/RunCMake/CMP0104/CMP0104-WARN-stderr.txt b/Tests/RunCMake/CMP0104/CMP0104-WARN-stderr.txt
new file mode 100644
index 0000000..2c9b7d7
--- /dev/null
+++ b/Tests/RunCMake/CMP0104/CMP0104-WARN-stderr.txt
@@ -0,0 +1,8 @@
+CMake Warning \(dev\) in CMakeLists.txt:
+ Policy CMP0104 is not set: CMAKE_CUDA_ARCHITECTURES now detected for NVCC,
+ empty CUDA_ARCHITECTURES not allowed. Run "cmake --help-policy CMP0104"
+ for policy details. Use the cmake_policy command to set the policy and
+ suppress this warning.
+
+ CUDA_ARCHITECTURES is empty for target "cuda".
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0104/CMP0104-WARN.cmake b/Tests/RunCMake/CMP0104/CMP0104-WARN.cmake
new file mode 100644
index 0000000..841d0a8
--- /dev/null
+++ b/Tests/RunCMake/CMP0104/CMP0104-WARN.cmake
@@ -0,0 +1 @@
+include(CMP0104-Common.cmake)
diff --git a/Tests/RunCMake/CMP0104/CMakeLists.txt b/Tests/RunCMake/CMP0104/CMakeLists.txt
new file mode 100644
index 0000000..2632ffa
--- /dev/null
+++ b/Tests/RunCMake/CMP0104/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.16)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0104/RunCMakeTest.cmake b/Tests/RunCMake/CMP0104/RunCMakeTest.cmake
new file mode 100644
index 0000000..bc8e1b1
--- /dev/null
+++ b/Tests/RunCMake/CMP0104/RunCMakeTest.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(CMP0104-OLD)
+run_cmake(CMP0104-NEW)
+run_cmake(CMP0104-WARN)
diff --git a/Tests/RunCMake/CMP0104/main.cu b/Tests/RunCMake/CMP0104/main.cu
new file mode 100644
index 0000000..5047a34
--- /dev/null
+++ b/Tests/RunCMake/CMP0104/main.cu
@@ -0,0 +1,3 @@
+int main()
+{
+}
diff --git a/Tests/RunCMake/CMP0106/CMP0106-Common.cmake b/Tests/RunCMake/CMP0106/CMP0106-Common.cmake
new file mode 100644
index 0000000..a1f7908
--- /dev/null
+++ b/Tests/RunCMake/CMP0106/CMP0106-Common.cmake
@@ -0,0 +1,10 @@
+include(Documentation OPTIONAL RESULT_VARIABLE found)
+if (NOT should_find AND found)
+ message(FATAL_ERROR
+ "The Documentation module should not have been found, but it was.")
+endif ()
+if (should_find AND NOT found)
+ message(FATAL_ERROR
+ "The Documentation module should have been found, but it was not.")
+endif ()
+include(${CMAKE_ROOT}/Modules/Documentation.cmake)
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/CMP0106/CMP0106-NEW-result.txt
index d00491f..d00491f 100644
--- a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
+++ b/Tests/RunCMake/CMP0106/CMP0106-NEW-result.txt
diff --git a/Tests/RunCMake/CMP0106/CMP0106-NEW-stderr.txt b/Tests/RunCMake/CMP0106/CMP0106-NEW-stderr.txt
new file mode 100644
index 0000000..7ad774e
--- /dev/null
+++ b/Tests/RunCMake/CMP0106/CMP0106-NEW-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at .*/Modules/Documentation.cmake:15 \(message\):
+ Documentation.cmake is VTK-specific code and should not be used in non-VTK
+ projects. This logic in this module is best shipped with the project using
+ it rather than with CMake. This is now an error according to policy
+ CMP0106.
+Call Stack \(most recent call first\):
+ CMP0106-Common.cmake:10 \(include\)
+ CMP0106-NEW.cmake:4 \(include\)
+ CMakeLists.txt:7 \(include\)
diff --git a/Tests/RunCMake/CMP0106/CMP0106-NEW.cmake b/Tests/RunCMake/CMP0106/CMP0106-NEW.cmake
new file mode 100644
index 0000000..e7d5bd1
--- /dev/null
+++ b/Tests/RunCMake/CMP0106/CMP0106-NEW.cmake
@@ -0,0 +1,4 @@
+cmake_policy(SET CMP0106 NEW)
+
+set(should_find OFF)
+include(CMP0106-Common.cmake)
diff --git a/Tests/RunCMake/CMP0106/CMP0106-OLD.cmake b/Tests/RunCMake/CMP0106/CMP0106-OLD.cmake
new file mode 100644
index 0000000..730e846
--- /dev/null
+++ b/Tests/RunCMake/CMP0106/CMP0106-OLD.cmake
@@ -0,0 +1,9 @@
+cmake_policy(SET CMP0106 OLD)
+
+set(should_find ON)
+include(CMP0106-Common.cmake)
+if (NOT DEFINED BUILD_DOCUMENTATION)
+ message(FATAL_ERROR
+ "Cache variables seem to have not been made with a `OLD` policy "
+ "setting.")
+endif ()
diff --git a/Tests/RunCMake/CMP0106/CMP0106-WARN-ParaView-stderr.txt b/Tests/RunCMake/CMP0106/CMP0106-WARN-ParaView-stderr.txt
new file mode 100644
index 0000000..b61889b
--- /dev/null
+++ b/Tests/RunCMake/CMP0106/CMP0106-WARN-ParaView-stderr.txt
@@ -0,0 +1,8 @@
+CMake Warning \(dev\) at CMP0106-Common.cmake:1 \(include\):
+ Policy CMP0106 is not set: The Documentation module is removed. Run "cmake
+ --help-policy CMP0106" for policy details. Use the cmake_policy command to
+ set the policy and suppress this warning.
+
+Call Stack \(most recent call first\):
+ subdir/CMakeLists.txt:2 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0106/CMP0106-WARN-ParaView.cmake b/Tests/RunCMake/CMP0106/CMP0106-WARN-ParaView.cmake
new file mode 100644
index 0000000..309abcc
--- /dev/null
+++ b/Tests/RunCMake/CMP0106/CMP0106-WARN-ParaView.cmake
@@ -0,0 +1,2 @@
+set(should_find ON)
+add_subdirectory(subdir)
diff --git a/Tests/RunCMake/CMP0106/CMP0106-WARN-VTK-stderr.txt b/Tests/RunCMake/CMP0106/CMP0106-WARN-VTK-stderr.txt
new file mode 100644
index 0000000..f8a754e
--- /dev/null
+++ b/Tests/RunCMake/CMP0106/CMP0106-WARN-VTK-stderr.txt
@@ -0,0 +1,9 @@
+CMake Warning \(dev\) at CMP0106-Common.cmake:1 \(include\):
+ Policy CMP0106 is not set: The Documentation module is removed. Run "cmake
+ --help-policy CMP0106" for policy details. Use the cmake_policy command to
+ set the policy and suppress this warning.
+
+Call Stack \(most recent call first\):
+ CMP0106-WARN-VTK.cmake:2 \(include\)
+ CMakeLists.txt:7 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0106/CMP0106-WARN-VTK.cmake b/Tests/RunCMake/CMP0106/CMP0106-WARN-VTK.cmake
new file mode 100644
index 0000000..99f6c39
--- /dev/null
+++ b/Tests/RunCMake/CMP0106/CMP0106-WARN-VTK.cmake
@@ -0,0 +1,2 @@
+set(should_find ON)
+include(CMP0106-Common.cmake)
diff --git a/Tests/RunCMake/CMP0106/CMP0106-WARN-stderr.txt b/Tests/RunCMake/CMP0106/CMP0106-WARN-stderr.txt
new file mode 100644
index 0000000..d0d48d0
--- /dev/null
+++ b/Tests/RunCMake/CMP0106/CMP0106-WARN-stderr.txt
@@ -0,0 +1,37 @@
+CMake Warning \(dev\) at CMP0106-Common.cmake:1 \(include\):
+ Policy CMP0106 is not set: The Documentation module is removed. Run "cmake
+ --help-policy CMP0106" for policy details. Use the cmake_policy command to
+ set the policy and suppress this warning.
+
+Call Stack \(most recent call first\):
+ CMP0106-WARN.cmake:2 \(include\)
+ CMakeLists.txt:7 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\) at .*/Modules/Documentation.cmake:27 \(message\):
+ Policy CMP0106 is not set: The Documentation module is removed. Run "cmake
+ --help-policy CMP0106" for policy details. Use the cmake_policy command to
+ set the policy and suppress this warning.
+
+ Documentation.cmake is VTK-specific code and should not be used in non-VTK
+ projects. This logic in this module is best shipped with the project using
+ it rather than with CMake.
+Call Stack \(most recent call first\):
+ CMP0106-Common.cmake:1 \(include\)
+ CMP0106-WARN.cmake:2 \(include\)
+ CMakeLists.txt:7 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\) at .*/Modules/Documentation.cmake:27 \(message\):
+ Policy CMP0106 is not set: The Documentation module is removed. Run "cmake
+ --help-policy CMP0106" for policy details. Use the cmake_policy command to
+ set the policy and suppress this warning.
+
+ Documentation.cmake is VTK-specific code and should not be used in non-VTK
+ projects. This logic in this module is best shipped with the project using
+ it rather than with CMake.
+Call Stack \(most recent call first\):
+ CMP0106-Common.cmake:10 \(include\)
+ CMP0106-WARN.cmake:2 \(include\)
+ CMakeLists.txt:7 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CMP0106/CMP0106-WARN.cmake b/Tests/RunCMake/CMP0106/CMP0106-WARN.cmake
new file mode 100644
index 0000000..99f6c39
--- /dev/null
+++ b/Tests/RunCMake/CMP0106/CMP0106-WARN.cmake
@@ -0,0 +1,2 @@
+set(should_find ON)
+include(CMP0106-Common.cmake)
diff --git a/Tests/RunCMake/CMP0106/CMakeLists.txt b/Tests/RunCMake/CMP0106/CMakeLists.txt
new file mode 100644
index 0000000..eafa642
--- /dev/null
+++ b/Tests/RunCMake/CMP0106/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 3.1)
+if (RunCMake_TEST STREQUAL "CMP0106-WARN-VTK")
+ project(VTK NONE)
+else ()
+ project(${RunCMake_TEST} NONE)
+endif ()
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0106/RunCMakeTest.cmake b/Tests/RunCMake/CMP0106/RunCMakeTest.cmake
new file mode 100644
index 0000000..acec054
--- /dev/null
+++ b/Tests/RunCMake/CMP0106/RunCMakeTest.cmake
@@ -0,0 +1,7 @@
+include(RunCMake)
+
+run_cmake(CMP0106-OLD)
+run_cmake(CMP0106-NEW)
+run_cmake(CMP0106-WARN)
+run_cmake(CMP0106-WARN-VTK)
+run_cmake(CMP0106-WARN-ParaView)
diff --git a/Tests/RunCMake/CMP0106/subdir/CMakeLists.txt b/Tests/RunCMake/CMP0106/subdir/CMakeLists.txt
new file mode 100644
index 0000000..ed1dd05
--- /dev/null
+++ b/Tests/RunCMake/CMP0106/subdir/CMakeLists.txt
@@ -0,0 +1,2 @@
+project(VTK NONE)
+include(${CMAKE_CURRENT_SOURCE_DIR}/../CMP0106-Common.cmake)
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 581a39e..8aeb412 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -115,6 +115,11 @@ if(CMAKE_SYSTEM_NAME MATCHES Darwin AND CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG)
endif()
add_RunCMake_test(CMP0069)
add_RunCMake_test(CMP0081)
+add_RunCMake_test(CMP0102)
+if(CMake_TEST_CUDA)
+ add_RunCMake_test(CMP0104)
+endif()
+add_RunCMake_test(CMP0106)
# The test for Policy 65 requires the use of the
# CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS variable, which both the VS and Xcode
@@ -125,7 +130,7 @@ endif()
if(CMAKE_GENERATOR MATCHES "Make")
add_RunCMake_test(Make -DMAKE_IS_GNU=${MAKE_IS_GNU})
endif()
-if(CMAKE_GENERATOR STREQUAL "Ninja")
+if(CMAKE_GENERATOR MATCHES "Ninja")
set(Ninja_ARGS
-DCMAKE_C_OUTPUT_EXTENSION=${CMAKE_C_OUTPUT_EXTENSION}
-DCMAKE_SHARED_LIBRARY_PREFIX=${CMAKE_SHARED_LIBRARY_PREFIX}
@@ -134,6 +139,16 @@ if(CMAKE_GENERATOR STREQUAL "Ninja")
list(APPEND Ninja_ARGS -DTEST_Fortran=1)
endif()
add_RunCMake_test(Ninja)
+ set(NinjaMultiConfig_ARGS
+ -DCYGWIN=${CYGWIN}
+ )
+ if(CMake_TEST_Qt5 AND Qt5Core_FOUND)
+ list(APPEND NinjaMultiConfig_ARGS -DCMake_TEST_Qt5=1)
+ endif()
+ if(DEFINED CMake_TEST_CUDA)
+ list(APPEND NinjaMultiConfig_ARGS -DCMake_TEST_CUDA=${CMake_TEST_CUDA})
+ endif()
+ add_RunCMake_test(NinjaMultiConfig)
endif()
add_RunCMake_test(CTest)
@@ -158,7 +173,20 @@ if(CMake_TEST_Qt5 AND Qt5Widgets_FOUND)
set(autogen_with_qt5 TRUE)
endif ()
add_RunCMake_test(Autogen -Dwith_qt5=${autogen_with_qt5})
-add_RunCMake_test(BuildDepends)
+if(NOT DEFINED CMake_TEST_BuildDepends_GNU_AS
+ AND CMAKE_C_COMPILER_ID STREQUAL "GNU"
+ AND CMAKE_GENERATOR MATCHES "^Ninja"
+ )
+ execute_process(COMMAND "${CMAKE_C_COMPILER}" -print-prog-name=as
+ RESULT_VARIABLE _gnu_res
+ OUTPUT_VARIABLE _gnu_as OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
+ if(_gnu_res EQUAL 0 AND _gnu_as)
+ set(CMake_TEST_BuildDepends_GNU_AS "${_gnu_as}")
+ endif()
+endif()
+add_RunCMake_test(BuildDepends
+ -DCMake_TEST_BuildDepends_GNU_AS=${CMake_TEST_BuildDepends_GNU_AS}
+ )
if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Unix Makefiles|Ninja")
add_RunCMake_test(Byproducts)
endif()
@@ -169,6 +197,9 @@ endif()
add_RunCMake_test(CompilerNotFound)
add_RunCMake_test(Configure -DMSVC_IDE=${MSVC_IDE})
add_RunCMake_test(DisallowedCommands)
+if("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles|Ninja")
+ add_RunCMake_test(ExportCompileCommands)
+endif()
add_RunCMake_test(ExternalData)
add_RunCMake_test(FeatureSummary)
add_RunCMake_test(FPHSA)
@@ -177,6 +208,7 @@ add_RunCMake_test(FindBoost)
add_RunCMake_test(FindLua)
add_RunCMake_test(FindOpenGL)
if(CMake_TEST_UseSWIG)
+ add_RunCMake_test(FindSWIG)
add_RunCMake_test(UseSWIG -DCMake_TEST_FindPython=${CMake_TEST_FindPython})
endif()
if(NOT CMAKE_C_COMPILER_ID MATCHES "Watcom")
@@ -189,6 +221,7 @@ add_RunCMake_test(GeneratorToolset)
add_RunCMake_test(GetPrerequisites)
add_RunCMake_test(GNUInstallDirs -DSYSTEM_NAME=${CMAKE_SYSTEM_NAME})
add_RunCMake_test(GoogleTest) # Note: does not actually depend on Google Test
+add_RunCMake_test(Graphviz)
add_RunCMake_test(TargetPropertyGeneratorExpressions)
add_RunCMake_test(Languages)
add_RunCMake_test(LinkStatic)
@@ -209,6 +242,7 @@ add_RunCMake_test(ScriptMode)
add_RunCMake_test(Swift -DCMAKE_Swift_COMPILER=${CMAKE_Swift_COMPILER})
add_RunCMake_test(TargetObjects)
add_RunCMake_test(TargetSources)
+add_RunCMake_test(TargetProperties)
add_RunCMake_test(ToolchainFile)
add_RunCMake_test(find_dependency)
add_RunCMake_test(CompileDefinitions)
@@ -271,6 +305,7 @@ add_RunCMake_test(find_package)
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(get_filename_component)
add_RunCMake_test(get_property)
add_RunCMake_test(if)
@@ -278,6 +313,7 @@ add_RunCMake_test(include)
add_RunCMake_test(include_directories)
add_RunCMake_test(include_guard)
add_RunCMake_test(list)
+add_RunCMake_test(load_cache)
add_RunCMake_test(math)
add_RunCMake_test(message)
add_RunCMake_test(option)
@@ -289,6 +325,10 @@ add_RunCMake_test(set_property)
add_RunCMake_test(string)
add_RunCMake_test(test_include_dirs)
add_RunCMake_test(BundleUtilities)
+if(APPLE)
+ add_RunCMake_test(INSTALL_NAME_DIR)
+ add_RunCMake_test(MacOSVersions)
+endif()
function(add_RunCMake_test_try_compile)
if(CMAKE_VERSION VERSION_LESS 3.9.20170907 AND "x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC")
@@ -335,6 +375,7 @@ add_RunCMake_test(alias_targets)
add_RunCMake_test(interface_library)
add_RunCMake_test(no_install_prefix)
add_RunCMake_test(configure_file)
+add_RunCMake_test(CTestTimeout -DTIMEOUT=${CTestTestTimeout_TIME})
add_RunCMake_test(CTestTimeoutAfterMatch)
# ctresalloc links against CMakeLib and CTestLib, which means it can't be built
@@ -427,21 +468,24 @@ if(CMAKE_C_COMPILER_ID STREQUAL "AppleClang"
add_RunCMake_test(Framework)
endif()
+add_RunCMake_test(File_Archive)
+add_RunCMake_test(File_Configure)
add_RunCMake_test(File_Generate)
add_RunCMake_test(ExportWithoutLanguage)
add_RunCMake_test(target_link_directories)
add_RunCMake_test(target_link_libraries)
add_RunCMake_test(add_link_options -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID})
-add_RunCMake_test(target_link_options -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID})
+add_RunCMake_test(target_link_options -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}
+ -DCMake_TEST_CUDA=${CMake_TEST_CUDA})
add_RunCMake_test(target_compile_definitions)
add_RunCMake_test(target_compile_features)
-add_RunCMake_test(target_compile_options)
+add_RunCMake_test(target_compile_options -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID})
add_RunCMake_test(target_include_directories)
add_RunCMake_test(target_sources)
add_RunCMake_test(CheckModules)
add_RunCMake_test(CheckIPOSupported)
-add_RunCMake_test(CommandLine -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME})
+add_RunCMake_test(CommandLine -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME} -DCYGWIN=${CYGWIN} -DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE})
add_RunCMake_test(CommandLineTar)
if(CMAKE_PLATFORM_NO_VERSIONED_SONAME OR (NOT CMAKE_SHARED_LIBRARY_SONAME_FLAG AND NOT CMAKE_SHARED_LIBRARY_SONAME_C_FLAG))
@@ -454,7 +498,9 @@ add_RunCMake_test(install -DNO_NAMELINK=${NO_NAMELINK} -DCYGWIN=${CYGWIN} -DCMAK
-DCMAKE_SHARED_LIBRARY_RPATH_ORIGIN_TOKEN=${CMAKE_SHARED_LIBRARY_RPATH_ORIGIN_TOKEN}
-DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}
-DCMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG=${CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG}
- -DCMAKE_EXECUTABLE_FORMAT=${CMAKE_EXECUTABLE_FORMAT})
+ -DCMAKE_EXECUTABLE_FORMAT=${CMAKE_EXECUTABLE_FORMAT}
+ -DCMake_INSTALL_NAME_TOOL_BUG=${CMake_INSTALL_NAME_TOOL_BUG}
+ )
add_RunCMake_test(CPackCommandLine)
add_RunCMake_test(CPackConfig)
@@ -554,6 +600,7 @@ set(cpack_tests
DEB.MD5SUMS
DEB.DEB_PACKAGE_VERSION_BACK_COMPATIBILITY
DEB.DEB_DESCRIPTION
+ DEB.PROJECT_META
RPM.CUSTOM_BINARY_SPEC_FILE
RPM.CUSTOM_NAMES
@@ -574,6 +621,7 @@ set(cpack_tests
RPM.SUGGESTS
RPM.SYMLINKS
RPM.USER_FILELIST
+ RPM.PROJECT_META
7Z
TBZ2
@@ -584,10 +632,16 @@ set(cpack_tests
STGZ
External
)
+if(APPLE)
+ list(APPEND cpack_tests DragNDrop)
+endif()
add_RunCMake_test_group(CPack "${cpack_tests}")
# add a test to make sure symbols are exported from a shared library
# for MSVC compilers CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS property is used
-add_RunCMake_test(AutoExportDll -DCMAKE_CXX_COMPILER_ID=${CMAKE_CXX_COMPILER_ID})
+add_RunCMake_test(AutoExportDll
+ -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}
+ -DCMAKE_CXX_COMPILER_ID=${CMAKE_CXX_COMPILER_ID}
+ )
add_RunCMake_test(AndroidMK)
@@ -619,5 +673,7 @@ endif()
add_RunCMake_test("CTestCommandExpandLists")
-add_RunCMake_test(PrecompileHeaders)
+add_RunCMake_test(PrecompileHeaders -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID})
add_RunCMake_test("UnityBuild")
+
+add_RunCMake_test(cmake_command)
diff --git a/Tests/RunCMake/CPack/CPackTestHelpers.cmake b/Tests/RunCMake/CPack/CPackTestHelpers.cmake
index f65cb9d..24f54c6 100644
--- a/Tests/RunCMake/CPack/CPackTestHelpers.cmake
+++ b/Tests/RunCMake/CPack/CPackTestHelpers.cmake
@@ -75,7 +75,7 @@ function(run_cpack_test_common_ TEST_NAME types build SUBTEST_SUFFIX source PACK
if(package_target)
set(cpack_command_ ${CMAKE_COMMAND} --build "${RunCMake_TEST_BINARY_DIR}" --target package)
else()
- set(cpack_command_ ${CMAKE_CPACK_COMMAND} ${pack_params_})
+ set(cpack_command_ ${CMAKE_CPACK_COMMAND} ${pack_params_} -C Debug)
endif()
# execute cpack
diff --git a/Tests/RunCMake/CPack/DragNDrop/Helpers.cmake b/Tests/RunCMake/CPack/DragNDrop/Helpers.cmake
new file mode 100644
index 0000000..023e597
--- /dev/null
+++ b/Tests/RunCMake/CPack/DragNDrop/Helpers.cmake
@@ -0,0 +1,54 @@
+set(ALL_FILES_GLOB "*.dmg")
+
+function(getPackageContent FILE RESULT_VAR)
+ get_filename_component(path_ "${FILE}" DIRECTORY)
+ file(REMOVE_RECURSE "${path_}/content")
+ file(MAKE_DIRECTORY "${path_}/content")
+ execute_process(COMMAND ${HDIUTIL_EXECUTABLE} attach -mountroot ${path_}/content -nobrowse ${FILE}
+ RESULT_VARIABLE attach_result_
+ ERROR_VARIABLE attach_error_
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ if(attach_result_)
+ message(FATAL_ERROR "Failed to attach DMG: '${attach_result_}';"
+ " '${attach_error_}'.")
+ endif()
+
+ file(GLOB_RECURSE package_content_ LIST_DIRECTORIES true RELATIVE
+ "${path_}/content" "${path_}/content/*")
+ # Some versions of macOS have .Trashes, others do not.
+ list(FILTER package_content_ EXCLUDE REGEX "/.Trashes$")
+ set(${RESULT_VAR} "${package_content_}" PARENT_SCOPE)
+
+ execute_process(COMMAND ${HDIUTIL_EXECUTABLE} detach ${path_}/content/volume-name
+ RESULT_VARIABLE detach_result_
+ ERROR_VARIABLE detach_error_
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ if(detach_result_)
+ message(FATAL_ERROR "Failed to detach DMG: '${detach_result_}';"
+ " '${detach_error_}'.")
+ endif()
+endfunction()
+
+function(getPackageNameGlobexpr NAME COMPONENT VERSION REVISION FILE_NO RESULT_VAR)
+ if(COMPONENT)
+ set(COMPONENT "-${COMPONENT}")
+ endif()
+
+ set(${RESULT_VAR} "${NAME}-${VERSION}-Darwin${COMPONENT}.dmg" PARENT_SCOPE)
+endfunction()
+
+function(getPackageContentList FILE RESULT_VAR)
+ getPackageContent("${FILE}" package_content_)
+
+ set(${RESULT_VAR} "${package_content_}" PARENT_SCOPE)
+endfunction()
+
+function(toExpectedContentList FILE_NO CONTENT_VAR)
+ set(prefix_ "volume-name")
+ list(TRANSFORM ${CONTENT_VAR} PREPEND "${prefix_}" OUTPUT_VARIABLE prepared_)
+ list(APPEND prepared_ "${prefix_}")
+
+ set(${CONTENT_VAR} "${prepared_}" PARENT_SCOPE)
+endfunction()
diff --git a/Tests/RunCMake/CPack/DragNDrop/Prerequirements.cmake b/Tests/RunCMake/CPack/DragNDrop/Prerequirements.cmake
new file mode 100644
index 0000000..f0aaf2c
--- /dev/null
+++ b/Tests/RunCMake/CPack/DragNDrop/Prerequirements.cmake
@@ -0,0 +1,8 @@
+function(get_test_prerequirements found_var config_file)
+ find_program(HDIUTIL_EXECUTABLE hdiutil)
+
+ if(HDIUTIL_EXECUTABLE)
+ file(WRITE "${config_file}" "set(HDIUTIL_EXECUTABLE \"${HDIUTIL_EXECUTABLE}\")")
+ set(${found_var} true PARENT_SCOPE)
+ endif()
+endfunction()
diff --git a/Tests/RunCMake/CPack/DragNDrop/packaging_COMPONENT_default.cmake b/Tests/RunCMake/CPack/DragNDrop/packaging_COMPONENT_default.cmake
new file mode 100644
index 0000000..aa6c8ff
--- /dev/null
+++ b/Tests/RunCMake/CPack/DragNDrop/packaging_COMPONENT_default.cmake
@@ -0,0 +1,3 @@
+set(CPACK_COMPONENTS_GROUPING "IGNORE")
+set(CPACK_DMG_DISABLE_APPLICATIONS_SYMLINK ON)
+set(CPACK_DMG_VOLUME_NAME "volume-name")
diff --git a/Tests/RunCMake/CPack/RunCMakeTest.cmake b/Tests/RunCMake/CPack/RunCMakeTest.cmake
index c2382b0..064b4dc 100644
--- a/Tests/RunCMake/CPack/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CPack/RunCMakeTest.cmake
@@ -5,7 +5,7 @@ include("${RunCMake_SOURCE_DIR}/CPackTestHelpers.cmake")
# run_cpack_test args: TEST_NAME "GENERATORS" RUN_CMAKE_BUILD_STEP "PACKAGING_TYPES"
run_cpack_test(CUSTOM_BINARY_SPEC_FILE "RPM.CUSTOM_BINARY_SPEC_FILE" false "MONOLITHIC;COMPONENT")
-run_cpack_test(CUSTOM_NAMES "RPM.CUSTOM_NAMES;DEB.CUSTOM_NAMES;TGZ" true "COMPONENT")
+run_cpack_test(CUSTOM_NAMES "RPM.CUSTOM_NAMES;DEB.CUSTOM_NAMES;TGZ;DragNDrop" true "COMPONENT")
run_cpack_test(DEBUGINFO "RPM.DEBUGINFO;DEB.DEBUGINFO" true "COMPONENT")
run_cpack_test_subtests(DEFAULT_PERMISSIONS "CMAKE_var_set;CPACK_var_set;both_set;invalid_CMAKE_var;invalid_CPACK_var" "RPM.DEFAULT_PERMISSIONS;DEB.DEFAULT_PERMISSIONS" false "MONOLITHIC;COMPONENT")
run_cpack_test(DEPENDENCIES "RPM.DEPENDENCIES;DEB.DEPENDENCIES" true "COMPONENT")
@@ -20,6 +20,8 @@ run_cpack_test(LONG_FILENAMES "DEB.LONG_FILENAMES" false "MONOLITHIC")
run_cpack_test_subtests(MAIN_COMPONENT "invalid;found" "RPM.MAIN_COMPONENT" false "COMPONENT")
run_cpack_test(MINIMAL "RPM.MINIMAL;DEB.MINIMAL;7Z;TBZ2;TGZ;TXZ;TZ;ZIP;STGZ;External" false "MONOLITHIC;COMPONENT")
run_cpack_test_package_target(MINIMAL "RPM.MINIMAL;DEB.MINIMAL;7Z;TBZ2;TGZ;TXZ;TZ;ZIP;STGZ;External" false "MONOLITHIC;COMPONENT")
+run_cpack_test_package_target(THREADED_ALL "TXZ" false "MONOLITHIC;COMPONENT")
+run_cpack_test_package_target(THREADED "TXZ" false "MONOLITHIC;COMPONENT")
run_cpack_test_subtests(PACKAGE_CHECKSUM "invalid;MD5;SHA1;SHA224;SHA256;SHA384;SHA512" "TGZ" false "MONOLITHIC")
run_cpack_test(PARTIALLY_RELOCATABLE_WARNING "RPM.PARTIALLY_RELOCATABLE_WARNING" false "COMPONENT")
run_cpack_test(PER_COMPONENT_FIELDS "RPM.PER_COMPONENT_FIELDS;DEB.PER_COMPONENT_FIELDS" false "COMPONENT")
@@ -43,3 +45,4 @@ run_cpack_test_subtests(
false
"MONOLITHIC;COMPONENT"
)
+run_cpack_test(PROJECT_META "RPM.PROJECT_META;DEB.PROJECT_META" false "MONOLITHIC;COMPONENT")
diff --git a/Tests/RunCMake/CPack/tests/CUSTOM_NAMES/ExpectedFiles.cmake b/Tests/RunCMake/CPack/tests/CUSTOM_NAMES/ExpectedFiles.cmake
index 07226df..9ac19e2 100644
--- a/Tests/RunCMake/CPack/tests/CUSTOM_NAMES/ExpectedFiles.cmake
+++ b/Tests/RunCMake/CPack/tests/CUSTOM_NAMES/ExpectedFiles.cmake
@@ -12,4 +12,7 @@ if(GENERATOR_TYPE STREQUAL "DEB" OR GENERATOR_TYPE STREQUAL "RPM")
elseif(GENERATOR_TYPE STREQUAL "TGZ")
set(EXPECTED_FILE_2 "second.tar.gz")
set(EXPECTED_FILE_3 "pkg_3_abc.tar.gz")
+elseif(GENERATOR_TYPE STREQUAL "DragNDrop")
+ set(EXPECTED_FILE_2 "second.dmg")
+ set(EXPECTED_FILE_3 "pkg_3_abc.dmg")
endif()
diff --git a/Tests/RunCMake/CPack/tests/CUSTOM_NAMES/test.cmake b/Tests/RunCMake/CPack/tests/CUSTOM_NAMES/test.cmake
index 4c20e41..899258e 100644
--- a/Tests/RunCMake/CPack/tests/CUSTOM_NAMES/test.cmake
+++ b/Tests/RunCMake/CPack/tests/CUSTOM_NAMES/test.cmake
@@ -10,6 +10,9 @@ if(GENERATOR_TYPE STREQUAL "DEB" OR GENERATOR_TYPE STREQUAL "RPM")
elseif(GENERATOR_TYPE STREQUAL "TGZ")
set(CPACK_ARCHIVE_PKG_2_FILE_NAME "second")
set(CPACK_ARCHIVE_PKG_3_FILE_NAME "pkg_3_abc")
+elseif(GENERATOR_TYPE STREQUAL "DragNDrop")
+ set(CPACK_DMG_PKG_2_FILE_NAME "second")
+ set(CPACK_DMG_PKG_3_FILE_NAME "pkg_3_abc")
endif()
install(FILES CMakeLists.txt DESTINATION foo COMPONENT pkg_1)
diff --git a/Tests/RunCMake/CPack/tests/EXTERNAL/expected-json-1.0.txt b/Tests/RunCMake/CPack/tests/EXTERNAL/expected-json-1.0.txt
index 18bf617..ca25b1e 100644
--- a/Tests/RunCMake/CPack/tests/EXTERNAL/expected-json-1.0.txt
+++ b/Tests/RunCMake/CPack/tests/EXTERNAL/expected-json-1.0.txt
@@ -1,5 +1,6 @@
^\{
- "componentGroups" :[ ]
+ ("buildConfig" : "Debug",
+)? "componentGroups" :[ ]
\{
"f12" :[ ]
\{
diff --git a/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/VerifyResult.cmake b/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/VerifyResult.cmake
index d7d82f2..1a1e983 100644
--- a/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/VerifyResult.cmake
+++ b/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/VerifyResult.cmake
@@ -25,5 +25,5 @@ function(checkScripts_ FILE COMPARE_LIST)
endforeach()
endfunction()
-checkScripts_("${FOUND_FILE_1}" "echo \"pre install foo\";echo \"post install foo\";echo \"pre uninstall foo\";echo \"post uninstall foo\"")
-checkScripts_("${FOUND_FILE_2}" "echo \"pre install\";echo \"post install\";echo \"pre uninstall\";echo \"post uninstall\"")
+checkScripts_("${FOUND_FILE_1}" "echo \"pre install foo\";echo \"post install foo\";echo \"pre uninstall foo\";echo \"post uninstall foo\";echo \"pre trans foo\";echo \"post trans foo\"")
+checkScripts_("${FOUND_FILE_2}" "echo \"pre install\";echo \"post install\";echo \"pre uninstall\";echo \"post uninstall\";echo \"pre trans\";echo \"post trans\"")
diff --git a/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/test.cmake b/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/test.cmake
index fb1b8de..c200fa5 100644
--- a/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/test.cmake
+++ b/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/test.cmake
@@ -7,6 +7,10 @@ if(GENERATOR_TYPE STREQUAL "RPM")
"${CMAKE_CURRENT_BINARY_DIR}/pre_uninstall.sh")
set(CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE
"${CMAKE_CURRENT_BINARY_DIR}/post_uninstall.sh")
+ set(CPACK_RPM_PRE_TRANS_SCRIPT_FILE
+ "${CMAKE_CURRENT_BINARY_DIR}/pre_trans.sh")
+ set(CPACK_RPM_POST_TRANS_SCRIPT_FILE
+ "${CMAKE_CURRENT_BINARY_DIR}/post_trans.sh")
set(CPACK_RPM_foo_PRE_INSTALL_SCRIPT_FILE
"${CMAKE_CURRENT_BINARY_DIR}/pre_install_foo.sh")
@@ -16,6 +20,10 @@ if(GENERATOR_TYPE STREQUAL "RPM")
"${CMAKE_CURRENT_BINARY_DIR}/pre_uninstall_foo.sh")
set(CPACK_RPM_foo_POST_UNINSTALL_SCRIPT_FILE
"${CMAKE_CURRENT_BINARY_DIR}/post_uninstall_foo.sh")
+ set(CPACK_RPM_foo_PRE_TRANS_SCRIPT_FILE
+ "${CMAKE_CURRENT_BINARY_DIR}/pre_trans_foo.sh")
+ set(CPACK_RPM_foo_POST_TRANS_SCRIPT_FILE
+ "${CMAKE_CURRENT_BINARY_DIR}/post_trans_foo.sh")
endif()
set(CMAKE_BUILD_WITH_INSTALL_RPATH 1)
@@ -29,6 +37,10 @@ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/pre_uninstall.sh"
"echo \"pre uninstall\"\n")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/post_uninstall.sh"
"echo \"post uninstall\"\n")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/pre_trans.sh"
+ "echo \"pre trans\"\n")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/post_trans.sh"
+ "echo \"post trans\"\n")
# specific
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/pre_install_foo.sh"
@@ -39,6 +51,10 @@ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/pre_uninstall_foo.sh"
"echo \"pre uninstall foo\"\n")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/post_uninstall_foo.sh"
"echo \"post uninstall foo\"\n")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/pre_trans_foo.sh"
+ "echo \"pre trans foo\"\n")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/post_trans_foo.sh"
+ "echo \"post trans foo\"\n")
install(FILES CMakeLists.txt DESTINATION foo COMPONENT foo)
install(FILES CMakeLists.txt DESTINATION bar COMPONENT bar)
diff --git a/Tests/RunCMake/CPack/tests/PROJECT_META/ExpectedFiles.cmake b/Tests/RunCMake/CPack/tests/PROJECT_META/ExpectedFiles.cmake
new file mode 100644
index 0000000..448ed2b
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/PROJECT_META/ExpectedFiles.cmake
@@ -0,0 +1,9 @@
+if(GENERATOR_TYPE STREQUAL DEB)
+ set(EXPECTED_FILE_1 "project_meta-1.2.3*.deb")
+elseif(GENERATOR_TYPE STREQUAL RPM)
+ set(EXPECTED_FILE_1 "project_meta-1.2.3*.rpm")
+else()
+ message(FATAL_ERROR "Unexpected CPack generator")
+endif()
+set(EXPECTED_FILES_COUNT "1")
+set(EXPECTED_FILE_CONTENT_1_LIST "/foo;/foo/CMakeLists.txt")
diff --git a/Tests/RunCMake/CPack/tests/PROJECT_META/VerifyResult.cmake b/Tests/RunCMake/CPack/tests/PROJECT_META/VerifyResult.cmake
new file mode 100644
index 0000000..b3accb5
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/PROJECT_META/VerifyResult.cmake
@@ -0,0 +1,30 @@
+function(checkPackageURL FILE TAG EXPECTED_URL)
+ getPackageInfo("${FILE}" "_file_info")
+ string(REPLACE "\n" ";" _file_info "${_file_info}")
+
+ set(_seen_url FALSE)
+ foreach(_line IN LISTS _file_info)
+ if(_line MATCHES "${TAG}: (.*)")
+ set(_seen_url TRUE)
+ if(NOT CMAKE_MATCH_1 STREQUAL EXPECTED_URL)
+ message(FATAL_ERROR "Unexpected `Homepage` URL: `${CMAKE_MATCH_1}` != `${EXPECTED_URL}`")
+ endif()
+ break()
+ endif()
+ endforeach()
+ if(NOT _seen_url)
+ message(FATAL_ERROR "The packge `${FILE}` do not have URL as expected")
+ endif()
+endfunction()
+
+if(GENERATOR_TYPE STREQUAL DEB)
+ set(_tag " Homepage") # NOTE The leading space
+elseif(GENERATOR_TYPE STREQUAL RPM)
+ set(_tag "URL.*")
+else()
+ message(FATAL_ERROR "Unexpected CPack generator")
+endif()
+
+checkPackageURL("${FOUND_FILE_1}" "${_tag}" "https://meta.test.info")
+
+# kate: indent-width 2;
diff --git a/Tests/RunCMake/CPack/tests/PROJECT_META/test.cmake b/Tests/RunCMake/CPack/tests/PROJECT_META/test.cmake
new file mode 100644
index 0000000..9c5266a
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/PROJECT_META/test.cmake
@@ -0,0 +1,11 @@
+project(
+ MetaInfoTest
+ VERSION 1.2.3
+ DESCRIPTION "This is going to be a summary"
+ HOMEPAGE_URL "https://meta.test.info"
+)
+install(FILES CMakeLists.txt DESTINATION foo COMPONENT test)
+
+if(PACKAGING_TYPE STREQUAL "COMPONENT")
+ set(CPACK_COMPONENTS_ALL test)
+endif()
diff --git a/Tests/RunCMake/CPack/tests/THREADED/ExpectedFiles.cmake b/Tests/RunCMake/CPack/tests/THREADED/ExpectedFiles.cmake
new file mode 100644
index 0000000..d1a3a5f
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/THREADED/ExpectedFiles.cmake
@@ -0,0 +1,2 @@
+set(EXPECTED_FILES_COUNT "1")
+set(EXPECTED_FILE_CONTENT_1_LIST "/foo;/foo/CMakeLists.txt")
diff --git a/Tests/RunCMake/CPack/tests/THREADED/test.cmake b/Tests/RunCMake/CPack/tests/THREADED/test.cmake
new file mode 100644
index 0000000..78fc9e9
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/THREADED/test.cmake
@@ -0,0 +1,7 @@
+install(FILES CMakeLists.txt DESTINATION foo COMPONENT test)
+
+set(CPACK_ARCHIVE_THREADS 2)
+
+if(PACKAGING_TYPE STREQUAL "COMPONENT")
+ set(CPACK_COMPONENTS_ALL test)
+endif()
diff --git a/Tests/RunCMake/CPack/tests/THREADED_ALL/ExpectedFiles.cmake b/Tests/RunCMake/CPack/tests/THREADED_ALL/ExpectedFiles.cmake
new file mode 100644
index 0000000..d1a3a5f
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/THREADED_ALL/ExpectedFiles.cmake
@@ -0,0 +1,2 @@
+set(EXPECTED_FILES_COUNT "1")
+set(EXPECTED_FILE_CONTENT_1_LIST "/foo;/foo/CMakeLists.txt")
diff --git a/Tests/RunCMake/CPack/tests/THREADED_ALL/test.cmake b/Tests/RunCMake/CPack/tests/THREADED_ALL/test.cmake
new file mode 100644
index 0000000..34051b8
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/THREADED_ALL/test.cmake
@@ -0,0 +1,7 @@
+install(FILES CMakeLists.txt DESTINATION foo COMPONENT test)
+
+set(CPACK_ARCHIVE_THREADS 0)
+
+if(PACKAGING_TYPE STREQUAL "COMPONENT")
+ set(CPACK_COMPONENTS_ALL test)
+endif()
diff --git a/Tests/RunCMake/CTest/CMakeCTestArguments-test-check.cmake b/Tests/RunCMake/CTest/CMakeCTestArguments-test-check.cmake
new file mode 100644
index 0000000..3e05953
--- /dev/null
+++ b/Tests/RunCMake/CTest/CMakeCTestArguments-test-check.cmake
@@ -0,0 +1,4 @@
+set(log "${RunCMake_TEST_BINARY_DIR}/output-log.txt")
+if(NOT EXISTS "${log}")
+ set(RunCMake_TEST_FAILED "The expected output log file is missing:\n ${log}")
+endif()
diff --git a/Tests/RunCMake/CTest/CMakeCTestArguments.cmake b/Tests/RunCMake/CTest/CMakeCTestArguments.cmake
new file mode 100644
index 0000000..37f2933
--- /dev/null
+++ b/Tests/RunCMake/CTest/CMakeCTestArguments.cmake
@@ -0,0 +1,2 @@
+include(CTest)
+add_test(NAME CMakeCTestArguments COMMAND ${CMAKE_COMMAND} -E echo CMakeCTestArguments)
diff --git a/Tests/RunCMake/CTest/RunCMakeTest.cmake b/Tests/RunCMake/CTest/RunCMakeTest.cmake
index 1392240..761224a 100644
--- a/Tests/RunCMake/CTest/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CTest/RunCMakeTest.cmake
@@ -5,3 +5,16 @@ run_cmake(BeforeProject)
unset(RunCMake_TEST_OPTIONS)
run_cmake(NotOn)
+
+function(run_CMakeCTestArguments)
+ run_cmake_with_options(CMakeCTestArguments "-DCMAKE_CTEST_ARGUMENTS=--quiet\\;--output-log\\;output-log.txt")
+ set(RunCMake_TEST_NO_CLEAN 1)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CMakeCTestArguments-build)
+ if(RunCMake_GENERATOR MATCHES "Make|Ninja")
+ set(test "test")
+ else()
+ set(test "RUN_TESTS")
+ endif()
+ run_cmake_command(CMakeCTestArguments-test ${CMAKE_COMMAND} --build . --config Debug --target "${test}")
+endfunction()
+run_CMakeCTestArguments()
diff --git a/Tests/RunCMake/CTestCommandLine/CMakeLists.txt.in b/Tests/RunCMake/CTestCommandLine/CMakeLists.txt.in
new file mode 100644
index 0000000..5437800
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/CMakeLists.txt.in
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.1)
+project(CTestCommandLine@CASE_NAME@ NONE)
+include(CTest)
+add_test(NAME RunCMakeVersion COMMAND "${CMAKE_COMMAND}" --version)
diff --git a/Tests/RunCMake/CTestCommandLine/MemCheckSan.cmake b/Tests/RunCMake/CTestCommandLine/MemCheckSan.cmake
new file mode 100644
index 0000000..192c30c
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/MemCheckSan.cmake
@@ -0,0 +1,7 @@
+set(MEMORYCHECK_COMMAND "")
+include(CTest)
+add_test(
+ NAME TestSan
+ COMMAND ${CMAKE_COMMAND}
+ -P ${CMAKE_CURRENT_LIST_DIR}/../ctest_memcheck/test${MEMORYCHECK_TYPE}.cmake
+ )
diff --git a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
index 6b23162..e05ad79 100644
--- a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
@@ -1,9 +1,33 @@
include(RunCMake)
+include(RunCTest)
+
set(RunCMake_TEST_TIMEOUT 60)
unset(ENV{CTEST_PARALLEL_LEVEL})
unset(ENV{CTEST_OUTPUT_ON_FAILURE})
+run_cmake_command(repeat-opt-bad1
+ ${CMAKE_CTEST_COMMAND} --repeat until-pass
+ )
+run_cmake_command(repeat-opt-bad2
+ ${CMAKE_CTEST_COMMAND} --repeat until-pass:foo
+ )
+run_cmake_command(repeat-opt-bad3
+ ${CMAKE_CTEST_COMMAND} --repeat until-fail:2 --repeat-until-fail 2
+ )
+run_cmake_command(repeat-opt-bad4
+ ${CMAKE_CTEST_COMMAND} --repeat-until-fail 2 --repeat until-fail:2
+ )
+run_cmake_command(repeat-opt-until-pass
+ ${CMAKE_CTEST_COMMAND} --repeat until-pass:2
+ )
+run_cmake_command(repeat-opt-until-fail
+ ${CMAKE_CTEST_COMMAND} --repeat until-fail:2
+ )
+run_cmake_command(repeat-opt-after-timeout
+ ${CMAKE_CTEST_COMMAND} --repeat after-timeout:2
+ )
+
run_cmake_command(repeat-until-fail-bad1
${CMAKE_CTEST_COMMAND} --repeat-until-fail
)
@@ -14,19 +38,39 @@ run_cmake_command(repeat-until-fail-good
${CMAKE_CTEST_COMMAND} --repeat-until-fail 2
)
-function(run_repeat_until_fail_tests)
+function(run_repeat_until_pass_tests)
# Use a single build tree for a few tests without cleaning.
- set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/repeat-until-fail-build)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/repeat-until-pass-build)
+ run_cmake(repeat-until-pass-cmake)
set(RunCMake_TEST_NO_CLEAN 1)
- file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
- file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ run_cmake_command(repeat-until-pass-ctest
+ ${CMAKE_CTEST_COMMAND} -C Debug --repeat until-pass:3
+ )
+endfunction()
+run_repeat_until_pass_tests()
+function(run_repeat_after_timeout_tests)
+ # Use a single build tree for a few tests without cleaning.
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/repeat-after-timeout-build)
+ run_cmake(repeat-after-timeout-cmake)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ run_cmake_command(repeat-after-timeout-ctest
+ ${CMAKE_CTEST_COMMAND} -C Debug --repeat after-timeout:3
+ )
+endfunction()
+run_repeat_after_timeout_tests()
+
+function(run_repeat_until_fail_tests)
+ # Use a single build tree for a few tests without cleaning.
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/repeat-until-fail-build)
run_cmake(repeat-until-fail-cmake)
+ set(RunCMake_TEST_NO_CLEAN 1)
run_cmake_command(repeat-until-fail-ctest
- ${CMAKE_CTEST_COMMAND} -C Debug --repeat-until-fail 3
+ ${CMAKE_CTEST_COMMAND} -C Debug ${ARGN}
)
endfunction()
-run_repeat_until_fail_tests()
+run_repeat_until_fail_tests(--repeat-until-fail 3)
+run_repeat_until_fail_tests(--repeat until-fail:3)
function(run_BadCTestTestfile)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/BadCTestTestfile)
@@ -198,6 +242,20 @@ function(run_TestOutputSize)
endfunction()
run_TestOutputSize()
+# Test --stop-on-failure
+function(run_stop_on_failure)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/stop-on-failure)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ file(WRITE "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake" "
+add_test(test1 \"${CMAKE_COMMAND}\" -E false)
+add_test(test2 \"${CMAKE_COMMAND}\" -E echo \"not running\")
+")
+ run_cmake_command(stop-on-failure ${CMAKE_CTEST_COMMAND} --stop-on-failure)
+endfunction()
+run_stop_on_failure()
+
function(run_TestAffinity)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/TestAffinity)
set(RunCMake_TEST_NO_CLEAN 1)
@@ -269,3 +327,56 @@ function(run_ShowOnly)
run_cmake_command(show-only_json-v1 ${CMAKE_CTEST_COMMAND} --show-only=json-v1)
endfunction()
run_ShowOnly()
+
+function(run_NoTests)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/NoTests)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ file(WRITE "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake" "")
+ run_cmake_command(no-tests_ignore ${CMAKE_CTEST_COMMAND} --no-tests=ignore)
+ run_cmake_command(no-tests_error ${CMAKE_CTEST_COMMAND} --no-tests=error)
+ run_cmake_command(no-tests_bad ${CMAKE_CTEST_COMMAND} --no-tests=bad)
+ run_cmake_command(no-tests_legacy ${CMAKE_CTEST_COMMAND})
+ file(WRITE "${RunCMake_TEST_BINARY_DIR}/NoTestsScript.cmake" "
+ set(CTEST_COMMAND \"${CMAKE_CTEST_COMMAND}\")
+ set(CTEST_SOURCE_DIRECTORY \"${RunCMake_SOURCE_DIR}\")
+ set(CTEST_BINARY_DIRECTORY \"${RunCMake_TEST_BINARY_DIR}\")
+ ctest_start(Experimental)
+ ctest_test()
+")
+ run_cmake_command(
+ no-tests-script_ignore ${CMAKE_CTEST_COMMAND} --no-tests=ignore
+ -S "${RunCMake_TEST_BINARY_DIR}/NoTestsScript.cmake")
+ run_cmake_command(
+ no-tests-script_error ${CMAKE_CTEST_COMMAND} --no-tests=error
+ -S "${RunCMake_TEST_BINARY_DIR}/NoTestsScript.cmake")
+ run_cmake_command(
+ no-tests-script_legacy ${CMAKE_CTEST_COMMAND}
+ -S "${RunCMake_TEST_BINARY_DIR}/NoTestsScript.cmake")
+endfunction()
+run_NoTests()
+
+# Check the configuration type variable is passed
+run_ctest(check-configuration-type)
+
+function(run_MemCheckSan case opts)
+ # Use a single build tree for a few tests without cleaning.
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/MemCheckSan${case}-build)
+ set(RunCMake_TEST_OPTIONS
+ "-DMEMORYCHECK_TYPE=${case}Sanitizer"
+ "-DMEMORYCHECK_SANITIZER_OPTIONS=${opts}"
+ )
+ run_cmake(MemCheckSan)
+ unset(RunCMake_TEST_OPTIONS)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ set(RunCMake-stdout-file "../ctest_memcheck/Dummy${case}Sanitizer-stdout.txt")
+ run_cmake_command(MemCheckSan${case}-ctest
+ ${CMAKE_CTEST_COMMAND} -C Debug -M Experimental -T MemCheck -V
+ )
+endfunction()
+run_MemCheckSan(Address "simulate_sanitizer=1:report_bugs=1:history_size=5:exitcode=55")
+run_MemCheckSan(Leak "simulate_sanitizer=1:report_bugs=1:history_size=5:exitcode=55")
+run_MemCheckSan(Memory "simulate_sanitizer=1:report_bugs=1:history_size=5:exitcode=55")
+run_MemCheckSan(Thread "report_bugs=1:history_size=5:exitcode=55")
+run_MemCheckSan(UndefinedBehavior "simulate_sanitizer=1")
diff --git a/Tests/RunCMake/CTestCommandLine/check-configuration-type-stderr.txt b/Tests/RunCMake/CTestCommandLine/check-configuration-type-stderr.txt
new file mode 100644
index 0000000..b2c1a45
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/check-configuration-type-stderr.txt
@@ -0,0 +1,2 @@
+Command line CTEST_CONFIGURATION_TYPE=Debug
+set CTEST_CONFIGURATION_TYPE=Release
diff --git a/Tests/RunCMake/CTestCommandLine/no-tests-script_error-result.txt b/Tests/RunCMake/CTestCommandLine/no-tests-script_error-result.txt
new file mode 100644
index 0000000..b57e2de
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/no-tests-script_error-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/CTestCommandLine/no-tests-script_error-stderr.txt b/Tests/RunCMake/CTestCommandLine/no-tests-script_error-stderr.txt
new file mode 100644
index 0000000..a7c4b11
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/no-tests-script_error-stderr.txt
@@ -0,0 +1 @@
+^No tests were found!!!$
diff --git a/Tests/RunCMake/CTestCommandLine/no-tests-script_legacy-result.txt b/Tests/RunCMake/CTestCommandLine/no-tests-script_legacy-result.txt
new file mode 100644
index 0000000..b57e2de
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/no-tests-script_legacy-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/CTestCommandLine/no-tests-script_legacy-stderr.txt b/Tests/RunCMake/CTestCommandLine/no-tests-script_legacy-stderr.txt
new file mode 100644
index 0000000..a7c4b11
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/no-tests-script_legacy-stderr.txt
@@ -0,0 +1 @@
+^No tests were found!!!$
diff --git a/Tests/RunCMake/CTestCommandLine/no-tests_bad-result.txt b/Tests/RunCMake/CTestCommandLine/no-tests_bad-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/no-tests_bad-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CTestCommandLine/no-tests_bad-stderr.txt b/Tests/RunCMake/CTestCommandLine/no-tests_bad-stderr.txt
new file mode 100644
index 0000000..1703539
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/no-tests_bad-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: '--no-tests=' given unknown value 'bad'$
diff --git a/Tests/RunCMake/CTestCommandLine/no-tests_error-result.txt b/Tests/RunCMake/CTestCommandLine/no-tests_error-result.txt
new file mode 100644
index 0000000..45a4fb7
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/no-tests_error-result.txt
@@ -0,0 +1 @@
+8
diff --git a/Tests/RunCMake/CTestCommandLine/no-tests_error-stderr.txt b/Tests/RunCMake/CTestCommandLine/no-tests_error-stderr.txt
new file mode 100644
index 0000000..eafba1c
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/no-tests_error-stderr.txt
@@ -0,0 +1 @@
+No tests were found!!!
diff --git a/Tests/RunCMake/CTestCommandLine/no-tests_legacy-stderr.txt b/Tests/RunCMake/CTestCommandLine/no-tests_legacy-stderr.txt
new file mode 100644
index 0000000..a7c4b11
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/no-tests_legacy-stderr.txt
@@ -0,0 +1 @@
+^No tests were found!!!$
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-after-timeout-cmake.cmake b/Tests/RunCMake/CTestCommandLine/repeat-after-timeout-cmake.cmake
new file mode 100644
index 0000000..873c0bd
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-after-timeout-cmake.cmake
@@ -0,0 +1,15 @@
+enable_testing()
+
+set(TEST_OUTPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/test_output.txt")
+add_test(NAME initialization
+ COMMAND ${CMAKE_COMMAND}
+ "-DTEST_OUTPUT_FILE=${TEST_OUTPUT_FILE}"
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/init.cmake")
+add_test(NAME test1
+ COMMAND ${CMAKE_COMMAND}
+ "-DTEST_OUTPUT_FILE=${TEST_OUTPUT_FILE}"
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/test1-timeout.cmake")
+set_tests_properties(test1 PROPERTIES DEPENDS "initialization" TIMEOUT 5)
+
+add_test(hello ${CMAKE_COMMAND} -E echo hello)
+add_test(goodbye ${CMAKE_COMMAND} -E echo goodbye)
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-after-timeout-ctest-stdout.txt b/Tests/RunCMake/CTestCommandLine/repeat-after-timeout-ctest-stdout.txt
new file mode 100644
index 0000000..d0a5487
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-after-timeout-ctest-stdout.txt
@@ -0,0 +1,15 @@
+^Test project .*/Tests/RunCMake/CTestCommandLine/repeat-after-timeout-build
+ Start 1: initialization
+1/4 Test #1: initialization ................... Passed +[0-9.]+ sec
+ Start 2: test1
+2/4 Test #2: test1 ............................\*\*\*Timeout +[0-9.]+ sec
+ Start 2: test1
+ Test #2: test1 ............................ Passed +[0-9.]+ sec
+ Start 3: hello
+3/4 Test #3: hello ............................ Passed +[0-9.]+ sec
+ Start 4: goodbye
+4/4 Test #4: goodbye .......................... Passed +[0-9.]+ sec
+
+100% tests passed, 0 tests failed out of 4
+
+Total Test time \(real\) = +[0-9.]+ sec$
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-opt-after-timeout-stderr.txt b/Tests/RunCMake/CTestCommandLine/repeat-opt-after-timeout-stderr.txt
new file mode 100644
index 0000000..a7c4b11
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-opt-after-timeout-stderr.txt
@@ -0,0 +1 @@
+^No tests were found!!!$
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-opt-bad1-result.txt b/Tests/RunCMake/CTestCommandLine/repeat-opt-bad1-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-opt-bad1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-opt-bad1-stderr.txt b/Tests/RunCMake/CTestCommandLine/repeat-opt-bad1-stderr.txt
new file mode 100644
index 0000000..f6f3241
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-opt-bad1-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: '--repeat' given invalid value 'until-pass'$
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-opt-bad2-result.txt b/Tests/RunCMake/CTestCommandLine/repeat-opt-bad2-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-opt-bad2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-opt-bad2-stderr.txt b/Tests/RunCMake/CTestCommandLine/repeat-opt-bad2-stderr.txt
new file mode 100644
index 0000000..2f9f32a
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-opt-bad2-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: '--repeat' given invalid value 'until-pass:foo'$
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-opt-bad3-result.txt b/Tests/RunCMake/CTestCommandLine/repeat-opt-bad3-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-opt-bad3-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-opt-bad3-stderr.txt b/Tests/RunCMake/CTestCommandLine/repeat-opt-bad3-stderr.txt
new file mode 100644
index 0000000..de4e11b
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-opt-bad3-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: At most one '--repeat' option may be used\.$
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-opt-bad4-result.txt b/Tests/RunCMake/CTestCommandLine/repeat-opt-bad4-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-opt-bad4-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-opt-bad4-stderr.txt b/Tests/RunCMake/CTestCommandLine/repeat-opt-bad4-stderr.txt
new file mode 100644
index 0000000..de4e11b
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-opt-bad4-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: At most one '--repeat' option may be used\.$
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-opt-until-fail-stderr.txt b/Tests/RunCMake/CTestCommandLine/repeat-opt-until-fail-stderr.txt
new file mode 100644
index 0000000..a7c4b11
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-opt-until-fail-stderr.txt
@@ -0,0 +1 @@
+^No tests were found!!!$
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-opt-until-pass-stderr.txt b/Tests/RunCMake/CTestCommandLine/repeat-opt-until-pass-stderr.txt
new file mode 100644
index 0000000..a7c4b11
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-opt-until-pass-stderr.txt
@@ -0,0 +1 @@
+^No tests were found!!!$
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-until-pass-cmake.cmake b/Tests/RunCMake/CTestCommandLine/repeat-until-pass-cmake.cmake
new file mode 100644
index 0000000..d109551
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-until-pass-cmake.cmake
@@ -0,0 +1,15 @@
+enable_testing()
+
+set(TEST_OUTPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/test_output.txt")
+add_test(NAME initialization
+ COMMAND ${CMAKE_COMMAND}
+ "-DTEST_OUTPUT_FILE=${TEST_OUTPUT_FILE}"
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/init.cmake")
+add_test(NAME test1
+ COMMAND ${CMAKE_COMMAND}
+ "-DTEST_OUTPUT_FILE=${TEST_OUTPUT_FILE}"
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/test1-pass.cmake")
+set_tests_properties(test1 PROPERTIES DEPENDS "initialization")
+
+add_test(hello ${CMAKE_COMMAND} -E echo hello)
+add_test(goodbye ${CMAKE_COMMAND} -E echo goodbye)
diff --git a/Tests/RunCMake/CTestCommandLine/repeat-until-pass-ctest-stdout.txt b/Tests/RunCMake/CTestCommandLine/repeat-until-pass-ctest-stdout.txt
new file mode 100644
index 0000000..3745dc2
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/repeat-until-pass-ctest-stdout.txt
@@ -0,0 +1,15 @@
+^Test project .*/Tests/RunCMake/CTestCommandLine/repeat-until-pass-build
+ Start 1: initialization
+1/4 Test #1: initialization ................... Passed +[0-9.]+ sec
+ Start 2: test1
+2/4 Test #2: test1 ............................\*\*\*Failed +[0-9.]+ sec
+ Start 2: test1
+ Test #2: test1 ............................ Passed +[0-9.]+ sec
+ Start 3: hello
+3/4 Test #3: hello ............................ Passed +[0-9.]+ sec
+ Start 4: goodbye
+4/4 Test #4: goodbye .......................... Passed +[0-9.]+ sec
+
+100% tests passed, 0 tests failed out of 4
+
+Total Test time \(real\) = +[0-9.]+ sec$
diff --git a/Tests/RunCMake/CTestCommandLine/stop-on-failure-result.txt b/Tests/RunCMake/CTestCommandLine/stop-on-failure-result.txt
new file mode 100644
index 0000000..45a4fb7
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/stop-on-failure-result.txt
@@ -0,0 +1 @@
+8
diff --git a/Tests/RunCMake/CTestCommandLine/stop-on-failure-stderr.txt b/Tests/RunCMake/CTestCommandLine/stop-on-failure-stderr.txt
new file mode 100644
index 0000000..ba4235d
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/stop-on-failure-stderr.txt
@@ -0,0 +1 @@
+Errors while running CTest
diff --git a/Tests/RunCMake/CTestCommandLine/stop-on-failure-stdout.txt b/Tests/RunCMake/CTestCommandLine/stop-on-failure-stdout.txt
new file mode 100644
index 0000000..12c77d0
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/stop-on-failure-stdout.txt
@@ -0,0 +1,10 @@
+^Test project .*/Tests/RunCMake/CTestCommandLine/stop-on-failure
+ Start 1: test1
+1/2 Test #1: test1 ............................\*\*\*Failed +[0-9.]+ sec
++
+0% tests passed, 1 tests failed out of 1
++
+Total Test time \(real\) = +[0-9.]+ sec
++
+The following tests FAILED:
+[ ]+1 - test1 \(Failed\)$
diff --git a/Tests/RunCMake/CTestCommandLine/test.cmake.in b/Tests/RunCMake/CTestCommandLine/test.cmake.in
new file mode 100644
index 0000000..b82968a
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/test.cmake.in
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 3.1)
+
+set(CTEST_SITE "test-site")
+set(CTEST_BUILD_NAME "test-build-name")
+set(CTEST_SOURCE_DIRECTORY "@RunCMake_BINARY_DIR@/@CASE_NAME@")
+set(CTEST_BINARY_DIRECTORY "@RunCMake_BINARY_DIR@/@CASE_NAME@-build")
+set(CTEST_CMAKE_GENERATOR "@RunCMake_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "@RunCMake_GENERATOR_PLATFORM@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@RunCMake_GENERATOR_TOOLSET@")
+set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC")
+set(CTEST_COMMAND "@CMAKE_CTEST_COMMAND@")
+
+if("@CASE_NAME@" MATCHES "^check-configuration-type")
+ message("Command line CTEST_CONFIGURATION_TYPE=" ${CTEST_CONFIGURATION_TYPE})
+ set(CTEST_CONFIGURATION_TYPE "Release")
+ message("set CTEST_CONFIGURATION_TYPE=" ${CTEST_CONFIGURATION_TYPE})
+
+ ctest_start(Experimental)
+endif()
diff --git a/Tests/RunCMake/CTestCommandLine/test1-pass.cmake b/Tests/RunCMake/CTestCommandLine/test1-pass.cmake
new file mode 100644
index 0000000..dda8dea
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/test1-pass.cmake
@@ -0,0 +1,13 @@
+# This is run by test test1 in repeat-until-pass-cmake.cmake with cmake -P.
+# It reads the file TEST_OUTPUT_FILE and increments the number
+# found in the file by 1. Unless the number is 2, then the
+# code sends out a cmake error causing the test to pass only on
+# the second time it is run.
+message("TEST_OUTPUT_FILE = ${TEST_OUTPUT_FILE}")
+file(READ "${TEST_OUTPUT_FILE}" COUNT)
+message("COUNT= ${COUNT}")
+math(EXPR COUNT "${COUNT} + 1")
+file(WRITE "${TEST_OUTPUT_FILE}" "${COUNT}")
+if(NOT COUNT EQUAL 2)
+ message(FATAL_ERROR "this test passes only on the 2nd run")
+endif()
diff --git a/Tests/RunCMake/CTestCommandLine/test1-timeout.cmake b/Tests/RunCMake/CTestCommandLine/test1-timeout.cmake
new file mode 100644
index 0000000..fbf2ccc
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/test1-timeout.cmake
@@ -0,0 +1,14 @@
+# This is run by test test1 in repeat-after-timeout-cmake.cmake with cmake -P.
+# It reads the file TEST_OUTPUT_FILE and increments the number
+# found in the file by 1. Unless the number is 2, then the
+# code sends out a cmake error causing the test to not timeout only on
+# the second time it is run.
+message("TEST_OUTPUT_FILE = ${TEST_OUTPUT_FILE}")
+file(READ "${TEST_OUTPUT_FILE}" COUNT)
+message("COUNT= ${COUNT}")
+math(EXPR COUNT "${COUNT} + 1")
+file(WRITE "${TEST_OUTPUT_FILE}" "${COUNT}")
+if(NOT COUNT EQUAL 2)
+ message("this test times out except on the 2nd run")
+ execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 10)
+endif()
diff --git a/Tests/RunCMake/CTestResourceAllocation/ResourceCommon.cmake b/Tests/RunCMake/CTestResourceAllocation/ResourceCommon.cmake
index 7d63299..ef79dce 100644
--- a/Tests/RunCMake/CTestResourceAllocation/ResourceCommon.cmake
+++ b/Tests/RunCMake/CTestResourceAllocation/ResourceCommon.cmake
@@ -1,6 +1,6 @@
function(setup_resource_tests)
if(CTEST_RESOURCE_ALLOC_ENABLED)
- add_test(NAME ResourceSetup COMMAND "${CMAKE_COMMAND}" -E remove -f "${CMAKE_BINARY_DIR}/ctresalloc.log")
+ add_test(NAME ResourceSetup COMMAND "${CMAKE_COMMAND}" -E rm -f "${CMAKE_BINARY_DIR}/ctresalloc.log")
endif()
endfunction()
diff --git a/Tests/RunCMake/CTestResourceAllocation/RunCMakeTest.cmake b/Tests/RunCMake/CTestResourceAllocation/RunCMakeTest.cmake
index 8584786..777f192 100644
--- a/Tests/RunCMake/CTestResourceAllocation/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CTestResourceAllocation/RunCMakeTest.cmake
@@ -140,9 +140,13 @@ run_ctresalloc_verify(ctresalloc-verify-noend "test1")
# Now test the resource allocation feature of CTest
###############################################################################
-function(run_ctest_resource name parallel random)
- run_ctest("${name}-ctest-s-res" "-DCTEST_RESOURCE_ALLOC_ENABLED=1" "-DCTRESALLOC_COMMAND=${CTRESALLOC_COMMAND}" "-DCTEST_PARALLEL=${parallel}" "-DCTEST_RANDOM=${random}")
- run_ctest("${name}-ctest-s-nores" "-DCTEST_RESOURCE_ALLOC_ENABLED=0" "-DCTRESALLOC_COMMAND=${CTRESALLOC_COMMAND}" "-DCTEST_PARALLEL=${parallel}" "-DCTEST_RANDOM=${random}")
+function(run_ctest_resource name parallel random extra)
+ run_ctest("${name}-ctest-s-res" "-DCTEST_RESOURCE_ALLOC_ENABLED=1" "-DCTEST_RESOURCE_SPEC_SOURCE=ARG" "-DCTRESALLOC_COMMAND=${CTRESALLOC_COMMAND}" "-DCTEST_PARALLEL=${parallel}" "-DCTEST_RANDOM=${random}")
+ run_ctest("${name}-ctest-s-nores" "-DCTEST_RESOURCE_ALLOC_ENABLED=0" "-DCTEST_RESOURCE_SPEC_SOURCE=NONE" "-DCTRESALLOC_COMMAND=${CTRESALLOC_COMMAND}" "-DCTEST_PARALLEL=${parallel}" "-DCTEST_RANDOM=${random}")
+ if(extra)
+ run_ctest("${name}-ctest-s-res-variable" "-DCTEST_RESOURCE_ALLOC_ENABLED=1" "-DCTEST_RESOURCE_SPEC_SOURCE=VARIABLE" "-DCTRESALLOC_COMMAND=${CTRESALLOC_COMMAND}" "-DCTEST_PARALLEL=${parallel}" "-DCTEST_RANDOM=${random}")
+ run_ctest("${name}-ctest-s-res-cache" "-DCTEST_RESOURCE_ALLOC_ENABLED=1" "-DCTEST_RESOURCE_SPEC_SOURCE=CACHE" "-DCTRESALLOC_COMMAND=${CTRESALLOC_COMMAND}" "-DCTEST_PARALLEL=${parallel}" "-DCTEST_RANDOM=${random}")
+ endif()
endfunction()
function(verify_ctest_resources)
@@ -155,15 +159,15 @@ function(verify_ctest_resources)
endif()
endfunction()
-run_ctest_resource(lotsoftests 10 1)
-run_ctest_resource(checkfree1 2 0)
-run_ctest_resource(checkfree2 1 0)
-run_ctest_resource(notenough1 1 0)
-run_ctest_resource(notenough2 1 0)
-run_ctest_resource(notenough3 1 0)
-run_ctest_resource(combine 1 0)
-run_ctest_resource(ensure_parallel 2 0)
+run_ctest_resource(lotsoftests 10 1 0)
+run_ctest_resource(checkfree1 2 0 1)
+run_ctest_resource(checkfree2 1 0 0)
+run_ctest_resource(notenough1 1 0 1)
+run_ctest_resource(notenough2 1 0 0)
+run_ctest_resource(notenough3 1 0 0)
+run_ctest_resource(combine 1 0 0)
+run_ctest_resource(ensure_parallel 2 0 0)
set(ENV{CTEST_RESOURCE_GROUP_COUNT} 2)
-run_ctest_resource(process_count 1 0)
+run_ctest_resource(process_count 1 0 0)
unset(ENV{CTEST_RESOURCE_GROUP_COUNT})
diff --git a/Tests/RunCMake/CTestResourceAllocation/checkfree1-ctest-s-res-cache-check.cmake b/Tests/RunCMake/CTestResourceAllocation/checkfree1-ctest-s-res-cache-check.cmake
new file mode 100644
index 0000000..ceda72e
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/checkfree1-ctest-s-res-cache-check.cmake
@@ -0,0 +1 @@
+verify_ctest_resources()
diff --git a/Tests/RunCMake/CTestResourceAllocation/checkfree1-ctest-s-res-variable-check.cmake b/Tests/RunCMake/CTestResourceAllocation/checkfree1-ctest-s-res-variable-check.cmake
new file mode 100644
index 0000000..ceda72e
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/checkfree1-ctest-s-res-variable-check.cmake
@@ -0,0 +1 @@
+verify_ctest_resources()
diff --git a/Tests/RunCMake/CTestResourceAllocation/ctresalloc.cxx b/Tests/RunCMake/CTestResourceAllocation/ctresalloc.cxx
index 80db05e..daf8a2d 100644
--- a/Tests/RunCMake/CTestResourceAllocation/ctresalloc.cxx
+++ b/Tests/RunCMake/CTestResourceAllocation/ctresalloc.cxx
@@ -1,6 +1,6 @@
#include <cassert>
#include <chrono>
-#include <cstddef>
+#include <cstddef> // IWYU pragma: keep
#include <cstdlib>
#include <iostream>
#include <map>
diff --git a/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cache-check.cmake b/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cache-check.cmake
new file mode 100644
index 0000000..321e9a2
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cache-check.cmake
@@ -0,0 +1,3 @@
+if(EXISTS "${RunCMake_TEST_BINARY_DIR}/ctresalloc.log")
+ set(RunCMake_TEST_FAILED "ctresalloc.log should not exist")
+endif()
diff --git a/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cache-result.txt b/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cache-result.txt
new file mode 100644
index 0000000..b57e2de
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cache-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cache-stderr.txt b/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cache-stderr.txt
new file mode 100644
index 0000000..521a34b
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cache-stderr.txt
@@ -0,0 +1,14 @@
+^Insufficient resources for test Test1:
+
+ Test requested resources of type 'fluxcapacitors' in the following amounts:
+ 200 slots
+ but only the following units were available:
+ 'outatime': 121 slots
+
+Resource spec file:
+
+ [^
+]*/Tests/RunCMake/CTestResourceAllocation/resspec.json
+CMake Error at [^
+]*/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-cache/test\.cmake:[0-9]+ \(message\):
+ Tests did not pass$
diff --git a/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-stderr.txt b/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-stderr.txt
index 41df5af..91d7ef9 100644
--- a/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-stderr.txt
+++ b/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-stderr.txt
@@ -1,4 +1,14 @@
-^Insufficient resources
+^Insufficient resources for test Test1:
+
+ Test requested resources of type 'fluxcapacitors' in the following amounts:
+ 200 slots
+ but only the following units were available:
+ 'outatime': 121 slots
+
+Resource spec file:
+
+ [^
+]*/Tests/RunCMake/CTestResourceAllocation/resspec.json
CMake Error at [^
]*/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res/test\.cmake:[0-9]+ \(message\):
Tests did not pass$
diff --git a/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-variable-check.cmake b/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-variable-check.cmake
new file mode 100644
index 0000000..321e9a2
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-variable-check.cmake
@@ -0,0 +1,3 @@
+if(EXISTS "${RunCMake_TEST_BINARY_DIR}/ctresalloc.log")
+ set(RunCMake_TEST_FAILED "ctresalloc.log should not exist")
+endif()
diff --git a/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-variable-result.txt b/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-variable-result.txt
new file mode 100644
index 0000000..b57e2de
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-variable-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-variable-stderr.txt b/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-variable-stderr.txt
new file mode 100644
index 0000000..dcf13e0
--- /dev/null
+++ b/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-variable-stderr.txt
@@ -0,0 +1,14 @@
+^Insufficient resources for test Test1:
+
+ Test requested resources of type 'fluxcapacitors' in the following amounts:
+ 200 slots
+ but only the following units were available:
+ 'outatime': 121 slots
+
+Resource spec file:
+
+ [^
+]*/Tests/RunCMake/CTestResourceAllocation/resspec.json
+CMake Error at [^
+]*/Tests/RunCMake/CTestResourceAllocation/notenough1-ctest-s-res-variable/test\.cmake:[0-9]+ \(message\):
+ Tests did not pass$
diff --git a/Tests/RunCMake/CTestResourceAllocation/notenough2-ctest-s-res-stderr.txt b/Tests/RunCMake/CTestResourceAllocation/notenough2-ctest-s-res-stderr.txt
index 6c2f554..5c75a3d 100644
--- a/Tests/RunCMake/CTestResourceAllocation/notenough2-ctest-s-res-stderr.txt
+++ b/Tests/RunCMake/CTestResourceAllocation/notenough2-ctest-s-res-stderr.txt
@@ -1,4 +1,11 @@
-^Insufficient resources
+^Insufficient resources for test Test1:
+
+ Test requested resources of type 'terminators' which does not exist
+
+Resource spec file:
+
+ [^
+]*/Tests/RunCMake/CTestResourceAllocation/resspec.json
CMake Error at [^
]*/Tests/RunCMake/CTestResourceAllocation/notenough2-ctest-s-res/test\.cmake:[0-9]+ \(message\):
Tests did not pass$
diff --git a/Tests/RunCMake/CTestResourceAllocation/notenough3-ctest-s-res-stderr.txt b/Tests/RunCMake/CTestResourceAllocation/notenough3-ctest-s-res-stderr.txt
index 82dfdef..4902a19 100644
--- a/Tests/RunCMake/CTestResourceAllocation/notenough3-ctest-s-res-stderr.txt
+++ b/Tests/RunCMake/CTestResourceAllocation/notenough3-ctest-s-res-stderr.txt
@@ -1,4 +1,21 @@
-^Insufficient resources
+^Insufficient resources for test Test1:
+
+ Test requested resources of type 'widgets' in the following amounts:
+ 12 slots
+ but only the following units were available:
+ '0': 4 slots
+ '1': 2 slots
+ '2': 4 slots
+ '3': 8 slots
+ '4': 1 slot
+ '5': 1 slot
+ '6': 1 slot
+ '7': 1 slot
+
+Resource spec file:
+
+ [^
+]*/Tests/RunCMake/CTestResourceAllocation/resspec.json
CMake Error at [^
]*/Tests/RunCMake/CTestResourceAllocation/notenough3-ctest-s-res/test\.cmake:[0-9]+ \(message\):
Tests did not pass$
diff --git a/Tests/RunCMake/CTestResourceAllocation/test.cmake.in b/Tests/RunCMake/CTestResourceAllocation/test.cmake.in
index 4b426f1..54eb4e9 100644
--- a/Tests/RunCMake/CTestResourceAllocation/test.cmake.in
+++ b/Tests/RunCMake/CTestResourceAllocation/test.cmake.in
@@ -8,15 +8,21 @@ set(CTEST_CMAKE_GENERATOR_TOOLSET "@RunCMake_GENERATOR_TOOLSET@")
set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC")
-ctest_start(Experimental QUIET)
-ctest_configure(OPTIONS
+set(config_options
"-DCTEST_RESOURCE_ALLOC_ENABLED=${CTEST_RESOURCE_ALLOC_ENABLED};-DCTRESALLOC_COMMAND=${CTRESALLOC_COMMAND}"
)
-ctest_build()
-if(CTEST_RESOURCE_ALLOC_ENABLED)
+if(CTEST_RESOURCE_SPEC_SOURCE STREQUAL "ARG")
set(resspec RESOURCE_SPEC_FILE "@RunCMake_SOURCE_DIR@/resspec.json")
+elseif(CTEST_RESOURCE_SPEC_SOURCE STREQUAL "VARIABLE")
+ set(CTEST_RESOURCE_SPEC_FILE "@RunCMake_SOURCE_DIR@/resspec.json")
+elseif(CTEST_RESOURCE_SPEC_SOURCE STREQUAL "CACHE")
+ list(APPEND config_options "-DCTEST_RESOURCE_SPEC_FILE=@RunCMake_SOURCE_DIR@/resspec.json")
endif()
+
+ctest_start(Experimental QUIET)
+ctest_configure(OPTIONS "${config_options}")
+ctest_build()
ctest_test(${resspec} RETURN_VALUE retval PARALLEL_LEVEL ${CTEST_PARALLEL} SCHEDULE_RANDOM ${CTEST_RANDOM})
if(retval)
message(FATAL_ERROR "Tests did not pass")
diff --git a/Tests/RunCMake/CTestTimeout/Basic-stdout.txt b/Tests/RunCMake/CTestTimeout/Basic-stdout.txt
new file mode 100644
index 0000000..db59dbf
--- /dev/null
+++ b/Tests/RunCMake/CTestTimeout/Basic-stdout.txt
@@ -0,0 +1,6 @@
+Test project [^
+]*/Tests/RunCMake/CTestTimeout/Basic-build
+ Start 1: TestTimeout
+1/1 Test #1: TestTimeout ......................\*\*\*Timeout +[1-9][0-9.]* sec
++
+0% tests passed, 1 tests failed out of 1
diff --git a/Tests/RunCMake/CTestTimeout/CMakeLists.txt.in b/Tests/RunCMake/CTestTimeout/CMakeLists.txt.in
new file mode 100644
index 0000000..20faa94
--- /dev/null
+++ b/Tests/RunCMake/CTestTimeout/CMakeLists.txt.in
@@ -0,0 +1,15 @@
+cmake_minimum_required(VERSION 3.16)
+project(CTestTest@CASE_NAME@ C)
+include(CTest)
+
+add_executable(TestTimeout TestTimeout.c)
+
+if(NOT TIMEOUT)
+ set(TIMEOUT 4)
+endif()
+target_compile_definitions(TestTimeout PRIVATE TIMEOUT=${TIMEOUT})
+
+add_test(NAME TestTimeout COMMAND TestTimeout)
+set_property(TEST TestTimeout PROPERTY TIMEOUT ${TIMEOUT})
+
+@CASE_CMAKELISTS_SUFFIX_CODE@
diff --git a/Tests/RunCMake/CTestTimeout/Fork-stdout.txt b/Tests/RunCMake/CTestTimeout/Fork-stdout.txt
new file mode 100644
index 0000000..2938d8e
--- /dev/null
+++ b/Tests/RunCMake/CTestTimeout/Fork-stdout.txt
@@ -0,0 +1,6 @@
+Test project [^
+]*/Tests/RunCMake/CTestTimeout/Fork-build
+ Start 1: TestTimeout
+1/1 Test #1: TestTimeout ......................\*\*\*Timeout +[1-9][0-9.]* sec
++
+0% tests passed, 1 tests failed out of 1
diff --git a/Tests/RunCMake/CTestTimeout/RunCMakeTest.cmake b/Tests/RunCMake/CTestTimeout/RunCMakeTest.cmake
new file mode 100644
index 0000000..7e96b6d
--- /dev/null
+++ b/Tests/RunCMake/CTestTimeout/RunCMakeTest.cmake
@@ -0,0 +1,22 @@
+include(RunCTest)
+
+if(NOT TIMEOUT)
+ # Give the process time to load and start running.
+ set(TIMEOUT 4)
+endif()
+
+function(run_ctest_timeout CASE_NAME)
+ configure_file(${RunCMake_SOURCE_DIR}/TestTimeout.c
+ ${RunCMake_BINARY_DIR}/${CASE_NAME}/TestTimeout.c COPYONLY)
+ run_ctest(${CASE_NAME})
+endfunction()
+
+run_ctest_timeout(Basic)
+
+if(UNIX)
+ string(CONCAT CASE_CMAKELISTS_SUFFIX_CODE [[
+ target_compile_definitions(TestTimeout PRIVATE FORK)
+]])
+ run_ctest_timeout(Fork)
+ unset(CASE_CMAKELISTS_SUFFIX_CODE)
+endif()
diff --git a/Tests/RunCMake/CTestTimeout/TestTimeout.c b/Tests/RunCMake/CTestTimeout/TestTimeout.c
new file mode 100644
index 0000000..5a008a7
--- /dev/null
+++ b/Tests/RunCMake/CTestTimeout/TestTimeout.c
@@ -0,0 +1,24 @@
+#if defined(_WIN32)
+# include <windows.h>
+#else
+# include <unistd.h>
+#endif
+
+#include <stdio.h>
+
+int main(void)
+{
+#ifdef FORK
+ pid_t pid = fork();
+ if (pid != 0) {
+ return 0;
+ }
+#endif
+
+#if defined(_WIN32)
+ Sleep((TIMEOUT + 4) * 1000);
+#else
+ sleep((TIMEOUT + 4));
+#endif
+ return 0;
+}
diff --git a/Tests/RunCMake/CTestTimeout/test.cmake.in b/Tests/RunCMake/CTestTimeout/test.cmake.in
new file mode 100644
index 0000000..be2625b
--- /dev/null
+++ b/Tests/RunCMake/CTestTimeout/test.cmake.in
@@ -0,0 +1,16 @@
+cmake_minimum_required(VERSION 3.16)
+@CASE_TEST_PREFIX_CODE@
+
+set(CTEST_SITE "test-site")
+set(CTEST_BUILD_NAME "test-build-name")
+set(CTEST_SOURCE_DIRECTORY "@RunCMake_BINARY_DIR@/@CASE_NAME@")
+set(CTEST_BINARY_DIRECTORY "@RunCMake_BINARY_DIR@/@CASE_NAME@-build")
+set(CTEST_CMAKE_GENERATOR "@RunCMake_GENERATOR@")
+set(CTEST_CMAKE_GENERATOR_PLATFORM "@RunCMake_GENERATOR_PLATFORM@")
+set(CTEST_CMAKE_GENERATOR_TOOLSET "@RunCMake_GENERATOR_TOOLSET@")
+set(CTEST_BUILD_CONFIGURATION "$ENV{CMAKE_CONFIG_TYPE}")
+
+ctest_start(Experimental)
+ctest_configure(OPTIONS "-DTIMEOUT=@TIMEOUT@")
+ctest_build()
+ctest_test()
diff --git a/Tests/RunCMake/CheckIPOSupported/cmp0069-is-old-stderr.txt b/Tests/RunCMake/CheckIPOSupported/cmp0069-is-old-stderr.txt
index f183594..1baa63a 100644
--- a/Tests/RunCMake/CheckIPOSupported/cmp0069-is-old-stderr.txt
+++ b/Tests/RunCMake/CheckIPOSupported/cmp0069-is-old-stderr.txt
@@ -1,4 +1,15 @@
-^CMake Error at .*/Modules/CheckIPOSupported\.cmake:[0-9]+ \(message\):
+^CMake Deprecation Warning at cmp0069-is-old.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0069 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\)
++
+CMake Error at .*/Modules/CheckIPOSupported\.cmake:[0-9]+ \(message\):
Policy CMP0069 set to OLD
Call Stack \(most recent call first\):
cmp0069-is-old\.cmake:[0-9]+ \(check_ipo_supported\)
diff --git a/Tests/RunCMake/CommandLine/E_cat_directory-result.txt b/Tests/RunCMake/CommandLine/E_cat_directory-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_directory-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_cat_directory-stderr.txt b/Tests/RunCMake/CommandLine/E_cat_directory-stderr.txt
new file mode 100644
index 0000000..c4d0d48
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_directory-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: .* is a directory
diff --git a/Tests/RunCMake/CommandLine/E_cat_good_cat-stdout.txt b/Tests/RunCMake/CommandLine/E_cat_good_cat-stdout.txt
new file mode 100644
index 0000000..aae90e6
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_good_cat-stdout.txt
@@ -0,0 +1,3 @@
+first file to append
+second file to append
+àéùç - 한국어
diff --git a/Tests/RunCMake/CommandLine/E_cat_non_existing_file-result.txt b/Tests/RunCMake/CommandLine/E_cat_non_existing_file-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_non_existing_file-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_cat_non_existing_file-stderr.txt b/Tests/RunCMake/CommandLine/E_cat_non_existing_file-stderr.txt
new file mode 100644
index 0000000..0d8fc4b
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_non_existing_file-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: .*: no such file or directory \(ignoring\)
diff --git a/Tests/RunCMake/CommandLine/E_cat_non_readable_file-result.txt b/Tests/RunCMake/CommandLine/E_cat_non_readable_file-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_non_readable_file-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_cat_non_readable_file-stderr.txt b/Tests/RunCMake/CommandLine/E_cat_non_readable_file-stderr.txt
new file mode 100644
index 0000000..97ec822
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_non_readable_file-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: .*: permission denied \(ignoring\)
diff --git a/Tests/RunCMake/CommandLine/E_cat_option_not_handled-result.txt b/Tests/RunCMake/CommandLine/E_cat_option_not_handled-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_option_not_handled-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_cat_option_not_handled-stderr.txt b/Tests/RunCMake/CommandLine/E_cat_option_not_handled-stderr.txt
new file mode 100644
index 0000000..92f7acf
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_cat_option_not_handled-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: -f: option not handled
diff --git a/Tests/RunCMake/CommandLine/E_rm_bad_argument-result.txt b/Tests/RunCMake/CommandLine/E_rm_bad_argument-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_bad_argument-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_rm_bad_argument-stderr.txt b/Tests/RunCMake/CommandLine/E_rm_bad_argument-stderr.txt
new file mode 100644
index 0000000..62b963a
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_bad_argument-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: Unknown -E rm argument: -rd$
diff --git a/Tests/RunCMake/CommandLine/E_rm_directory_link_existing-check.cmake b/Tests/RunCMake/CommandLine/E_rm_directory_link_existing-check.cmake
new file mode 100644
index 0000000..b1a29a2
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_directory_link_existing-check.cmake
@@ -0,0 +1,3 @@
+if(NOT EXISTS ${out}/dir/existing.txt)
+ set(RunCMake_TEST_FAILED "${out}/dir/existing.txt should exist (we only removed the link to dir folder)")
+endif()
diff --git a/Tests/RunCMake/CommandLine/E_rm_directory_link_existing-result.txt b/Tests/RunCMake/CommandLine/E_rm_directory_link_existing-result.txt
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_directory_link_existing-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CommandLine/E_rm_empty_file_specified-stderr.txt b/Tests/RunCMake/CommandLine/E_rm_empty_file_specified-stderr.txt
new file mode 100644
index 0000000..1ac7dba
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_empty_file_specified-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: Missing file/directory to remove$
diff --git a/Tests/RunCMake/CommandLine/E_rm_empty_file_specified.cmake b/Tests/RunCMake/CommandLine/E_rm_empty_file_specified.cmake
new file mode 100644
index 0000000..6cd4edd
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_empty_file_specified.cmake
@@ -0,0 +1,8 @@
+execute_process(
+ COMMAND ${CMAKE_COMMAND} -E rm ""
+ RESULT_VARIABLE actual_result
+ )
+
+if(NOT "${actual_result}" EQUAL "1")
+ message(SEND_ERROR "cmake -E rm \"\" should have returned 1, got ${actual_result}")
+endif()
diff --git a/Tests/RunCMake/CommandLine/E_rm_file_force_existing-check.cmake b/Tests/RunCMake/CommandLine/E_rm_file_force_existing-check.cmake
new file mode 100644
index 0000000..e28b160
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_file_force_existing-check.cmake
@@ -0,0 +1,3 @@
+if(EXISTS ${out}/existing.txt)
+ set(RunCMake_TEST_FAILED "${out}/existing.txt not removed")
+endif()
diff --git a/Tests/RunCMake/CommandLine/E_rm_file_force_existing-result.txt b/Tests/RunCMake/CommandLine/E_rm_file_force_existing-result.txt
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_file_force_existing-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CommandLine/E_rm_file_force_non_existing-result.txt b/Tests/RunCMake/CommandLine/E_rm_file_force_non_existing-result.txt
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_file_force_non_existing-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CommandLine/E_rm_file_link_existing-check.cmake b/Tests/RunCMake/CommandLine/E_rm_file_link_existing-check.cmake
new file mode 100644
index 0000000..a0a9b20
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_file_link_existing-check.cmake
@@ -0,0 +1,3 @@
+if(NOT EXISTS ${out}/existing.txt)
+ set(RunCMake_TEST_FAILED "${out}/existing.txt should exist (we only removed the link)")
+endif()
diff --git a/Tests/RunCMake/CommandLine/E_rm_file_link_existing-result.txt b/Tests/RunCMake/CommandLine/E_rm_file_link_existing-result.txt
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_file_link_existing-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CommandLine/E_rm_file_link_non_existing-result.txt b/Tests/RunCMake/CommandLine/E_rm_file_link_non_existing-result.txt
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_file_link_non_existing-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CommandLine/E_rm_file_non_force_existing-check.cmake b/Tests/RunCMake/CommandLine/E_rm_file_non_force_existing-check.cmake
new file mode 100644
index 0000000..e28b160
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_file_non_force_existing-check.cmake
@@ -0,0 +1,3 @@
+if(EXISTS ${out}/existing.txt)
+ set(RunCMake_TEST_FAILED "${out}/existing.txt not removed")
+endif()
diff --git a/Tests/RunCMake/CommandLine/E_rm_file_non_force_existing-result.txt b/Tests/RunCMake/CommandLine/E_rm_file_non_force_existing-result.txt
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_file_non_force_existing-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CommandLine/E_rm_file_non_force_non_existing-result.txt b/Tests/RunCMake/CommandLine/E_rm_file_non_force_non_existing-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_file_non_force_non_existing-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_rm_file_non_force_non_existing-stderr.txt b/Tests/RunCMake/CommandLine/E_rm_file_non_force_non_existing-stderr.txt
new file mode 100644
index 0000000..05df88a
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_file_non_force_non_existing-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: File to remove does not exist and force is not set: .*/rm_tests/not_existing.txt
diff --git a/Tests/RunCMake/CommandLine/E_rm_file_recursive_existing-check.cmake b/Tests/RunCMake/CommandLine/E_rm_file_recursive_existing-check.cmake
new file mode 100644
index 0000000..e28b160
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_file_recursive_existing-check.cmake
@@ -0,0 +1,3 @@
+if(EXISTS ${out}/existing.txt)
+ set(RunCMake_TEST_FAILED "${out}/existing.txt not removed")
+endif()
diff --git a/Tests/RunCMake/CommandLine/E_rm_file_recursive_existing-result.txt b/Tests/RunCMake/CommandLine/E_rm_file_recursive_existing-result.txt
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_file_recursive_existing-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CommandLine/E_rm_file_recursive_non_existing-result.txt b/Tests/RunCMake/CommandLine/E_rm_file_recursive_non_existing-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_file_recursive_non_existing-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_rm_file_recursive_non_existing-stderr.txt b/Tests/RunCMake/CommandLine/E_rm_file_recursive_non_existing-stderr.txt
new file mode 100644
index 0000000..05df88a
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_file_recursive_non_existing-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: File to remove does not exist and force is not set: .*/rm_tests/not_existing.txt
diff --git a/Tests/RunCMake/CommandLine/E_rm_force_recursive_directory_with_files-check.cmake b/Tests/RunCMake/CommandLine/E_rm_force_recursive_directory_with_files-check.cmake
new file mode 100644
index 0000000..1a976cb
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_force_recursive_directory_with_files-check.cmake
@@ -0,0 +1,3 @@
+if(EXISTS ${out})
+ set(RunCMake_TEST_FAILED "${out} not removed")
+endif()
diff --git a/Tests/RunCMake/CommandLine/E_rm_force_recursive_directory_with_files-result.txt b/Tests/RunCMake/CommandLine/E_rm_force_recursive_directory_with_files-result.txt
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_force_recursive_directory_with_files-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CommandLine/E_rm_force_recursive_non_existing_file-result.txt b/Tests/RunCMake/CommandLine/E_rm_force_recursive_non_existing_file-result.txt
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_force_recursive_non_existing_file-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CommandLine/E_rm_no_file_specified-result.txt b/Tests/RunCMake/CommandLine/E_rm_no_file_specified-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_no_file_specified-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_rm_no_file_specified-stderr.txt b/Tests/RunCMake/CommandLine/E_rm_no_file_specified-stderr.txt
new file mode 100644
index 0000000..1ac7dba
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_no_file_specified-stderr.txt
@@ -0,0 +1 @@
+^CMake Error: Missing file/directory to remove$
diff --git a/Tests/RunCMake/CommandLine/E_rm_non_recursive_directory-two-directories-check.cmake b/Tests/RunCMake/CommandLine/E_rm_non_recursive_directory-two-directories-check.cmake
new file mode 100644
index 0000000..609271e
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_non_recursive_directory-two-directories-check.cmake
@@ -0,0 +1,3 @@
+if(NOT EXISTS ${out}/d1 OR NOT EXISTS ${out}/d2)
+ set(RunCMake_TEST_FAILED "${out}/d1 or ${out}/d2 is removed but should not")
+endif()
diff --git a/Tests/RunCMake/CommandLine/E_rm_non_recursive_directory-two-directories-result.txt b/Tests/RunCMake/CommandLine/E_rm_non_recursive_directory-two-directories-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_non_recursive_directory-two-directories-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_rm_non_recursive_directory-two-directories-stderr.txt b/Tests/RunCMake/CommandLine/E_rm_non_recursive_directory-two-directories-stderr.txt
new file mode 100644
index 0000000..33ea2e3
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_non_recursive_directory-two-directories-stderr.txt
@@ -0,0 +1,2 @@
+^Error removing directory ".*/rm_tests/d1" without recursive option\.
+Error removing directory ".*/rm_tests/d2" without recursive option\.$
diff --git a/Tests/RunCMake/CommandLine/E_rm_recursive_directory-two-directories-check.cmake b/Tests/RunCMake/CommandLine/E_rm_recursive_directory-two-directories-check.cmake
new file mode 100644
index 0000000..5282da7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_recursive_directory-two-directories-check.cmake
@@ -0,0 +1,3 @@
+if(EXISTS ${out}/d1 OR EXISTS ${out}/d2)
+ set(RunCMake_TEST_FAILED "${out}/d1 or ${out}/d2 should be removed")
+endif()
diff --git a/Tests/RunCMake/CommandLine/E_rm_recursive_directory-two-directories-result.txt b/Tests/RunCMake/CommandLine/E_rm_recursive_directory-two-directories-result.txt
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_recursive_directory-two-directories-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CommandLine/E_rm_recursive_directory_link_existing-check.cmake b/Tests/RunCMake/CommandLine/E_rm_recursive_directory_link_existing-check.cmake
new file mode 100644
index 0000000..b1a29a2
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_recursive_directory_link_existing-check.cmake
@@ -0,0 +1,3 @@
+if(NOT EXISTS ${out}/dir/existing.txt)
+ set(RunCMake_TEST_FAILED "${out}/dir/existing.txt should exist (we only removed the link to dir folder)")
+endif()
diff --git a/Tests/RunCMake/CommandLine/E_rm_recursive_directory_link_existing-result.txt b/Tests/RunCMake/CommandLine/E_rm_recursive_directory_link_existing-result.txt
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_recursive_directory_link_existing-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CommandLine/E_rm_recursive_file_link_existing-check.cmake b/Tests/RunCMake/CommandLine/E_rm_recursive_file_link_existing-check.cmake
new file mode 100644
index 0000000..a0a9b20
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_recursive_file_link_existing-check.cmake
@@ -0,0 +1,3 @@
+if(NOT EXISTS ${out}/existing.txt)
+ set(RunCMake_TEST_FAILED "${out}/existing.txt should exist (we only removed the link)")
+endif()
diff --git a/Tests/RunCMake/CommandLine/E_rm_recursive_file_link_existing-result.txt b/Tests/RunCMake/CommandLine/E_rm_recursive_file_link_existing-result.txt
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_recursive_file_link_existing-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CommandLine/E_rm_recursive_file_link_non_existing-result.txt b/Tests/RunCMake/CommandLine/E_rm_recursive_file_link_non_existing-result.txt
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_rm_recursive_file_link_non_existing-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CommandLine/P_arbitrary_args.cmake b/Tests/RunCMake/CommandLine/P_arbitrary_args.cmake
new file mode 100644
index 0000000..29faae3
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/P_arbitrary_args.cmake
@@ -0,0 +1,3 @@
+if(NOT ("${CMAKE_ARGV3}" STREQUAL "--" AND "${CMAKE_ARGV4}" STREQUAL "-DFOO"))
+ message(FATAL_ERROR "`-DFOO` shouldn't trigger an error after `--`")
+endif()
diff --git a/Tests/RunCMake/CommandLine/ProfilingTest-check.cmake b/Tests/RunCMake/CommandLine/ProfilingTest-check.cmake
new file mode 100644
index 0000000..19ece86
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/ProfilingTest-check.cmake
@@ -0,0 +1,18 @@
+if (NOT EXISTS ${ProfilingTestOutput})
+ set(RunCMake_TEST_FAILED "Expected ${ProfilingTestOutput} to exists")
+endif()
+
+file(READ "${ProfilingTestOutput}" JSON_HEADER LIMIT 2)
+if (NOT JSON_HEADER MATCHES "^\\[{")
+ set(RunCMake_TEST_FAILED "Expected valid JSON start")
+ return()
+endif()
+
+file(SIZE "${ProfilingTestOutput}" OUTPUT_SIZE)
+math(EXPR END_OFFSET "${OUTPUT_SIZE} -2 ")
+
+file(READ "${ProfilingTestOutput}" JSON_TRAILER OFFSET ${END_OFFSET})
+if (NOT JSON_TRAILER MATCHES "^}]$")
+ set(RunCMake_TEST_FAILED "Expected valid JSON end")
+ return()
+endif()
diff --git a/Tests/RunCMake/CommandLine/ProfilingTest.cmake b/Tests/RunCMake/CommandLine/ProfilingTest.cmake
new file mode 100644
index 0000000..837f4bf
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/ProfilingTest.cmake
@@ -0,0 +1 @@
+# This file is intentionally left blank
diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
index b608d33..973391d 100644
--- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -46,6 +46,7 @@ run_cmake_command(G_no-arg ${CMAKE_COMMAND} -B DummyBuildDir -G)
run_cmake_command(G_bad-arg ${CMAKE_COMMAND} -B DummyBuildDir -G NoSuchGenerator)
run_cmake_command(P_no-arg ${CMAKE_COMMAND} -P)
run_cmake_command(P_no-file ${CMAKE_COMMAND} -P nosuchscriptfile.cmake)
+run_cmake_command(P_arbitrary_args ${CMAKE_COMMAND} -P "${RunCMake_SOURCE_DIR}/P_arbitrary_args.cmake" -- -DFOO)
run_cmake_command(build-no-dir
${CMAKE_COMMAND} --build)
@@ -254,6 +255,24 @@ function(run_EnvironmentGenerator)
endfunction()
run_EnvironmentGenerator()
+function(run_EnvironmentExportCompileCommands)
+ set(RunCMake_TEST_SOURCE_DIR ${RunCMake_SOURCE_DIR}/env-export-compile-commands)
+
+ run_cmake(env-export-compile-commands-unset)
+
+ set(ENV{CMAKE_EXPORT_COMPILE_COMMANDS} ON)
+ run_cmake(env-export-compile-commands-set)
+
+ set(RunCMake_TEST_OPTIONS -DCMAKE_EXPORT_COMPILE_COMMANDS=OFF)
+ run_cmake(env-export-compile-commands-override)
+
+ unset(ENV{CMAKE_EXPORT_COMPILE_COMMANDS})
+endfunction(run_EnvironmentExportCompileCommands)
+
+if(RunCMake_GENERATOR MATCHES "Unix Makefiles" OR RunCMake_GENERATOR MATCHES "Ninja")
+ run_EnvironmentExportCompileCommands()
+endif()
+
if(RunCMake_GENERATOR STREQUAL "Ninja")
# Use a single build tree for a few tests without cleaning.
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Build-build)
@@ -370,6 +389,114 @@ endif()
unset(out)
unset(outfile)
+set(out ${RunCMake_BINARY_DIR}/rm_tests)
+file(REMOVE_RECURSE "${out}")
+file(MAKE_DIRECTORY ${out})
+file(TOUCH ${out}/existing.txt)
+run_cmake_command(E_rm_file_force_existing
+ ${CMAKE_COMMAND} -E rm -f ${out}/existing.txt)
+file(TOUCH ${out}/existing.txt)
+run_cmake_command(E_rm_file_non_force_existing
+ ${CMAKE_COMMAND} -E rm ${out}/existing.txt)
+run_cmake_command(E_rm_file_force_non_existing
+ ${CMAKE_COMMAND} -E rm -f ${out}/not_existing.txt)
+run_cmake_command(E_rm_file_non_force_non_existing
+ ${CMAKE_COMMAND} -E rm ${out}/not_existing.txt)
+
+file(TOUCH ${out}/existing.txt)
+run_cmake_command(E_rm_file_recursive_existing
+ ${CMAKE_COMMAND} -E rm -r ${out}/existing.txt)
+run_cmake_command(E_rm_file_recursive_non_existing
+ ${CMAKE_COMMAND} -E rm -r ${out}/not_existing.txt)
+
+file(MAKE_DIRECTORY ${out}/d1 ${out}/d2)
+run_cmake_command(E_rm_non_recursive_directory-two-directories
+ ${CMAKE_COMMAND} -E rm ${out}/d1 ${out}/d2)
+
+run_cmake_command(E_rm_recursive_directory-two-directories
+ ${CMAKE_COMMAND} -E rm -R ${out}/d1 ${out}/d2)
+
+run_cmake_command(E_rm_no_file_specified
+ ${CMAKE_COMMAND} -E rm -rf)
+
+run_cmake_command(E_rm_empty_file_specified
+ ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/E_rm_empty_file_specified.cmake)
+
+run_cmake_command(E_rm_bad_argument
+ ${CMAKE_COMMAND} -E rm -rd ${out}/d1 ${out}/d2)
+
+file(MAKE_DIRECTORY ${out}/d1 ${out}/d2)
+file(WRITE ${out}/test.txt "")
+run_cmake_command(E_rm_force_recursive_directory_with_files
+ ${CMAKE_COMMAND} -E rm -rf ${out}/)
+
+run_cmake_command(E_rm_force_recursive_non_existing_file
+ ${CMAKE_COMMAND} -E rm -Rf ${out}/test.txt)
+
+if(NOT WIN32 AND NOT CYGWIN)
+ file(MAKE_DIRECTORY ${out})
+ file(TOUCH ${out}/existing.txt)
+ file(MAKE_DIRECTORY ${out}/dir)
+ file(TOUCH ${out}/dir/existing.txt) # add a file in the folder
+ file(CREATE_LINK ${out}/dir ${out}/link_dir SYMBOLIC)
+ file(CREATE_LINK ${out}/existing.txt ${out}/existing_file_link.txt SYMBOLIC)
+ file(CREATE_LINK ${out}/non_existing.txt ${out}/non_existing_file_link.txt SYMBOLIC)
+ run_cmake_command(E_rm_file_link_existing
+ ${CMAKE_COMMAND} -E rm ${out}/existing_file_link.txt)
+ run_cmake_command(E_rm_directory_link_existing
+ ${CMAKE_COMMAND} -E rm ${out}/link_dir)
+ run_cmake_command(E_rm_file_link_non_existing
+ ${CMAKE_COMMAND} -E rm ${out}/non_existing_file_link.txt)
+
+ file(CREATE_LINK ${out}/dir ${out}/link_dir SYMBOLIC)
+ file(CREATE_LINK ${out}/existing.txt ${out}/existing_file_link.txt SYMBOLIC)
+ file(CREATE_LINK ${out}/non_existing.txt ${out}/non_existing_file_link.txt SYMBOLIC)
+ run_cmake_command(E_rm_recursive_file_link_existing
+ ${CMAKE_COMMAND} -E rm -R ${out}/existing_file_link.txt)
+ run_cmake_command(E_rm_recursive_directory_link_existing
+ ${CMAKE_COMMAND} -E rm -r ${out}/link_dir)
+ run_cmake_command(E_rm_recursive_file_link_non_existing
+ ${CMAKE_COMMAND} -E rm -r ${out}/non_existing_file_link.txt)
+endif()
+unset(out)
+
+# cat tests
+set(out ${RunCMake_BINARY_DIR}/cat_tests)
+file(REMOVE_RECURSE "${out}")
+file(MAKE_DIRECTORY ${out})
+run_cmake_command(E_cat_non_existing_file
+ ${CMAKE_COMMAND} -E cat ${out}/non-existing-file.txt)
+
+if(UNIX)
+ # test non readable file only if not root
+ execute_process(
+ COMMAND id -u $ENV{USER}
+ OUTPUT_VARIABLE uid
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ if(NOT "${uid}" STREQUAL "0")
+ # Create non readable file
+ set(inside_folder "${out}/in")
+ file(MAKE_DIRECTORY ${inside_folder})
+ file(WRITE "${inside_folder}/non_readable_file.txt" "first file to append\n")
+ file(COPY "${inside_folder}/non_readable_file.txt" DESTINATION "${out}" FILE_PERMISSIONS OWNER_WRITE)
+ run_cmake_command(E_cat_non_readable_file
+ ${CMAKE_COMMAND} -E cat "${out}/non_readable_file.txt")
+ endif()
+endif()
+
+run_cmake_command(E_cat_option_not_handled
+ ${CMAKE_COMMAND} -E cat -f)
+
+run_cmake_command(E_cat_directory
+ ${CMAKE_COMMAND} -E cat ${out})
+
+file(WRITE "${out}/first_file.txt" "first file to append\n")
+file(WRITE "${out}/second_file.txt" "second file to append\n")
+file(WRITE "${out}/unicode_file.txt" "àéùç - 한국어") # Korean in Korean
+run_cmake_command(E_cat_good_cat
+ ${CMAKE_COMMAND} -E cat "${out}/first_file.txt" "${out}/second_file.txt" "${out}/unicode_file.txt")
+unset(out)
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)
@@ -519,6 +646,14 @@ set(RunCMake_TEST_OPTIONS --trace-redirect=/no/such/file.txt)
run_cmake(trace-redirect-nofile)
unset(RunCMake_TEST_OPTIONS)
+set(RunCMake_TEST_OPTIONS --trace --trace-format=json-v1 --trace-redirect=${RunCMake_BINARY_DIR}/json-v1.trace)
+run_cmake(trace-json-v1)
+unset(RunCMake_TEST_OPTIONS)
+
+set(RunCMake_TEST_OPTIONS --trace-expand --trace-format=json-v1 --trace-redirect=${RunCMake_BINARY_DIR}/json-v1-expand.trace)
+run_cmake(trace-json-v1-expand)
+unset(RunCMake_TEST_OPTIONS)
+
set(RunCMake_TEST_OPTIONS -Wno-deprecated --warn-uninitialized)
run_cmake(warn-uninitialized)
unset(RunCMake_TEST_OPTIONS)
@@ -571,3 +706,54 @@ if(CMAKE_HOST_UNIX AND NOT CMAKE_SYSTEM_NAME STREQUAL "CYGWIN")
run_cmake_command(closed_stderr sh -c "\"${CMAKE_COMMAND}\" --version 2>&-")
run_cmake_command(closed_stdall sh -c "\"${CMAKE_COMMAND}\" --version <&- >&- 2>&-")
endif()
+
+function(run_llvm_rc)
+ set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/llvm_rc-build")
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ run_cmake_command(llvm_rc_no_args ${CMAKE_COMMAND} -E cmake_llvm_rc)
+ run_cmake_command(llvm_rc_no_-- ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/source_file test.tmp ${CMAKE_COMMAND} -E echo "This is a test")
+ run_cmake_command(llvm_rc_empty_preprocessor ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/source_file test.tmp -- ${CMAKE_COMMAND} -E echo "This is a test")
+ run_cmake_command(llvm_rc_failing_first_command ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/source_file test.tmp ${CMAKE_COMMAND} -P FailedProgram.cmake -- ${CMAKE_COMMAND} -E echo "This is a test")
+ run_cmake_command(llvm_rc_failing_second_command ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/source_file test.tmp ${CMAKE_COMMAND} -E echo "This is a test" -- ${CMAKE_COMMAND} -P FailedProgram.cmake )
+ if(EXISTS ${RunCMake_TEST_BINARY_DIR}/test.tmp)
+ message(SEND_ERROR "${test} - FAILED:\n"
+ "test.tmp was not deleted")
+ endif()
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}/ExpandSourceDir")
+ run_cmake_command(llvm_rc_full_run ${CMAKE_COMMAND} -E cmake_llvm_rc ${RunCMake_TEST_BINARY_DIR}/ExpandSourceDir/source_file test.tmp ${CMAKE_COMMAND} -E echo "This is a test" -- ${CMAKE_COMMAND} -E copy test.tmp SOURCE_DIR/llvmrc.result )
+ if(EXISTS ${RunCMake_TEST_BINARY_DIR}/ExpandSourceDir/test.tmp)
+ message(SEND_ERROR "${test} - FAILED:\n"
+ "test.tmp was not deleted")
+ endif()
+ file(READ ${RunCMake_TEST_BINARY_DIR}/ExpandSourceDir/llvmrc.result LLVMRC_RESULT)
+ if(NOT "${LLVMRC_RESULT}" STREQUAL "This is a test\n")
+ message(SEND_ERROR "${test} - FAILED:\n"
+ "llvmrc.result was not created")
+ endif()
+ unset(LLVMRC_RESULT)
+endfunction()
+run_llvm_rc()
+
+set(RunCMake_TEST_OPTIONS --profiling-output=/no/such/file.txt --profiling-format=google-trace)
+run_cmake(profiling-all-params)
+unset(RunCMake_TEST_OPTIONS)
+
+set(RunCMake_TEST_OPTIONS --profiling-output=/no/such/file.txt --profiling-format=invalid-format)
+run_cmake(profiling-invalid-format)
+unset(RunCMake_TEST_OPTIONS)
+
+set(RunCMake_TEST_OPTIONS --profiling-output=/no/such/file.txt)
+run_cmake(profiling-missing-format)
+unset(RunCMake_TEST_OPTIONS)
+
+set(RunCMake_TEST_OPTIONS --profiling-format=google-trace)
+run_cmake(profiling-missing-output)
+unset(RunCMake_TEST_OPTIONS)
+
+set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/profiling-test")
+set(ProfilingTestOutput ${RunCMake_TEST_BINARY_DIR}/output.json)
+set(RunCMake_TEST_OPTIONS --profiling-format=google-trace --profiling-output=${ProfilingTestOutput})
+run_cmake(ProfilingTest)
+unset(RunCMake_TEST_OPTIONS)
diff --git a/Tests/RunCMake/CommandLine/cmake_depends/test_UTF-16LE.h b/Tests/RunCMake/CommandLine/cmake_depends/test_UTF-16LE.h
index bf56ec6..2d39178 100644
--- a/Tests/RunCMake/CommandLine/cmake_depends/test_UTF-16LE.h
+++ b/Tests/RunCMake/CommandLine/cmake_depends/test_UTF-16LE.h
Binary files differ
diff --git a/Tests/RunCMake/CommandLine/env-export-compile-commands-override-check.cmake b/Tests/RunCMake/CommandLine/env-export-compile-commands-override-check.cmake
new file mode 100644
index 0000000..032a1ae
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/env-export-compile-commands-override-check.cmake
@@ -0,0 +1,3 @@
+if(EXISTS "${RunCMake_TEST_BINARY_DIR}/compile_commands.json")
+ set(RunCMake_TEST_FAILED "compile_commands.json generated with CMAKE_EXPORT_COMPILE_COMMANDS overridden")
+endif()
diff --git a/Tests/RunCMake/CommandLine/env-export-compile-commands-set-check.cmake b/Tests/RunCMake/CommandLine/env-export-compile-commands-set-check.cmake
new file mode 100644
index 0000000..a749a55
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/env-export-compile-commands-set-check.cmake
@@ -0,0 +1,3 @@
+if(NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/compile_commands.json")
+ set(RunCMake_TEST_FAILED "compile_commands.json not generated with CMAKE_EXPORT_COMPILE_COMMANDS set")
+endif()
diff --git a/Tests/RunCMake/CommandLine/env-export-compile-commands-unset-check.cmake b/Tests/RunCMake/CommandLine/env-export-compile-commands-unset-check.cmake
new file mode 100644
index 0000000..c5878f0
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/env-export-compile-commands-unset-check.cmake
@@ -0,0 +1,3 @@
+if(EXISTS "${RunCMake_TEST_BINARY_DIR}/compile_commands.json")
+ set(RunCMake_TEST_FAILED "compile_commands.json generated with CMAKE_EXPORT_COMPILE_COMMANDS unset")
+endif()
diff --git a/Tests/RunCMake/CommandLine/env-export-compile-commands/CMakeLists.txt b/Tests/RunCMake/CommandLine/env-export-compile-commands/CMakeLists.txt
new file mode 100644
index 0000000..aa6fbfd
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/env-export-compile-commands/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 3.14)
+project(env-export-compile-commands C)
+
+# Add target with a source file to make sure compile_commands.json gets
+# generated.
+file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/main.c)
+add_executable(env-export-compile-commands ${CMAKE_CURRENT_BINARY_DIR}/main.c)
diff --git a/Tests/RunCMake/CommandLine/llvm_rc_empty_preprocessor-result.txt b/Tests/RunCMake/CommandLine/llvm_rc_empty_preprocessor-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/llvm_rc_empty_preprocessor-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/llvm_rc_empty_preprocessor-stderr.txt b/Tests/RunCMake/CommandLine/llvm_rc_empty_preprocessor-stderr.txt
new file mode 100644
index 0000000..cb69366
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/llvm_rc_empty_preprocessor-stderr.txt
@@ -0,0 +1 @@
+Empty preprocessing command
diff --git a/Tests/RunCMake/CommandLine/llvm_rc_failing_first_command-result.txt b/Tests/RunCMake/CommandLine/llvm_rc_failing_first_command-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/llvm_rc_failing_first_command-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/llvm_rc_failing_first_command-stderr.txt b/Tests/RunCMake/CommandLine/llvm_rc_failing_first_command-stderr.txt
new file mode 100644
index 0000000..765b708
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/llvm_rc_failing_first_command-stderr.txt
@@ -0,0 +1 @@
+CMake Error
diff --git a/Tests/RunCMake/CommandLine/llvm_rc_failing_second_command-result.txt b/Tests/RunCMake/CommandLine/llvm_rc_failing_second_command-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/llvm_rc_failing_second_command-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/llvm_rc_failing_second_command-stderr.txt b/Tests/RunCMake/CommandLine/llvm_rc_failing_second_command-stderr.txt
new file mode 100644
index 0000000..765b708
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/llvm_rc_failing_second_command-stderr.txt
@@ -0,0 +1 @@
+CMake Error
diff --git a/Tests/RunCMake/CommandLine/llvm_rc_no_---result.txt b/Tests/RunCMake/CommandLine/llvm_rc_no_---result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/llvm_rc_no_---result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/llvm_rc_no_---stderr.txt b/Tests/RunCMake/CommandLine/llvm_rc_no_---stderr.txt
new file mode 100644
index 0000000..9c140b7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/llvm_rc_no_---stderr.txt
@@ -0,0 +1 @@
+Empty resource compilation command
diff --git a/Tests/RunCMake/CommandLine/llvm_rc_no_args-result.txt b/Tests/RunCMake/CommandLine/llvm_rc_no_args-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/llvm_rc_no_args-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/llvm_rc_no_args-stderr.txt b/Tests/RunCMake/CommandLine/llvm_rc_no_args-stderr.txt
new file mode 100644
index 0000000..d66b547
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/llvm_rc_no_args-stderr.txt
@@ -0,0 +1 @@
+Invalid cmake_llvm_rc arguments
diff --git a/Tests/RunCMake/CommandLine/profiling-all-params-result.txt b/Tests/RunCMake/CommandLine/profiling-all-params-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/profiling-all-params-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/profiling-all-params-stderr.txt b/Tests/RunCMake/CommandLine/profiling-all-params-stderr.txt
new file mode 100644
index 0000000..6b5c373
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/profiling-all-params-stderr.txt
@@ -0,0 +1 @@
+^.*Could not start profiling: Unable to open: /no/such/file.txt$
diff --git a/Tests/RunCMake/CommandLine/profiling-invalid-format-result.txt b/Tests/RunCMake/CommandLine/profiling-invalid-format-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/profiling-invalid-format-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/profiling-invalid-format-stderr.txt b/Tests/RunCMake/CommandLine/profiling-invalid-format-stderr.txt
new file mode 100644
index 0000000..459bc3a
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/profiling-invalid-format-stderr.txt
@@ -0,0 +1 @@
+^.*Invalid format specified for --profiling-format$
diff --git a/Tests/RunCMake/CommandLine/profiling-missing-format-result.txt b/Tests/RunCMake/CommandLine/profiling-missing-format-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/profiling-missing-format-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/profiling-missing-format-stderr.txt b/Tests/RunCMake/CommandLine/profiling-missing-format-stderr.txt
new file mode 100644
index 0000000..459bc3a
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/profiling-missing-format-stderr.txt
@@ -0,0 +1 @@
+^.*Invalid format specified for --profiling-format$
diff --git a/Tests/RunCMake/CommandLine/profiling-missing-output-result.txt b/Tests/RunCMake/CommandLine/profiling-missing-output-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/profiling-missing-output-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/profiling-missing-output-stderr.txt b/Tests/RunCMake/CommandLine/profiling-missing-output-stderr.txt
new file mode 100644
index 0000000..9ab0c8f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/profiling-missing-output-stderr.txt
@@ -0,0 +1 @@
+^.*--profiling-format specified but no --profiling-output!$
diff --git a/Tests/RunCMake/CommandLine/trace-json-v1-check.cmake b/Tests/RunCMake/CommandLine/trace-json-v1-check.cmake
new file mode 100644
index 0000000..66af039
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/trace-json-v1-check.cmake
@@ -0,0 +1,11 @@
+if(PYTHON_EXECUTABLE)
+ execute_process(
+ COMMAND ${PYTHON_EXECUTABLE} "${RunCMake_SOURCE_DIR}/trace-json-v1-check.py" "${RunCMake_BINARY_DIR}/json-v1.trace"
+ RESULT_VARIABLE result
+ OUTPUT_VARIABLE output
+ ERROR_VARIABLE output
+ )
+ if(NOT result EQUAL 0)
+ set(RunCMake_TEST_FAILED "JSON trace validation failed:\n${output}")
+ endif()
+endif()
diff --git a/Tests/RunCMake/CommandLine/trace-json-v1-check.py b/Tests/RunCMake/CommandLine/trace-json-v1-check.py
new file mode 100755
index 0000000..e617b76
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/trace-json-v1-check.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python3
+
+import json
+import os
+import sys
+
+if sys.version_info[0] >= 3:
+ unicode = str
+
+trace_file = None
+expand = False
+
+for i in sys.argv[1:]:
+ if trace_file is None and not i.startswith('-'):
+ trace_file = i
+ continue
+
+ if i in ['-e', '--expand']:
+ expand = True
+
+assert trace_file is not None
+assert os.path.exists(trace_file)
+
+if expand:
+ msg_args = ['STATUS', 'fff', 'fff;sss; SPACES !!! ', ' 42 space in string!', ' SPACES !!! ']
+else:
+ msg_args = ['STATUS', 'fff', '${ASDF}', ' ${FOO} ${BAR}', ' SPACES !!! ']
+
+required_traces = [
+ {
+ 'args': ['STATUS', 'JSON-V1 str', 'spaces'],
+ 'cmd': 'message',
+ },
+ {
+ 'args': ['ASDF', 'fff', 'sss', ' SPACES !!! '],
+ 'cmd': 'set',
+ },
+ {
+ 'args': ['FOO', '42'],
+ 'cmd': 'set',
+ },
+ {
+ 'args': ['BAR', ' space in string!'],
+ 'cmd': 'set',
+ },
+ {
+ 'args': msg_args,
+ 'cmd': 'message',
+ 'frame': 3 if expand else 2
+ },
+]
+
+with open(trace_file, 'r') as fp:
+ # Check for version (must be the first document)
+ vers = json.loads(fp.readline())
+ assert sorted(vers.keys()) == ['version']
+ assert sorted(vers['version'].keys()) == ['major', 'minor']
+ assert vers['version']['major'] == 1
+ assert vers['version']['minor'] == 0
+
+ for i in fp.readlines():
+ line = json.loads(i)
+ assert sorted(line.keys()) == ['args', 'cmd', 'file', 'frame', 'line', 'time']
+ assert isinstance(line['args'], list)
+ assert isinstance(line['cmd'], unicode)
+ assert isinstance(line['file'], unicode)
+ assert isinstance(line['frame'], int)
+ assert isinstance(line['line'], int)
+ assert isinstance(line['time'], float)
+
+ for j in required_traces:
+ # Compare the subset of required keys with line
+ if {k: line[k] for k in j} == j:
+ required_traces.remove(j)
+
+assert not required_traces
diff --git a/Tests/RunCMake/CommandLine/trace-json-v1-expand-check.cmake b/Tests/RunCMake/CommandLine/trace-json-v1-expand-check.cmake
new file mode 100644
index 0000000..7916d2e
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/trace-json-v1-expand-check.cmake
@@ -0,0 +1,11 @@
+if(PYTHON_EXECUTABLE)
+ execute_process(
+ COMMAND ${PYTHON_EXECUTABLE} "${RunCMake_SOURCE_DIR}/trace-json-v1-check.py" --expand "${RunCMake_BINARY_DIR}/json-v1-expand.trace"
+ RESULT_VARIABLE result
+ OUTPUT_VARIABLE output
+ ERROR_VARIABLE output
+ )
+ if(NOT result EQUAL 0)
+ set(RunCMake_TEST_FAILED "JSON trace validation failed:\n${output}")
+ endif()
+endif()
diff --git a/Tests/RunCMake/CommandLine/trace-json-v1-expand.cmake b/Tests/RunCMake/CommandLine/trace-json-v1-expand.cmake
new file mode 100644
index 0000000..5c190e6
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/trace-json-v1-expand.cmake
@@ -0,0 +1 @@
+include(trace-json-v1.cmake)
diff --git a/Tests/RunCMake/CommandLine/trace-json-v1.cmake b/Tests/RunCMake/CommandLine/trace-json-v1.cmake
new file mode 100644
index 0000000..ed0a0f9
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/trace-json-v1.cmake
@@ -0,0 +1,5 @@
+message(STATUS "JSON-V1 str" "spaces")
+set(ASDF fff sss " SPACES !!! ")
+set(FOO 42)
+set(BAR " space in string!")
+message(STATUS fff ${ASDF} " ${FOO} ${BAR}" " SPACES !!! ")
diff --git a/Tests/RunCMake/CompilerLauncher/C-common.cmake b/Tests/RunCMake/CompilerLauncher/C-common.cmake
new file mode 100644
index 0000000..96b004b
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/C-common.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+set(CMAKE_VERBOSE_MAKEFILE TRUE)
+add_executable(main main.c)
diff --git a/Tests/RunCMake/CompilerLauncher/C-env-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/C-env-Build-stdout.txt
new file mode 100644
index 0000000..3313e31
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/C-env-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/CompilerLauncher/C-env-launch-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/C-env-launch-Build-stdout.txt
new file mode 100644
index 0000000..3313e31
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/C-env-launch-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/CompilerLauncher/C-env.cmake b/Tests/RunCMake/CompilerLauncher/C-env.cmake
new file mode 100644
index 0000000..09b5167
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/C-env.cmake
@@ -0,0 +1 @@
+include(C-common.cmake)
diff --git a/Tests/RunCMake/CompilerLauncher/C-launch-env.cmake b/Tests/RunCMake/CompilerLauncher/C-launch-env.cmake
new file mode 100644
index 0000000..68abcb5
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/C-launch-env.cmake
@@ -0,0 +1,3 @@
+set(CTEST_USE_LAUNCHERS 1)
+include(CTestUseLaunchers)
+include(C-env.cmake)
diff --git a/Tests/RunCMake/CompilerLauncher/C.cmake b/Tests/RunCMake/CompilerLauncher/C.cmake
index 67bf7c4..481e74d 100644
--- a/Tests/RunCMake/CompilerLauncher/C.cmake
+++ b/Tests/RunCMake/CompilerLauncher/C.cmake
@@ -1,4 +1,2 @@
-enable_language(C)
set(CMAKE_C_COMPILER_LAUNCHER "${CMAKE_COMMAND};-E;env;USED_LAUNCHER=1")
-set(CMAKE_VERBOSE_MAKEFILE TRUE)
-add_executable(main main.c)
+include(C-common.cmake)
diff --git a/Tests/RunCMake/CompilerLauncher/CUDA-common.cmake b/Tests/RunCMake/CompilerLauncher/CUDA-common.cmake
new file mode 100644
index 0000000..ca25b2a
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/CUDA-common.cmake
@@ -0,0 +1,4 @@
+cmake_policy(SET CMP0104 NEW)
+enable_language(CUDA)
+set(CMAKE_VERBOSE_MAKEFILE TRUE)
+add_executable(main main.cu)
diff --git a/Tests/RunCMake/CompilerLauncher/CUDA-env-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/CUDA-env-Build-stdout.txt
new file mode 100644
index 0000000..3313e31
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/CUDA-env-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/CompilerLauncher/CUDA-env-launch-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/CUDA-env-launch-Build-stdout.txt
new file mode 100644
index 0000000..3313e31
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/CUDA-env-launch-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/CompilerLauncher/CUDA-env.cmake b/Tests/RunCMake/CompilerLauncher/CUDA-env.cmake
new file mode 100644
index 0000000..cefbe9e
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/CUDA-env.cmake
@@ -0,0 +1 @@
+include(CUDA-common.cmake)
diff --git a/Tests/RunCMake/CompilerLauncher/CUDA-launch-env.cmake b/Tests/RunCMake/CompilerLauncher/CUDA-launch-env.cmake
new file mode 100644
index 0000000..d0d777a
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/CUDA-launch-env.cmake
@@ -0,0 +1,3 @@
+set(CTEST_USE_LAUNCHERS 1)
+include(CTestUseLaunchers)
+include(CUDA-env.cmake)
diff --git a/Tests/RunCMake/CompilerLauncher/CUDA.cmake b/Tests/RunCMake/CompilerLauncher/CUDA.cmake
index fe5560b..7f1652b 100644
--- a/Tests/RunCMake/CompilerLauncher/CUDA.cmake
+++ b/Tests/RunCMake/CompilerLauncher/CUDA.cmake
@@ -1,4 +1,2 @@
-enable_language(CUDA)
set(CMAKE_CUDA_COMPILER_LAUNCHER "${CMAKE_COMMAND};-E;env;USED_LAUNCHER=1")
-set(CMAKE_VERBOSE_MAKEFILE TRUE)
-add_executable(main main.cu)
+include(CUDA-common.cmake)
diff --git a/Tests/RunCMake/CompilerLauncher/CXX-common.cmake b/Tests/RunCMake/CompilerLauncher/CXX-common.cmake
new file mode 100644
index 0000000..3d2ee00
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/CXX-common.cmake
@@ -0,0 +1,3 @@
+enable_language(CXX)
+set(CMAKE_VERBOSE_MAKEFILE TRUE)
+add_executable(main main.cxx)
diff --git a/Tests/RunCMake/CompilerLauncher/CXX-env-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/CXX-env-Build-stdout.txt
new file mode 100644
index 0000000..3313e31
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/CXX-env-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/CompilerLauncher/CXX-env-launch-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/CXX-env-launch-Build-stdout.txt
new file mode 100644
index 0000000..3313e31
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/CXX-env-launch-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/CompilerLauncher/CXX-env.cmake b/Tests/RunCMake/CompilerLauncher/CXX-env.cmake
new file mode 100644
index 0000000..db36956
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/CXX-env.cmake
@@ -0,0 +1 @@
+include(CXX-common.cmake)
diff --git a/Tests/RunCMake/CompilerLauncher/CXX-launch-env.cmake b/Tests/RunCMake/CompilerLauncher/CXX-launch-env.cmake
new file mode 100644
index 0000000..a65cc89
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/CXX-launch-env.cmake
@@ -0,0 +1,3 @@
+set(CTEST_USE_LAUNCHERS 1)
+include(CTestUseLaunchers)
+include(CXX-env.cmake)
diff --git a/Tests/RunCMake/CompilerLauncher/CXX.cmake b/Tests/RunCMake/CompilerLauncher/CXX.cmake
index cdd3478..1f9a12b 100644
--- a/Tests/RunCMake/CompilerLauncher/CXX.cmake
+++ b/Tests/RunCMake/CompilerLauncher/CXX.cmake
@@ -1,4 +1,2 @@
-enable_language(CXX)
set(CMAKE_CXX_COMPILER_LAUNCHER "${CMAKE_COMMAND};-E;env;USED_LAUNCHER=1")
-set(CMAKE_VERBOSE_MAKEFILE TRUE)
-add_executable(main main.cxx)
+include(CXX-common.cmake)
diff --git a/Tests/RunCMake/CompilerLauncher/Fortran-common.cmake b/Tests/RunCMake/CompilerLauncher/Fortran-common.cmake
new file mode 100644
index 0000000..e33c2ca
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/Fortran-common.cmake
@@ -0,0 +1,3 @@
+enable_language(Fortran)
+set(CMAKE_VERBOSE_MAKEFILE TRUE)
+add_executable(main main.F)
diff --git a/Tests/RunCMake/CompilerLauncher/Fortran-env-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/Fortran-env-Build-stdout.txt
new file mode 100644
index 0000000..3313e31
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/Fortran-env-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/CompilerLauncher/Fortran-env-launch-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/Fortran-env-launch-Build-stdout.txt
new file mode 100644
index 0000000..3313e31
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/Fortran-env-launch-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/CompilerLauncher/Fortran-env.cmake b/Tests/RunCMake/CompilerLauncher/Fortran-env.cmake
new file mode 100644
index 0000000..3dc27c3
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/Fortran-env.cmake
@@ -0,0 +1 @@
+include(Fortran-common.cmake)
diff --git a/Tests/RunCMake/CompilerLauncher/Fortran-launch-env.cmake b/Tests/RunCMake/CompilerLauncher/Fortran-launch-env.cmake
new file mode 100644
index 0000000..30a196c
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/Fortran-launch-env.cmake
@@ -0,0 +1,3 @@
+set(CTEST_USE_LAUNCHERS 1)
+include(CTestUseLaunchers)
+include(Fortran-env.cmake)
diff --git a/Tests/RunCMake/CompilerLauncher/Fortran.cmake b/Tests/RunCMake/CompilerLauncher/Fortran.cmake
index 72cc03e..dc46173 100644
--- a/Tests/RunCMake/CompilerLauncher/Fortran.cmake
+++ b/Tests/RunCMake/CompilerLauncher/Fortran.cmake
@@ -1,4 +1,2 @@
-enable_language(Fortran)
set(CMAKE_Fortran_COMPILER_LAUNCHER "${CMAKE_COMMAND};-E;env;USED_LAUNCHER=1")
-set(CMAKE_VERBOSE_MAKEFILE TRUE)
-add_executable(main main.F)
+include(Fortran-common.cmake)
diff --git a/Tests/RunCMake/CompilerLauncher/OBJC-common.cmake b/Tests/RunCMake/CompilerLauncher/OBJC-common.cmake
new file mode 100644
index 0000000..7b565f4
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/OBJC-common.cmake
@@ -0,0 +1,3 @@
+enable_language(OBJC)
+set(CMAKE_VERBOSE_MAKEFILE TRUE)
+add_executable(main main.m)
diff --git a/Tests/RunCMake/CompilerLauncher/OBJC-env-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/OBJC-env-Build-stdout.txt
new file mode 100644
index 0000000..3313e31
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/OBJC-env-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/CompilerLauncher/OBJC-env-launch-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/OBJC-env-launch-Build-stdout.txt
new file mode 100644
index 0000000..3313e31
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/OBJC-env-launch-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/CompilerLauncher/OBJC-env.cmake b/Tests/RunCMake/CompilerLauncher/OBJC-env.cmake
new file mode 100644
index 0000000..949e88d
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/OBJC-env.cmake
@@ -0,0 +1 @@
+include(OBJC-common.cmake)
diff --git a/Tests/RunCMake/CompilerLauncher/OBJC-launch-env.cmake b/Tests/RunCMake/CompilerLauncher/OBJC-launch-env.cmake
new file mode 100644
index 0000000..1cf13d3
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/OBJC-launch-env.cmake
@@ -0,0 +1,3 @@
+set(CTEST_USE_LAUNCHERS 1)
+include(CTestUseLaunchers)
+include(OBJC-env.cmake)
diff --git a/Tests/RunCMake/CompilerLauncher/OBJC.cmake b/Tests/RunCMake/CompilerLauncher/OBJC.cmake
index 55c4493..3374e82 100644
--- a/Tests/RunCMake/CompilerLauncher/OBJC.cmake
+++ b/Tests/RunCMake/CompilerLauncher/OBJC.cmake
@@ -1,4 +1,2 @@
-enable_language(OBJC)
set(CMAKE_OBJC_COMPILER_LAUNCHER "${CMAKE_COMMAND};-E;env;USED_LAUNCHER=1")
-set(CMAKE_VERBOSE_MAKEFILE TRUE)
-add_executable(main main.m)
+include(OBJC-common.cmake)
diff --git a/Tests/RunCMake/CompilerLauncher/OBJCXX-common.cmake b/Tests/RunCMake/CompilerLauncher/OBJCXX-common.cmake
new file mode 100644
index 0000000..e2ee4eb
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/OBJCXX-common.cmake
@@ -0,0 +1,3 @@
+enable_language(OBJCXX)
+set(CMAKE_VERBOSE_MAKEFILE TRUE)
+add_executable(main main.mm)
diff --git a/Tests/RunCMake/CompilerLauncher/OBJCXX-env-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/OBJCXX-env-Build-stdout.txt
new file mode 100644
index 0000000..3313e31
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/OBJCXX-env-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/CompilerLauncher/OBJCXX-env-launch-Build-stdout.txt b/Tests/RunCMake/CompilerLauncher/OBJCXX-env-launch-Build-stdout.txt
new file mode 100644
index 0000000..3313e31
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/OBJCXX-env-launch-Build-stdout.txt
@@ -0,0 +1 @@
+.*-E env USED_LAUNCHER=1.*
diff --git a/Tests/RunCMake/CompilerLauncher/OBJCXX-env.cmake b/Tests/RunCMake/CompilerLauncher/OBJCXX-env.cmake
new file mode 100644
index 0000000..3ed966d
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/OBJCXX-env.cmake
@@ -0,0 +1 @@
+include(OBJCXX-common.cmake)
diff --git a/Tests/RunCMake/CompilerLauncher/OBJCXX-launch-env.cmake b/Tests/RunCMake/CompilerLauncher/OBJCXX-launch-env.cmake
new file mode 100644
index 0000000..04c916a
--- /dev/null
+++ b/Tests/RunCMake/CompilerLauncher/OBJCXX-launch-env.cmake
@@ -0,0 +1,3 @@
+set(CTEST_USE_LAUNCHERS 1)
+include(CTestUseLaunchers)
+include(OBJCXX-env.cmake)
diff --git a/Tests/RunCMake/CompilerLauncher/OBJCXX.cmake b/Tests/RunCMake/CompilerLauncher/OBJCXX.cmake
index e629603..993ec90 100644
--- a/Tests/RunCMake/CompilerLauncher/OBJCXX.cmake
+++ b/Tests/RunCMake/CompilerLauncher/OBJCXX.cmake
@@ -1,4 +1,2 @@
-enable_language(OBJCXX)
set(CMAKE_OBJCXX_COMPILER_LAUNCHER "${CMAKE_COMMAND};-E;env;USED_LAUNCHER=1")
-set(CMAKE_VERBOSE_MAKEFILE TRUE)
-add_executable(main main.mm)
+include(OBJCXX-common.cmake)
diff --git a/Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake b/Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake
index 4420260..69fff20 100644
--- a/Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake
@@ -9,12 +9,19 @@ function(run_compiler_launcher lang)
run_cmake(${lang})
set(RunCMake_TEST_OUTPUT_MERGE 1)
- if("${RunCMake_GENERATOR}" STREQUAL "Ninja")
+ if("${RunCMake_GENERATOR}" MATCHES "Ninja")
set(verbose_args -- -v)
endif()
run_cmake_command(${lang}-Build ${CMAKE_COMMAND} --build . ${verbose_args})
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")
+ run_compiler_launcher(${lang})
+ unset(ENV{CMAKE_${core_lang}_COMPILER_LAUNCHER})
+endfunction()
+
set(langs C CXX)
if(CMake_TEST_CUDA)
list(APPEND langs CUDA)
@@ -28,7 +35,9 @@ endif()
foreach(lang ${langs})
run_compiler_launcher(${lang})
+ run_compiler_launcher_env(${lang}-env)
if (NOT RunCMake_GENERATOR STREQUAL "Watcom WMake")
run_compiler_launcher(${lang}-launch)
+ run_compiler_launcher_env(${lang}-launch-env)
endif()
endforeach()
diff --git a/Tests/RunCMake/Configure/NoCMAKE_CROSS_CONFIGS-result.txt b/Tests/RunCMake/Configure/NoCMAKE_CROSS_CONFIGS-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Configure/NoCMAKE_CROSS_CONFIGS-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Configure/NoCMAKE_CROSS_CONFIGS-stderr.txt b/Tests/RunCMake/Configure/NoCMAKE_CROSS_CONFIGS-stderr.txt
new file mode 100644
index 0000000..a5d149d
--- /dev/null
+++ b/Tests/RunCMake/Configure/NoCMAKE_CROSS_CONFIGS-stderr.txt
@@ -0,0 +1,11 @@
+^CMake Error:
+ Generator
+
+ [^
+]*
+
+ does not support variable
+
+ CMAKE_CROSS_CONFIGS
+
+ but it has been specified.
diff --git a/Tests/RunCMake/Configure/NoCMAKE_CROSS_CONFIGS.cmake b/Tests/RunCMake/Configure/NoCMAKE_CROSS_CONFIGS.cmake
new file mode 100644
index 0000000..75d0c47
--- /dev/null
+++ b/Tests/RunCMake/Configure/NoCMAKE_CROSS_CONFIGS.cmake
@@ -0,0 +1 @@
+set(CMAKE_CROSS_CONFIGS "")
diff --git a/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_BUILD_TYPE-result.txt b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_BUILD_TYPE-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_BUILD_TYPE-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_BUILD_TYPE-stderr.txt b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_BUILD_TYPE-stderr.txt
new file mode 100644
index 0000000..8aa3ed3
--- /dev/null
+++ b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_BUILD_TYPE-stderr.txt
@@ -0,0 +1,11 @@
+^CMake Error:
+ Generator
+
+ [^
+]*
+
+ does not support variable
+
+ CMAKE_DEFAULT_BUILD_TYPE
+
+ but it has been specified.
diff --git a/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_BUILD_TYPE.cmake b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_BUILD_TYPE.cmake
new file mode 100644
index 0000000..64c7feb
--- /dev/null
+++ b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_BUILD_TYPE.cmake
@@ -0,0 +1 @@
+set(CMAKE_DEFAULT_BUILD_TYPE "")
diff --git a/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS-result.txt b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS-stderr.txt b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS-stderr.txt
new file mode 100644
index 0000000..040bf4d
--- /dev/null
+++ b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS-stderr.txt
@@ -0,0 +1,11 @@
+^CMake Error:
+ Generator
+
+ [^
+]*
+
+ does not support variable
+
+ CMAKE_DEFAULT_CONFIGS
+
+ but it has been specified.
diff --git a/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS.cmake b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS.cmake
new file mode 100644
index 0000000..5b65172
--- /dev/null
+++ b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS.cmake
@@ -0,0 +1 @@
+set(CMAKE_DEFAULT_CONFIGS "")
diff --git a/Tests/RunCMake/Configure/RunCMakeTest.cmake b/Tests/RunCMake/Configure/RunCMakeTest.cmake
index 76d843c..9fd4499 100644
--- a/Tests/RunCMake/Configure/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Configure/RunCMakeTest.cmake
@@ -50,3 +50,9 @@ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
run_cmake(RemoveCache)
file(REMOVE "${RunCMake_TEST_BINARY_DIR}/CMakeCache.txt")
run_cmake(RemoveCache)
+
+if(NOT RunCMake_GENERATOR MATCHES "^Ninja Multi-Config$")
+ run_cmake(NoCMAKE_CROSS_CONFIGS)
+ run_cmake(NoCMAKE_DEFAULT_BUILD_TYPE)
+ run_cmake(NoCMAKE_DEFAULT_CONFIGS)
+endif()
diff --git a/Tests/RunCMake/ExportCompileCommands/BeforeProject-check.cmake b/Tests/RunCMake/ExportCompileCommands/BeforeProject-check.cmake
new file mode 100644
index 0000000..87058e2
--- /dev/null
+++ b/Tests/RunCMake/ExportCompileCommands/BeforeProject-check.cmake
@@ -0,0 +1,4 @@
+if(NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/compile_commands.json")
+ set(RunCMake_TEST_FAILED "compile_commands.json not generated")
+ return()
+endif()
diff --git a/Tests/RunCMake/ExportCompileCommands/BeforeProject.cmake b/Tests/RunCMake/ExportCompileCommands/BeforeProject.cmake
new file mode 100644
index 0000000..b8cbdef
--- /dev/null
+++ b/Tests/RunCMake/ExportCompileCommands/BeforeProject.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+add_library(empty STATIC empty.c)
+message(STATUS "CMAKE_EXPORT_COMPILE_COMMANDS='${CMAKE_EXPORT_COMPILE_COMMANDS}'")
diff --git a/Tests/RunCMake/ExportCompileCommands/BeforeProjectBEFORE.cmake b/Tests/RunCMake/ExportCompileCommands/BeforeProjectBEFORE.cmake
new file mode 100644
index 0000000..87f9c87
--- /dev/null
+++ b/Tests/RunCMake/ExportCompileCommands/BeforeProjectBEFORE.cmake
@@ -0,0 +1 @@
+set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
diff --git a/Tests/RunCMake/ExportCompileCommands/CMakeLists.txt b/Tests/RunCMake/ExportCompileCommands/CMakeLists.txt
new file mode 100644
index 0000000..b7117bd
--- /dev/null
+++ b/Tests/RunCMake/ExportCompileCommands/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.17)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/ExportCompileCommands/RunCMakeTest.cmake b/Tests/RunCMake/ExportCompileCommands/RunCMakeTest.cmake
new file mode 100644
index 0000000..b540a04
--- /dev/null
+++ b/Tests/RunCMake/ExportCompileCommands/RunCMakeTest.cmake
@@ -0,0 +1,3 @@
+include(RunCMake)
+
+run_cmake_with_options(BeforeProject -DCMAKE_PROJECT_INCLUDE_BEFORE=BeforeProjectBEFORE.cmake)
diff --git a/Tests/RunCMake/ExportCompileCommands/empty.c b/Tests/RunCMake/ExportCompileCommands/empty.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/ExportCompileCommands/empty.c
diff --git a/Tests/RunCMake/ExternalProject/Add_StepDependencies_iface_step-stderr.txt b/Tests/RunCMake/ExternalProject/Add_StepDependencies_iface_step-stderr.txt
index 22e13bf..5fa75e8 100644
--- a/Tests/RunCMake/ExternalProject/Add_StepDependencies_iface_step-stderr.txt
+++ b/Tests/RunCMake/ExternalProject/Add_StepDependencies_iface_step-stderr.txt
@@ -1,5 +1,5 @@
^CMake Error at .*/Modules/ExternalProject.cmake:[0-9]+ \(message\):
- Target "MyProj-IFace" was not generated by ExternalProject_Add_StepTargets.
+ External project "MyProj" does not have a step "IFace".
Call Stack \(most recent call first\):
Add_StepDependencies_iface_step.cmake:[0-9]+ \(ExternalProject_Add_StepDependencies\)
CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/FPHSA/FindNameMismatch.cmake b/Tests/RunCMake/FPHSA/FindNameMismatch.cmake
new file mode 100644
index 0000000..540aa67
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/FindNameMismatch.cmake
@@ -0,0 +1,4 @@
+set("${CMAKE_FIND_PACKAGE_NAME}_MODULE" "${CMAKE_CURRENT_LIST_FILE}")
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(NAMEMISMATCH REQUIRED_VARS "${CMAKE_FIND_PACKAGE_NAME}_MODULE")
+set("${CMAKE_FIND_PACKAGE_NAME}_FOUND" 1)
diff --git a/Tests/RunCMake/FPHSA/FindNameMismatchOld.cmake b/Tests/RunCMake/FPHSA/FindNameMismatchOld.cmake
new file mode 100644
index 0000000..d155ea7
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/FindNameMismatchOld.cmake
@@ -0,0 +1,4 @@
+set("${CMAKE_FIND_PACKAGE_NAME}_MODULE" "${CMAKE_CURRENT_LIST_FILE}")
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(NAMEMISMATCH "old signature" "${CMAKE_FIND_PACKAGE_NAME}_MODULE")
+set("${CMAKE_FIND_PACKAGE_NAME}_FOUND" 1)
diff --git a/Tests/RunCMake/FPHSA/FindNameMismatchSuppressed.cmake b/Tests/RunCMake/FPHSA/FindNameMismatchSuppressed.cmake
new file mode 100644
index 0000000..042a59a
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/FindNameMismatchSuppressed.cmake
@@ -0,0 +1,6 @@
+set("${CMAKE_FIND_PACKAGE_NAME}_MODULE" "${CMAKE_CURRENT_LIST_FILE}")
+include(FindPackageHandleStandardArgs)
+set(FPHSA_NAME_MISMATCHED 1)
+find_package_handle_standard_args(NAMEMISMATCH "old signature" "${CMAKE_FIND_PACKAGE_NAME}_MODULE")
+unset(FPHSA_NAME_MISMATCHED)
+set("${CMAKE_FIND_PACKAGE_NAME}_FOUND" 1)
diff --git a/Tests/RunCMake/FPHSA/FindNameMismatchSuppressedArg.cmake b/Tests/RunCMake/FPHSA/FindNameMismatchSuppressedArg.cmake
new file mode 100644
index 0000000..6a0e964
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/FindNameMismatchSuppressedArg.cmake
@@ -0,0 +1,4 @@
+set("${CMAKE_FIND_PACKAGE_NAME}_MODULE" "${CMAKE_CURRENT_LIST_FILE}")
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(NAMEMISMATCH NAME_MISMATCHED REQUIRED_VARS "${CMAKE_FIND_PACKAGE_NAME}_MODULE")
+set("${CMAKE_FIND_PACKAGE_NAME}_FOUND" 1)
diff --git a/Tests/RunCMake/FPHSA/FindNameMismatchSuppressedCompat.cmake b/Tests/RunCMake/FPHSA/FindNameMismatchSuppressedCompat.cmake
new file mode 100644
index 0000000..791cfee
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/FindNameMismatchSuppressedCompat.cmake
@@ -0,0 +1,6 @@
+set("${CMAKE_FIND_PACKAGE_NAME}_MODULE" "${CMAKE_CURRENT_LIST_FILE}")
+include(FindPackageHandleStandardArgs)
+set(FPHSA_NAME_MISMATCHED 1)
+find_package_handle_standard_args(NAMEMISMATCH REQUIRED_VARS "${CMAKE_FIND_PACKAGE_NAME}_MODULE")
+unset(FPHSA_NAME_MISMATCHED)
+set("${CMAKE_FIND_PACKAGE_NAME}_FOUND" 1)
diff --git a/Tests/RunCMake/FPHSA/FindUseComponents.cmake b/Tests/RunCMake/FPHSA/FindUseComponents.cmake
new file mode 100644
index 0000000..4168f1d
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/FindUseComponents.cmake
@@ -0,0 +1,15 @@
+# pseudo find_module
+
+if (UseComponents_REQUIRE_VARS)
+ set(FOOBAR TRUE)
+ set(REQUIRED_VARS REQUIRED_VARS FOOBAR)
+endif()
+
+set (UseComponents_Comp1_FOUND TRUE)
+set (UseComponents_Comp2_FOUND TRUE)
+set (UseComponents_Comp3_FOUND FALSE)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(UseComponents ${REQUIRED_VARS}
+ VERSION_VAR Pseudo_VERSION
+ HANDLE_COMPONENTS)
diff --git a/Tests/RunCMake/FPHSA/NameMismatch-stderr.txt b/Tests/RunCMake/FPHSA/NameMismatch-stderr.txt
new file mode 100644
index 0000000..722b50b
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/NameMismatch-stderr.txt
@@ -0,0 +1,23 @@
+CMake Warning \(dev\) at .*/Modules/FindPackageHandleStandardArgs.cmake:[0-9]+ \(message\):
+ The package name passed to `find_package_handle_standard_args`
+ \(NAMEMISMATCH\) does not match the name of the calling package
+ \(NameMismatch\). This can lead to problems in calling code that expects
+ `find_package` result variables \(e.g., `_FOUND`\) to follow a certain
+ pattern.
+Call Stack \(most recent call first\):
+ FindNameMismatch.cmake:3 \(find_package_handle_standard_args\)
+ NameMismatch.cmake:3 \(find_package\)
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\) at .*/Modules/FindPackageHandleStandardArgs.cmake:[0-9]+ \(message\):
+ The package name passed to `find_package_handle_standard_args`
+ \(NAMEMISMATCH\) does not match the name of the calling package
+ \(NameMismatchOld\). This can lead to problems in calling code that expects
+ `find_package` result variables \(e.g., `_FOUND`\) to follow a certain
+ pattern.
+Call Stack \(most recent call first\):
+ FindNameMismatchOld.cmake:3 \(find_package_handle_standard_args\)
+ NameMismatch.cmake:4 \(find_package\)
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/FPHSA/NameMismatch.cmake b/Tests/RunCMake/FPHSA/NameMismatch.cmake
new file mode 100644
index 0000000..9ca3cc6
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/NameMismatch.cmake
@@ -0,0 +1,7 @@
+set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}")
+
+find_package(NameMismatch REQUIRED)
+find_package(NameMismatchOld REQUIRED)
+find_package(NameMismatchSuppressed REQUIRED)
+find_package(NameMismatchSuppressedCompat REQUIRED)
+find_package(NameMismatchSuppressedArg REQUIRED)
diff --git a/Tests/RunCMake/FPHSA/RunCMakeTest.cmake b/Tests/RunCMake/FPHSA/RunCMakeTest.cmake
index f3e6c3e..8e39090 100644
--- a/Tests/RunCMake/FPHSA/RunCMakeTest.cmake
+++ b/Tests/RunCMake/FPHSA/RunCMakeTest.cmake
@@ -1,6 +1,7 @@
include(RunCMake)
run_cmake(BadFoundVar)
+run_cmake(NameMismatch)
# The pseudo module will "find" a package with the given version. Check if the
# version selection code in FPHSA works correctly.
@@ -46,3 +47,11 @@ run_cmake(custom_message_1)
set(RunCMake_TEST_OPTIONS "-DCMAKE_MODULE_PATH=${CMAKE_CURRENT_LIST_DIR}" "-DCONFIG_MODE=TRUE")
run_cmake(custom_message_2)
run_cmake(custom_message_3)
+
+# check handling of components
+set(RunCMake_TEST_OPTIONS "-DCMAKE_MODULE_PATH=${CMAKE_CURRENT_LIST_DIR}" "-DUseComponents_VERSION=1.2.3.4")
+run_cmake(required_components)
+run_cmake(required_and_optional_components)
+run_cmake(all_optional_components)
+list(APPEND RunCMake_TEST_OPTIONS "-DUseComponents_REQUIRE_VARS=TRUE")
+run_cmake(required_components_with_vars)
diff --git a/Tests/RunCMake/FPHSA/all_optional_components.cmake b/Tests/RunCMake/FPHSA/all_optional_components.cmake
new file mode 100644
index 0000000..f4d8b5e
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/all_optional_components.cmake
@@ -0,0 +1,14 @@
+find_package(UseComponents OPTIONAL_COMPONENTS Comp1 Comp2 Comp3)
+
+if (NOT UseComponents_FOUND)
+ message (FATAL_ERROR "package UseComponents Not Found.")
+endif()
+if (NOT UseComponents_Comp1_FOUND)
+ message (FATAL_ERROR "package UseComponents, component Comp1 not found.")
+endif()
+if (NOT UseComponents_Comp2_FOUND)
+ message (FATAL_ERROR "package UseComponents, component Comp2 not found.")
+endif()
+if (UseComponents_Comp3_FOUND)
+ message (FATAL_ERROR "package UseComponents, component Comp2 unexpectedly found.")
+endif()
diff --git a/Tests/RunCMake/FPHSA/required_and_optional_components.cmake b/Tests/RunCMake/FPHSA/required_and_optional_components.cmake
new file mode 100644
index 0000000..836dcac
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/required_and_optional_components.cmake
@@ -0,0 +1,14 @@
+find_package(UseComponents COMPONENTS Comp1 Comp2 OPTIONAL_COMPONENTS Comp3)
+
+if (NOT UseComponents_FOUND)
+ message (FATAL_ERROR "package UseComponents Not Found.")
+endif()
+if (NOT UseComponents_Comp1_FOUND)
+ message (FATAL_ERROR "package UseComponents, component Comp1 not found.")
+endif()
+if (NOT UseComponents_Comp2_FOUND)
+ message (FATAL_ERROR "package UseComponents, component Comp2 not found.")
+endif()
+if (UseComponents_Comp3_FOUND)
+ message (FATAL_ERROR "package UseComponents, component Comp2 unexpectedly found.")
+endif()
diff --git a/Tests/RunCMake/FPHSA/required_components.cmake b/Tests/RunCMake/FPHSA/required_components.cmake
new file mode 100644
index 0000000..0dd8e9c
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/required_components.cmake
@@ -0,0 +1,11 @@
+find_package(UseComponents COMPONENTS Comp1 Comp2)
+
+if (NOT UseComponents_FOUND)
+ message (FATAL_ERROR "package UseComponents Not Found.")
+endif()
+if (NOT UseComponents_Comp1_FOUND)
+ message (FATAL_ERROR "package UseComponents, component Comp1 Not Found.")
+endif()
+if (NOT UseComponents_Comp2_FOUND)
+ message (FATAL_ERROR "package UseComponents, component Comp2 Not Found.")
+endif()
diff --git a/Tests/RunCMake/FPHSA/required_components_with_vars.cmake b/Tests/RunCMake/FPHSA/required_components_with_vars.cmake
new file mode 100644
index 0000000..842ef15
--- /dev/null
+++ b/Tests/RunCMake/FPHSA/required_components_with_vars.cmake
@@ -0,0 +1 @@
+include ("required_components.cmake")
diff --git a/Tests/RunCMake/FetchContent/DownloadFile.cmake b/Tests/RunCMake/FetchContent/DownloadFile.cmake
new file mode 100644
index 0000000..741b6d3
--- /dev/null
+++ b/Tests/RunCMake/FetchContent/DownloadFile.cmake
@@ -0,0 +1,9 @@
+include(FetchContent)
+
+FetchContent_Declare(
+ t1
+ URL ${CMAKE_CURRENT_LIST_DIR}/dummyFile.txt
+ DOWNLOAD_NO_EXTRACT YES
+)
+
+FetchContent_Populate(t1)
diff --git a/Tests/RunCMake/FetchContent/RunCMakeTest.cmake b/Tests/RunCMake/FetchContent/RunCMakeTest.cmake
index e28ae96..5e2e5e1 100644
--- a/Tests/RunCMake/FetchContent/RunCMakeTest.cmake
+++ b/Tests/RunCMake/FetchContent/RunCMakeTest.cmake
@@ -6,6 +6,7 @@ run_cmake(MissingDetails)
run_cmake(DirectIgnoresDetails)
run_cmake(FirstDetailsWin)
run_cmake(DownloadTwice)
+run_cmake(DownloadFile)
run_cmake(SameGenerator)
run_cmake(VarDefinitions)
run_cmake(GetProperties)
diff --git a/Tests/RunCMake/FetchContent/dummyFile.txt b/Tests/RunCMake/FetchContent/dummyFile.txt
new file mode 100644
index 0000000..0a12ce1
--- /dev/null
+++ b/Tests/RunCMake/FetchContent/dummyFile.txt
@@ -0,0 +1 @@
+# This file is used to verify fetching a single file directly
diff --git a/Tests/RunCMake/FileAPI/RunCMakeTest.cmake b/Tests/RunCMake/FileAPI/RunCMakeTest.cmake
index f8adb64..8cdc00c 100644
--- a/Tests/RunCMake/FileAPI/RunCMakeTest.cmake
+++ b/Tests/RunCMake/FileAPI/RunCMakeTest.cmake
@@ -34,6 +34,10 @@ function(check_python case)
endif()
endfunction()
+if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+ set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release\\;MinSizeRel\\;RelWithDebInfo")
+endif()
+
run_cmake(Nothing)
run_cmake(Empty)
run_cmake(EmptyClient)
diff --git a/Tests/RunCMake/FileAPI/check_index.py b/Tests/RunCMake/FileAPI/check_index.py
index cda7234..20243c0 100644
--- a/Tests/RunCMake/FileAPI/check_index.py
+++ b/Tests/RunCMake/FileAPI/check_index.py
@@ -109,10 +109,11 @@ def check_cmake_generator(g):
name = g.get("name", None)
assert is_string(name)
if name.startswith("Visual Studio"):
- assert sorted(g.keys()) == ["name", "platform"]
+ assert sorted(g.keys()) == ["multiConfig", "name", "platform"]
assert is_string(g["platform"])
else:
- assert sorted(g.keys()) == ["name"]
+ assert sorted(g.keys()) == ["multiConfig", "name"]
+ assert is_bool(g["multiConfig"], matches(name, "^(Visual Studio |Xcode$|Ninja Multi-Config$)"))
def check_index_object(indexEntry, kind, major, minor, check):
assert is_dict(indexEntry)
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-check.py b/Tests/RunCMake/FileAPI/codemodel-v2-check.py
index 66c559d..9ee0c20 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-check.py
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-check.py
@@ -1,8 +1,14 @@
from check_index import *
+import json
import sys
import os
+def read_codemodel_json_data(filename):
+ abs_filename = os.path.join(os.path.dirname(os.path.realpath(__file__)), "codemodel-v2-data", filename)
+ with open(abs_filename, "r") as f:
+ return json.load(f)
+
def check_objects(o, g):
assert is_list(o)
assert len(o) == 1
@@ -471,162 +477,23 @@ def check_project(c):
def gen_check_directories(c, g):
expected = [
- {
- "source": "^\\.$",
- "build": "^\\.$",
- "parentSource": None,
- "childSources": [
- "^alias$",
- "^custom$",
- "^cxx$",
- "^imported$",
- "^object$",
- "^.*/Tests/RunCMake/FileAPIExternalSource$",
- "^dir$",
- ],
- "targetIds": [
- "^ALL_BUILD::@6890427a1f51a3e7e1df$",
- "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
- "^c_exe::@6890427a1f51a3e7e1df$",
- "^c_lib::@6890427a1f51a3e7e1df$",
- "^c_shared_exe::@6890427a1f51a3e7e1df$",
- "^c_shared_lib::@6890427a1f51a3e7e1df$",
- "^c_static_exe::@6890427a1f51a3e7e1df$",
- "^c_static_lib::@6890427a1f51a3e7e1df$",
- "^interface_exe::@6890427a1f51a3e7e1df$",
- ],
- "projectName": "codemodel-v2",
- "minimumCMakeVersion": "3.12",
- "hasInstallRule": True,
- },
- {
- "source": "^alias$",
- "build": "^alias$",
- "parentSource": "^\\.$",
- "childSources": None,
- "targetIds": [
- "^ALL_BUILD::@53632cba2752272bb008$",
- "^ZERO_CHECK::@53632cba2752272bb008$",
- "^c_alias_exe::@53632cba2752272bb008$",
- "^cxx_alias_exe::@53632cba2752272bb008$",
- ],
- "projectName": "Alias",
- "minimumCMakeVersion": "3.12",
- "hasInstallRule": None,
- },
- {
- "source": "^custom$",
- "build": "^custom$",
- "parentSource": "^\\.$",
- "childSources": None,
- "targetIds": [
- "^ALL_BUILD::@c11385ffed57b860da63$",
- "^ZERO_CHECK::@c11385ffed57b860da63$",
- "^custom_exe::@c11385ffed57b860da63$",
- "^custom_tgt::@c11385ffed57b860da63$",
- ],
- "projectName": "Custom",
- "minimumCMakeVersion": "3.12",
- "hasInstallRule": None,
- },
- {
- "source": "^cxx$",
- "build": "^cxx$",
- "parentSource": "^\\.$",
- "childSources": None,
- "targetIds": [
- "^ALL_BUILD::@a56b12a3f5c0529fb296$",
- "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
- "^cxx_exe::@a56b12a3f5c0529fb296$",
- "^cxx_lib::@a56b12a3f5c0529fb296$",
- "^cxx_shared_exe::@a56b12a3f5c0529fb296$",
- "^cxx_shared_lib::@a56b12a3f5c0529fb296$",
- "^cxx_static_exe::@a56b12a3f5c0529fb296$",
- "^cxx_static_lib::@a56b12a3f5c0529fb296$",
- ],
- "projectName": "Cxx",
- "minimumCMakeVersion": "3.12",
- "hasInstallRule": None,
- },
- {
- "source": "^imported$",
- "build": "^imported$",
- "parentSource": "^\\.$",
- "childSources": None,
- "targetIds": [
- "^ALL_BUILD::@ba7eb709d0b48779c6c8$",
- "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
- "^link_imported_exe::@ba7eb709d0b48779c6c8$",
- "^link_imported_interface_exe::@ba7eb709d0b48779c6c8$",
- "^link_imported_object_exe::@ba7eb709d0b48779c6c8$",
- "^link_imported_shared_exe::@ba7eb709d0b48779c6c8$",
- "^link_imported_static_exe::@ba7eb709d0b48779c6c8$",
- ],
- "projectName": "Imported",
- "minimumCMakeVersion": "3.12",
- "hasInstallRule": None,
- },
- {
- "source": "^object$",
- "build": "^object$",
- "parentSource": "^\\.$",
- "childSources": None,
- "targetIds": [
- "^ALL_BUILD::@5ed5358f70faf8d8af7a$",
- "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
- "^c_object_exe::@5ed5358f70faf8d8af7a$",
- "^c_object_lib::@5ed5358f70faf8d8af7a$",
- "^cxx_object_exe::@5ed5358f70faf8d8af7a$",
- "^cxx_object_lib::@5ed5358f70faf8d8af7a$",
- ],
- "projectName": "Object",
- "minimumCMakeVersion": "3.13",
- "hasInstallRule": True,
- },
- {
- "source": "^dir$",
- "build": "^dir$",
- "parentSource": "^\\.$",
- "childSources": [
- "^dir/dir$",
- ],
- "targetIds": None,
- "projectName": "codemodel-v2",
- "minimumCMakeVersion": "3.12",
- "hasInstallRule": None,
- },
- {
- "source": "^dir/dir$",
- "build": "^dir/dir$",
- "parentSource": "^dir$",
- "childSources": None,
- "targetIds": None,
- "projectName": "codemodel-v2",
- "minimumCMakeVersion": "3.12",
- "hasInstallRule": None,
- },
- {
- "source": "^.*/Tests/RunCMake/FileAPIExternalSource$",
- "build": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild$",
- "parentSource": "^\\.$",
- "childSources": None,
- "targetIds": [
- "^ALL_BUILD::@[0-9a-f]+$",
- "^ZERO_CHECK::@[0-9a-f]+$",
- "^generated_exe::@[0-9a-f]+$",
- ],
- "projectName": "External",
- "minimumCMakeVersion": "3.12",
- "hasInstallRule": None,
- },
+ read_codemodel_json_data("directories/top.json"),
+ read_codemodel_json_data("directories/alias.json"),
+ read_codemodel_json_data("directories/custom.json"),
+ read_codemodel_json_data("directories/cxx.json"),
+ read_codemodel_json_data("directories/imported.json"),
+ read_codemodel_json_data("directories/object.json"),
+ read_codemodel_json_data("directories/dir.json"),
+ read_codemodel_json_data("directories/dir_dir.json"),
+ read_codemodel_json_data("directories/external.json"),
]
- if matches(g, "^Visual Studio "):
+ if matches(g["name"], "^Visual Studio "):
for e in expected:
if e["parentSource"] is not None:
e["targetIds"] = filter_list(lambda t: not matches(t, "^\\^ZERO_CHECK"), e["targetIds"])
- elif g == "Xcode":
+ elif g["name"] == "Xcode":
if ';' in os.environ.get("CMAKE_OSX_ARCHITECTURES", ""):
for e in expected:
e["targetIds"] = filter_list(lambda t: not matches(t, "^\\^(link_imported_object_exe)"), e["targetIds"])
@@ -646,4428 +513,52 @@ def check_directories(c, g):
def gen_check_targets(c, g, inSource):
expected = [
- {
- "name": "ALL_BUILD",
- "id": "^ALL_BUILD::@6890427a1f51a3e7e1df$",
- "directorySource": "^\\.$",
- "projectName": "codemodel-v2",
- "type": "UTILITY",
- "isGeneratorProvided": True,
- "sources": [
- {
- "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ALL_BUILD$",
- "isGenerated": True,
- "sourceGroupName": "",
- "compileGroupLanguage": None,
- "backtrace": [
- {
- "file": "^CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ALL_BUILD\\.rule$",
- "isGenerated": True,
- "sourceGroupName": "CMake Rules",
- "compileGroupLanguage": None,
- "backtrace": [
- {
- "file": "^CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ALL_BUILD$",
- ],
- },
- {
- "name": "CMake Rules",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ALL_BUILD\\.rule$",
- ],
- },
- ],
- "compileGroups": None,
- "backtrace": [
- {
- "file": "^CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": None,
- "artifacts": None,
- "build": "^\\.$",
- "source": "^\\.$",
- "install": None,
- "link": None,
- "archive": None,
- "dependencies": [
- {
- "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
- "backtrace": None,
- },
- {
- "id": "^interface_exe::@6890427a1f51a3e7e1df$",
- "backtrace": None,
- },
- {
- "id": "^c_lib::@6890427a1f51a3e7e1df$",
- "backtrace": None,
- },
- {
- "id": "^c_exe::@6890427a1f51a3e7e1df$",
- "backtrace": None,
- },
- {
- "id": "^c_shared_lib::@6890427a1f51a3e7e1df$",
- "backtrace": None,
- },
- {
- "id": "^c_shared_exe::@6890427a1f51a3e7e1df$",
- "backtrace": None,
- },
- {
- "id": "^c_static_lib::@6890427a1f51a3e7e1df$",
- "backtrace": None,
- },
- {
- "id": "^c_static_exe::@6890427a1f51a3e7e1df$",
- "backtrace": None,
- },
- {
- "id": "^c_alias_exe::@53632cba2752272bb008$",
- "backtrace": None,
- },
- {
- "id": "^cxx_alias_exe::@53632cba2752272bb008$",
- "backtrace": None,
- },
- {
- "id": "^cxx_lib::@a56b12a3f5c0529fb296$",
- "backtrace": None,
- },
- {
- "id": "^cxx_exe::@a56b12a3f5c0529fb296$",
- "backtrace": None,
- },
- {
- "id": "^cxx_shared_lib::@a56b12a3f5c0529fb296$",
- "backtrace": None,
- },
- {
- "id": "^cxx_shared_exe::@a56b12a3f5c0529fb296$",
- "backtrace": None,
- },
- {
- "id": "^cxx_static_lib::@a56b12a3f5c0529fb296$",
- "backtrace": None,
- },
- {
- "id": "^cxx_static_exe::@a56b12a3f5c0529fb296$",
- "backtrace": None,
- },
- {
- "id": "^c_object_lib::@5ed5358f70faf8d8af7a$",
- "backtrace": None,
- },
- {
- "id": "^c_object_exe::@5ed5358f70faf8d8af7a$",
- "backtrace": None,
- },
- {
- "id": "^cxx_object_lib::@5ed5358f70faf8d8af7a$",
- "backtrace": None,
- },
- {
- "id": "^cxx_object_exe::@5ed5358f70faf8d8af7a$",
- "backtrace": None,
- },
- {
- "id": "^link_imported_exe::@ba7eb709d0b48779c6c8$",
- "backtrace": None,
- },
- {
- "id": "^link_imported_shared_exe::@ba7eb709d0b48779c6c8$",
- "backtrace": None,
- },
- {
- "id": "^link_imported_static_exe::@ba7eb709d0b48779c6c8$",
- "backtrace": None,
- },
- {
- "id": "^link_imported_object_exe::@ba7eb709d0b48779c6c8$",
- "backtrace": None,
- },
- {
- "id": "^link_imported_interface_exe::@ba7eb709d0b48779c6c8$",
- "backtrace": None,
- },
- {
- "id": "^custom_exe::@c11385ffed57b860da63$",
- "backtrace": None,
- },
- {
- "id": "^generated_exe::@[0-9a-f]+$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "ZERO_CHECK",
- "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
- "directorySource": "^\\.$",
- "projectName": "codemodel-v2",
- "type": "UTILITY",
- "isGeneratorProvided": True,
- "sources": [
- {
- "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ZERO_CHECK$",
- "isGenerated": True,
- "sourceGroupName": "",
- "compileGroupLanguage": None,
- "backtrace": [
- {
- "file": "^CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ZERO_CHECK\\.rule$",
- "isGenerated": True,
- "sourceGroupName": "CMake Rules",
- "compileGroupLanguage": None,
- "backtrace": [
- {
- "file": "^CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ZERO_CHECK$",
- ],
- },
- {
- "name": "CMake Rules",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ZERO_CHECK\\.rule$",
- ],
- },
- ],
- "compileGroups": None,
- "backtrace": [
- {
- "file": "^CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": None,
- "artifacts": None,
- "build": "^\\.$",
- "source": "^\\.$",
- "install": None,
- "link": None,
- "archive": None,
- "dependencies": None,
- },
- {
- "name": "interface_exe",
- "id": "^interface_exe::@6890427a1f51a3e7e1df$",
- "directorySource": "^\\.$",
- "projectName": "codemodel-v2",
- "type": "EXECUTABLE",
- "isGeneratorProvided": None,
- "sources": [
- {
- "path": "^empty\\.c$",
- "isGenerated": None,
- "sourceGroupName": "Source Files",
- "compileGroupLanguage": "C",
- "backtrace": [
- {
- "file": "^include_test\\.cmake$",
- "line": 3,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^include_test\\.cmake$",
- "line": None,
- "command": None,
- "hasParent": True,
- },
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": 3,
- "command": "include",
- "hasParent": True,
- },
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": None,
- "command": None,
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": 3,
- "command": "include",
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "Source Files",
- "sourcePaths": [
- "^empty\\.c$",
- ],
- },
- ],
- "compileGroups": [
- {
- "language": "C",
- "sourcePaths": [
- "^empty\\.c$",
- ],
- "includes": None,
- "defines": [
- {
- "define": "interface_exe_EXPORTS",
- "backtrace": None,
- },
- ],
- "compileCommandFragments": None,
- },
- ],
- "backtrace": [
- {
- "file": "^include_test\\.cmake$",
- "line": 3,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^include_test\\.cmake$",
- "line": None,
- "command": None,
- "hasParent": True,
- },
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": 3,
- "command": "include",
- "hasParent": True,
- },
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": None,
- "command": None,
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": 3,
- "command": "include",
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": "^my_interface_exe\\.myexe$",
- "artifacts": [
- {
- "path": "^bin/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?my_interface_exe\\.myexe$",
- "_dllExtra": False,
- },
- {
- "path": "^lib/my_interface_exe\\.imp$",
- "_aixExtra": True,
- "_dllExtra": False,
- },
- {
- "path": "^lib/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib)?my_interface_exe\\.(dll\\.a|lib)$",
- "_dllExtra": True,
- },
- {
- "path": "^bin/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?my_interface_exe\\.pdb$",
- "_dllExtra": True,
- },
- ],
- "build": "^\\.$",
- "source": "^\\.$",
- "install": None,
- "link": {
- "language": "C",
- "lto": None,
- "commandFragments": None,
- },
- "archive": None,
- "dependencies": [
- {
- "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "c_lib",
- "id": "^c_lib::@6890427a1f51a3e7e1df$",
- "directorySource": "^\\.$",
- "projectName": "codemodel-v2",
- "type": "STATIC_LIBRARY",
- "isGeneratorProvided": None,
- "sources": [
- {
- "path": "^empty\\.c$",
- "isGenerated": None,
- "sourceGroupName": "Source Files",
- "compileGroupLanguage": "C",
- "backtrace": [
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": 5,
- "command": "add_library",
- "hasParent": True,
- },
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": None,
- "command": None,
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": 3,
- "command": "include",
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "Source Files",
- "sourcePaths": [
- "^empty\\.c$",
- ],
- },
- ],
- "compileGroups": [
- {
- "language": "C",
- "sourcePaths": [
- "^empty\\.c$",
- ],
- "includes": None,
- "defines": None,
- "compileCommandFragments": None,
- },
- ],
- "backtrace": [
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": 5,
- "command": "add_library",
- "hasParent": True,
- },
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": None,
- "command": None,
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": 3,
- "command": "include",
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": "^(lib)?c_lib\\.(a|lib)$",
- "artifacts": [
- {
- "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib)?c_lib\\.(a|lib)$",
- "_dllExtra": False,
- },
- ],
- "build": "^\\.$",
- "source": "^\\.$",
- "install": None,
- "link": None,
- "archive": {
- "lto": None,
- },
- "dependencies": [
- {
- "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "c_exe",
- "id": "^c_exe::@6890427a1f51a3e7e1df$",
- "directorySource": "^\\.$",
- "projectName": "codemodel-v2",
- "type": "EXECUTABLE",
- "isGeneratorProvided": None,
- "sources": [
- {
- "path": "^empty\\.c$",
- "isGenerated": None,
- "sourceGroupName": "Source Files",
- "compileGroupLanguage": "C",
- "backtrace": [
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": 6,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": None,
- "command": None,
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": 3,
- "command": "include",
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "Source Files",
- "sourcePaths": [
- "^empty\\.c$",
- ],
- },
- ],
- "compileGroups": [
- {
- "language": "C",
- "sourcePaths": [
- "^empty\\.c$",
- ],
- "includes": None,
- "defines": None,
- "compileCommandFragments": None,
- },
- ],
- "backtrace": [
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": 6,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": None,
- "command": None,
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": 3,
- "command": "include",
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": "^c_exe(\\.exe)?$",
- "artifacts": [
- {
- "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_exe(\\.exe)?$",
- "_dllExtra": False,
- },
- {
- "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_exe\\.pdb$",
- "_dllExtra": True,
- },
- ],
- "build": "^\\.$",
- "source": "^\\.$",
- "install": None,
- "link": {
- "language": "C",
- "lto": None,
- "commandFragments": None,
- },
- "archive": None,
- "dependencies": [
- {
- "id": "^c_lib::@6890427a1f51a3e7e1df$",
- "backtrace": [
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": 7,
- "command": "target_link_libraries",
- "hasParent": True,
- },
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": None,
- "command": None,
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": 3,
- "command": "include",
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "c_shared_lib",
- "id": "^c_shared_lib::@6890427a1f51a3e7e1df$",
- "directorySource": "^\\.$",
- "projectName": "codemodel-v2",
- "type": "SHARED_LIBRARY",
- "isGeneratorProvided": None,
- "sources": [
- {
- "path": "^empty\\.c$",
- "isGenerated": None,
- "sourceGroupName": "Source Files",
- "compileGroupLanguage": "C",
- "backtrace": [
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": 9,
- "command": "add_library",
- "hasParent": True,
- },
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": None,
- "command": None,
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": 3,
- "command": "include",
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "Source Files",
- "sourcePaths": [
- "^empty\\.c$",
- ],
- },
- ],
- "compileGroups": [
- {
- "language": "C",
- "sourcePaths": [
- "^empty\\.c$",
- ],
- "includes": None,
- "defines": [
- {
- "define": "c_shared_lib_EXPORTS",
- "backtrace": None,
- },
- ],
- "compileCommandFragments": None,
- },
- ],
- "backtrace": [
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": 9,
- "command": "add_library",
- "hasParent": True,
- },
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": None,
- "command": None,
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": 3,
- "command": "include",
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": "^(lib|cyg)?c_shared_lib\\.(so|dylib|dll)$",
- "artifacts": [
- {
- "path": "^lib/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib|cyg)?c_shared_lib\\.(so|dylib|dll)$",
- "_dllExtra": False,
- },
- {
- "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib)?c_shared_lib\\.(dll\\.a|lib)$",
- "_dllExtra": True,
- },
- {
- "path": "^lib/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib|cyg)?c_shared_lib\\.pdb$",
- "_dllExtra": True,
- },
- ],
- "build": "^\\.$",
- "source": "^\\.$",
- "install": None,
- "link": {
- "language": "C",
- "lto": True,
- "commandFragments": None,
- },
- "archive": None,
- "dependencies": [
- {
- "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "c_shared_exe",
- "id": "^c_shared_exe::@6890427a1f51a3e7e1df$",
- "directorySource": "^\\.$",
- "projectName": "codemodel-v2",
- "type": "EXECUTABLE",
- "isGeneratorProvided": None,
- "sources": [
- {
- "path": "^empty\\.c$",
- "isGenerated": None,
- "sourceGroupName": "Source Files",
- "compileGroupLanguage": "C",
- "backtrace": [
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": 10,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": None,
- "command": None,
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": 3,
- "command": "include",
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "Source Files",
- "sourcePaths": [
- "^empty\\.c$",
- ],
- },
- ],
- "compileGroups": [
- {
- "language": "C",
- "sourcePaths": [
- "^empty\\.c$",
- ],
- "includes": None,
- "defines": None,
- "compileCommandFragments": None,
- },
- ],
- "backtrace": [
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": 10,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": None,
- "command": None,
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": 3,
- "command": "include",
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": "^c_shared_exe(\\.exe)?$",
- "artifacts": [
- {
- "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_shared_exe(\\.exe)?$",
- "_dllExtra": False,
- },
- {
- "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_shared_exe\\.pdb$",
- "_dllExtra": True,
- },
- ],
- "build": "^\\.$",
- "source": "^\\.$",
- "install": None,
- "link": {
- "language": "C",
- "lto": True,
- "commandFragments": None,
- },
- "archive": None,
- "dependencies": [
- {
- "id": "^c_shared_lib::@6890427a1f51a3e7e1df$",
- "backtrace": [
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": 11,
- "command": "target_link_libraries",
- "hasParent": True,
- },
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": None,
- "command": None,
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": 3,
- "command": "include",
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "c_static_lib",
- "id": "^c_static_lib::@6890427a1f51a3e7e1df$",
- "directorySource": "^\\.$",
- "projectName": "codemodel-v2",
- "type": "STATIC_LIBRARY",
- "isGeneratorProvided": None,
- "sources": [
- {
- "path": "^empty\\.c$",
- "isGenerated": None,
- "sourceGroupName": "Source Files",
- "compileGroupLanguage": "C",
- "backtrace": [
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": 13,
- "command": "add_library",
- "hasParent": True,
- },
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": None,
- "command": None,
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": 3,
- "command": "include",
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "Source Files",
- "sourcePaths": [
- "^empty\\.c$",
- ],
- },
- ],
- "compileGroups": [
- {
- "language": "C",
- "sourcePaths": [
- "^empty\\.c$",
- ],
- "includes": None,
- "defines": None,
- "compileCommandFragments": None,
- },
- ],
- "backtrace": [
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": 13,
- "command": "add_library",
- "hasParent": True,
- },
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": None,
- "command": None,
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": 3,
- "command": "include",
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": "^(lib)?c_static_lib\\.(a|lib)$",
- "artifacts": [
- {
- "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib)?c_static_lib\\.(a|lib)$",
- "_dllExtra": False,
- },
- ],
- "build": "^\\.$",
- "source": "^\\.$",
- "install": None,
- "link": None,
- "archive": {
- "lto": True,
- },
- "dependencies": [
- {
- "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "c_static_exe",
- "id": "^c_static_exe::@6890427a1f51a3e7e1df$",
- "directorySource": "^\\.$",
- "projectName": "codemodel-v2",
- "type": "EXECUTABLE",
- "isGeneratorProvided": None,
- "sources": [
- {
- "path": "^empty\\.c$",
- "isGenerated": None,
- "sourceGroupName": "Source Files",
- "compileGroupLanguage": "C",
- "backtrace": [
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": 14,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": None,
- "command": None,
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": 3,
- "command": "include",
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "Source Files",
- "sourcePaths": [
- "^empty\\.c$",
- ],
- },
- ],
- "compileGroups": [
- {
- "language": "C",
- "sourcePaths": [
- "^empty\\.c$",
- ],
- "includes": None,
- "defines": None,
- "compileCommandFragments": None,
- },
- ],
- "backtrace": [
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": 14,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": None,
- "command": None,
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": 3,
- "command": "include",
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": "^c_static_exe(\\.exe)?$",
- "artifacts": [
- {
- "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_static_exe(\\.exe)?$",
- "_dllExtra": False,
- },
- {
- "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_static_exe\\.pdb$",
- "_dllExtra": True,
- },
- ],
- "build": "^\\.$",
- "source": "^\\.$",
- "install": None,
- "link": {
- "language": "C",
- "lto": None,
- "commandFragments": None,
- },
- "archive": None,
- "dependencies": [
- {
- "id": "^c_static_lib::@6890427a1f51a3e7e1df$",
- "backtrace": [
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": 15,
- "command": "target_link_libraries",
- "hasParent": True,
- },
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": None,
- "command": None,
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": 3,
- "command": "include",
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "ALL_BUILD",
- "id": "^ALL_BUILD::@a56b12a3f5c0529fb296$",
- "directorySource": "^cxx$",
- "projectName": "Cxx",
- "type": "UTILITY",
- "isGeneratorProvided": True,
- "sources": [
- {
- "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ALL_BUILD$",
- "isGenerated": True,
- "sourceGroupName": "",
- "compileGroupLanguage": None,
- "backtrace": [
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ALL_BUILD\\.rule$",
- "isGenerated": True,
- "sourceGroupName": "CMake Rules",
- "compileGroupLanguage": None,
- "backtrace": [
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ALL_BUILD$",
- ],
- },
- {
- "name": "CMake Rules",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ALL_BUILD\\.rule$",
- ],
- },
- ],
- "compileGroups": None,
- "backtrace": [
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": None,
- "artifacts": None,
- "build": "^cxx$",
- "source": "^cxx$",
- "install": None,
- "link": None,
- "archive": None,
- "dependencies": [
- {
- "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
- "backtrace": None,
- },
- {
- "id": "^cxx_lib::@a56b12a3f5c0529fb296$",
- "backtrace": None,
- },
- {
- "id": "^cxx_exe::@a56b12a3f5c0529fb296$",
- "backtrace": None,
- },
- {
- "id": "^cxx_shared_lib::@a56b12a3f5c0529fb296$",
- "backtrace": None,
- },
- {
- "id": "^cxx_shared_exe::@a56b12a3f5c0529fb296$",
- "backtrace": None,
- },
- {
- "id": "^cxx_static_lib::@a56b12a3f5c0529fb296$",
- "backtrace": None,
- },
- {
- "id": "^cxx_static_exe::@a56b12a3f5c0529fb296$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "ZERO_CHECK",
- "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
- "directorySource": "^cxx$",
- "projectName": "Cxx",
- "type": "UTILITY",
- "isGeneratorProvided": True,
- "sources": [
- {
- "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ZERO_CHECK$",
- "isGenerated": True,
- "sourceGroupName": "",
- "compileGroupLanguage": None,
- "backtrace": [
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ZERO_CHECK\\.rule$",
- "isGenerated": True,
- "sourceGroupName": "CMake Rules",
- "compileGroupLanguage": None,
- "backtrace": [
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ZERO_CHECK$",
- ],
- },
- {
- "name": "CMake Rules",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ZERO_CHECK\\.rule$",
- ],
- },
- ],
- "compileGroups": None,
- "backtrace": [
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": None,
- "artifacts": None,
- "build": "^cxx$",
- "source": "^cxx$",
- "install": None,
- "link": None,
- "archive": None,
- "dependencies": None,
- },
- {
- "name": "cxx_lib",
- "id": "^cxx_lib::@a56b12a3f5c0529fb296$",
- "directorySource": "^cxx$",
- "projectName": "Cxx",
- "type": "STATIC_LIBRARY",
- "isGeneratorProvided": None,
- "sources": [
- {
- "path": "^empty\\.cxx$",
- "isGenerated": None,
- "sourceGroupName": "Source Files",
- "compileGroupLanguage": "CXX",
- "backtrace": [
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": 4,
- "command": "add_library",
- "hasParent": True,
- },
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "Source Files",
- "sourcePaths": [
- "^empty\\.cxx$",
- ],
- },
- ],
- "compileGroups": [
- {
- "language": "CXX",
- "sourcePaths": [
- "^empty\\.cxx$",
- ],
- "includes": None,
- "defines": None,
- "compileCommandFragments": None,
- },
- ],
- "backtrace": [
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": 4,
- "command": "add_library",
- "hasParent": True,
- },
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": "^(lib)?cxx_lib\\.(a|lib)$",
- "artifacts": [
- {
- "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib)?cxx_lib\\.(a|lib)$",
- "_dllExtra": False,
- },
- ],
- "build": "^cxx$",
- "source": "^cxx$",
- "install": None,
- "link": None,
- "archive": {
- "lto": None,
- },
- "dependencies": [
- {
- "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "cxx_exe",
- "id": "^cxx_exe::@a56b12a3f5c0529fb296$",
- "directorySource": "^cxx$",
- "projectName": "Cxx",
- "type": "EXECUTABLE",
- "isGeneratorProvided": None,
- "sources": [
- {
- "path": "^empty\\.cxx$",
- "isGenerated": None,
- "sourceGroupName": "Source Files",
- "compileGroupLanguage": "CXX",
- "backtrace": [
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": 5,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "Source Files",
- "sourcePaths": [
- "^empty\\.cxx$",
- ],
- },
- ],
- "compileGroups": [
- {
- "language": "CXX",
- "sourcePaths": [
- "^empty\\.cxx$",
- ],
- "includes": None,
- "defines": None,
- "compileCommandFragments": [
- {
- "fragment" : "TargetCompileOptions",
- "backtrace": [
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": 17,
- "command": "target_compile_options",
- "hasParent": True,
- },
- {
- "file" : "^cxx/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- }
- ],
- },
- ],
- "backtrace": [
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": 5,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": "bin",
- "nameOnDisk": "^cxx_exe(\\.exe)?$",
- "artifacts": [
- {
- "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_exe(\\.exe)?$",
- "_dllExtra": False,
- },
- {
- "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_exe\\.pdb$",
- "_dllExtra": True,
- },
- ],
- "build": "^cxx$",
- "source": "^cxx$",
- "install": {
- "prefix": "^(/usr/local|[A-Za-z]:.*/codemodel-v2)$",
- "destinations": [
- {
- "path": "bin",
- "backtrace": [
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": 37,
- "command": "install",
- "hasParent": True,
- },
- {
- "file": "^codemodel-v2\\.cmake$",
- "line": None,
- "command": None,
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": 3,
- "command": "include",
- "hasParent": True,
- },
- {
- "file": "^CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- },
- "link": {
- "language": "CXX",
- "lto": None,
- "commandFragments": [
- {
- "fragment" : "TargetLinkOptions",
- "role" : "flags",
- "backtrace": [
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": 18,
- "command": "target_link_options",
- "hasParent": True,
- },
- {
- "file" : "^cxx/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "fragment" : ".*TargetLinkDir\\\"?$",
- "role" : "libraryPath",
- "backtrace": [
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": 19,
- "command": "target_link_directories",
- "hasParent": True,
- },
- {
- "file" : "^cxx/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "fragment" : ".*cxx_lib.*",
- "role" : "libraries",
- "backtrace": [
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": 6,
- "command": "target_link_libraries",
- "hasParent": True,
- },
- {
- "file" : "^cxx/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- },
- "archive": None,
- "dependencies": [
- {
- "id": "^cxx_lib::@a56b12a3f5c0529fb296$",
- "backtrace": [
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": 6,
- "command": "target_link_libraries",
- "hasParent": True,
- },
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "cxx_shared_lib",
- "id": "^cxx_shared_lib::@a56b12a3f5c0529fb296$",
- "directorySource": "^cxx$",
- "projectName": "Cxx",
- "type": "SHARED_LIBRARY",
- "isGeneratorProvided": None,
- "sources": [
- {
- "path": "^empty\\.cxx$",
- "isGenerated": None,
- "sourceGroupName": "Source Files",
- "compileGroupLanguage": "CXX",
- "backtrace": [
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": 9,
- "command": "add_library",
- "hasParent": True,
- },
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "Source Files",
- "sourcePaths": [
- "^empty\\.cxx$",
- ],
- },
- ],
- "compileGroups": [
- {
- "language": "CXX",
- "sourcePaths": [
- "^empty\\.cxx$",
- ],
- "includes": None,
- "defines": [
- {
- "define": "cxx_shared_lib_EXPORTS",
- "backtrace": None,
- },
- ],
- "compileCommandFragments": None,
- },
- ],
- "backtrace": [
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": 9,
- "command": "add_library",
- "hasParent": True,
- },
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": "^(lib|cyg)?cxx_shared_lib\\.(so|dylib|dll)$",
- "artifacts": [
- {
- "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib|cyg)?cxx_shared_lib\\.(so|dylib|dll)$",
- "_dllExtra": False,
- },
- {
- "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib)?cxx_shared_lib\\.(dll\\.a|lib)$",
- "_dllExtra": True,
- },
- {
- "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib|cyg)?cxx_shared_lib\\.pdb$",
- "_dllExtra": True,
- },
- ],
- "build": "^cxx$",
- "source": "^cxx$",
- "install": None,
- "link": {
- "language": "CXX",
- "lto": None,
- "commandFragments": None,
- },
- "archive": None,
- "dependencies": [
- {
- "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "cxx_shared_exe",
- "id": "^cxx_shared_exe::@a56b12a3f5c0529fb296$",
- "directorySource": "^cxx$",
- "projectName": "Cxx",
- "type": "EXECUTABLE",
- "isGeneratorProvided": None,
- "sources": [
- {
- "path": "^empty\\.cxx$",
- "isGenerated": None,
- "sourceGroupName": "Source Files",
- "compileGroupLanguage": "CXX",
- "backtrace": [
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": 10,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "Source Files",
- "sourcePaths": [
- "^empty\\.cxx$",
- ],
- },
- ],
- "compileGroups": [
- {
- "language": "CXX",
- "sourcePaths": [
- "^empty\\.cxx$",
- ],
- "includes": None,
- "defines": None,
- "compileCommandFragments": None,
- },
- ],
- "backtrace": [
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": 10,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": "^cxx_shared_exe(\\.exe)?$",
- "artifacts": [
- {
- "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_shared_exe(\\.exe)?$",
- "_dllExtra": False,
- },
- {
- "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_shared_exe\\.pdb$",
- "_dllExtra": True,
- },
- ],
- "build": "^cxx$",
- "source": "^cxx$",
- "install": None,
- "link": {
- "language": "CXX",
- "lto": None,
- "commandFragments": None,
- },
- "archive": None,
- "dependencies": [
- {
- "id": "^cxx_shared_lib::@a56b12a3f5c0529fb296$",
- "backtrace": [
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": 11,
- "command": "target_link_libraries",
- "hasParent": True,
- },
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "cxx_static_lib",
- "id": "^cxx_static_lib::@a56b12a3f5c0529fb296$",
- "directorySource": "^cxx$",
- "projectName": "Cxx",
- "type": "STATIC_LIBRARY",
- "isGeneratorProvided": None,
- "sources": [
- {
- "path": "^empty\\.cxx$",
- "isGenerated": None,
- "sourceGroupName": "Source Files",
- "compileGroupLanguage": "CXX",
- "backtrace": [
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": 13,
- "command": "add_library",
- "hasParent": True,
- },
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "Source Files",
- "sourcePaths": [
- "^empty\\.cxx$",
- ],
- },
- ],
- "compileGroups": [
- {
- "language": "CXX",
- "sourcePaths": [
- "^empty\\.cxx$",
- ],
- "includes": None,
- "defines": None,
- "compileCommandFragments": None,
- },
- ],
- "backtrace": [
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": 13,
- "command": "add_library",
- "hasParent": True,
- },
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": "^(lib)?cxx_static_lib\\.(a|lib)$",
- "artifacts": [
- {
- "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib)?cxx_static_lib\\.(a|lib)$",
- "_dllExtra": False,
- },
- ],
- "build": "^cxx$",
- "source": "^cxx$",
- "install": None,
- "link": None,
- "archive": {
- "lto": None,
- },
- "dependencies": [
- {
- "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "cxx_static_exe",
- "id": "^cxx_static_exe::@a56b12a3f5c0529fb296$",
- "directorySource": "^cxx$",
- "projectName": "Cxx",
- "type": "EXECUTABLE",
- "isGeneratorProvided": None,
- "sources": [
- {
- "path": "^empty\\.cxx$",
- "isGenerated": None,
- "sourceGroupName": "Source Files",
- "compileGroupLanguage": "CXX",
- "backtrace": [
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": 14,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "Source Files",
- "sourcePaths": [
- "^empty\\.cxx$",
- ],
- },
- ],
- "compileGroups": [
- {
- "language": "CXX",
- "sourcePaths": [
- "^empty\\.cxx$",
- ],
- "includes": None,
- "defines": None,
- "compileCommandFragments": None,
- },
- ],
- "backtrace": [
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": 14,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": "^cxx_static_exe(\\.exe)?$",
- "artifacts": [
- {
- "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_static_exe(\\.exe)?$",
- "_dllExtra": False,
- },
- {
- "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_static_exe\\.pdb$",
- "_dllExtra": True,
- },
- ],
- "build": "^cxx$",
- "source": "^cxx$",
- "install": None,
- "link": {
- "language": "CXX",
- "lto": None,
- "commandFragments": None,
- },
- "archive": None,
- "dependencies": [
- {
- "id": "^cxx_static_lib::@a56b12a3f5c0529fb296$",
- "backtrace": [
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": 15,
- "command": "target_link_libraries",
- "hasParent": True,
- },
- {
- "file": "^cxx/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "ALL_BUILD",
- "id": "^ALL_BUILD::@53632cba2752272bb008$",
- "directorySource": "^alias$",
- "projectName": "Alias",
- "type": "UTILITY",
- "isGeneratorProvided": True,
- "sources": [
- {
- "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ALL_BUILD$",
- "isGenerated": True,
- "sourceGroupName": "",
- "compileGroupLanguage": None,
- "backtrace": [
- {
- "file": "^alias/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ALL_BUILD\\.rule$",
- "isGenerated": True,
- "sourceGroupName": "CMake Rules",
- "compileGroupLanguage": None,
- "backtrace": [
- {
- "file": "^alias/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ALL_BUILD$",
- ],
- },
- {
- "name": "CMake Rules",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ALL_BUILD\\.rule$",
- ],
- },
- ],
- "compileGroups": None,
- "backtrace": [
- {
- "file": "^alias/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": None,
- "artifacts": None,
- "build": "^alias$",
- "source": "^alias$",
- "install": None,
- "link": None,
- "archive": None,
- "dependencies": [
- {
- "id": "^ZERO_CHECK::@53632cba2752272bb008$",
- "backtrace": None,
- },
- {
- "id": "^c_alias_exe::@53632cba2752272bb008$",
- "backtrace": None,
- },
- {
- "id": "^cxx_alias_exe::@53632cba2752272bb008$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "ZERO_CHECK",
- "id": "^ZERO_CHECK::@53632cba2752272bb008$",
- "directorySource": "^alias$",
- "projectName": "Alias",
- "type": "UTILITY",
- "isGeneratorProvided": True,
- "sources": [
- {
- "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ZERO_CHECK$",
- "isGenerated": True,
- "sourceGroupName": "",
- "compileGroupLanguage": None,
- "backtrace": [
- {
- "file": "^alias/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ZERO_CHECK\\.rule$",
- "isGenerated": True,
- "sourceGroupName": "CMake Rules",
- "compileGroupLanguage": None,
- "backtrace": [
- {
- "file": "^alias/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ZERO_CHECK$",
- ],
- },
- {
- "name": "CMake Rules",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ZERO_CHECK\\.rule$",
- ],
- },
- ],
- "compileGroups": None,
- "backtrace": [
- {
- "file": "^alias/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": None,
- "artifacts": None,
- "build": "^alias$",
- "source": "^alias$",
- "install": None,
- "link": None,
- "archive": None,
- "dependencies": None,
- },
- {
- "name": "c_alias_exe",
- "id": "^c_alias_exe::@53632cba2752272bb008$",
- "directorySource": "^alias$",
- "projectName": "Alias",
- "type": "EXECUTABLE",
- "isGeneratorProvided": None,
- "sources": [
- {
- "path": "^empty\\.c$",
- "isGenerated": None,
- "sourceGroupName": "Source Files",
- "compileGroupLanguage": "C",
- "backtrace": [
- {
- "file": "^alias/CMakeLists\\.txt$",
- "line": 5,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^alias/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "Source Files",
- "sourcePaths": [
- "^empty\\.c$",
- ],
- },
- ],
- "compileGroups": [
- {
- "language": "C",
- "sourcePaths": [
- "^empty\\.c$",
- ],
- "includes": None,
- "defines": None,
- "compileCommandFragments": None,
- },
- ],
- "backtrace": [
- {
- "file": "^alias/CMakeLists\\.txt$",
- "line": 5,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^alias/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": "^c_alias_exe(\\.exe)?$",
- "artifacts": [
- {
- "path": "^alias/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_alias_exe(\\.exe)?$",
- "_dllExtra": False,
- },
- {
- "path": "^alias/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_alias_exe\\.pdb$",
- "_dllExtra": True,
- },
- ],
- "build": "^alias$",
- "source": "^alias$",
- "install": None,
- "link": {
- "language": "C",
- "lto": None,
- "commandFragments": None,
- },
- "archive": None,
- "dependencies": [
- {
- "id": "^c_lib::@6890427a1f51a3e7e1df$",
- "backtrace": [
- {
- "file": "^alias/CMakeLists\\.txt$",
- "line": 6,
- "command": "target_link_libraries",
- "hasParent": True,
- },
- {
- "file": "^alias/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "id": "^ZERO_CHECK::@53632cba2752272bb008$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "cxx_alias_exe",
- "id": "^cxx_alias_exe::@53632cba2752272bb008$",
- "directorySource": "^alias$",
- "projectName": "Alias",
- "type": "EXECUTABLE",
- "isGeneratorProvided": None,
- "sources": [
- {
- "path": "^empty\\.cxx$",
- "isGenerated": None,
- "sourceGroupName": "Source Files",
- "compileGroupLanguage": "CXX",
- "backtrace": [
- {
- "file": "^alias/CMakeLists\\.txt$",
- "line": 9,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^alias/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "Source Files",
- "sourcePaths": [
- "^empty\\.cxx$",
- ],
- },
- ],
- "compileGroups": [
- {
- "language": "CXX",
- "sourcePaths": [
- "^empty\\.cxx$",
- ],
- "includes": None,
- "defines": None,
- "compileCommandFragments": None,
- },
- ],
- "backtrace": [
- {
- "file": "^alias/CMakeLists\\.txt$",
- "line": 9,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^alias/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": "^cxx_alias_exe(\\.exe)?$",
- "artifacts": [
- {
- "path": "^alias/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_alias_exe(\\.exe)?$",
- "_dllExtra": False,
- },
- {
- "path": "^alias/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_alias_exe\\.pdb$",
- "_dllExtra": True,
- },
- ],
- "build": "^alias$",
- "source": "^alias$",
- "install": None,
- "link": {
- "language": "CXX",
- "lto": None,
- "commandFragments": None,
- },
- "archive": None,
- "dependencies": [
- {
- "id": "^cxx_lib::@a56b12a3f5c0529fb296$",
- "backtrace": [
- {
- "file": "^alias/CMakeLists\\.txt$",
- "line": 10,
- "command": "target_link_libraries",
- "hasParent": True,
- },
- {
- "file": "^alias/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "id": "^ZERO_CHECK::@53632cba2752272bb008$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "ALL_BUILD",
- "id": "^ALL_BUILD::@5ed5358f70faf8d8af7a$",
- "directorySource": "^object$",
- "projectName": "Object",
- "type": "UTILITY",
- "isGeneratorProvided": True,
- "sources": [
- {
- "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ALL_BUILD$",
- "isGenerated": True,
- "sourceGroupName": "",
- "compileGroupLanguage": None,
- "backtrace": [
- {
- "file": "^object/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ALL_BUILD\\.rule$",
- "isGenerated": True,
- "sourceGroupName": "CMake Rules",
- "compileGroupLanguage": None,
- "backtrace": [
- {
- "file": "^object/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ALL_BUILD$",
- ],
- },
- {
- "name": "CMake Rules",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ALL_BUILD\\.rule$",
- ],
- },
- ],
- "compileGroups": None,
- "backtrace": [
- {
- "file": "^object/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": None,
- "artifacts": None,
- "build": "^object$",
- "source": "^object$",
- "install": None,
- "link": None,
- "archive": None,
- "dependencies": [
- {
- "id": "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
- "backtrace": None,
- },
- {
- "id": "^c_object_lib::@5ed5358f70faf8d8af7a$",
- "backtrace": None,
- },
- {
- "id": "^c_object_exe::@5ed5358f70faf8d8af7a$",
- "backtrace": None,
- },
- {
- "id": "^cxx_object_lib::@5ed5358f70faf8d8af7a$",
- "backtrace": None,
- },
- {
- "id": "^cxx_object_exe::@5ed5358f70faf8d8af7a$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "ZERO_CHECK",
- "id": "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
- "directorySource": "^object$",
- "projectName": "Object",
- "type": "UTILITY",
- "isGeneratorProvided": True,
- "sources": [
- {
- "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ZERO_CHECK$",
- "isGenerated": True,
- "sourceGroupName": "",
- "compileGroupLanguage": None,
- "backtrace": [
- {
- "file": "^object/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ZERO_CHECK\\.rule$",
- "isGenerated": True,
- "sourceGroupName": "CMake Rules",
- "compileGroupLanguage": None,
- "backtrace": [
- {
- "file": "^object/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ZERO_CHECK$",
- ],
- },
- {
- "name": "CMake Rules",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ZERO_CHECK\\.rule$",
- ],
- },
- ],
- "compileGroups": None,
- "backtrace": [
- {
- "file": "^object/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": None,
- "artifacts": None,
- "build": "^object$",
- "source": "^object$",
- "install": None,
- "link": None,
- "archive": None,
- "dependencies": None,
- },
- {
- "name": "c_object_lib",
- "id": "^c_object_lib::@5ed5358f70faf8d8af7a$",
- "directorySource": "^object$",
- "projectName": "Object",
- "type": "OBJECT_LIBRARY",
- "isGeneratorProvided": None,
- "sources": [
- {
- "path": "^empty\\.c$",
- "isGenerated": None,
- "sourceGroupName": "Source Files",
- "compileGroupLanguage": "C",
- "backtrace": [
- {
- "file": "^object/CMakeLists\\.txt$",
- "line": 5,
- "command": "add_library",
- "hasParent": True,
- },
- {
- "file": "^object/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "Source Files",
- "sourcePaths": [
- "^empty\\.c$",
- ],
- },
- ],
- "compileGroups": [
- {
- "language": "C",
- "sourcePaths": [
- "^empty\\.c$",
- ],
- "includes": None,
- "defines": None,
- "compileCommandFragments": None,
- },
- ],
- "backtrace": [
- {
- "file": "^object/CMakeLists\\.txt$",
- "line": 5,
- "command": "add_library",
- "hasParent": True,
- },
- {
- "file": "^object/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": None,
- "artifacts": [
- {
- "path": "^object/.*/empty(\\.c)?\\.o(bj)?$",
- "_dllExtra": False,
- },
- ],
- "build": "^object$",
- "source": "^object$",
- "install": None,
- "link": None,
- "archive": None,
- "dependencies": [
- {
- "id": "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "c_object_exe",
- "id": "^c_object_exe::@5ed5358f70faf8d8af7a$",
- "directorySource": "^object$",
- "projectName": "Object",
- "type": "EXECUTABLE",
- "isGeneratorProvided": None,
- "sources": [
- {
- "path": "^empty\\.c$",
- "isGenerated": None,
- "sourceGroupName": "Source Files",
- "compileGroupLanguage": "C",
- "backtrace": [
- {
- "file": "^object/CMakeLists\\.txt$",
- "line": 6,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^object/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/.*/empty(\\.c)?\\.o(bj)?$",
- "isGenerated": True,
- "sourceGroupName": "Object Libraries",
- "compileGroupLanguage": None,
- "backtrace": [
- {
- "file": "^object/CMakeLists\\.txt$",
- "line": 7,
- "command": "target_link_libraries",
- "hasParent": True,
- },
- {
- "file": "^object/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "Source Files",
- "sourcePaths": [
- "^empty\\.c$",
- ],
- },
- {
- "name": "Object Libraries",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/.*/empty(\\.c)?\\.o(bj)?$",
- ],
- },
- ],
- "compileGroups": [
- {
- "language": "C",
- "sourcePaths": [
- "^empty\\.c$",
- ],
- "includes": None,
- "defines": None,
- "compileCommandFragments": None,
- },
- ],
- "backtrace": [
- {
- "file": "^object/CMakeLists\\.txt$",
- "line": 6,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^object/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": "^c_object_exe(\\.exe)?$",
- "artifacts": [
- {
- "path": "^object/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_object_exe(\\.exe)?$",
- "_dllExtra": False,
- },
- {
- "path": "^object/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_object_exe\\.pdb$",
- "_dllExtra": True,
- },
- ],
- "build": "^object$",
- "source": "^object$",
- "install": {
- "prefix": "^(/usr/local|[A-Za-z]:.*/codemodel-v2)$",
- "destinations": [
- {
- "path": "bin",
- "backtrace": [
- {
- "file": "^object/CMakeLists\\.txt$",
- "line": 13,
- "command": "install",
- "hasParent": True,
- },
- {
- "file": "^object/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- },
- "link": {
- "language": "C",
- "lto": None,
- "commandFragments": None,
- },
- "archive": None,
- "dependencies": [
- {
- "id": "^c_object_lib::@5ed5358f70faf8d8af7a$",
- # FIXME: Add a backtrace here when it becomes available.
- # You'll know when it's available, because this test will
- # fail.
- "backtrace": None,
- },
- {
- "id": "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "cxx_object_lib",
- "id": "^cxx_object_lib::@5ed5358f70faf8d8af7a$",
- "directorySource": "^object$",
- "projectName": "Object",
- "type": "OBJECT_LIBRARY",
- "isGeneratorProvided": None,
- "sources": [
- {
- "path": "^empty\\.cxx$",
- "isGenerated": None,
- "sourceGroupName": "Source Files",
- "compileGroupLanguage": "CXX",
- "backtrace": [
- {
- "file": "^object/CMakeLists\\.txt$",
- "line": 9,
- "command": "add_library",
- "hasParent": True,
- },
- {
- "file": "^object/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "Source Files",
- "sourcePaths": [
- "^empty\\.cxx$",
- ],
- },
- ],
- "compileGroups": [
- {
- "language": "CXX",
- "sourcePaths": [
- "^empty\\.cxx$",
- ],
- "includes": None,
- "defines": None,
- "compileCommandFragments": None,
- },
- ],
- "backtrace": [
- {
- "file": "^object/CMakeLists\\.txt$",
- "line": 9,
- "command": "add_library",
- "hasParent": True,
- },
- {
- "file": "^object/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": None,
- "artifacts": [
- {
- "path": "^object/.*/empty(\\.cxx)?\\.o(bj)?$",
- "_dllExtra": False,
- },
- ],
- "build": "^object$",
- "source": "^object$",
- "install": None,
- "link": None,
- "archive": None,
- "dependencies": [
- {
- "id": "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "cxx_object_exe",
- "id": "^cxx_object_exe::@5ed5358f70faf8d8af7a$",
- "directorySource": "^object$",
- "projectName": "Object",
- "type": "EXECUTABLE",
- "isGeneratorProvided": None,
- "sources": [
- {
- "path": "^empty\\.cxx$",
- "isGenerated": None,
- "sourceGroupName": "Source Files",
- "compileGroupLanguage": "CXX",
- "backtrace": [
- {
- "file": "^object/CMakeLists\\.txt$",
- "line": 10,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^object/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/.*/empty(\\.cxx)?\\.o(bj)?$",
- "isGenerated": True,
- "sourceGroupName": "Object Libraries",
- "compileGroupLanguage": None,
- "backtrace": [
- {
- "file": "^object/CMakeLists\\.txt$",
- "line": 11,
- "command": "target_link_libraries",
- "hasParent": True,
- },
- {
- "file": "^object/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "Source Files",
- "sourcePaths": [
- "^empty\\.cxx$",
- ],
- },
- {
- "name": "Object Libraries",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/.*/empty(\\.cxx)?\\.o(bj)?$",
- ],
- },
- ],
- "compileGroups": [
- {
- "language": "CXX",
- "sourcePaths": [
- "^empty\\.cxx$",
- ],
- "includes": None,
- "defines": None,
- "compileCommandFragments": None,
- },
- ],
- "backtrace": [
- {
- "file": "^object/CMakeLists\\.txt$",
- "line": 10,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^object/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": "^cxx_object_exe(\\.exe)?$",
- "artifacts": [
- {
- "path": "^object/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_object_exe(\\.exe)?$",
- "_dllExtra": False,
- },
- {
- "path": "^object/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_object_exe\\.pdb$",
- "_dllExtra": True,
- },
- ],
- "build": "^object$",
- "source": "^object$",
- "install": {
- "prefix": "^(/usr/local|[A-Za-z]:.*/codemodel-v2)$",
- "destinations": [
- {
- "path": "bin",
- "backtrace": [
- {
- "file": "^object/CMakeLists\\.txt$",
- "line": 13,
- "command": "install",
- "hasParent": True,
- },
- {
- "file": "^object/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- },
- "link": {
- "language": "CXX",
- "lto": None,
- "commandFragments": None,
- },
- "archive": None,
- "dependencies": [
- {
- "id": "^cxx_object_lib::@5ed5358f70faf8d8af7a$",
- # FIXME: Add a backtrace here when it becomes available.
- # You'll know when it's available, because this test will
- # fail.
- "backtrace": None,
- },
- {
- "id": "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "ALL_BUILD",
- "id": "^ALL_BUILD::@ba7eb709d0b48779c6c8$",
- "directorySource": "^imported$",
- "projectName": "Imported",
- "type": "UTILITY",
- "isGeneratorProvided": True,
- "sources": [
- {
- "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ALL_BUILD$",
- "isGenerated": True,
- "sourceGroupName": "",
- "compileGroupLanguage": None,
- "backtrace": [
- {
- "file": "^imported/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ALL_BUILD\\.rule$",
- "isGenerated": True,
- "sourceGroupName": "CMake Rules",
- "compileGroupLanguage": None,
- "backtrace": [
- {
- "file": "^imported/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ALL_BUILD$",
- ],
- },
- {
- "name": "CMake Rules",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ALL_BUILD\\.rule$",
- ],
- },
- ],
- "compileGroups": None,
- "backtrace": [
- {
- "file": "^imported/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": None,
- "artifacts": None,
- "build": "^imported$",
- "source": "^imported$",
- "install": None,
- "link": None,
- "archive": None,
- "dependencies": [
- {
- "id": "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
- "backtrace": None,
- },
- {
- "id": "^link_imported_exe::@ba7eb709d0b48779c6c8$",
- "backtrace": None,
- },
- {
- "id": "^link_imported_shared_exe::@ba7eb709d0b48779c6c8$",
- "backtrace": None,
- },
- {
- "id": "^link_imported_static_exe::@ba7eb709d0b48779c6c8$",
- "backtrace": None,
- },
- {
- "id": "^link_imported_object_exe::@ba7eb709d0b48779c6c8$",
- "backtrace": None,
- },
- {
- "id": "^link_imported_interface_exe::@ba7eb709d0b48779c6c8$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "ZERO_CHECK",
- "id": "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
- "directorySource": "^imported$",
- "projectName": "Imported",
- "type": "UTILITY",
- "isGeneratorProvided": True,
- "sources": [
- {
- "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ZERO_CHECK$",
- "isGenerated": True,
- "sourceGroupName": "",
- "compileGroupLanguage": None,
- "backtrace": [
- {
- "file": "^imported/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ZERO_CHECK\\.rule$",
- "isGenerated": True,
- "sourceGroupName": "CMake Rules",
- "compileGroupLanguage": None,
- "backtrace": [
- {
- "file": "^imported/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ZERO_CHECK$",
- ],
- },
- {
- "name": "CMake Rules",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ZERO_CHECK\\.rule$",
- ],
- },
- ],
- "compileGroups": None,
- "backtrace": [
- {
- "file": "^imported/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": None,
- "artifacts": None,
- "build": "^imported$",
- "source": "^imported$",
- "install": None,
- "link": None,
- "archive": None,
- "dependencies": None,
- },
- {
- "name": "link_imported_exe",
- "id": "^link_imported_exe::@ba7eb709d0b48779c6c8$",
- "directorySource": "^imported$",
- "projectName": "Imported",
- "type": "EXECUTABLE",
- "isGeneratorProvided": None,
- "sources": [
- {
- "path": "^empty\\.c$",
- "isGenerated": None,
- "sourceGroupName": "Source Files",
- "compileGroupLanguage": "C",
- "backtrace": [
- {
- "file": "^imported/CMakeLists\\.txt$",
- "line": 5,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^imported/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "Source Files",
- "sourcePaths": [
- "^empty\\.c$",
- ],
- },
- ],
- "compileGroups": [
- {
- "language": "C",
- "sourcePaths": [
- "^empty\\.c$",
- ],
- "includes": None,
- "defines": None,
- "compileCommandFragments": None,
- },
- ],
- "backtrace": [
- {
- "file": "^imported/CMakeLists\\.txt$",
- "line": 5,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^imported/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": "^link_imported_exe(\\.exe)?$",
- "artifacts": [
- {
- "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_exe(\\.exe)?$",
- "_dllExtra": False,
- },
- {
- "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_exe\\.pdb$",
- "_dllExtra": True,
- },
- ],
- "build": "^imported$",
- "source": "^imported$",
- "install": None,
- "link": {
- "language": "C",
- "lto": None,
- "commandFragments": None,
- },
- "archive": None,
- "dependencies": [
- {
- "id": "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "link_imported_shared_exe",
- "id": "^link_imported_shared_exe::@ba7eb709d0b48779c6c8$",
- "directorySource": "^imported$",
- "projectName": "Imported",
- "type": "EXECUTABLE",
- "isGeneratorProvided": None,
- "sources": [
- {
- "path": "^empty\\.c$",
- "isGenerated": None,
- "sourceGroupName": "Source Files",
- "compileGroupLanguage": "C",
- "backtrace": [
- {
- "file": "^imported/CMakeLists\\.txt$",
- "line": 9,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^imported/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "Source Files",
- "sourcePaths": [
- "^empty\\.c$",
- ],
- },
- ],
- "compileGroups": [
- {
- "language": "C",
- "sourcePaths": [
- "^empty\\.c$",
- ],
- "includes": None,
- "defines": None,
- "compileCommandFragments": None,
- },
- ],
- "backtrace": [
- {
- "file": "^imported/CMakeLists\\.txt$",
- "line": 9,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^imported/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": "^link_imported_shared_exe(\\.exe)?$",
- "artifacts": [
- {
- "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_shared_exe(\\.exe)?$",
- "_dllExtra": False,
- },
- {
- "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_shared_exe\\.pdb$",
- "_dllExtra": True,
- },
- ],
- "build": "^imported$",
- "source": "^imported$",
- "install": None,
- "link": {
- "language": "C",
- "lto": None,
- "commandFragments": None,
- },
- "archive": None,
- "dependencies": [
- {
- "id": "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "link_imported_static_exe",
- "id": "^link_imported_static_exe::@ba7eb709d0b48779c6c8$",
- "directorySource": "^imported$",
- "projectName": "Imported",
- "type": "EXECUTABLE",
- "isGeneratorProvided": None,
- "sources": [
- {
- "path": "^empty\\.c$",
- "isGenerated": None,
- "sourceGroupName": "Source Files",
- "compileGroupLanguage": "C",
- "backtrace": [
- {
- "file": "^imported/CMakeLists\\.txt$",
- "line": 13,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^imported/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "Source Files",
- "sourcePaths": [
- "^empty\\.c$",
- ],
- },
- ],
- "compileGroups": [
- {
- "language": "C",
- "sourcePaths": [
- "^empty\\.c$",
- ],
- "includes": None,
- "defines": None,
- "compileCommandFragments": None,
- },
- ],
- "backtrace": [
- {
- "file": "^imported/CMakeLists\\.txt$",
- "line": 13,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^imported/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": "^link_imported_static_exe(\\.exe)?$",
- "artifacts": [
- {
- "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_static_exe(\\.exe)?$",
- "_dllExtra": False,
- },
- {
- "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_static_exe\\.pdb$",
- "_dllExtra": True,
- },
- ],
- "build": "^imported$",
- "source": "^imported$",
- "install": None,
- "link": {
- "language": "C",
- "lto": None,
- "commandFragments": None,
- },
- "archive": None,
- "dependencies": [
- {
- "id": "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "link_imported_object_exe",
- "id": "^link_imported_object_exe::@ba7eb709d0b48779c6c8$",
- "directorySource": "^imported$",
- "projectName": "Imported",
- "type": "EXECUTABLE",
- "isGeneratorProvided": None,
- "sources": [
- {
- "path": "^empty\\.c$",
- "isGenerated": None,
- "sourceGroupName": "Source Files",
- "compileGroupLanguage": "C",
- "backtrace": [
- {
- "file": "^imported/CMakeLists\\.txt$",
- "line": 18,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^imported/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "Source Files",
- "sourcePaths": [
- "^empty\\.c$",
- ],
- },
- ],
- "compileGroups": [
- {
- "language": "C",
- "sourcePaths": [
- "^empty\\.c$",
- ],
- "includes": None,
- "defines": None,
- "compileCommandFragments": None,
- },
- ],
- "backtrace": [
- {
- "file": "^imported/CMakeLists\\.txt$",
- "line": 18,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^imported/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": "^link_imported_object_exe(\\.exe)?$",
- "artifacts": [
- {
- "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_object_exe(\\.exe)?$",
- "_dllExtra": False,
- },
- {
- "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_object_exe\\.pdb$",
- "_dllExtra": True,
- },
- ],
- "build": "^imported$",
- "source": "^imported$",
- "install": None,
- "link": {
- "language": "C",
- "lto": None,
- "commandFragments": None,
- },
- "archive": None,
- "dependencies": [
- {
- "id": "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "link_imported_interface_exe",
- "id": "^link_imported_interface_exe::@ba7eb709d0b48779c6c8$",
- "directorySource": "^imported$",
- "projectName": "Imported",
- "type": "EXECUTABLE",
- "isGeneratorProvided": None,
- "sources": [
- {
- "path": "^empty\\.c$",
- "isGenerated": None,
- "sourceGroupName": "Source Files",
- "compileGroupLanguage": "C",
- "backtrace": [
- {
- "file": "^imported/CMakeLists\\.txt$",
- "line": 23,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^imported/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "Source Files",
- "sourcePaths": [
- "^empty\\.c$",
- ],
- },
- ],
- "compileGroups": [
- {
- "language": "C",
- "sourcePaths": [
- "^empty\\.c$",
- ],
- "includes": None,
- "defines": None,
- "compileCommandFragments": None,
- },
- ],
- "backtrace": [
- {
- "file": "^imported/CMakeLists\\.txt$",
- "line": 23,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^imported/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": "^link_imported_interface_exe(\\.exe)?$",
- "artifacts": [
- {
- "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_interface_exe(\\.exe)?$",
- "_dllExtra": False,
- },
- {
- "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_interface_exe\\.pdb$",
- "_dllExtra": True,
- },
- ],
- "build": "^imported$",
- "source": "^imported$",
- "install": None,
- "link": {
- "language": "C",
- "lto": None,
- "commandFragments": None,
- },
- "archive": None,
- "dependencies": [
- {
- "id": "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "ALL_BUILD",
- "id": "^ALL_BUILD::@c11385ffed57b860da63$",
- "directorySource": "^custom$",
- "projectName": "Custom",
- "type": "UTILITY",
- "isGeneratorProvided": True,
- "sources": [
- {
- "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ALL_BUILD$",
- "isGenerated": True,
- "sourceGroupName": "",
- "compileGroupLanguage": None,
- "backtrace": [
- {
- "file": "^custom/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ALL_BUILD\\.rule$",
- "isGenerated": True,
- "sourceGroupName": "CMake Rules",
- "compileGroupLanguage": None,
- "backtrace": [
- {
- "file": "^custom/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ALL_BUILD$",
- ],
- },
- {
- "name": "CMake Rules",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ALL_BUILD\\.rule$",
- ],
- },
- ],
- "compileGroups": None,
- "backtrace": [
- {
- "file": "^custom/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": None,
- "artifacts": None,
- "build": "^custom$",
- "source": "^custom$",
- "install": None,
- "link": None,
- "archive": None,
- "dependencies": [
- {
- "id": "^ZERO_CHECK::@c11385ffed57b860da63$",
- "backtrace": None,
- },
- {
- "id": "^custom_exe::@c11385ffed57b860da63$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "ZERO_CHECK",
- "id": "^ZERO_CHECK::@c11385ffed57b860da63$",
- "directorySource": "^custom$",
- "projectName": "Custom",
- "type": "UTILITY",
- "isGeneratorProvided": True,
- "sources": [
- {
- "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ZERO_CHECK$",
- "isGenerated": True,
- "sourceGroupName": "",
- "compileGroupLanguage": None,
- "backtrace": [
- {
- "file": "^custom/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ZERO_CHECK\\.rule$",
- "isGenerated": True,
- "sourceGroupName": "CMake Rules",
- "compileGroupLanguage": None,
- "backtrace": [
- {
- "file": "^custom/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ZERO_CHECK$",
- ],
- },
- {
- "name": "CMake Rules",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ZERO_CHECK\\.rule$",
- ],
- },
- ],
- "compileGroups": None,
- "backtrace": [
- {
- "file": "^custom/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": None,
- "artifacts": None,
- "build": "^custom$",
- "source": "^custom$",
- "install": None,
- "link": None,
- "archive": None,
- "dependencies": None,
- },
- {
- "name": "custom_tgt",
- "id": "^custom_tgt::@c11385ffed57b860da63$",
- "directorySource": "^custom$",
- "projectName": "Custom",
- "type": "UTILITY",
- "isGeneratorProvided": None,
- "sources": [
- {
- "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/custom_tgt$",
- "isGenerated": True,
- "sourceGroupName": "",
- "compileGroupLanguage": None,
- "backtrace": [
- {
- "file": "^custom/CMakeLists\\.txt$",
- "line": 3,
- "command": "add_custom_target",
- "hasParent": True,
- },
- {
- "file": "^custom/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/(custom/)?CMakeFiles/([0-9a-f]+/)?custom_tgt\\.rule$",
- "isGenerated": True,
- "sourceGroupName": "CMake Rules",
- "compileGroupLanguage": None,
- "backtrace": [
- {
- "file": "^custom/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/custom_tgt$",
- ],
- },
- {
- "name": "CMake Rules",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/(custom/)?CMakeFiles/([0-9a-f]+/)?custom_tgt\\.rule$",
- ],
- },
- ],
- "compileGroups": None,
- "backtrace": [
- {
- "file": "^custom/CMakeLists\\.txt$",
- "line": 3,
- "command": "add_custom_target",
- "hasParent": True,
- },
- {
- "file": "^custom/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": None,
- "artifacts": None,
- "build": "^custom$",
- "source": "^custom$",
- "install": None,
- "link": None,
- "archive": None,
- "dependencies": [
- {
- "id": "^ZERO_CHECK::@c11385ffed57b860da63$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "custom_exe",
- "id": "^custom_exe::@c11385ffed57b860da63$",
- "directorySource": "^custom$",
- "projectName": "Custom",
- "type": "EXECUTABLE",
- "isGeneratorProvided": None,
- "sources": [
- {
- "path": "^empty\\.c$",
- "isGenerated": None,
- "sourceGroupName": "Source Files",
- "compileGroupLanguage": "C",
- "backtrace": [
- {
- "file": "^custom/CMakeLists\\.txt$",
- "line": 4,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^custom/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "Source Files",
- "sourcePaths": [
- "^empty\\.c$",
- ],
- },
- ],
- "compileGroups": [
- {
- "language": "C",
- "sourcePaths": [
- "^empty\\.c$",
- ],
- "includes": None,
- "defines": None,
- "compileCommandFragments": None,
- },
- ],
- "backtrace": [
- {
- "file": "^custom/CMakeLists\\.txt$",
- "line": 4,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^custom/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": "^custom_exe(\\.exe)?$",
- "artifacts": [
- {
- "path": "^custom/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?custom_exe(\\.exe)?$",
- "_dllExtra": False,
- },
- {
- "path": "^custom/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?custom_exe\\.pdb$",
- "_dllExtra": True,
- },
- ],
- "build": "^custom$",
- "source": "^custom$",
- "install": None,
- "link": {
- "language": "C",
- "lto": None,
- "commandFragments": None,
- },
- "archive": None,
- "dependencies": [
- {
- "id": "^custom_tgt::@c11385ffed57b860da63$",
- "backtrace": [
- {
- "file": "^custom/CMakeLists\\.txt$",
- "line": 5,
- "command": "add_dependencies",
- "hasParent": True,
- },
- {
- "file": "^custom/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "id": "^ZERO_CHECK::@c11385ffed57b860da63$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "ALL_BUILD",
- "id": "^ALL_BUILD::@[0-9a-f]+$",
- "directorySource": "^.*/Tests/RunCMake/FileAPIExternalSource$",
- "projectName": "External",
- "type": "UTILITY",
- "isGeneratorProvided": True,
- "sources": [
- {
- "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ALL_BUILD$",
- "isGenerated": True,
- "sourceGroupName": "",
- "compileGroupLanguage": None,
- "backtrace": [
- {
- "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ALL_BUILD\\.rule$",
- "isGenerated": True,
- "sourceGroupName": "CMake Rules",
- "compileGroupLanguage": None,
- "backtrace": [
- {
- "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ALL_BUILD$",
- ],
- },
- {
- "name": "CMake Rules",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ALL_BUILD\\.rule$",
- ],
- },
- ],
- "compileGroups": None,
- "backtrace": [
- {
- "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": None,
- "artifacts": None,
- "build": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild$",
- "source": "^.*/Tests/RunCMake/FileAPIExternalSource$",
- "install": None,
- "link": None,
- "archive": None,
- "dependencies": [
- {
- "id": "^ZERO_CHECK::@[0-9a-f]+$",
- "backtrace": None,
- },
- {
- "id": "^generated_exe::@[0-9a-f]+$",
- "backtrace": None,
- },
- ],
- },
- {
- "name": "ZERO_CHECK",
- "id": "^ZERO_CHECK::@[0-9a-f]+$",
- "directorySource": "^.*/Tests/RunCMake/FileAPIExternalSource$",
- "projectName": "External",
- "type": "UTILITY",
- "isGeneratorProvided": True,
- "sources": [
- {
- "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ZERO_CHECK$",
- "isGenerated": True,
- "sourceGroupName": "",
- "compileGroupLanguage": None,
- "backtrace": [
- {
- "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ZERO_CHECK\\.rule$",
- "isGenerated": True,
- "sourceGroupName": "CMake Rules",
- "compileGroupLanguage": None,
- "backtrace": [
- {
- "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ZERO_CHECK$",
- ],
- },
- {
- "name": "CMake Rules",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ZERO_CHECK\\.rule$",
- ],
- },
- ],
- "compileGroups": None,
- "backtrace": [
- {
- "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": None,
- "artifacts": None,
- "build": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild$",
- "source": "^.*/Tests/RunCMake/FileAPIExternalSource$",
- "install": None,
- "link": None,
- "archive": None,
- "dependencies": None,
- },
- {
- "name": "generated_exe",
- "id": "^generated_exe::@[0-9a-f]+$",
- "directorySource": "^.*/Tests/RunCMake/FileAPIExternalSource$",
- "projectName": "External",
- "type": "EXECUTABLE",
- "isGeneratorProvided": None,
- "sources": [
- {
- "path": "^.*/Tests/RunCMake/FileAPIExternalSource/empty\\.c$",
- "isGenerated": None,
- "sourceGroupName": "Source Files",
- "compileGroupLanguage": "C",
- "backtrace": [
- {
- "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
- "line": 5,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/generated\\.cxx$",
- "isGenerated": True,
- "sourceGroupName": "Generated Source Files",
- "compileGroupLanguage": "CXX",
- "backtrace": [
- {
- "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
- "line": 6,
- "command": "target_sources",
- "hasParent": True,
- },
- {
- "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "sourceGroups": [
- {
- "name": "Source Files",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPIExternalSource/empty\\.c$",
- ],
- },
- {
- "name": "Generated Source Files",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/generated\\.cxx$",
- ],
- },
- ],
- "compileGroups": [
- {
- "language": "C",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPIExternalSource/empty\\.c$",
- ],
- "includes": [
- {
- "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild$",
- "isSystem": None,
- "backtrace": [
- {
- "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
- "line": 10,
- "command": "set_property",
- "hasParent": True,
- },
- {
- "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "path": "^.*/Tests/RunCMake/FileAPIExternalSource$",
- "isSystem": True,
- "backtrace": [
- {
- "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
- "line": 11,
- "command": "target_include_directories",
- "hasParent": True,
- },
- {
- "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "defines": [
- {
- "define": "EMPTY_C=1",
- "backtrace": [
- {
- "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
- "line": 9,
- "command": "set_property",
- "hasParent": True,
- },
- {
- "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "define": "SRC_DUMMY",
- "backtrace": [
- {
- "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
- "line": 9,
- "command": "set_property",
- "hasParent": True,
- },
- {
- "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "define": "GENERATED_EXE=1",
- "backtrace": [
- {
- "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
- "line": 12,
- "command": "target_compile_definitions",
- "hasParent": True,
- },
- {
- "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "define": "TGT_DUMMY",
- "backtrace": [
- {
- "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
- "line": 12,
- "command": "target_compile_definitions",
- "hasParent": True,
- },
- {
- "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "compileCommandFragments": [
- {
- "fragment" : "SRC_COMPILE_OPTIONS_DUMMY",
- "backtrace": [
- {
- "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
- "line": 13,
- "command": "set_source_files_properties",
- "hasParent": True,
- },
- {
- "file" : "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- }
- ],
- },
- {
- "language": "CXX",
- "sourcePaths": [
- "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/generated\\.cxx$",
- ],
- "includes": [
- {
- "path": "^.*/Tests/RunCMake/FileAPIExternalSource$",
- "isSystem": True,
- "backtrace": [
- {
- "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
- "line": 11,
- "command": "target_include_directories",
- "hasParent": True,
- },
- {
- "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "defines": [
- {
- "define": "GENERATED_EXE=1",
- "backtrace": [
- {
- "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
- "line": 12,
- "command": "target_compile_definitions",
- "hasParent": True,
- },
- {
- "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- {
- "define": "TGT_DUMMY",
- "backtrace": [
- {
- "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
- "line": 12,
- "command": "target_compile_definitions",
- "hasParent": True,
- },
- {
- "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- },
- ],
- "compileCommandFragments": None,
- },
- ],
- "backtrace": [
- {
- "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
- "line": 5,
- "command": "add_executable",
- "hasParent": True,
- },
- {
- "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
- "line": None,
- "command": None,
- "hasParent": False,
- },
- ],
- "folder": None,
- "nameOnDisk": "^generated_exe(\\.exe)?$",
- "artifacts": [
- {
- "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?generated_exe(\\.exe)?$",
- "_dllExtra": False,
- },
- {
- "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?generated_exe\\.pdb$",
- "_dllExtra": True,
- },
- ],
- "build": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild$",
- "source": "^.*/Tests/RunCMake/FileAPIExternalSource$",
- "install": None,
- "link": {
- "language": "CXX",
- "lto": None,
- "commandFragments": None,
- },
- "archive": None,
- "dependencies": [
- {
- "id": "^ZERO_CHECK::@[0-9a-f]+$",
- "backtrace": None,
- },
- ],
- },
+ read_codemodel_json_data("targets/all_build_top.json"),
+ read_codemodel_json_data("targets/zero_check_top.json"),
+ read_codemodel_json_data("targets/interface_exe.json"),
+ read_codemodel_json_data("targets/c_lib.json"),
+ read_codemodel_json_data("targets/c_exe.json"),
+ read_codemodel_json_data("targets/c_shared_lib.json"),
+ 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/all_build_cxx.json"),
+ read_codemodel_json_data("targets/zero_check_cxx.json"),
+ read_codemodel_json_data("targets/cxx_lib.json"),
+ read_codemodel_json_data("targets/cxx_exe.json"),
+ read_codemodel_json_data("targets/cxx_shared_lib.json"),
+ read_codemodel_json_data("targets/cxx_shared_exe.json"),
+ read_codemodel_json_data("targets/cxx_static_lib.json"),
+ read_codemodel_json_data("targets/cxx_static_exe.json"),
+
+ read_codemodel_json_data("targets/all_build_alias.json"),
+ read_codemodel_json_data("targets/zero_check_alias.json"),
+ read_codemodel_json_data("targets/c_alias_exe.json"),
+ read_codemodel_json_data("targets/cxx_alias_exe.json"),
+
+ read_codemodel_json_data("targets/all_build_object.json"),
+ read_codemodel_json_data("targets/zero_check_object.json"),
+ read_codemodel_json_data("targets/c_object_lib.json"),
+ read_codemodel_json_data("targets/c_object_exe.json"),
+ read_codemodel_json_data("targets/cxx_object_lib.json"),
+ read_codemodel_json_data("targets/cxx_object_exe.json"),
+
+ read_codemodel_json_data("targets/all_build_imported.json"),
+ read_codemodel_json_data("targets/zero_check_imported.json"),
+ read_codemodel_json_data("targets/link_imported_exe.json"),
+ read_codemodel_json_data("targets/link_imported_shared_exe.json"),
+ read_codemodel_json_data("targets/link_imported_static_exe.json"),
+ read_codemodel_json_data("targets/link_imported_object_exe.json"),
+ read_codemodel_json_data("targets/link_imported_interface_exe.json"),
+
+ read_codemodel_json_data("targets/all_build_custom.json"),
+ read_codemodel_json_data("targets/zero_check_custom.json"),
+ read_codemodel_json_data("targets/custom_tgt.json"),
+ read_codemodel_json_data("targets/custom_exe.json"),
+ read_codemodel_json_data("targets/all_build_external.json"),
+ read_codemodel_json_data("targets/zero_check_external.json"),
+ read_codemodel_json_data("targets/generated_exe.json"),
]
if not os.path.exists(os.path.join(reply_dir, "..", "..", "..", "..", "ipo_enabled.txt")):
@@ -5087,13 +578,13 @@ def gen_check_targets(c, g, inSource):
for s in e["sources"]:
s["path"] = s["path"].replace("^.*/Tests/RunCMake/FileAPI/", "^", 1)
if e["sourceGroups"] is not None:
- for g in e["sourceGroups"]:
- g["sourcePaths"] = [p.replace("^.*/Tests/RunCMake/FileAPI/", "^", 1) for p in g["sourcePaths"]]
+ for group in e["sourceGroups"]:
+ group["sourcePaths"] = [p.replace("^.*/Tests/RunCMake/FileAPI/", "^", 1) for p in group["sourcePaths"]]
if e["compileGroups"] is not None:
- for g in e["compileGroups"]:
- g["sourcePaths"] = [p.replace("^.*/Tests/RunCMake/FileAPI/", "^", 1) for p in g["sourcePaths"]]
+ for group in e["compileGroups"]:
+ group["sourcePaths"] = [p.replace("^.*/Tests/RunCMake/FileAPI/", "^", 1) for p in group["sourcePaths"]]
- if matches(g, "^Visual Studio "):
+ if matches(g["name"], "^Visual Studio "):
expected = filter_list(lambda e: e["name"] not in ("ZERO_CHECK") or e["id"] == "^ZERO_CHECK::@6890427a1f51a3e7e1df$", expected)
for e in expected:
if e["type"] == "UTILITY":
@@ -5130,7 +621,7 @@ def gen_check_targets(c, g, inSource):
if matches(d["id"], "^\\^ZERO_CHECK::@"):
d["id"] = "^ZERO_CHECK::@6890427a1f51a3e7e1df$"
- elif g == "Xcode":
+ elif g["name"] == "Xcode":
if ';' in os.environ.get("CMAKE_OSX_ARCHITECTURES", ""):
expected = filter_list(lambda e: e["name"] not in ("link_imported_object_exe"), expected)
for e in expected:
@@ -5164,134 +655,21 @@ def check_targets(c, g, inSource):
def gen_check_projects(c, g):
expected = [
- {
- "name": "codemodel-v2",
- "parentName": None,
- "childNames": [
- "Alias",
- "Custom",
- "Cxx",
- "Imported",
- "Object",
- "External",
- ],
- "directorySources": [
- "^\\.$",
- "^dir$",
- "^dir/dir$",
- ],
- "targetIds": [
- "^ALL_BUILD::@6890427a1f51a3e7e1df$",
- "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
- "^interface_exe::@6890427a1f51a3e7e1df$",
- "^c_lib::@6890427a1f51a3e7e1df$",
- "^c_exe::@6890427a1f51a3e7e1df$",
- "^c_shared_lib::@6890427a1f51a3e7e1df$",
- "^c_shared_exe::@6890427a1f51a3e7e1df$",
- "^c_static_lib::@6890427a1f51a3e7e1df$",
- "^c_static_exe::@6890427a1f51a3e7e1df$",
- ],
- },
- {
- "name": "Cxx",
- "parentName": "codemodel-v2",
- "childNames": None,
- "directorySources": [
- "^cxx$",
- ],
- "targetIds": [
- "^ALL_BUILD::@a56b12a3f5c0529fb296$",
- "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
- "^cxx_lib::@a56b12a3f5c0529fb296$",
- "^cxx_exe::@a56b12a3f5c0529fb296$",
- "^cxx_shared_lib::@a56b12a3f5c0529fb296$",
- "^cxx_shared_exe::@a56b12a3f5c0529fb296$",
- "^cxx_static_lib::@a56b12a3f5c0529fb296$",
- "^cxx_static_exe::@a56b12a3f5c0529fb296$",
- ],
- },
- {
- "name": "Alias",
- "parentName": "codemodel-v2",
- "childNames": None,
- "directorySources": [
- "^alias$",
- ],
- "targetIds": [
- "^ALL_BUILD::@53632cba2752272bb008$",
- "^ZERO_CHECK::@53632cba2752272bb008$",
- "^c_alias_exe::@53632cba2752272bb008$",
- "^cxx_alias_exe::@53632cba2752272bb008$",
- ],
- },
- {
- "name": "Object",
- "parentName": "codemodel-v2",
- "childNames": None,
- "directorySources": [
- "^object$",
- ],
- "targetIds": [
- "^ALL_BUILD::@5ed5358f70faf8d8af7a$",
- "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
- "^c_object_lib::@5ed5358f70faf8d8af7a$",
- "^c_object_exe::@5ed5358f70faf8d8af7a$",
- "^cxx_object_lib::@5ed5358f70faf8d8af7a$",
- "^cxx_object_exe::@5ed5358f70faf8d8af7a$",
- ],
- },
- {
- "name": "Imported",
- "parentName": "codemodel-v2",
- "childNames": None,
- "directorySources": [
- "^imported$",
- ],
- "targetIds": [
- "^ALL_BUILD::@ba7eb709d0b48779c6c8$",
- "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
- "^link_imported_exe::@ba7eb709d0b48779c6c8$",
- "^link_imported_shared_exe::@ba7eb709d0b48779c6c8$",
- "^link_imported_static_exe::@ba7eb709d0b48779c6c8$",
- "^link_imported_object_exe::@ba7eb709d0b48779c6c8$",
- "^link_imported_interface_exe::@ba7eb709d0b48779c6c8$",
- ],
- },
- {
- "name": "Custom",
- "parentName": "codemodel-v2",
- "childNames": None,
- "directorySources": [
- "^custom$",
- ],
- "targetIds": [
- "^ALL_BUILD::@c11385ffed57b860da63$",
- "^ZERO_CHECK::@c11385ffed57b860da63$",
- "^custom_tgt::@c11385ffed57b860da63$",
- "^custom_exe::@c11385ffed57b860da63$",
- ],
- },
- {
- "name": "External",
- "parentName": "codemodel-v2",
- "childNames": None,
- "directorySources": [
- "^.*/Tests/RunCMake/FileAPIExternalSource$",
- ],
- "targetIds": [
- "^ALL_BUILD::@[0-9a-f]+$",
- "^ZERO_CHECK::@[0-9a-f]+$",
- "^generated_exe::@[0-9a-f]+$",
- ],
- },
+ read_codemodel_json_data("projects/codemodel-v2.json"),
+ read_codemodel_json_data("projects/cxx.json"),
+ read_codemodel_json_data("projects/alias.json"),
+ read_codemodel_json_data("projects/object.json"),
+ read_codemodel_json_data("projects/imported.json"),
+ read_codemodel_json_data("projects/custom.json"),
+ read_codemodel_json_data("projects/external.json"),
]
- if matches(g, "^Visual Studio "):
+ if matches(g["name"], "^Visual Studio "):
for e in expected:
if e["parentName"] is not None:
e["targetIds"] = filter_list(lambda t: not matches(t, "^\\^ZERO_CHECK"), e["targetIds"])
- elif g == "Xcode":
+ elif g["name"] == "Xcode":
if ';' in os.environ.get("CMAKE_OSX_ARCHITECTURES", ""):
for e in expected:
e["targetIds"] = filter_list(lambda t: not matches(t, "^\\^(link_imported_object_exe)"), e["targetIds"])
@@ -5327,7 +705,7 @@ def check_object_codemodel(g):
inSource = os.path.dirname(o["paths"]["build"]) == o["paths"]["source"]
- if matches(g, "^(Visual Studio |Xcode$)"):
+ if g["multiConfig"]:
assert sorted([c["name"] for c in o["configurations"]]) == ["Debug", "MinSizeRel", "RelWithDebInfo", "Release"]
else:
assert len(o["configurations"]) == 1
@@ -5339,4 +717,4 @@ def check_object_codemodel(g):
assert is_dict(index)
assert sorted(index.keys()) == ["cmake", "objects", "reply"]
-check_objects(index["objects"], index["cmake"]["generator"]["name"])
+check_objects(index["objects"], index["cmake"]["generator"])
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/alias.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/alias.json
new file mode 100644
index 0000000..9f0c48a
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/alias.json
@@ -0,0 +1,15 @@
+{
+ "source": "^alias$",
+ "build": "^alias$",
+ "parentSource": "^\\.$",
+ "childSources": null,
+ "targetIds": [
+ "^ALL_BUILD::@53632cba2752272bb008$",
+ "^ZERO_CHECK::@53632cba2752272bb008$",
+ "^c_alias_exe::@53632cba2752272bb008$",
+ "^cxx_alias_exe::@53632cba2752272bb008$"
+ ],
+ "projectName": "Alias",
+ "minimumCMakeVersion": "3.12",
+ "hasInstallRule": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/custom.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/custom.json
new file mode 100644
index 0000000..afd41f3
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/custom.json
@@ -0,0 +1,15 @@
+{
+ "source": "^custom$",
+ "build": "^custom$",
+ "parentSource": "^\\.$",
+ "childSources": null,
+ "targetIds": [
+ "^ALL_BUILD::@c11385ffed57b860da63$",
+ "^ZERO_CHECK::@c11385ffed57b860da63$",
+ "^custom_exe::@c11385ffed57b860da63$",
+ "^custom_tgt::@c11385ffed57b860da63$"
+ ],
+ "projectName": "Custom",
+ "minimumCMakeVersion": "3.12",
+ "hasInstallRule": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/cxx.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/cxx.json
new file mode 100644
index 0000000..ebe717a
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/cxx.json
@@ -0,0 +1,19 @@
+{
+ "source": "^cxx$",
+ "build": "^cxx$",
+ "parentSource": "^\\.$",
+ "childSources": null,
+ "targetIds": [
+ "^ALL_BUILD::@a56b12a3f5c0529fb296$",
+ "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
+ "^cxx_exe::@a56b12a3f5c0529fb296$",
+ "^cxx_lib::@a56b12a3f5c0529fb296$",
+ "^cxx_shared_exe::@a56b12a3f5c0529fb296$",
+ "^cxx_shared_lib::@a56b12a3f5c0529fb296$",
+ "^cxx_static_exe::@a56b12a3f5c0529fb296$",
+ "^cxx_static_lib::@a56b12a3f5c0529fb296$"
+ ],
+ "projectName": "Cxx",
+ "minimumCMakeVersion": "3.12",
+ "hasInstallRule": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/dir.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/dir.json
new file mode 100644
index 0000000..afbd43a
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/dir.json
@@ -0,0 +1,12 @@
+{
+ "source": "^dir$",
+ "build": "^dir$",
+ "parentSource": "^\\.$",
+ "childSources": [
+ "^dir/dir$"
+ ],
+ "targetIds": null,
+ "projectName": "codemodel-v2",
+ "minimumCMakeVersion": "3.12",
+ "hasInstallRule": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/dir_dir.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/dir_dir.json
new file mode 100644
index 0000000..3737ad5
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/dir_dir.json
@@ -0,0 +1,10 @@
+{
+ "source": "^dir/dir$",
+ "build": "^dir/dir$",
+ "parentSource": "^dir$",
+ "childSources": null,
+ "targetIds": null,
+ "projectName": "codemodel-v2",
+ "minimumCMakeVersion": "3.12",
+ "hasInstallRule": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/external.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/external.json
new file mode 100644
index 0000000..521e3c7
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/external.json
@@ -0,0 +1,14 @@
+{
+ "source": "^.*/Tests/RunCMake/FileAPIExternalSource$",
+ "build": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild$",
+ "parentSource": "^\\.$",
+ "childSources": null,
+ "targetIds": [
+ "^ALL_BUILD::@[0-9a-f]+$",
+ "^ZERO_CHECK::@[0-9a-f]+$",
+ "^generated_exe::@[0-9a-f]+$"
+ ],
+ "projectName": "External",
+ "minimumCMakeVersion": "3.12",
+ "hasInstallRule": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/imported.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/imported.json
new file mode 100644
index 0000000..a41b79b
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/imported.json
@@ -0,0 +1,18 @@
+{
+ "source": "^imported$",
+ "build": "^imported$",
+ "parentSource": "^\\.$",
+ "childSources": null,
+ "targetIds": [
+ "^ALL_BUILD::@ba7eb709d0b48779c6c8$",
+ "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
+ "^link_imported_exe::@ba7eb709d0b48779c6c8$",
+ "^link_imported_interface_exe::@ba7eb709d0b48779c6c8$",
+ "^link_imported_object_exe::@ba7eb709d0b48779c6c8$",
+ "^link_imported_shared_exe::@ba7eb709d0b48779c6c8$",
+ "^link_imported_static_exe::@ba7eb709d0b48779c6c8$"
+ ],
+ "projectName": "Imported",
+ "minimumCMakeVersion": "3.12",
+ "hasInstallRule": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/object.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/object.json
new file mode 100644
index 0000000..1e647ad
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/object.json
@@ -0,0 +1,17 @@
+{
+ "source": "^object$",
+ "build": "^object$",
+ "parentSource": "^\\.$",
+ "childSources": null,
+ "targetIds": [
+ "^ALL_BUILD::@5ed5358f70faf8d8af7a$",
+ "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
+ "^c_object_exe::@5ed5358f70faf8d8af7a$",
+ "^c_object_lib::@5ed5358f70faf8d8af7a$",
+ "^cxx_object_exe::@5ed5358f70faf8d8af7a$",
+ "^cxx_object_lib::@5ed5358f70faf8d8af7a$"
+ ],
+ "projectName": "Object",
+ "minimumCMakeVersion": "3.13",
+ "hasInstallRule": true
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json
new file mode 100644
index 0000000..c144953
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json
@@ -0,0 +1,28 @@
+{
+ "source": "^\\.$",
+ "build": "^\\.$",
+ "parentSource": null,
+ "childSources": [
+ "^alias$",
+ "^custom$",
+ "^cxx$",
+ "^imported$",
+ "^object$",
+ "^.*/Tests/RunCMake/FileAPIExternalSource$",
+ "^dir$"
+ ],
+ "targetIds": [
+ "^ALL_BUILD::@6890427a1f51a3e7e1df$",
+ "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
+ "^c_exe::@6890427a1f51a3e7e1df$",
+ "^c_lib::@6890427a1f51a3e7e1df$",
+ "^c_shared_exe::@6890427a1f51a3e7e1df$",
+ "^c_shared_lib::@6890427a1f51a3e7e1df$",
+ "^c_static_exe::@6890427a1f51a3e7e1df$",
+ "^c_static_lib::@6890427a1f51a3e7e1df$",
+ "^interface_exe::@6890427a1f51a3e7e1df$"
+ ],
+ "projectName": "codemodel-v2",
+ "minimumCMakeVersion": "3.12",
+ "hasInstallRule": true
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/alias.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/alias.json
new file mode 100644
index 0000000..8ede60f
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/alias.json
@@ -0,0 +1,14 @@
+{
+ "name": "Alias",
+ "parentName": "codemodel-v2",
+ "childNames": null,
+ "directorySources": [
+ "^alias$"
+ ],
+ "targetIds": [
+ "^ALL_BUILD::@53632cba2752272bb008$",
+ "^ZERO_CHECK::@53632cba2752272bb008$",
+ "^c_alias_exe::@53632cba2752272bb008$",
+ "^cxx_alias_exe::@53632cba2752272bb008$"
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/codemodel-v2.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/codemodel-v2.json
new file mode 100644
index 0000000..f3aac63
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/codemodel-v2.json
@@ -0,0 +1,28 @@
+{
+ "name": "codemodel-v2",
+ "parentName": null,
+ "childNames": [
+ "Alias",
+ "Custom",
+ "Cxx",
+ "Imported",
+ "Object",
+ "External"
+ ],
+ "directorySources": [
+ "^\\.$",
+ "^dir$",
+ "^dir/dir$"
+ ],
+ "targetIds": [
+ "^ALL_BUILD::@6890427a1f51a3e7e1df$",
+ "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
+ "^interface_exe::@6890427a1f51a3e7e1df$",
+ "^c_lib::@6890427a1f51a3e7e1df$",
+ "^c_exe::@6890427a1f51a3e7e1df$",
+ "^c_shared_lib::@6890427a1f51a3e7e1df$",
+ "^c_shared_exe::@6890427a1f51a3e7e1df$",
+ "^c_static_lib::@6890427a1f51a3e7e1df$",
+ "^c_static_exe::@6890427a1f51a3e7e1df$"
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/custom.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/custom.json
new file mode 100644
index 0000000..0aeb727
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/custom.json
@@ -0,0 +1,14 @@
+{
+ "name": "Custom",
+ "parentName": "codemodel-v2",
+ "childNames": null,
+ "directorySources": [
+ "^custom$"
+ ],
+ "targetIds": [
+ "^ALL_BUILD::@c11385ffed57b860da63$",
+ "^ZERO_CHECK::@c11385ffed57b860da63$",
+ "^custom_tgt::@c11385ffed57b860da63$",
+ "^custom_exe::@c11385ffed57b860da63$"
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/cxx.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/cxx.json
new file mode 100644
index 0000000..296ae6c
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/cxx.json
@@ -0,0 +1,18 @@
+{
+ "name": "Cxx",
+ "parentName": "codemodel-v2",
+ "childNames": null,
+ "directorySources": [
+ "^cxx$"
+ ],
+ "targetIds": [
+ "^ALL_BUILD::@a56b12a3f5c0529fb296$",
+ "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
+ "^cxx_lib::@a56b12a3f5c0529fb296$",
+ "^cxx_exe::@a56b12a3f5c0529fb296$",
+ "^cxx_shared_lib::@a56b12a3f5c0529fb296$",
+ "^cxx_shared_exe::@a56b12a3f5c0529fb296$",
+ "^cxx_static_lib::@a56b12a3f5c0529fb296$",
+ "^cxx_static_exe::@a56b12a3f5c0529fb296$"
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/external.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/external.json
new file mode 100644
index 0000000..3c9afff
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/external.json
@@ -0,0 +1,13 @@
+{
+ "name": "External",
+ "parentName": "codemodel-v2",
+ "childNames": null,
+ "directorySources": [
+ "^.*/Tests/RunCMake/FileAPIExternalSource$"
+ ],
+ "targetIds": [
+ "^ALL_BUILD::@[0-9a-f]+$",
+ "^ZERO_CHECK::@[0-9a-f]+$",
+ "^generated_exe::@[0-9a-f]+$"
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/imported.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/imported.json
new file mode 100644
index 0000000..dc40b72
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/imported.json
@@ -0,0 +1,17 @@
+{
+ "name": "Imported",
+ "parentName": "codemodel-v2",
+ "childNames": null,
+ "directorySources": [
+ "^imported$"
+ ],
+ "targetIds": [
+ "^ALL_BUILD::@ba7eb709d0b48779c6c8$",
+ "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
+ "^link_imported_exe::@ba7eb709d0b48779c6c8$",
+ "^link_imported_shared_exe::@ba7eb709d0b48779c6c8$",
+ "^link_imported_static_exe::@ba7eb709d0b48779c6c8$",
+ "^link_imported_object_exe::@ba7eb709d0b48779c6c8$",
+ "^link_imported_interface_exe::@ba7eb709d0b48779c6c8$"
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/object.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/object.json
new file mode 100644
index 0000000..219f4eb
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/object.json
@@ -0,0 +1,16 @@
+{
+ "name": "Object",
+ "parentName": "codemodel-v2",
+ "childNames": null,
+ "directorySources": [
+ "^object$"
+ ],
+ "targetIds": [
+ "^ALL_BUILD::@5ed5358f70faf8d8af7a$",
+ "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
+ "^c_object_lib::@5ed5358f70faf8d8af7a$",
+ "^c_object_exe::@5ed5358f70faf8d8af7a$",
+ "^cxx_object_lib::@5ed5358f70faf8d8af7a$",
+ "^cxx_object_exe::@5ed5358f70faf8d8af7a$"
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_alias.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_alias.json
new file mode 100644
index 0000000..eabf739
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_alias.json
@@ -0,0 +1,83 @@
+{
+ "name": "ALL_BUILD",
+ "id": "^ALL_BUILD::@53632cba2752272bb008$",
+ "directorySource": "^alias$",
+ "projectName": "Alias",
+ "type": "UTILITY",
+ "isGeneratorProvided": true,
+ "sources": [
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ALL_BUILD$",
+ "isGenerated": true,
+ "sourceGroupName": "",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^alias/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ALL_BUILD\\.rule$",
+ "isGenerated": true,
+ "sourceGroupName": "CMake Rules",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^alias/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ALL_BUILD$"
+ ]
+ },
+ {
+ "name": "CMake Rules",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ALL_BUILD\\.rule$"
+ ]
+ }
+ ],
+ "compileGroups": null,
+ "backtrace": [
+ {
+ "file": "^alias/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": null,
+ "artifacts": null,
+ "build": "^alias$",
+ "source": "^alias$",
+ "install": null,
+ "link": null,
+ "archive": null,
+ "dependencies": [
+ {
+ "id": "^ZERO_CHECK::@53632cba2752272bb008$",
+ "backtrace": null
+ },
+ {
+ "id": "^c_alias_exe::@53632cba2752272bb008$",
+ "backtrace": null
+ },
+ {
+ "id": "^cxx_alias_exe::@53632cba2752272bb008$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_custom.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_custom.json
new file mode 100644
index 0000000..a5ff686
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_custom.json
@@ -0,0 +1,79 @@
+{
+ "name": "ALL_BUILD",
+ "id": "^ALL_BUILD::@c11385ffed57b860da63$",
+ "directorySource": "^custom$",
+ "projectName": "Custom",
+ "type": "UTILITY",
+ "isGeneratorProvided": true,
+ "sources": [
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ALL_BUILD$",
+ "isGenerated": true,
+ "sourceGroupName": "",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^custom/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ALL_BUILD\\.rule$",
+ "isGenerated": true,
+ "sourceGroupName": "CMake Rules",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^custom/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ALL_BUILD$"
+ ]
+ },
+ {
+ "name": "CMake Rules",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ALL_BUILD\\.rule$"
+ ]
+ }
+ ],
+ "compileGroups": null,
+ "backtrace": [
+ {
+ "file": "^custom/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": null,
+ "artifacts": null,
+ "build": "^custom$",
+ "source": "^custom$",
+ "install": null,
+ "link": null,
+ "archive": null,
+ "dependencies": [
+ {
+ "id": "^ZERO_CHECK::@c11385ffed57b860da63$",
+ "backtrace": null
+ },
+ {
+ "id": "^custom_exe::@c11385ffed57b860da63$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_cxx.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_cxx.json
new file mode 100644
index 0000000..92a7944
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_cxx.json
@@ -0,0 +1,99 @@
+{
+ "name": "ALL_BUILD",
+ "id": "^ALL_BUILD::@a56b12a3f5c0529fb296$",
+ "directorySource": "^cxx$",
+ "projectName": "Cxx",
+ "type": "UTILITY",
+ "isGeneratorProvided": true,
+ "sources": [
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ALL_BUILD$",
+ "isGenerated": true,
+ "sourceGroupName": "",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ALL_BUILD\\.rule$",
+ "isGenerated": true,
+ "sourceGroupName": "CMake Rules",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ALL_BUILD$"
+ ]
+ },
+ {
+ "name": "CMake Rules",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ALL_BUILD\\.rule$"
+ ]
+ }
+ ],
+ "compileGroups": null,
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": null,
+ "artifacts": null,
+ "build": "^cxx$",
+ "source": "^cxx$",
+ "install": null,
+ "link": null,
+ "archive": null,
+ "dependencies": [
+ {
+ "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
+ "backtrace": null
+ },
+ {
+ "id": "^cxx_lib::@a56b12a3f5c0529fb296$",
+ "backtrace": null
+ },
+ {
+ "id": "^cxx_exe::@a56b12a3f5c0529fb296$",
+ "backtrace": null
+ },
+ {
+ "id": "^cxx_shared_lib::@a56b12a3f5c0529fb296$",
+ "backtrace": null
+ },
+ {
+ "id": "^cxx_shared_exe::@a56b12a3f5c0529fb296$",
+ "backtrace": null
+ },
+ {
+ "id": "^cxx_static_lib::@a56b12a3f5c0529fb296$",
+ "backtrace": null
+ },
+ {
+ "id": "^cxx_static_exe::@a56b12a3f5c0529fb296$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_external.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_external.json
new file mode 100644
index 0000000..017335c
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_external.json
@@ -0,0 +1,79 @@
+{
+ "name": "ALL_BUILD",
+ "id": "^ALL_BUILD::@[0-9a-f]+$",
+ "directorySource": "^.*/Tests/RunCMake/FileAPIExternalSource$",
+ "projectName": "External",
+ "type": "UTILITY",
+ "isGeneratorProvided": true,
+ "sources": [
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ALL_BUILD$",
+ "isGenerated": true,
+ "sourceGroupName": "",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ALL_BUILD\\.rule$",
+ "isGenerated": true,
+ "sourceGroupName": "CMake Rules",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ALL_BUILD$"
+ ]
+ },
+ {
+ "name": "CMake Rules",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ALL_BUILD\\.rule$"
+ ]
+ }
+ ],
+ "compileGroups": null,
+ "backtrace": [
+ {
+ "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": null,
+ "artifacts": null,
+ "build": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild$",
+ "source": "^.*/Tests/RunCMake/FileAPIExternalSource$",
+ "install": null,
+ "link": null,
+ "archive": null,
+ "dependencies": [
+ {
+ "id": "^ZERO_CHECK::@[0-9a-f]+$",
+ "backtrace": null
+ },
+ {
+ "id": "^generated_exe::@[0-9a-f]+$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_imported.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_imported.json
new file mode 100644
index 0000000..2de5b15
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_imported.json
@@ -0,0 +1,95 @@
+{
+ "name": "ALL_BUILD",
+ "id": "^ALL_BUILD::@ba7eb709d0b48779c6c8$",
+ "directorySource": "^imported$",
+ "projectName": "Imported",
+ "type": "UTILITY",
+ "isGeneratorProvided": true,
+ "sources": [
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ALL_BUILD$",
+ "isGenerated": true,
+ "sourceGroupName": "",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^imported/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ALL_BUILD\\.rule$",
+ "isGenerated": true,
+ "sourceGroupName": "CMake Rules",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^imported/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ALL_BUILD$"
+ ]
+ },
+ {
+ "name": "CMake Rules",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ALL_BUILD\\.rule$"
+ ]
+ }
+ ],
+ "compileGroups": null,
+ "backtrace": [
+ {
+ "file": "^imported/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": null,
+ "artifacts": null,
+ "build": "^imported$",
+ "source": "^imported$",
+ "install": null,
+ "link": null,
+ "archive": null,
+ "dependencies": [
+ {
+ "id": "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
+ "backtrace": null
+ },
+ {
+ "id": "^link_imported_exe::@ba7eb709d0b48779c6c8$",
+ "backtrace": null
+ },
+ {
+ "id": "^link_imported_shared_exe::@ba7eb709d0b48779c6c8$",
+ "backtrace": null
+ },
+ {
+ "id": "^link_imported_static_exe::@ba7eb709d0b48779c6c8$",
+ "backtrace": null
+ },
+ {
+ "id": "^link_imported_object_exe::@ba7eb709d0b48779c6c8$",
+ "backtrace": null
+ },
+ {
+ "id": "^link_imported_interface_exe::@ba7eb709d0b48779c6c8$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_object.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_object.json
new file mode 100644
index 0000000..9d8899a
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_object.json
@@ -0,0 +1,91 @@
+{
+ "name": "ALL_BUILD",
+ "id": "^ALL_BUILD::@5ed5358f70faf8d8af7a$",
+ "directorySource": "^object$",
+ "projectName": "Object",
+ "type": "UTILITY",
+ "isGeneratorProvided": true,
+ "sources": [
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ALL_BUILD$",
+ "isGenerated": true,
+ "sourceGroupName": "",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ALL_BUILD\\.rule$",
+ "isGenerated": true,
+ "sourceGroupName": "CMake Rules",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ALL_BUILD$"
+ ]
+ },
+ {
+ "name": "CMake Rules",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ALL_BUILD\\.rule$"
+ ]
+ }
+ ],
+ "compileGroups": null,
+ "backtrace": [
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": null,
+ "artifacts": null,
+ "build": "^object$",
+ "source": "^object$",
+ "install": null,
+ "link": null,
+ "archive": null,
+ "dependencies": [
+ {
+ "id": "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
+ "backtrace": null
+ },
+ {
+ "id": "^c_object_lib::@5ed5358f70faf8d8af7a$",
+ "backtrace": null
+ },
+ {
+ "id": "^c_object_exe::@5ed5358f70faf8d8af7a$",
+ "backtrace": null
+ },
+ {
+ "id": "^cxx_object_lib::@5ed5358f70faf8d8af7a$",
+ "backtrace": null
+ },
+ {
+ "id": "^cxx_object_exe::@5ed5358f70faf8d8af7a$",
+ "backtrace": null
+ }
+ ]
+}
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
new file mode 100644
index 0000000..b4def78
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_top.json
@@ -0,0 +1,179 @@
+{
+ "name": "ALL_BUILD",
+ "id": "^ALL_BUILD::@6890427a1f51a3e7e1df$",
+ "directorySource": "^\\.$",
+ "projectName": "codemodel-v2",
+ "type": "UTILITY",
+ "isGeneratorProvided": true,
+ "sources": [
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ALL_BUILD$",
+ "isGenerated": true,
+ "sourceGroupName": "",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ALL_BUILD\\.rule$",
+ "isGenerated": true,
+ "sourceGroupName": "CMake Rules",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ALL_BUILD$"
+ ]
+ },
+ {
+ "name": "CMake Rules",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ALL_BUILD\\.rule$"
+ ]
+ }
+ ],
+ "compileGroups": null,
+ "backtrace": [
+ {
+ "file": "^CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": null,
+ "artifacts": null,
+ "build": "^\\.$",
+ "source": "^\\.$",
+ "install": null,
+ "link": null,
+ "archive": null,
+ "dependencies": [
+ {
+ "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
+ "backtrace": null
+ },
+ {
+ "id": "^interface_exe::@6890427a1f51a3e7e1df$",
+ "backtrace": null
+ },
+ {
+ "id": "^c_lib::@6890427a1f51a3e7e1df$",
+ "backtrace": null
+ },
+ {
+ "id": "^c_exe::@6890427a1f51a3e7e1df$",
+ "backtrace": null
+ },
+ {
+ "id": "^c_shared_lib::@6890427a1f51a3e7e1df$",
+ "backtrace": null
+ },
+ {
+ "id": "^c_shared_exe::@6890427a1f51a3e7e1df$",
+ "backtrace": null
+ },
+ {
+ "id": "^c_static_lib::@6890427a1f51a3e7e1df$",
+ "backtrace": null
+ },
+ {
+ "id": "^c_static_exe::@6890427a1f51a3e7e1df$",
+ "backtrace": null
+ },
+ {
+ "id": "^c_alias_exe::@53632cba2752272bb008$",
+ "backtrace": null
+ },
+ {
+ "id": "^cxx_alias_exe::@53632cba2752272bb008$",
+ "backtrace": null
+ },
+ {
+ "id": "^cxx_lib::@a56b12a3f5c0529fb296$",
+ "backtrace": null
+ },
+ {
+ "id": "^cxx_exe::@a56b12a3f5c0529fb296$",
+ "backtrace": null
+ },
+ {
+ "id": "^cxx_shared_lib::@a56b12a3f5c0529fb296$",
+ "backtrace": null
+ },
+ {
+ "id": "^cxx_shared_exe::@a56b12a3f5c0529fb296$",
+ "backtrace": null
+ },
+ {
+ "id": "^cxx_static_lib::@a56b12a3f5c0529fb296$",
+ "backtrace": null
+ },
+ {
+ "id": "^cxx_static_exe::@a56b12a3f5c0529fb296$",
+ "backtrace": null
+ },
+ {
+ "id": "^c_object_lib::@5ed5358f70faf8d8af7a$",
+ "backtrace": null
+ },
+ {
+ "id": "^c_object_exe::@5ed5358f70faf8d8af7a$",
+ "backtrace": null
+ },
+ {
+ "id": "^cxx_object_lib::@5ed5358f70faf8d8af7a$",
+ "backtrace": null
+ },
+ {
+ "id": "^cxx_object_exe::@5ed5358f70faf8d8af7a$",
+ "backtrace": null
+ },
+ {
+ "id": "^link_imported_exe::@ba7eb709d0b48779c6c8$",
+ "backtrace": null
+ },
+ {
+ "id": "^link_imported_shared_exe::@ba7eb709d0b48779c6c8$",
+ "backtrace": null
+ },
+ {
+ "id": "^link_imported_static_exe::@ba7eb709d0b48779c6c8$",
+ "backtrace": null
+ },
+ {
+ "id": "^link_imported_object_exe::@ba7eb709d0b48779c6c8$",
+ "backtrace": null
+ },
+ {
+ "id": "^link_imported_interface_exe::@ba7eb709d0b48779c6c8$",
+ "backtrace": null
+ },
+ {
+ "id": "^custom_exe::@c11385ffed57b860da63$",
+ "backtrace": null
+ },
+ {
+ "id": "^generated_exe::@[0-9a-f]+$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_alias_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_alias_exe.json
new file mode 100644
index 0000000..ac7c94d
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_alias_exe.json
@@ -0,0 +1,107 @@
+{
+ "name": "c_alias_exe",
+ "id": "^c_alias_exe::@53632cba2752272bb008$",
+ "directorySource": "^alias$",
+ "projectName": "Alias",
+ "type": "EXECUTABLE",
+ "isGeneratorProvided": null,
+ "sources": [
+ {
+ "path": "^empty\\.c$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "C",
+ "backtrace": [
+ {
+ "file": "^alias/CMakeLists\\.txt$",
+ "line": 5,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^alias/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "Source Files",
+ "sourcePaths": [
+ "^empty\\.c$"
+ ]
+ }
+ ],
+ "compileGroups": [
+ {
+ "language": "C",
+ "sourcePaths": [
+ "^empty\\.c$"
+ ],
+ "includes": null,
+ "defines": null,
+ "compileCommandFragments": null
+ }
+ ],
+ "backtrace": [
+ {
+ "file": "^alias/CMakeLists\\.txt$",
+ "line": 5,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^alias/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": "^c_alias_exe(\\.exe)?$",
+ "artifacts": [
+ {
+ "path": "^alias/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_alias_exe(\\.exe)?$",
+ "_dllExtra": false
+ },
+ {
+ "path": "^alias/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_alias_exe\\.pdb$",
+ "_dllExtra": true
+ }
+ ],
+ "build": "^alias$",
+ "source": "^alias$",
+ "install": null,
+ "link": {
+ "language": "C",
+ "lto": null,
+ "commandFragments": null
+ },
+ "archive": null,
+ "dependencies": [
+ {
+ "id": "^c_lib::@6890427a1f51a3e7e1df$",
+ "backtrace": [
+ {
+ "file": "^alias/CMakeLists\\.txt$",
+ "line": 6,
+ "command": "target_link_libraries",
+ "hasParent": true
+ },
+ {
+ "file": "^alias/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "id": "^ZERO_CHECK::@53632cba2752272bb008$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_exe.json
new file mode 100644
index 0000000..7af74c4
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_exe.json
@@ -0,0 +1,143 @@
+{
+ "name": "c_exe",
+ "id": "^c_exe::@6890427a1f51a3e7e1df$",
+ "directorySource": "^\\.$",
+ "projectName": "codemodel-v2",
+ "type": "EXECUTABLE",
+ "isGeneratorProvided": null,
+ "sources": [
+ {
+ "path": "^empty\\.c$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "C",
+ "backtrace": [
+ {
+ "file": "^codemodel-v2\\.cmake$",
+ "line": 6,
+ "command": "add_executable",
+ "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
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "Source Files",
+ "sourcePaths": [
+ "^empty\\.c$"
+ ]
+ }
+ ],
+ "compileGroups": [
+ {
+ "language": "C",
+ "sourcePaths": [
+ "^empty\\.c$"
+ ],
+ "includes": null,
+ "defines": null,
+ "compileCommandFragments": null
+ }
+ ],
+ "backtrace": [
+ {
+ "file": "^codemodel-v2\\.cmake$",
+ "line": 6,
+ "command": "add_executable",
+ "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": "^c_exe(\\.exe)?$",
+ "artifacts": [
+ {
+ "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_exe(\\.exe)?$",
+ "_dllExtra": false
+ },
+ {
+ "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_exe\\.pdb$",
+ "_dllExtra": true
+ }
+ ],
+ "build": "^\\.$",
+ "source": "^\\.$",
+ "install": null,
+ "link": {
+ "language": "C",
+ "lto": null,
+ "commandFragments": null
+ },
+ "archive": null,
+ "dependencies": [
+ {
+ "id": "^c_lib::@6890427a1f51a3e7e1df$",
+ "backtrace": [
+ {
+ "file": "^codemodel-v2\\.cmake$",
+ "line": 7,
+ "command": "target_link_libraries",
+ "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
+ }
+ ]
+ },
+ {
+ "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_lib.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_lib.json
new file mode 100644
index 0000000..0ca1962
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_lib.json
@@ -0,0 +1,108 @@
+{
+ "name": "c_lib",
+ "id": "^c_lib::@6890427a1f51a3e7e1df$",
+ "directorySource": "^\\.$",
+ "projectName": "codemodel-v2",
+ "type": "STATIC_LIBRARY",
+ "isGeneratorProvided": null,
+ "sources": [
+ {
+ "path": "^empty\\.c$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "C",
+ "backtrace": [
+ {
+ "file": "^codemodel-v2\\.cmake$",
+ "line": 5,
+ "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
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "Source Files",
+ "sourcePaths": [
+ "^empty\\.c$"
+ ]
+ }
+ ],
+ "compileGroups": [
+ {
+ "language": "C",
+ "sourcePaths": [
+ "^empty\\.c$"
+ ],
+ "includes": null,
+ "defines": null,
+ "compileCommandFragments": null
+ }
+ ],
+ "backtrace": [
+ {
+ "file": "^codemodel-v2\\.cmake$",
+ "line": 5,
+ "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_lib\\.(a|lib)$",
+ "artifacts": [
+ {
+ "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib)?c_lib\\.(a|lib)$",
+ "_dllExtra": false
+ }
+ ],
+ "build": "^\\.$",
+ "source": "^\\.$",
+ "install": null,
+ "link": null,
+ "archive": {
+ "lto": null
+ },
+ "dependencies": [
+ {
+ "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_object_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_object_exe.json
new file mode 100644
index 0000000..3c9ace3
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_object_exe.json
@@ -0,0 +1,154 @@
+{
+ "name": "c_object_exe",
+ "id": "^c_object_exe::@5ed5358f70faf8d8af7a$",
+ "directorySource": "^object$",
+ "projectName": "Object",
+ "type": "EXECUTABLE",
+ "isGeneratorProvided": null,
+ "sources": [
+ {
+ "path": "^empty\\.c$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "C",
+ "backtrace": [
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": 6,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/.*/empty(\\.c)?\\.o(bj)?$",
+ "isGenerated": true,
+ "sourceGroupName": "Object Libraries",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": 7,
+ "command": "target_link_libraries",
+ "hasParent": true
+ },
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "Source Files",
+ "sourcePaths": [
+ "^empty\\.c$"
+ ]
+ },
+ {
+ "name": "Object Libraries",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/.*/empty(\\.c)?\\.o(bj)?$"
+ ]
+ }
+ ],
+ "compileGroups": [
+ {
+ "language": "C",
+ "sourcePaths": [
+ "^empty\\.c$"
+ ],
+ "includes": null,
+ "defines": null,
+ "compileCommandFragments": null
+ }
+ ],
+ "backtrace": [
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": 6,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": "^c_object_exe(\\.exe)?$",
+ "artifacts": [
+ {
+ "path": "^object/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_object_exe(\\.exe)?$",
+ "_dllExtra": false
+ },
+ {
+ "path": "^object/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_object_exe\\.pdb$",
+ "_dllExtra": true
+ }
+ ],
+ "build": "^object$",
+ "source": "^object$",
+ "install": {
+ "prefix": "^(/usr/local|[A-Za-z]:.*/codemodel-v2)$",
+ "destinations": [
+ {
+ "path": "bin",
+ "backtrace": [
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": 13,
+ "command": "install",
+ "hasParent": true
+ },
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ]
+ },
+ "link": {
+ "language": "C",
+ "lto": null,
+ "commandFragments": null
+ },
+ "archive": null,
+ "dependencies": [
+ {
+ "id": "^c_object_lib::@5ed5358f70faf8d8af7a$",
+ "backtrace": [
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": 7,
+ "command": "target_link_libraries",
+ "hasParent": true
+ },
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "id": "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_object_lib.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_object_lib.json
new file mode 100644
index 0000000..e3a20df
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_object_lib.json
@@ -0,0 +1,82 @@
+{
+ "name": "c_object_lib",
+ "id": "^c_object_lib::@5ed5358f70faf8d8af7a$",
+ "directorySource": "^object$",
+ "projectName": "Object",
+ "type": "OBJECT_LIBRARY",
+ "isGeneratorProvided": null,
+ "sources": [
+ {
+ "path": "^empty\\.c$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "C",
+ "backtrace": [
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": 5,
+ "command": "add_library",
+ "hasParent": true
+ },
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "Source Files",
+ "sourcePaths": [
+ "^empty\\.c$"
+ ]
+ }
+ ],
+ "compileGroups": [
+ {
+ "language": "C",
+ "sourcePaths": [
+ "^empty\\.c$"
+ ],
+ "includes": null,
+ "defines": null,
+ "compileCommandFragments": null
+ }
+ ],
+ "backtrace": [
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": 5,
+ "command": "add_library",
+ "hasParent": true
+ },
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": null,
+ "artifacts": [
+ {
+ "path": "^object/.*/empty(\\.c)?\\.o(bj)?$",
+ "_dllExtra": false
+ }
+ ],
+ "build": "^object$",
+ "source": "^object$",
+ "install": null,
+ "link": null,
+ "archive": null,
+ "dependencies": [
+ {
+ "id": "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_exe.json
new file mode 100644
index 0000000..0d4018a
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_exe.json
@@ -0,0 +1,143 @@
+{
+ "name": "c_shared_exe",
+ "id": "^c_shared_exe::@6890427a1f51a3e7e1df$",
+ "directorySource": "^\\.$",
+ "projectName": "codemodel-v2",
+ "type": "EXECUTABLE",
+ "isGeneratorProvided": null,
+ "sources": [
+ {
+ "path": "^empty\\.c$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "C",
+ "backtrace": [
+ {
+ "file": "^codemodel-v2\\.cmake$",
+ "line": 10,
+ "command": "add_executable",
+ "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
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "Source Files",
+ "sourcePaths": [
+ "^empty\\.c$"
+ ]
+ }
+ ],
+ "compileGroups": [
+ {
+ "language": "C",
+ "sourcePaths": [
+ "^empty\\.c$"
+ ],
+ "includes": null,
+ "defines": null,
+ "compileCommandFragments": null
+ }
+ ],
+ "backtrace": [
+ {
+ "file": "^codemodel-v2\\.cmake$",
+ "line": 10,
+ "command": "add_executable",
+ "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": "^c_shared_exe(\\.exe)?$",
+ "artifacts": [
+ {
+ "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_shared_exe(\\.exe)?$",
+ "_dllExtra": false
+ },
+ {
+ "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_shared_exe\\.pdb$",
+ "_dllExtra": true
+ }
+ ],
+ "build": "^\\.$",
+ "source": "^\\.$",
+ "install": null,
+ "link": {
+ "language": "C",
+ "lto": true,
+ "commandFragments": null
+ },
+ "archive": null,
+ "dependencies": [
+ {
+ "id": "^c_shared_lib::@6890427a1f51a3e7e1df$",
+ "backtrace": [
+ {
+ "file": "^codemodel-v2\\.cmake$",
+ "line": 11,
+ "command": "target_link_libraries",
+ "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
+ }
+ ]
+ },
+ {
+ "id": "^ZERO_CHECK::@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
new file mode 100644
index 0000000..176a857
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_lib.json
@@ -0,0 +1,123 @@
+{
+ "name": "c_shared_lib",
+ "id": "^c_shared_lib::@6890427a1f51a3e7e1df$",
+ "directorySource": "^\\.$",
+ "projectName": "codemodel-v2",
+ "type": "SHARED_LIBRARY",
+ "isGeneratorProvided": null,
+ "sources": [
+ {
+ "path": "^empty\\.c$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "C",
+ "backtrace": [
+ {
+ "file": "^codemodel-v2\\.cmake$",
+ "line": 9,
+ "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
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "Source Files",
+ "sourcePaths": [
+ "^empty\\.c$"
+ ]
+ }
+ ],
+ "compileGroups": [
+ {
+ "language": "C",
+ "sourcePaths": [
+ "^empty\\.c$"
+ ],
+ "includes": null,
+ "defines": [
+ {
+ "define": "c_shared_lib_EXPORTS",
+ "backtrace": null
+ }
+ ],
+ "compileCommandFragments": null
+ }
+ ],
+ "backtrace": [
+ {
+ "file": "^codemodel-v2\\.cmake$",
+ "line": 9,
+ "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|cyg)?c_shared_lib\\.(so|dylib|dll)$",
+ "artifacts": [
+ {
+ "path": "^lib/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib|cyg)?c_shared_lib\\.(so|dylib|dll)$",
+ "_dllExtra": false
+ },
+ {
+ "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib)?c_shared_lib\\.(dll\\.a|lib)$",
+ "_dllExtra": true
+ },
+ {
+ "path": "^lib/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib|cyg)?c_shared_lib\\.pdb$",
+ "_dllExtra": true
+ }
+ ],
+ "build": "^\\.$",
+ "source": "^\\.$",
+ "install": null,
+ "link": {
+ "language": "C",
+ "lto": true,
+ "commandFragments": null
+ },
+ "archive": null,
+ "dependencies": [
+ {
+ "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_exe.json
new file mode 100644
index 0000000..5542277
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_exe.json
@@ -0,0 +1,143 @@
+{
+ "name": "c_static_exe",
+ "id": "^c_static_exe::@6890427a1f51a3e7e1df$",
+ "directorySource": "^\\.$",
+ "projectName": "codemodel-v2",
+ "type": "EXECUTABLE",
+ "isGeneratorProvided": null,
+ "sources": [
+ {
+ "path": "^empty\\.c$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "C",
+ "backtrace": [
+ {
+ "file": "^codemodel-v2\\.cmake$",
+ "line": 14,
+ "command": "add_executable",
+ "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
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "Source Files",
+ "sourcePaths": [
+ "^empty\\.c$"
+ ]
+ }
+ ],
+ "compileGroups": [
+ {
+ "language": "C",
+ "sourcePaths": [
+ "^empty\\.c$"
+ ],
+ "includes": null,
+ "defines": null,
+ "compileCommandFragments": null
+ }
+ ],
+ "backtrace": [
+ {
+ "file": "^codemodel-v2\\.cmake$",
+ "line": 14,
+ "command": "add_executable",
+ "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": "^c_static_exe(\\.exe)?$",
+ "artifacts": [
+ {
+ "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_static_exe(\\.exe)?$",
+ "_dllExtra": false
+ },
+ {
+ "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?c_static_exe\\.pdb$",
+ "_dllExtra": true
+ }
+ ],
+ "build": "^\\.$",
+ "source": "^\\.$",
+ "install": null,
+ "link": {
+ "language": "C",
+ "lto": null,
+ "commandFragments": null
+ },
+ "archive": null,
+ "dependencies": [
+ {
+ "id": "^c_static_lib::@6890427a1f51a3e7e1df$",
+ "backtrace": [
+ {
+ "file": "^codemodel-v2\\.cmake$",
+ "line": 15,
+ "command": "target_link_libraries",
+ "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
+ }
+ ]
+ },
+ {
+ "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_lib.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_lib.json
new file mode 100644
index 0000000..4b63897
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_static_lib.json
@@ -0,0 +1,108 @@
+{
+ "name": "c_static_lib",
+ "id": "^c_static_lib::@6890427a1f51a3e7e1df$",
+ "directorySource": "^\\.$",
+ "projectName": "codemodel-v2",
+ "type": "STATIC_LIBRARY",
+ "isGeneratorProvided": null,
+ "sources": [
+ {
+ "path": "^empty\\.c$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "C",
+ "backtrace": [
+ {
+ "file": "^codemodel-v2\\.cmake$",
+ "line": 13,
+ "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
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "Source Files",
+ "sourcePaths": [
+ "^empty\\.c$"
+ ]
+ }
+ ],
+ "compileGroups": [
+ {
+ "language": "C",
+ "sourcePaths": [
+ "^empty\\.c$"
+ ],
+ "includes": null,
+ "defines": null,
+ "compileCommandFragments": null
+ }
+ ],
+ "backtrace": [
+ {
+ "file": "^codemodel-v2\\.cmake$",
+ "line": 13,
+ "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_static_lib\\.(a|lib)$",
+ "artifacts": [
+ {
+ "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib)?c_static_lib\\.(a|lib)$",
+ "_dllExtra": false
+ }
+ ],
+ "build": "^\\.$",
+ "source": "^\\.$",
+ "install": null,
+ "link": null,
+ "archive": {
+ "lto": true
+ },
+ "dependencies": [
+ {
+ "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/custom_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/custom_exe.json
new file mode 100644
index 0000000..ab301e9
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/custom_exe.json
@@ -0,0 +1,107 @@
+{
+ "name": "custom_exe",
+ "id": "^custom_exe::@c11385ffed57b860da63$",
+ "directorySource": "^custom$",
+ "projectName": "Custom",
+ "type": "EXECUTABLE",
+ "isGeneratorProvided": null,
+ "sources": [
+ {
+ "path": "^empty\\.c$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "C",
+ "backtrace": [
+ {
+ "file": "^custom/CMakeLists\\.txt$",
+ "line": 4,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^custom/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "Source Files",
+ "sourcePaths": [
+ "^empty\\.c$"
+ ]
+ }
+ ],
+ "compileGroups": [
+ {
+ "language": "C",
+ "sourcePaths": [
+ "^empty\\.c$"
+ ],
+ "includes": null,
+ "defines": null,
+ "compileCommandFragments": null
+ }
+ ],
+ "backtrace": [
+ {
+ "file": "^custom/CMakeLists\\.txt$",
+ "line": 4,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^custom/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": "^custom_exe(\\.exe)?$",
+ "artifacts": [
+ {
+ "path": "^custom/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?custom_exe(\\.exe)?$",
+ "_dllExtra": false
+ },
+ {
+ "path": "^custom/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?custom_exe\\.pdb$",
+ "_dllExtra": true
+ }
+ ],
+ "build": "^custom$",
+ "source": "^custom$",
+ "install": null,
+ "link": {
+ "language": "C",
+ "lto": null,
+ "commandFragments": null
+ },
+ "archive": null,
+ "dependencies": [
+ {
+ "id": "^custom_tgt::@c11385ffed57b860da63$",
+ "backtrace": [
+ {
+ "file": "^custom/CMakeLists\\.txt$",
+ "line": 5,
+ "command": "add_dependencies",
+ "hasParent": true
+ },
+ {
+ "file": "^custom/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "id": "^ZERO_CHECK::@c11385ffed57b860da63$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/custom_tgt.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/custom_tgt.json
new file mode 100644
index 0000000..a7106fc
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/custom_tgt.json
@@ -0,0 +1,87 @@
+{
+ "name": "custom_tgt",
+ "id": "^custom_tgt::@c11385ffed57b860da63$",
+ "directorySource": "^custom$",
+ "projectName": "Custom",
+ "type": "UTILITY",
+ "isGeneratorProvided": null,
+ "sources": [
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/custom_tgt$",
+ "isGenerated": true,
+ "sourceGroupName": "",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^custom/CMakeLists\\.txt$",
+ "line": 3,
+ "command": "add_custom_target",
+ "hasParent": true
+ },
+ {
+ "file": "^custom/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/(custom/)?CMakeFiles/([0-9a-f]+/)?custom_tgt\\.rule$",
+ "isGenerated": true,
+ "sourceGroupName": "CMake Rules",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^custom/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/custom_tgt$"
+ ]
+ },
+ {
+ "name": "CMake Rules",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/(custom/)?CMakeFiles/([0-9a-f]+/)?custom_tgt\\.rule$"
+ ]
+ }
+ ],
+ "compileGroups": null,
+ "backtrace": [
+ {
+ "file": "^custom/CMakeLists\\.txt$",
+ "line": 3,
+ "command": "add_custom_target",
+ "hasParent": true
+ },
+ {
+ "file": "^custom/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": null,
+ "artifacts": null,
+ "build": "^custom$",
+ "source": "^custom$",
+ "install": null,
+ "link": null,
+ "archive": null,
+ "dependencies": [
+ {
+ "id": "^ZERO_CHECK::@c11385ffed57b860da63$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_alias_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_alias_exe.json
new file mode 100644
index 0000000..837f252
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_alias_exe.json
@@ -0,0 +1,107 @@
+{
+ "name": "cxx_alias_exe",
+ "id": "^cxx_alias_exe::@53632cba2752272bb008$",
+ "directorySource": "^alias$",
+ "projectName": "Alias",
+ "type": "EXECUTABLE",
+ "isGeneratorProvided": null,
+ "sources": [
+ {
+ "path": "^empty\\.cxx$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "CXX",
+ "backtrace": [
+ {
+ "file": "^alias/CMakeLists\\.txt$",
+ "line": 9,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^alias/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "Source Files",
+ "sourcePaths": [
+ "^empty\\.cxx$"
+ ]
+ }
+ ],
+ "compileGroups": [
+ {
+ "language": "CXX",
+ "sourcePaths": [
+ "^empty\\.cxx$"
+ ],
+ "includes": null,
+ "defines": null,
+ "compileCommandFragments": null
+ }
+ ],
+ "backtrace": [
+ {
+ "file": "^alias/CMakeLists\\.txt$",
+ "line": 9,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^alias/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": "^cxx_alias_exe(\\.exe)?$",
+ "artifacts": [
+ {
+ "path": "^alias/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_alias_exe(\\.exe)?$",
+ "_dllExtra": false
+ },
+ {
+ "path": "^alias/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_alias_exe\\.pdb$",
+ "_dllExtra": true
+ }
+ ],
+ "build": "^alias$",
+ "source": "^alias$",
+ "install": null,
+ "link": {
+ "language": "CXX",
+ "lto": null,
+ "commandFragments": null
+ },
+ "archive": null,
+ "dependencies": [
+ {
+ "id": "^cxx_lib::@a56b12a3f5c0529fb296$",
+ "backtrace": [
+ {
+ "file": "^alias/CMakeLists\\.txt$",
+ "line": 10,
+ "command": "target_link_libraries",
+ "hasParent": true
+ },
+ {
+ "file": "^alias/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "id": "^ZERO_CHECK::@53632cba2752272bb008$",
+ "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
new file mode 100644
index 0000000..7631837
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json
@@ -0,0 +1,213 @@
+{
+ "name": "cxx_exe",
+ "id": "^cxx_exe::@a56b12a3f5c0529fb296$",
+ "directorySource": "^cxx$",
+ "projectName": "Cxx",
+ "type": "EXECUTABLE",
+ "isGeneratorProvided": null,
+ "sources": [
+ {
+ "path": "^empty\\.cxx$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "CXX",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 5,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "Source Files",
+ "sourcePaths": [
+ "^empty\\.cxx$"
+ ]
+ }
+ ],
+ "compileGroups": [
+ {
+ "language": "CXX",
+ "sourcePaths": [
+ "^empty\\.cxx$"
+ ],
+ "includes": null,
+ "defines": null,
+ "compileCommandFragments": [
+ {
+ "fragment" : "TargetCompileOptions",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 17,
+ "command": "target_compile_options",
+ "hasParent": true
+ },
+ {
+ "file" : "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 5,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": "bin",
+ "nameOnDisk": "^cxx_exe(\\.exe)?$",
+ "artifacts": [
+ {
+ "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_exe(\\.exe)?$",
+ "_dllExtra": false
+ },
+ {
+ "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_exe\\.pdb$",
+ "_dllExtra": true
+ }
+ ],
+ "build": "^cxx$",
+ "source": "^cxx$",
+ "install": {
+ "prefix": "^(/usr/local|[A-Za-z]:.*/codemodel-v2)$",
+ "destinations": [
+ {
+ "path": "bin",
+ "backtrace": [
+ {
+ "file": "^codemodel-v2\\.cmake$",
+ "line": 37,
+ "command": "install",
+ "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
+ }
+ ]
+ }
+ ]
+ },
+ "link": {
+ "language": "CXX",
+ "lto": null,
+ "commandFragments": [
+ {
+ "fragment" : "TargetLinkOptions",
+ "role" : "flags",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 18,
+ "command": "target_link_options",
+ "hasParent": true
+ },
+ {
+ "file" : "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "fragment" : ".*TargetLinkDir\\\"?$",
+ "role" : "libraryPath",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 19,
+ "command": "target_link_directories",
+ "hasParent": true
+ },
+ {
+ "file" : "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "fragment" : ".*cxx_lib.*",
+ "role" : "libraries",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 6,
+ "command": "target_link_libraries",
+ "hasParent": true
+ },
+ {
+ "file" : "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ]
+ },
+ "archive": null,
+ "dependencies": [
+ {
+ "id": "^cxx_lib::@a56b12a3f5c0529fb296$",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 6,
+ "command": "target_link_libraries",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_lib.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_lib.json
new file mode 100644
index 0000000..94ac081
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_lib.json
@@ -0,0 +1,84 @@
+{
+ "name": "cxx_lib",
+ "id": "^cxx_lib::@a56b12a3f5c0529fb296$",
+ "directorySource": "^cxx$",
+ "projectName": "Cxx",
+ "type": "STATIC_LIBRARY",
+ "isGeneratorProvided": null,
+ "sources": [
+ {
+ "path": "^empty\\.cxx$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "CXX",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 4,
+ "command": "add_library",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "Source Files",
+ "sourcePaths": [
+ "^empty\\.cxx$"
+ ]
+ }
+ ],
+ "compileGroups": [
+ {
+ "language": "CXX",
+ "sourcePaths": [
+ "^empty\\.cxx$"
+ ],
+ "includes": null,
+ "defines": null,
+ "compileCommandFragments": null
+ }
+ ],
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 4,
+ "command": "add_library",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": "^(lib)?cxx_lib\\.(a|lib)$",
+ "artifacts": [
+ {
+ "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib)?cxx_lib\\.(a|lib)$",
+ "_dllExtra": false
+ }
+ ],
+ "build": "^cxx$",
+ "source": "^cxx$",
+ "install": null,
+ "link": null,
+ "archive": {
+ "lto": null
+ },
+ "dependencies": [
+ {
+ "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_object_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_object_exe.json
new file mode 100644
index 0000000..119c91d
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_object_exe.json
@@ -0,0 +1,154 @@
+{
+ "name": "cxx_object_exe",
+ "id": "^cxx_object_exe::@5ed5358f70faf8d8af7a$",
+ "directorySource": "^object$",
+ "projectName": "Object",
+ "type": "EXECUTABLE",
+ "isGeneratorProvided": null,
+ "sources": [
+ {
+ "path": "^empty\\.cxx$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "CXX",
+ "backtrace": [
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": 10,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/.*/empty(\\.cxx)?\\.o(bj)?$",
+ "isGenerated": true,
+ "sourceGroupName": "Object Libraries",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": 11,
+ "command": "target_link_libraries",
+ "hasParent": true
+ },
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "Source Files",
+ "sourcePaths": [
+ "^empty\\.cxx$"
+ ]
+ },
+ {
+ "name": "Object Libraries",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/.*/empty(\\.cxx)?\\.o(bj)?$"
+ ]
+ }
+ ],
+ "compileGroups": [
+ {
+ "language": "CXX",
+ "sourcePaths": [
+ "^empty\\.cxx$"
+ ],
+ "includes": null,
+ "defines": null,
+ "compileCommandFragments": null
+ }
+ ],
+ "backtrace": [
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": 10,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": "^cxx_object_exe(\\.exe)?$",
+ "artifacts": [
+ {
+ "path": "^object/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_object_exe(\\.exe)?$",
+ "_dllExtra": false
+ },
+ {
+ "path": "^object/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_object_exe\\.pdb$",
+ "_dllExtra": true
+ }
+ ],
+ "build": "^object$",
+ "source": "^object$",
+ "install": {
+ "prefix": "^(/usr/local|[A-Za-z]:.*/codemodel-v2)$",
+ "destinations": [
+ {
+ "path": "bin",
+ "backtrace": [
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": 13,
+ "command": "install",
+ "hasParent": true
+ },
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ]
+ },
+ "link": {
+ "language": "CXX",
+ "lto": null,
+ "commandFragments": null
+ },
+ "archive": null,
+ "dependencies": [
+ {
+ "id": "^cxx_object_lib::@5ed5358f70faf8d8af7a$",
+ "backtrace": [
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": 11,
+ "command": "target_link_libraries",
+ "hasParent": true
+ },
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "id": "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_object_lib.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_object_lib.json
new file mode 100644
index 0000000..8e99f7d
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_object_lib.json
@@ -0,0 +1,82 @@
+{
+ "name": "cxx_object_lib",
+ "id": "^cxx_object_lib::@5ed5358f70faf8d8af7a$",
+ "directorySource": "^object$",
+ "projectName": "Object",
+ "type": "OBJECT_LIBRARY",
+ "isGeneratorProvided": null,
+ "sources": [
+ {
+ "path": "^empty\\.cxx$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "CXX",
+ "backtrace": [
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": 9,
+ "command": "add_library",
+ "hasParent": true
+ },
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "Source Files",
+ "sourcePaths": [
+ "^empty\\.cxx$"
+ ]
+ }
+ ],
+ "compileGroups": [
+ {
+ "language": "CXX",
+ "sourcePaths": [
+ "^empty\\.cxx$"
+ ],
+ "includes": null,
+ "defines": null,
+ "compileCommandFragments": null
+ }
+ ],
+ "backtrace": [
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": 9,
+ "command": "add_library",
+ "hasParent": true
+ },
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": null,
+ "artifacts": [
+ {
+ "path": "^object/.*/empty(\\.cxx)?\\.o(bj)?$",
+ "_dllExtra": false
+ }
+ ],
+ "build": "^object$",
+ "source": "^object$",
+ "install": null,
+ "link": null,
+ "archive": null,
+ "dependencies": [
+ {
+ "id": "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_exe.json
new file mode 100644
index 0000000..4421c8f
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_exe.json
@@ -0,0 +1,107 @@
+{
+ "name": "cxx_shared_exe",
+ "id": "^cxx_shared_exe::@a56b12a3f5c0529fb296$",
+ "directorySource": "^cxx$",
+ "projectName": "Cxx",
+ "type": "EXECUTABLE",
+ "isGeneratorProvided": null,
+ "sources": [
+ {
+ "path": "^empty\\.cxx$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "CXX",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 10,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "Source Files",
+ "sourcePaths": [
+ "^empty\\.cxx$"
+ ]
+ }
+ ],
+ "compileGroups": [
+ {
+ "language": "CXX",
+ "sourcePaths": [
+ "^empty\\.cxx$"
+ ],
+ "includes": null,
+ "defines": null,
+ "compileCommandFragments": null
+ }
+ ],
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 10,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": "^cxx_shared_exe(\\.exe)?$",
+ "artifacts": [
+ {
+ "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_shared_exe(\\.exe)?$",
+ "_dllExtra": false
+ },
+ {
+ "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_shared_exe\\.pdb$",
+ "_dllExtra": true
+ }
+ ],
+ "build": "^cxx$",
+ "source": "^cxx$",
+ "install": null,
+ "link": {
+ "language": "CXX",
+ "lto": null,
+ "commandFragments": null
+ },
+ "archive": null,
+ "dependencies": [
+ {
+ "id": "^cxx_shared_lib::@a56b12a3f5c0529fb296$",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 11,
+ "command": "target_link_libraries",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
+ "backtrace": null
+ }
+ ]
+}
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
new file mode 100644
index 0000000..171a4f5
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_lib.json
@@ -0,0 +1,99 @@
+{
+ "name": "cxx_shared_lib",
+ "id": "^cxx_shared_lib::@a56b12a3f5c0529fb296$",
+ "directorySource": "^cxx$",
+ "projectName": "Cxx",
+ "type": "SHARED_LIBRARY",
+ "isGeneratorProvided": null,
+ "sources": [
+ {
+ "path": "^empty\\.cxx$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "CXX",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 9,
+ "command": "add_library",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "Source Files",
+ "sourcePaths": [
+ "^empty\\.cxx$"
+ ]
+ }
+ ],
+ "compileGroups": [
+ {
+ "language": "CXX",
+ "sourcePaths": [
+ "^empty\\.cxx$"
+ ],
+ "includes": null,
+ "defines": [
+ {
+ "define": "cxx_shared_lib_EXPORTS",
+ "backtrace": null
+ }
+ ],
+ "compileCommandFragments": null
+ }
+ ],
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 9,
+ "command": "add_library",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": "^(lib|cyg)?cxx_shared_lib\\.(so|dylib|dll)$",
+ "artifacts": [
+ {
+ "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib|cyg)?cxx_shared_lib\\.(so|dylib|dll)$",
+ "_dllExtra": false
+ },
+ {
+ "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib)?cxx_shared_lib\\.(dll\\.a|lib)$",
+ "_dllExtra": true
+ },
+ {
+ "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib|cyg)?cxx_shared_lib\\.pdb$",
+ "_dllExtra": true
+ }
+ ],
+ "build": "^cxx$",
+ "source": "^cxx$",
+ "install": null,
+ "link": {
+ "language": "CXX",
+ "lto": null,
+ "commandFragments": null
+ },
+ "archive": null,
+ "dependencies": [
+ {
+ "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_static_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_static_exe.json
new file mode 100644
index 0000000..52c42de
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_static_exe.json
@@ -0,0 +1,107 @@
+{
+ "name": "cxx_static_exe",
+ "id": "^cxx_static_exe::@a56b12a3f5c0529fb296$",
+ "directorySource": "^cxx$",
+ "projectName": "Cxx",
+ "type": "EXECUTABLE",
+ "isGeneratorProvided": null,
+ "sources": [
+ {
+ "path": "^empty\\.cxx$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "CXX",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 14,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "Source Files",
+ "sourcePaths": [
+ "^empty\\.cxx$"
+ ]
+ }
+ ],
+ "compileGroups": [
+ {
+ "language": "CXX",
+ "sourcePaths": [
+ "^empty\\.cxx$"
+ ],
+ "includes": null,
+ "defines": null,
+ "compileCommandFragments": null
+ }
+ ],
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 14,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": "^cxx_static_exe(\\.exe)?$",
+ "artifacts": [
+ {
+ "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_static_exe(\\.exe)?$",
+ "_dllExtra": false
+ },
+ {
+ "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?cxx_static_exe\\.pdb$",
+ "_dllExtra": true
+ }
+ ],
+ "build": "^cxx$",
+ "source": "^cxx$",
+ "install": null,
+ "link": {
+ "language": "CXX",
+ "lto": null,
+ "commandFragments": null
+ },
+ "archive": null,
+ "dependencies": [
+ {
+ "id": "^cxx_static_lib::@a56b12a3f5c0529fb296$",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 15,
+ "command": "target_link_libraries",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_static_lib.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_static_lib.json
new file mode 100644
index 0000000..98298be
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_static_lib.json
@@ -0,0 +1,84 @@
+{
+ "name": "cxx_static_lib",
+ "id": "^cxx_static_lib::@a56b12a3f5c0529fb296$",
+ "directorySource": "^cxx$",
+ "projectName": "Cxx",
+ "type": "STATIC_LIBRARY",
+ "isGeneratorProvided": null,
+ "sources": [
+ {
+ "path": "^empty\\.cxx$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "CXX",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 13,
+ "command": "add_library",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "Source Files",
+ "sourcePaths": [
+ "^empty\\.cxx$"
+ ]
+ }
+ ],
+ "compileGroups": [
+ {
+ "language": "CXX",
+ "sourcePaths": [
+ "^empty\\.cxx$"
+ ],
+ "includes": null,
+ "defines": null,
+ "compileCommandFragments": null
+ }
+ ],
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 13,
+ "command": "add_library",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": "^(lib)?cxx_static_lib\\.(a|lib)$",
+ "artifacts": [
+ {
+ "path": "^cxx/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib)?cxx_static_lib\\.(a|lib)$",
+ "_dllExtra": false
+ }
+ ],
+ "build": "^cxx$",
+ "source": "^cxx$",
+ "install": null,
+ "link": null,
+ "archive": {
+ "lto": null
+ },
+ "dependencies": [
+ {
+ "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/generated_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/generated_exe.json
new file mode 100644
index 0000000..d41bbb2
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/generated_exe.json
@@ -0,0 +1,303 @@
+{
+ "name": "generated_exe",
+ "id": "^generated_exe::@[0-9a-f]+$",
+ "directorySource": "^.*/Tests/RunCMake/FileAPIExternalSource$",
+ "projectName": "External",
+ "type": "EXECUTABLE",
+ "isGeneratorProvided": null,
+ "sources": [
+ {
+ "path": "^.*/Tests/RunCMake/FileAPIExternalSource/empty\\.c$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "C",
+ "backtrace": [
+ {
+ "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+ "line": 5,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/generated\\.cxx$",
+ "isGenerated": true,
+ "sourceGroupName": "Generated Source Files",
+ "compileGroupLanguage": "CXX",
+ "backtrace": [
+ {
+ "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+ "line": 6,
+ "command": "target_sources",
+ "hasParent": true
+ },
+ {
+ "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "Source Files",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPIExternalSource/empty\\.c$"
+ ]
+ },
+ {
+ "name": "Generated Source Files",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/generated\\.cxx$"
+ ]
+ }
+ ],
+ "compileGroups": [
+ {
+ "language": "C",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPIExternalSource/empty\\.c$"
+ ],
+ "includes": [
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild$",
+ "isSystem": null,
+ "backtrace": [
+ {
+ "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+ "line": 10,
+ "command": "set_property",
+ "hasParent": true
+ },
+ {
+ "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "path": "^.*/Tests/RunCMake/FileAPIExternalSource$",
+ "isSystem": true,
+ "backtrace": [
+ {
+ "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+ "line": 11,
+ "command": "target_include_directories",
+ "hasParent": true
+ },
+ {
+ "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "defines": [
+ {
+ "define": "EMPTY_C=1",
+ "backtrace": [
+ {
+ "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+ "line": 9,
+ "command": "set_property",
+ "hasParent": true
+ },
+ {
+ "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "define": "SRC_DUMMY",
+ "backtrace": [
+ {
+ "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+ "line": 9,
+ "command": "set_property",
+ "hasParent": true
+ },
+ {
+ "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "define": "GENERATED_EXE=1",
+ "backtrace": [
+ {
+ "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+ "line": 12,
+ "command": "target_compile_definitions",
+ "hasParent": true
+ },
+ {
+ "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "define": "TGT_DUMMY",
+ "backtrace": [
+ {
+ "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+ "line": 12,
+ "command": "target_compile_definitions",
+ "hasParent": true
+ },
+ {
+ "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "compileCommandFragments": [
+ {
+ "fragment" : "SRC_COMPILE_OPTIONS_DUMMY",
+ "backtrace": [
+ {
+ "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+ "line": 13,
+ "command": "set_source_files_properties",
+ "hasParent": true
+ },
+ {
+ "file" : "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "language": "CXX",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/generated\\.cxx$"
+ ],
+ "includes": [
+ {
+ "path": "^.*/Tests/RunCMake/FileAPIExternalSource$",
+ "isSystem": true,
+ "backtrace": [
+ {
+ "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+ "line": 11,
+ "command": "target_include_directories",
+ "hasParent": true
+ },
+ {
+ "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "defines": [
+ {
+ "define": "GENERATED_EXE=1",
+ "backtrace": [
+ {
+ "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+ "line": 12,
+ "command": "target_compile_definitions",
+ "hasParent": true
+ },
+ {
+ "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "define": "TGT_DUMMY",
+ "backtrace": [
+ {
+ "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+ "line": 12,
+ "command": "target_compile_definitions",
+ "hasParent": true
+ },
+ {
+ "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "compileCommandFragments": null
+ }
+ ],
+ "backtrace": [
+ {
+ "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+ "line": 5,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": "^generated_exe(\\.exe)?$",
+ "artifacts": [
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?generated_exe(\\.exe)?$",
+ "_dllExtra": false
+ },
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?generated_exe\\.pdb$",
+ "_dllExtra": true
+ }
+ ],
+ "build": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild$",
+ "source": "^.*/Tests/RunCMake/FileAPIExternalSource$",
+ "install": null,
+ "link": {
+ "language": "CXX",
+ "lto": null,
+ "commandFragments": null
+ },
+ "archive": null,
+ "dependencies": [
+ {
+ "id": "^ZERO_CHECK::@[0-9a-f]+$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/interface_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/interface_exe.json
new file mode 100644
index 0000000..fe0524c
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/interface_exe.json
@@ -0,0 +1,152 @@
+{
+ "name": "interface_exe",
+ "id": "^interface_exe::@6890427a1f51a3e7e1df$",
+ "directorySource": "^\\.$",
+ "projectName": "codemodel-v2",
+ "type": "EXECUTABLE",
+ "isGeneratorProvided": null,
+ "sources": [
+ {
+ "path": "^empty\\.c$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "C",
+ "backtrace": [
+ {
+ "file": "^include_test\\.cmake$",
+ "line": 3,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^include_test\\.cmake$",
+ "line": null,
+ "command": null,
+ "hasParent": true
+ },
+ {
+ "file": "^codemodel-v2\\.cmake$",
+ "line": 3,
+ "command": "include",
+ "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
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "Source Files",
+ "sourcePaths": [
+ "^empty\\.c$"
+ ]
+ }
+ ],
+ "compileGroups": [
+ {
+ "language": "C",
+ "sourcePaths": [
+ "^empty\\.c$"
+ ],
+ "includes": null,
+ "defines": [
+ {
+ "define": "interface_exe_EXPORTS",
+ "backtrace": null
+ }
+ ],
+ "compileCommandFragments": null
+ }
+ ],
+ "backtrace": [
+ {
+ "file": "^include_test\\.cmake$",
+ "line": 3,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^include_test\\.cmake$",
+ "line": null,
+ "command": null,
+ "hasParent": true
+ },
+ {
+ "file": "^codemodel-v2\\.cmake$",
+ "line": 3,
+ "command": "include",
+ "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": "^my_interface_exe\\.myexe$",
+ "artifacts": [
+ {
+ "path": "^bin/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?my_interface_exe\\.myexe$",
+ "_dllExtra": false
+ },
+ {
+ "path": "^lib/my_interface_exe\\.imp$",
+ "_aixExtra": true,
+ "_dllExtra": false
+ },
+ {
+ "path": "^lib/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib)?my_interface_exe\\.(dll\\.a|lib)$",
+ "_dllExtra": true
+ },
+ {
+ "path": "^bin/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?my_interface_exe\\.pdb$",
+ "_dllExtra": true
+ }
+ ],
+ "build": "^\\.$",
+ "source": "^\\.$",
+ "install": null,
+ "link": {
+ "language": "C",
+ "lto": null,
+ "commandFragments": null
+ },
+ "archive": null,
+ "dependencies": [
+ {
+ "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_exe.json
new file mode 100644
index 0000000..312f4c5
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_exe.json
@@ -0,0 +1,90 @@
+{
+ "name": "link_imported_exe",
+ "id": "^link_imported_exe::@ba7eb709d0b48779c6c8$",
+ "directorySource": "^imported$",
+ "projectName": "Imported",
+ "type": "EXECUTABLE",
+ "isGeneratorProvided": null,
+ "sources": [
+ {
+ "path": "^empty\\.c$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "C",
+ "backtrace": [
+ {
+ "file": "^imported/CMakeLists\\.txt$",
+ "line": 5,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^imported/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "Source Files",
+ "sourcePaths": [
+ "^empty\\.c$"
+ ]
+ }
+ ],
+ "compileGroups": [
+ {
+ "language": "C",
+ "sourcePaths": [
+ "^empty\\.c$"
+ ],
+ "includes": null,
+ "defines": null,
+ "compileCommandFragments": null
+ }
+ ],
+ "backtrace": [
+ {
+ "file": "^imported/CMakeLists\\.txt$",
+ "line": 5,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^imported/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": "^link_imported_exe(\\.exe)?$",
+ "artifacts": [
+ {
+ "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_exe(\\.exe)?$",
+ "_dllExtra": false
+ },
+ {
+ "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_exe\\.pdb$",
+ "_dllExtra": true
+ }
+ ],
+ "build": "^imported$",
+ "source": "^imported$",
+ "install": null,
+ "link": {
+ "language": "C",
+ "lto": null,
+ "commandFragments": null
+ },
+ "archive": null,
+ "dependencies": [
+ {
+ "id": "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_interface_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_interface_exe.json
new file mode 100644
index 0000000..7d0e6df
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_interface_exe.json
@@ -0,0 +1,90 @@
+{
+ "name": "link_imported_interface_exe",
+ "id": "^link_imported_interface_exe::@ba7eb709d0b48779c6c8$",
+ "directorySource": "^imported$",
+ "projectName": "Imported",
+ "type": "EXECUTABLE",
+ "isGeneratorProvided": null,
+ "sources": [
+ {
+ "path": "^empty\\.c$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "C",
+ "backtrace": [
+ {
+ "file": "^imported/CMakeLists\\.txt$",
+ "line": 23,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^imported/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "Source Files",
+ "sourcePaths": [
+ "^empty\\.c$"
+ ]
+ }
+ ],
+ "compileGroups": [
+ {
+ "language": "C",
+ "sourcePaths": [
+ "^empty\\.c$"
+ ],
+ "includes": null,
+ "defines": null,
+ "compileCommandFragments": null
+ }
+ ],
+ "backtrace": [
+ {
+ "file": "^imported/CMakeLists\\.txt$",
+ "line": 23,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^imported/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": "^link_imported_interface_exe(\\.exe)?$",
+ "artifacts": [
+ {
+ "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_interface_exe(\\.exe)?$",
+ "_dllExtra": false
+ },
+ {
+ "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_interface_exe\\.pdb$",
+ "_dllExtra": true
+ }
+ ],
+ "build": "^imported$",
+ "source": "^imported$",
+ "install": null,
+ "link": {
+ "language": "C",
+ "lto": null,
+ "commandFragments": null
+ },
+ "archive": null,
+ "dependencies": [
+ {
+ "id": "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_object_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_object_exe.json
new file mode 100644
index 0000000..4aec524
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_object_exe.json
@@ -0,0 +1,90 @@
+{
+ "name": "link_imported_object_exe",
+ "id": "^link_imported_object_exe::@ba7eb709d0b48779c6c8$",
+ "directorySource": "^imported$",
+ "projectName": "Imported",
+ "type": "EXECUTABLE",
+ "isGeneratorProvided": null,
+ "sources": [
+ {
+ "path": "^empty\\.c$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "C",
+ "backtrace": [
+ {
+ "file": "^imported/CMakeLists\\.txt$",
+ "line": 18,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^imported/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "Source Files",
+ "sourcePaths": [
+ "^empty\\.c$"
+ ]
+ }
+ ],
+ "compileGroups": [
+ {
+ "language": "C",
+ "sourcePaths": [
+ "^empty\\.c$"
+ ],
+ "includes": null,
+ "defines": null,
+ "compileCommandFragments": null
+ }
+ ],
+ "backtrace": [
+ {
+ "file": "^imported/CMakeLists\\.txt$",
+ "line": 18,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^imported/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": "^link_imported_object_exe(\\.exe)?$",
+ "artifacts": [
+ {
+ "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_object_exe(\\.exe)?$",
+ "_dllExtra": false
+ },
+ {
+ "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_object_exe\\.pdb$",
+ "_dllExtra": true
+ }
+ ],
+ "build": "^imported$",
+ "source": "^imported$",
+ "install": null,
+ "link": {
+ "language": "C",
+ "lto": null,
+ "commandFragments": null
+ },
+ "archive": null,
+ "dependencies": [
+ {
+ "id": "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_shared_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_shared_exe.json
new file mode 100644
index 0000000..f5846ec
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_shared_exe.json
@@ -0,0 +1,90 @@
+{
+ "name": "link_imported_shared_exe",
+ "id": "^link_imported_shared_exe::@ba7eb709d0b48779c6c8$",
+ "directorySource": "^imported$",
+ "projectName": "Imported",
+ "type": "EXECUTABLE",
+ "isGeneratorProvided": null,
+ "sources": [
+ {
+ "path": "^empty\\.c$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "C",
+ "backtrace": [
+ {
+ "file": "^imported/CMakeLists\\.txt$",
+ "line": 9,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^imported/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "Source Files",
+ "sourcePaths": [
+ "^empty\\.c$"
+ ]
+ }
+ ],
+ "compileGroups": [
+ {
+ "language": "C",
+ "sourcePaths": [
+ "^empty\\.c$"
+ ],
+ "includes": null,
+ "defines": null,
+ "compileCommandFragments": null
+ }
+ ],
+ "backtrace": [
+ {
+ "file": "^imported/CMakeLists\\.txt$",
+ "line": 9,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^imported/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": "^link_imported_shared_exe(\\.exe)?$",
+ "artifacts": [
+ {
+ "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_shared_exe(\\.exe)?$",
+ "_dllExtra": false
+ },
+ {
+ "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_shared_exe\\.pdb$",
+ "_dllExtra": true
+ }
+ ],
+ "build": "^imported$",
+ "source": "^imported$",
+ "install": null,
+ "link": {
+ "language": "C",
+ "lto": null,
+ "commandFragments": null
+ },
+ "archive": null,
+ "dependencies": [
+ {
+ "id": "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_static_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_static_exe.json
new file mode 100644
index 0000000..29a1695
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/link_imported_static_exe.json
@@ -0,0 +1,90 @@
+{
+ "name": "link_imported_static_exe",
+ "id": "^link_imported_static_exe::@ba7eb709d0b48779c6c8$",
+ "directorySource": "^imported$",
+ "projectName": "Imported",
+ "type": "EXECUTABLE",
+ "isGeneratorProvided": null,
+ "sources": [
+ {
+ "path": "^empty\\.c$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "C",
+ "backtrace": [
+ {
+ "file": "^imported/CMakeLists\\.txt$",
+ "line": 13,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^imported/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "Source Files",
+ "sourcePaths": [
+ "^empty\\.c$"
+ ]
+ }
+ ],
+ "compileGroups": [
+ {
+ "language": "C",
+ "sourcePaths": [
+ "^empty\\.c$"
+ ],
+ "includes": null,
+ "defines": null,
+ "compileCommandFragments": null
+ }
+ ],
+ "backtrace": [
+ {
+ "file": "^imported/CMakeLists\\.txt$",
+ "line": 13,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^imported/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": "^link_imported_static_exe(\\.exe)?$",
+ "artifacts": [
+ {
+ "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_static_exe(\\.exe)?$",
+ "_dllExtra": false
+ },
+ {
+ "path": "^imported/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?link_imported_static_exe\\.pdb$",
+ "_dllExtra": true
+ }
+ ],
+ "build": "^imported$",
+ "source": "^imported$",
+ "install": null,
+ "link": {
+ "language": "C",
+ "lto": null,
+ "commandFragments": null
+ },
+ "archive": null,
+ "dependencies": [
+ {
+ "id": "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_alias.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_alias.json
new file mode 100644
index 0000000..941c172
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_alias.json
@@ -0,0 +1,70 @@
+{
+ "name": "ZERO_CHECK",
+ "id": "^ZERO_CHECK::@53632cba2752272bb008$",
+ "directorySource": "^alias$",
+ "projectName": "Alias",
+ "type": "UTILITY",
+ "isGeneratorProvided": true,
+ "sources": [
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ZERO_CHECK$",
+ "isGenerated": true,
+ "sourceGroupName": "",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^alias/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ZERO_CHECK\\.rule$",
+ "isGenerated": true,
+ "sourceGroupName": "CMake Rules",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^alias/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ZERO_CHECK$"
+ ]
+ },
+ {
+ "name": "CMake Rules",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/alias/CMakeFiles/ZERO_CHECK\\.rule$"
+ ]
+ }
+ ],
+ "compileGroups": null,
+ "backtrace": [
+ {
+ "file": "^alias/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": null,
+ "artifacts": null,
+ "build": "^alias$",
+ "source": "^alias$",
+ "install": null,
+ "link": null,
+ "archive": null,
+ "dependencies": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_custom.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_custom.json
new file mode 100644
index 0000000..98c6dd9
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_custom.json
@@ -0,0 +1,70 @@
+{
+ "name": "ZERO_CHECK",
+ "id": "^ZERO_CHECK::@c11385ffed57b860da63$",
+ "directorySource": "^custom$",
+ "projectName": "Custom",
+ "type": "UTILITY",
+ "isGeneratorProvided": true,
+ "sources": [
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ZERO_CHECK$",
+ "isGenerated": true,
+ "sourceGroupName": "",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^custom/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ZERO_CHECK\\.rule$",
+ "isGenerated": true,
+ "sourceGroupName": "CMake Rules",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^custom/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ZERO_CHECK$"
+ ]
+ },
+ {
+ "name": "CMake Rules",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/custom/CMakeFiles/ZERO_CHECK\\.rule$"
+ ]
+ }
+ ],
+ "compileGroups": null,
+ "backtrace": [
+ {
+ "file": "^custom/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": null,
+ "artifacts": null,
+ "build": "^custom$",
+ "source": "^custom$",
+ "install": null,
+ "link": null,
+ "archive": null,
+ "dependencies": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_cxx.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_cxx.json
new file mode 100644
index 0000000..b72ff82
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_cxx.json
@@ -0,0 +1,70 @@
+{
+ "name": "ZERO_CHECK",
+ "id": "^ZERO_CHECK::@a56b12a3f5c0529fb296$",
+ "directorySource": "^cxx$",
+ "projectName": "Cxx",
+ "type": "UTILITY",
+ "isGeneratorProvided": true,
+ "sources": [
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ZERO_CHECK$",
+ "isGenerated": true,
+ "sourceGroupName": "",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ZERO_CHECK\\.rule$",
+ "isGenerated": true,
+ "sourceGroupName": "CMake Rules",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ZERO_CHECK$"
+ ]
+ },
+ {
+ "name": "CMake Rules",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/cxx/CMakeFiles/ZERO_CHECK\\.rule$"
+ ]
+ }
+ ],
+ "compileGroups": null,
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": null,
+ "artifacts": null,
+ "build": "^cxx$",
+ "source": "^cxx$",
+ "install": null,
+ "link": null,
+ "archive": null,
+ "dependencies": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_external.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_external.json
new file mode 100644
index 0000000..9e73806
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_external.json
@@ -0,0 +1,70 @@
+{
+ "name": "ZERO_CHECK",
+ "id": "^ZERO_CHECK::@[0-9a-f]+$",
+ "directorySource": "^.*/Tests/RunCMake/FileAPIExternalSource$",
+ "projectName": "External",
+ "type": "UTILITY",
+ "isGeneratorProvided": true,
+ "sources": [
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ZERO_CHECK$",
+ "isGenerated": true,
+ "sourceGroupName": "",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ZERO_CHECK\\.rule$",
+ "isGenerated": true,
+ "sourceGroupName": "CMake Rules",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ZERO_CHECK$"
+ ]
+ },
+ {
+ "name": "CMake Rules",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild/CMakeFiles/ZERO_CHECK\\.rule$"
+ ]
+ }
+ ],
+ "compileGroups": null,
+ "backtrace": [
+ {
+ "file": "^.*/Tests/RunCMake/FileAPIExternalSource/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": null,
+ "artifacts": null,
+ "build": "^.*/Tests/RunCMake/FileAPI/FileAPIExternalBuild$",
+ "source": "^.*/Tests/RunCMake/FileAPIExternalSource$",
+ "install": null,
+ "link": null,
+ "archive": null,
+ "dependencies": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_imported.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_imported.json
new file mode 100644
index 0000000..7534c84
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_imported.json
@@ -0,0 +1,70 @@
+{
+ "name": "ZERO_CHECK",
+ "id": "^ZERO_CHECK::@ba7eb709d0b48779c6c8$",
+ "directorySource": "^imported$",
+ "projectName": "Imported",
+ "type": "UTILITY",
+ "isGeneratorProvided": true,
+ "sources": [
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ZERO_CHECK$",
+ "isGenerated": true,
+ "sourceGroupName": "",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^imported/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ZERO_CHECK\\.rule$",
+ "isGenerated": true,
+ "sourceGroupName": "CMake Rules",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^imported/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ZERO_CHECK$"
+ ]
+ },
+ {
+ "name": "CMake Rules",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/imported/CMakeFiles/ZERO_CHECK\\.rule$"
+ ]
+ }
+ ],
+ "compileGroups": null,
+ "backtrace": [
+ {
+ "file": "^imported/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": null,
+ "artifacts": null,
+ "build": "^imported$",
+ "source": "^imported$",
+ "install": null,
+ "link": null,
+ "archive": null,
+ "dependencies": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_object.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_object.json
new file mode 100644
index 0000000..bcd7616
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_object.json
@@ -0,0 +1,70 @@
+{
+ "name": "ZERO_CHECK",
+ "id": "^ZERO_CHECK::@5ed5358f70faf8d8af7a$",
+ "directorySource": "^object$",
+ "projectName": "Object",
+ "type": "UTILITY",
+ "isGeneratorProvided": true,
+ "sources": [
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ZERO_CHECK$",
+ "isGenerated": true,
+ "sourceGroupName": "",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ZERO_CHECK\\.rule$",
+ "isGenerated": true,
+ "sourceGroupName": "CMake Rules",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ZERO_CHECK$"
+ ]
+ },
+ {
+ "name": "CMake Rules",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/object/CMakeFiles/ZERO_CHECK\\.rule$"
+ ]
+ }
+ ],
+ "compileGroups": null,
+ "backtrace": [
+ {
+ "file": "^object/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": null,
+ "artifacts": null,
+ "build": "^object$",
+ "source": "^object$",
+ "install": null,
+ "link": null,
+ "archive": null,
+ "dependencies": null
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_top.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_top.json
new file mode 100644
index 0000000..b3030bd
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/zero_check_top.json
@@ -0,0 +1,70 @@
+{
+ "name": "ZERO_CHECK",
+ "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
+ "directorySource": "^\\.$",
+ "projectName": "codemodel-v2",
+ "type": "UTILITY",
+ "isGeneratorProvided": true,
+ "sources": [
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ZERO_CHECK$",
+ "isGenerated": true,
+ "sourceGroupName": "",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ZERO_CHECK\\.rule$",
+ "isGenerated": true,
+ "sourceGroupName": "CMake Rules",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ZERO_CHECK$"
+ ]
+ },
+ {
+ "name": "CMake Rules",
+ "sourcePaths": [
+ "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/ZERO_CHECK\\.rule$"
+ ]
+ }
+ ],
+ "compileGroups": null,
+ "backtrace": [
+ {
+ "file": "^CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": null,
+ "artifacts": null,
+ "build": "^\\.$",
+ "source": "^\\.$",
+ "install": null,
+ "link": null,
+ "archive": null,
+ "dependencies": null
+}
diff --git a/Tests/RunCMake/File_Archive/7zip.cmake b/Tests/RunCMake/File_Archive/7zip.cmake
new file mode 100644
index 0000000..7b0b9b7
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/7zip.cmake
@@ -0,0 +1,7 @@
+set(OUTPUT_NAME "test.7z")
+
+set(COMPRESSION_FORMAT 7zip)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
+
+check_magic("377abcaf271c" LIMIT 6 HEX)
diff --git a/Tests/RunCMake/File_Archive/CMakeLists.txt b/Tests/RunCMake/File_Archive/CMakeLists.txt
new file mode 100644
index 0000000..2897109
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.0)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/File_Archive/RunCMakeTest.cmake b/Tests/RunCMake/File_Archive/RunCMakeTest.cmake
new file mode 100644
index 0000000..871cb6d
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/RunCMakeTest.cmake
@@ -0,0 +1,17 @@
+include(RunCMake)
+
+run_cmake(7zip)
+run_cmake(gnutar)
+run_cmake(gnutar-gz)
+run_cmake(pax)
+run_cmake(pax-xz)
+run_cmake(pax-zstd)
+run_cmake(paxr)
+run_cmake(paxr-bz2)
+run_cmake(zip)
+
+# Extracting only selected files or directories
+run_cmake(zip-filtered)
+
+run_cmake(unsupported-format)
+run_cmake(zip-with-bad-type)
diff --git a/Tests/RunCMake/File_Archive/gnutar-gz.cmake b/Tests/RunCMake/File_Archive/gnutar-gz.cmake
new file mode 100644
index 0000000..f4e3975
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/gnutar-gz.cmake
@@ -0,0 +1,8 @@
+set(OUTPUT_NAME "test.tar.gz")
+
+set(COMPRESSION_FORMAT gnutar)
+set(COMPRESSION_TYPE GZip)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
+
+check_magic("1f8b" LIMIT 2 HEX)
diff --git a/Tests/RunCMake/File_Archive/gnutar.cmake b/Tests/RunCMake/File_Archive/gnutar.cmake
new file mode 100644
index 0000000..e5cbd35
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/gnutar.cmake
@@ -0,0 +1,7 @@
+set(OUTPUT_NAME "test.tar")
+
+set(COMPRESSION_FORMAT gnutar)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
+
+check_magic("7573746172202000" OFFSET 257 LIMIT 8 HEX)
diff --git a/Tests/RunCMake/File_Archive/pax-xz.cmake b/Tests/RunCMake/File_Archive/pax-xz.cmake
new file mode 100644
index 0000000..47fb0fd
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/pax-xz.cmake
@@ -0,0 +1,8 @@
+set(OUTPUT_NAME "test.tar.xz")
+
+set(COMPRESSION_FORMAT pax)
+set(COMPRESSION_TYPE XZ)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
+
+check_magic("fd377a585a00" LIMIT 6 HEX)
diff --git a/Tests/RunCMake/File_Archive/pax-zstd.cmake b/Tests/RunCMake/File_Archive/pax-zstd.cmake
new file mode 100644
index 0000000..59e0443
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/pax-zstd.cmake
@@ -0,0 +1,8 @@
+set(OUTPUT_NAME "test.tar.zstd")
+
+set(COMPRESSION_FORMAT pax)
+set(COMPRESSION_TYPE Zstd)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
+
+check_magic("28b52ffd0058" LIMIT 6 HEX)
diff --git a/Tests/RunCMake/File_Archive/pax.cmake b/Tests/RunCMake/File_Archive/pax.cmake
new file mode 100644
index 0000000..e50c74f
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/pax.cmake
@@ -0,0 +1,7 @@
+set(OUTPUT_NAME "test.tar")
+
+set(COMPRESSION_FORMAT pax)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
+
+check_magic("7573746172003030" OFFSET 257 LIMIT 8 HEX)
diff --git a/Tests/RunCMake/File_Archive/paxr-bz2.cmake b/Tests/RunCMake/File_Archive/paxr-bz2.cmake
new file mode 100644
index 0000000..469a131
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/paxr-bz2.cmake
@@ -0,0 +1,8 @@
+set(OUTPUT_NAME "test.tar.bz2")
+
+set(COMPRESSION_FORMAT paxr)
+set(COMPRESSION_TYPE BZip2)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
+
+check_magic("425a68" LIMIT 3 HEX)
diff --git a/Tests/RunCMake/File_Archive/paxr.cmake b/Tests/RunCMake/File_Archive/paxr.cmake
new file mode 100644
index 0000000..e3a4d5c
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/paxr.cmake
@@ -0,0 +1,7 @@
+set(OUTPUT_NAME "test.tar")
+
+set(COMPRESSION_FORMAT paxr)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
+
+check_magic("7573746172003030" OFFSET 257 LIMIT 8 HEX)
diff --git a/Tests/RunCMake/File_Archive/roundtrip.cmake b/Tests/RunCMake/File_Archive/roundtrip.cmake
new file mode 100644
index 0000000..9050400
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/roundtrip.cmake
@@ -0,0 +1,92 @@
+foreach(parameter OUTPUT_NAME COMPRESSION_FORMAT)
+ if(NOT DEFINED ${parameter})
+ message(FATAL_ERROR "missing required parameter ${parameter}")
+ endif()
+endforeach()
+
+set(COMPRESS_DIR compress_dir)
+set(FULL_COMPRESS_DIR ${CMAKE_CURRENT_BINARY_DIR}/${COMPRESS_DIR})
+
+set(DECOMPRESS_DIR decompress_dir)
+set(FULL_DECOMPRESS_DIR ${CMAKE_CURRENT_BINARY_DIR}/${DECOMPRESS_DIR})
+
+set(FULL_OUTPUT_NAME ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_NAME})
+
+set(CHECK_FILES
+ "f1.txt"
+ "d1/f1.txt"
+ "d 2/f1.txt"
+ "d + 3/f1.txt"
+ "d_4/f1.txt"
+ "d-4/f1.txt"
+ "My Special Directory/f1.txt"
+)
+
+foreach(file ${CHECK_FILES})
+ configure_file(${CMAKE_CURRENT_LIST_FILE} ${FULL_COMPRESS_DIR}/${file} COPYONLY)
+endforeach()
+
+if(UNIX)
+ execute_process(COMMAND ln -sf f1.txt ${FULL_COMPRESS_DIR}/d1/f2.txt)
+ list(APPEND CHECK_FILES "d1/f2.txt")
+endif()
+
+file(REMOVE ${FULL_OUTPUT_NAME})
+file(REMOVE_RECURSE ${FULL_DECOMPRESS_DIR})
+file(MAKE_DIRECTORY ${FULL_DECOMPRESS_DIR})
+
+file(ARCHIVE_CREATE
+ OUTPUT ${FULL_OUTPUT_NAME}
+ FORMAT "${COMPRESSION_FORMAT}"
+ TYPE "${COMPRESSION_TYPE}"
+ VERBOSE
+ DIRECTORY ${COMPRESS_DIR})
+
+file(ARCHIVE_EXTRACT
+ INPUT ${FULL_OUTPUT_NAME}
+ ${DECOMPRESSION_OPTIONS}
+ DESTINATION ${FULL_DECOMPRESS_DIR}
+ VERBOSE)
+
+if(CUSTOM_CHECK_FILES)
+ set(CHECK_FILES ${CUSTOM_CHECK_FILES})
+endif()
+
+foreach(file ${CHECK_FILES})
+ set(input ${FULL_COMPRESS_DIR}/${file})
+ set(output ${FULL_DECOMPRESS_DIR}/${COMPRESS_DIR}/${file})
+
+ if(NOT EXISTS ${input})
+ message(SEND_ERROR "Cannot find input file ${output}")
+ endif()
+
+ if(NOT EXISTS ${output})
+ message(SEND_ERROR "Cannot find output file ${output}")
+ endif()
+
+ file(MD5 ${input} input_md5)
+ file(MD5 ${output} output_md5)
+
+ if(NOT input_md5 STREQUAL output_md5)
+ message(SEND_ERROR "Files \"${input}\" and \"${output}\" are different")
+ endif()
+endforeach()
+
+foreach(file ${NOT_EXISTING_FILES_CHECK})
+ set(output ${FULL_DECOMPRESS_DIR}/${COMPRESS_DIR}/${file})
+
+ if(EXISTS ${output})
+ message(SEND_ERROR "File ${output} exists but it shouldn't")
+ endif()
+endforeach()
+
+function(check_magic EXPECTED)
+ file(READ ${FULL_OUTPUT_NAME} ACTUAL
+ ${ARGN}
+ )
+
+ if(NOT ACTUAL STREQUAL EXPECTED)
+ message(FATAL_ERROR
+ "Actual [${ACTUAL}] does not match expected [${EXPECTED}]")
+ endif()
+endfunction()
diff --git a/Tests/RunCMake/File_Archive/unsupported-format-result.txt b/Tests/RunCMake/File_Archive/unsupported-format-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/unsupported-format-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/File_Archive/unsupported-format-stderr.txt b/Tests/RunCMake/File_Archive/unsupported-format-stderr.txt
new file mode 100644
index 0000000..4328022
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/unsupported-format-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at roundtrip.cmake:38 \(file\):
+ file archive format rar not supported
+Call Stack \(most recent call first\):
+ unsupported-format.cmake:5 \(include\)
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/File_Archive/unsupported-format.cmake b/Tests/RunCMake/File_Archive/unsupported-format.cmake
new file mode 100644
index 0000000..61edc1b
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/unsupported-format.cmake
@@ -0,0 +1,5 @@
+set(OUTPUT_NAME "test.rar")
+
+set(COMPRESSION_FORMAT rar)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
diff --git a/Tests/RunCMake/File_Archive/zip-filtered.cmake b/Tests/RunCMake/File_Archive/zip-filtered.cmake
new file mode 100644
index 0000000..2d259bc
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/zip-filtered.cmake
@@ -0,0 +1,26 @@
+set(OUTPUT_NAME "test.zip")
+
+set(COMPRESSION_FORMAT zip)
+
+set(DECOMPRESSION_OPTIONS
+ FILES
+ compress_dir/f1.txt # Decompress only file
+ compress_dir/d1 # and whole directory
+)
+
+set(CUSTOM_CHECK_FILES
+ "f1.txt"
+ "d1/f1.txt"
+)
+
+# This files shouldn't exists
+set(NOT_EXISTING_FILES_CHECK
+ "d 2/f1.txt"
+ "d + 3/f1.txt"
+ "d_4/f1.txt"
+ "d-4/f1.txt"
+)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
+
+check_magic("504b0304" LIMIT 4 HEX)
diff --git a/Tests/RunCMake/File_Archive/zip-with-bad-type-result.txt b/Tests/RunCMake/File_Archive/zip-with-bad-type-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/zip-with-bad-type-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/File_Archive/zip-with-bad-type-stderr.txt b/Tests/RunCMake/File_Archive/zip-with-bad-type-stderr.txt
new file mode 100644
index 0000000..fe12feb
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/zip-with-bad-type-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at roundtrip.cmake:38 \(file\):
+ file archive format zip does not support TYPE arguments
+Call Stack \(most recent call first\):
+ zip-with-bad-type.cmake:6 \(include\)
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/File_Archive/zip-with-bad-type.cmake b/Tests/RunCMake/File_Archive/zip-with-bad-type.cmake
new file mode 100644
index 0000000..ebb97a3
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/zip-with-bad-type.cmake
@@ -0,0 +1,6 @@
+set(OUTPUT_NAME "test.zip")
+
+set(COMPRESSION_FORMAT zip)
+set(COMPRESSION_TYPE BZip2)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
diff --git a/Tests/RunCMake/File_Archive/zip.cmake b/Tests/RunCMake/File_Archive/zip.cmake
new file mode 100644
index 0000000..1b93058
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/zip.cmake
@@ -0,0 +1,7 @@
+set(OUTPUT_NAME "test.zip")
+
+set(COMPRESSION_FORMAT zip)
+
+include(${CMAKE_CURRENT_LIST_DIR}/roundtrip.cmake)
+
+check_magic("504b0304" LIMIT 4 HEX)
diff --git a/Tests/RunCMake/File_Configure/BadArg-result.txt b/Tests/RunCMake/File_Configure/BadArg-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/BadArg-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/File_Configure/BadArg-stderr.txt b/Tests/RunCMake/File_Configure/BadArg-stderr.txt
new file mode 100644
index 0000000..5423a28
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/BadArg-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at BadArg.cmake:[0-9]+ \(file\):
+ file Incorrect arguments to CONFIGURE subcommand.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/File_Configure/BadArg.cmake b/Tests/RunCMake/File_Configure/BadArg.cmake
new file mode 100644
index 0000000..7c7fcda
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/BadArg.cmake
@@ -0,0 +1 @@
+file(CONFIGURE OUTPUT)
diff --git a/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionContent-result.txt b/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionContent-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionContent-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionContent-stderr.txt b/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionContent-stderr.txt
new file mode 100644
index 0000000..acda654
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionContent-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at BadArgGeneratorExpressionContent.cmake:[0-9]+ \(file\):
+ file CONFIGURE called with CONTENT containing a "<". This character is not
+ allowed.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionContent.cmake b/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionContent.cmake
new file mode 100644
index 0000000..75fe9e5
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionContent.cmake
@@ -0,0 +1,4 @@
+file(CONFIGURE
+ OUTPUT "file.txt"
+ CONTENT "foo-$<CONFIG>"
+)
diff --git a/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionOutput-result.txt b/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionOutput-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionOutput-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionOutput-stderr.txt b/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionOutput-stderr.txt
new file mode 100644
index 0000000..329d956
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionOutput-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at BadArgGeneratorExpressionOutput.cmake:[0-9]+ \(file\):
+ file CONFIGURE called with OUTPUT containing a "<". This character is not
+ allowed.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionOutput.cmake b/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionOutput.cmake
new file mode 100644
index 0000000..31a79a7
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/BadArgGeneratorExpressionOutput.cmake
@@ -0,0 +1,4 @@
+file(CONFIGURE
+ OUTPUT "file-$<CONFIG>.txt"
+ CONTENT "foo"
+)
diff --git a/Tests/RunCMake/File_Configure/CMakeLists.txt b/Tests/RunCMake/File_Configure/CMakeLists.txt
new file mode 100644
index 0000000..b7117bd
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.17)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/File_Configure/DirOutput-stderr.txt b/Tests/RunCMake/File_Configure/DirOutput-stderr.txt
new file mode 100644
index 0000000..d051f7c
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/DirOutput-stderr.txt
@@ -0,0 +1 @@
+^DirOutput test file$
diff --git a/Tests/RunCMake/File_Configure/DirOutput.cmake b/Tests/RunCMake/File_Configure/DirOutput.cmake
new file mode 100644
index 0000000..aa0fadf
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/DirOutput.cmake
@@ -0,0 +1,4 @@
+file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/DirOutput)
+configure_file(DirOutput.txt DirOutput)
+file(READ ${CMAKE_CURRENT_BINARY_DIR}/DirOutput/DirOutput.txt out)
+message("${out}")
diff --git a/Tests/RunCMake/File_Configure/DirOutput.txt b/Tests/RunCMake/File_Configure/DirOutput.txt
new file mode 100644
index 0000000..16388a6
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/DirOutput.txt
@@ -0,0 +1 @@
+DirOutput test file
diff --git a/Tests/RunCMake/File_Configure/NewLineStyle-NoArg-result.txt b/Tests/RunCMake/File_Configure/NewLineStyle-NoArg-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/NewLineStyle-NoArg-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/File_Configure/NewLineStyle-NoArg-stderr.txt b/Tests/RunCMake/File_Configure/NewLineStyle-NoArg-stderr.txt
new file mode 100644
index 0000000..5a8ed2c
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/NewLineStyle-NoArg-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at NewLineStyle-NoArg.cmake:[0-9]+ \(file\):
+ file CONFIGURE NEWLINE_STYLE must set a style: LF, CRLF, UNIX, DOS, or
+ WIN32
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/File_Configure/NewLineStyle-NoArg.cmake b/Tests/RunCMake/File_Configure/NewLineStyle-NoArg.cmake
new file mode 100644
index 0000000..d6738b4
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/NewLineStyle-NoArg.cmake
@@ -0,0 +1,6 @@
+set(file_name ${CMAKE_CURRENT_BINARY_DIR}/NewLineStyle.txt)
+file(CONFIGURE
+ OUTPUT ${file_name}
+ CONTENT "Data\n"
+ NEWLINE_STYLE
+)
diff --git a/Tests/RunCMake/File_Configure/NewLineStyle-ValidArg.cmake b/Tests/RunCMake/File_Configure/NewLineStyle-ValidArg.cmake
new file mode 100644
index 0000000..e384873
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/NewLineStyle-ValidArg.cmake
@@ -0,0 +1,20 @@
+set(file_name ${CMAKE_CURRENT_BINARY_DIR}/NewLineStyle.txt)
+
+function(test_eol style in out)
+ file(CONFIGURE
+ OUTPUT ${file_name}
+ CONTENT "@in@"
+ NEWLINE_STYLE ${style}
+ )
+ file(READ ${file_name} new HEX)
+ if(NOT "${new}" STREQUAL "${out}")
+ message(FATAL_ERROR "No ${style} line endings")
+ endif()
+endfunction()
+
+test_eol(DOS "a" "610d0a")
+test_eol(WIN32 "b" "620d0a")
+test_eol(CRLF "c" "630d0a")
+
+test_eol(UNIX "d" "640a")
+test_eol(LF "e" "650a")
diff --git a/Tests/RunCMake/File_Configure/NewLineStyle-WrongArg-result.txt b/Tests/RunCMake/File_Configure/NewLineStyle-WrongArg-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/NewLineStyle-WrongArg-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/File_Configure/NewLineStyle-WrongArg-stderr.txt b/Tests/RunCMake/File_Configure/NewLineStyle-WrongArg-stderr.txt
new file mode 100644
index 0000000..c1bb42c
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/NewLineStyle-WrongArg-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at NewLineStyle-WrongArg.cmake:[0-9]+ \(file\):
+ file CONFIGURE NEWLINE_STYLE sets an unknown style, only LF, CRLF, UNIX,
+ DOS, and WIN32 are supported
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/File_Configure/NewLineStyle-WrongArg.cmake b/Tests/RunCMake/File_Configure/NewLineStyle-WrongArg.cmake
new file mode 100644
index 0000000..7d38167
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/NewLineStyle-WrongArg.cmake
@@ -0,0 +1,6 @@
+set(file_name ${CMAKE_CURRENT_BINARY_DIR}/NewLineStyle.txt)
+file(CONFIGURE
+ OUTPUT ${file_name}
+ CONTENT "Data\n"
+ NEWLINE_STYLE FOO
+)
diff --git a/Tests/RunCMake/File_Configure/RunCMakeTest.cmake b/Tests/RunCMake/File_Configure/RunCMakeTest.cmake
new file mode 100644
index 0000000..d09d648
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/RunCMakeTest.cmake
@@ -0,0 +1,9 @@
+include(RunCMake)
+
+run_cmake(BadArg)
+run_cmake(BadArgGeneratorExpressionContent)
+run_cmake(BadArgGeneratorExpressionOutput)
+run_cmake(DirOutput)
+run_cmake(NewLineStyle-NoArg)
+run_cmake(NewLineStyle-ValidArg)
+run_cmake(NewLineStyle-WrongArg)
diff --git a/Tests/RunCMake/File_Generate/CMP0070-OLD-stderr.txt b/Tests/RunCMake/File_Generate/CMP0070-OLD-stderr.txt
new file mode 100644
index 0000000..bb578e5
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/CMP0070-OLD-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at CMP0070-OLD.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0070 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/FindPkgConfig/FindPkgConfig_CMAKE_APPBUNDLE_PATH.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_CMAKE_APPBUNDLE_PATH.cmake
index 2687efe..bf8cd4e 100644
--- a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_CMAKE_APPBUNDLE_PATH.cmake
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_CMAKE_APPBUNDLE_PATH.cmake
@@ -4,53 +4,13 @@ enable_language(C)
# Prepare environment and variables
set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH TRUE)
set(CMAKE_APPBUNDLE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/pc-foo")
-if(WIN32)
- set(PKG_CONFIG_EXECUTABLE "${CMAKE_CURRENT_SOURCE_DIR}\\dummy-pkg-config.bat")
- set(ENV{CMAKE_APPBUNDLE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}\\pc-bar;X:\\this\\directory\\should\\not\\exist\\in\\the\\filesystem")
- set(ENV{PKG_CONFIG_PATH} "C:\\baz")
-else()
- set(PKG_CONFIG_EXECUTABLE "${CMAKE_CURRENT_SOURCE_DIR}/dummy-pkg-config.sh")
- set(ENV{CMAKE_APPBUNDLE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/pc-bar:/this/directory/should/not/exist/in/the/filesystem")
- set(ENV{PKG_CONFIG_PATH} "/baz")
-endif()
-
+set(PKG_CONFIG_EXECUTABLE "${CMAKE_CURRENT_SOURCE_DIR}/dummy-pkg-config.sh")
+set(ENV{CMAKE_APPBUNDLE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/pc-bar:/this/directory/should/not/exist/in/the/filesystem")
+set(ENV{PKG_CONFIG_PATH} "/baz")
find_package(PkgConfig)
-
-if(NOT DEFINED CMAKE_SYSTEM_NAME
- OR (CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU)$"
- AND NOT CMAKE_CROSSCOMPILING))
- if(EXISTS "/etc/debian_version") # is this a debian system ?
- if(CMAKE_LIBRARY_ARCHITECTURE MATCHES "^(i386-linux-gnu|x86_64-linux-gnu)$")
- # Cannot create directories for all the existing architectures...
- set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/${CMAKE_LIBRARY_ARCHITECTURE}/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/${CMAKE_LIBRARY_ARCHITECTURE}/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
- else()
- set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
- endif()
- else()
- # not debian, check the FIND_LIBRARY_USE_LIB32_PATHS and FIND_LIBRARY_USE_LIB64_PATHS properties
- get_property(uselibx32 GLOBAL PROPERTY FIND_LIBRARY_USE_LIBX32_PATHS)
- get_property(uselib32 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB32_PATHS)
- get_property(uselib64 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS)
- if(uselibx32 AND CMAKE_INTERNAL_PLATFORM_ABI STREQUAL "ELF X32")
- set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/libx32/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/libx32/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
- elseif(uselib32 AND CMAKE_SIZEOF_VOID_P EQUAL 4)
- set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib32/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib32/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
- elseif(uselib64 AND CMAKE_SIZEOF_VOID_P EQUAL 8)
- set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib64/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib64/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
- else()
- set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
- endif()
- endif()
-else()
- if(WIN32)
- set(expected_path "C:\\baz;${CMAKE_CURRENT_SOURCE_DIR}\\pc-foo\\lib\\pkgconfig;${CMAKE_CURRENT_SOURCE_DIR}\\pc-bar\\lib\\pkgconfig")
- else()
- set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
- endif()
-endif()
-
+set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
pkg_check_modules(FOO "${expected_path}")
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_CMAKE_FRAMEWORK_PATH.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_CMAKE_FRAMEWORK_PATH.cmake
index 74cda25..37c18fc 100644
--- a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_CMAKE_FRAMEWORK_PATH.cmake
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_CMAKE_FRAMEWORK_PATH.cmake
@@ -4,53 +4,13 @@ enable_language(C)
# Prepare environment and variables
set(PKG_CONFIG_USE_CMAKE_PREFIX_PATH TRUE)
set(CMAKE_FRAMEWORK_PATH "${CMAKE_CURRENT_SOURCE_DIR}/pc-foo")
-if(WIN32)
- set(PKG_CONFIG_EXECUTABLE "${CMAKE_CURRENT_SOURCE_DIR}\\dummy-pkg-config.bat")
- set(ENV{CMAKE_FRAMEWORK_PATH} "${CMAKE_CURRENT_SOURCE_DIR}\\pc-bar;X:\\this\\directory\\should\\not\\exist\\in\\the\\filesystem")
- set(ENV{PKG_CONFIG_PATH} "C:\\baz")
-else()
- set(PKG_CONFIG_EXECUTABLE "${CMAKE_CURRENT_SOURCE_DIR}/dummy-pkg-config.sh")
- set(ENV{CMAKE_FRAMEWORK_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/pc-bar:/this/directory/should/not/exist/in/the/filesystem")
- set(ENV{PKG_CONFIG_PATH} "/baz")
-endif()
-
+set(PKG_CONFIG_EXECUTABLE "${CMAKE_CURRENT_SOURCE_DIR}/dummy-pkg-config.sh")
+set(ENV{CMAKE_FRAMEWORK_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/pc-bar:/this/directory/should/not/exist/in/the/filesystem")
+set(ENV{PKG_CONFIG_PATH} "/baz")
find_package(PkgConfig)
-
-if(NOT DEFINED CMAKE_SYSTEM_NAME
- OR (CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU)$"
- AND NOT CMAKE_CROSSCOMPILING))
- if(EXISTS "/etc/debian_version") # is this a debian system ?
- if(CMAKE_LIBRARY_ARCHITECTURE MATCHES "^(i386-linux-gnu|x86_64-linux-gnu)$")
- # Cannot create directories for all the existing architectures...
- set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/${CMAKE_LIBRARY_ARCHITECTURE}/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/${CMAKE_LIBRARY_ARCHITECTURE}/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
- else()
- set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
- endif()
- else()
- # not debian, check the FIND_LIBRARY_USE_LIB64_PATHS and FIND_LIBRARY_USE_LIB64_PATHS properties
- get_property(uselibx32 GLOBAL PROPERTY FIND_LIBRARY_USE_LIBX32_PATHS)
- get_property(uselib32 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB32_PATHS)
- get_property(uselib64 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS)
- if(uselibx32 AND CMAKE_INTERNAL_PLATFORM_ABI STREQUAL "ELF X32")
- set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/libx32/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/libx32/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
- elseif(uselib32 AND CMAKE_SIZEOF_VOID_P EQUAL 4)
- set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib32/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib32/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
- elseif(uselib64 AND CMAKE_SIZEOF_VOID_P EQUAL 8)
- set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib64/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib64/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
- else()
- set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
- endif()
- endif()
-else()
- if(WIN32)
- set(expected_path "C:\\baz;${CMAKE_CURRENT_SOURCE_DIR}\\pc-foo\\lib\\pkgconfig;${CMAKE_CURRENT_SOURCE_DIR}\\pc-bar\\lib\\pkgconfig")
- else()
- set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
- endif()
-endif()
-
+set(expected_path "/baz:${CMAKE_CURRENT_SOURCE_DIR}/pc-foo/lib/pkgconfig:${CMAKE_CURRENT_SOURCE_DIR}/pc-bar/lib/pkgconfig")
pkg_check_modules(FOO "${expected_path}")
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_extract_frameworks.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_extract_frameworks.cmake
new file mode 100644
index 0000000..fde886d
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_extract_frameworks.cmake
@@ -0,0 +1,13 @@
+find_package(PkgConfig)
+
+set(foobar_LDFLAGS_OTHER "-Wl,xy;-framework;bar;-Wl,other-framework;-framework;baz;-Wl,abc;-framework;gosh;-frameworkcrap;-frame;j;-framework;nix;-Wl,def")
+set(foobar_LIBRARIES "-lz;-lm")
+
+_pkgconfig_extract_frameworks("foobar")
+
+if (NOT foobar_LDFLAGS_OTHER STREQUAL "-Wl,xy;-Wl,other-framework;-Wl,abc;-frameworkcrap;-frame;j;-Wl,def")
+ message(SEND_ERROR "foobar_LDFLAGS_OTHER did not match: ${foobar_LDFLAGS_OTHER}")
+endif ()
+if (NOT foobar_LIBRARIES STREQUAL "-lz;-lm;-framework bar;-framework baz;-framework gosh;-framework nix")
+ message(SEND_ERROR "foobar_LIBRARIES did not match: ${foobar_LIBRARIES}")
+endif ()
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_extract_frameworks_target.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_extract_frameworks_target.cmake
new file mode 100644
index 0000000..5501d9f
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_extract_frameworks_target.cmake
@@ -0,0 +1,29 @@
+# Prepare environment to reuse bletch.pc
+file(TO_NATIVE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/pc-bletch/lib/pkgconfig" PC_PATH)
+if(UNIX)
+ string(REPLACE "\\ " " " PC_PATH "${PC_PATH}")
+endif()
+set(ENV{PKG_CONFIG_PATH} "${PC_PATH}")
+
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(Bletch IMPORTED_TARGET REQUIRED bletch-framework)
+
+if (Bletch_LDFLAGS_OTHER)
+ message(SEND_ERROR "Bletch_LDFLAGS_OTHER should be empty, but is '${Bletch_LDFLAGS_OTHER}'")
+endif ()
+
+if (NOT Bletch_LINK_LIBRARIES STREQUAL "-framework foo;-framework bar;bletch;-framework baz")
+ message(SEND_ERROR "Bletch_LINK_LIBRARIES has wrong value '${Bletch_LINK_LIBRARIES}'")
+endif ()
+
+foreach (prop IN ITEMS INTERFACE_INCLUDE_DIRECTORIES INTERFACE_LINK_OPTIONS INTERFACE_COMPILE_OPTIONS)
+ get_target_property(prop_value PkgConfig::Bletch ${prop})
+ if (prop_value)
+ message(SEND_ERROR "target property ${prop} should not be set, but is '${prop_value}'")
+ endif ()
+endforeach ()
+
+get_target_property(prop_value PkgConfig::Bletch INTERFACE_LINK_LIBRARIES)
+if (NOT prop_value STREQUAL Bletch_LINK_LIBRARIES)
+ message(SEND_ERROR "target property INTERFACE_LINK_LIBRARIES has wrong value '${prop_value}'")
+endif ()
diff --git a/Tests/RunCMake/FindPkgConfig/PkgConfigDoesNotExist-stdout.txt b/Tests/RunCMake/FindPkgConfig/PkgConfigDoesNotExist-stdout.txt
new file mode 100644
index 0000000..ef5f7f6
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/PkgConfigDoesNotExist-stdout.txt
@@ -0,0 +1,6 @@
+-- Could NOT find PkgConfig \(missing: PKG_CONFIG_EXECUTABLE\) *
+ Reason given by package: The command
+ "pkg-config-does-not-exist" --version
+ failed with output.*
+-- PKG_CONFIG_FOUND='FALSE'
+-- PKG_CONFIG_EXECUTABLE=''
diff --git a/Tests/RunCMake/FindPkgConfig/PkgConfigDoesNotExist.cmake b/Tests/RunCMake/FindPkgConfig/PkgConfigDoesNotExist.cmake
new file mode 100644
index 0000000..a4fabde
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/PkgConfigDoesNotExist.cmake
@@ -0,0 +1,4 @@
+set(PKG_CONFIG_EXECUTABLE "pkg-config-does-not-exist" CACHE FILEPATH "")
+find_package(PkgConfig)
+message(STATUS "PKG_CONFIG_FOUND='${PKG_CONFIG_FOUND}'")
+message(STATUS "PKG_CONFIG_EXECUTABLE='${PKG_CONFIG_EXECUTABLE}'")
diff --git a/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake b/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake
index b77bb54..dc77915 100644
--- a/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake
+++ b/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake
@@ -1,11 +1,15 @@
include(RunCMake)
+run_cmake(PkgConfigDoesNotExist)
+
run_cmake(FindPkgConfig_NO_PKGCONFIG_PATH)
run_cmake(FindPkgConfig_PKGCONFIG_PATH)
run_cmake(FindPkgConfig_PKGCONFIG_PATH_NO_CMAKE_PATH)
run_cmake(FindPkgConfig_PKGCONFIG_PATH_NO_CMAKE_ENVIRONMENT_PATH)
+run_cmake(FindPkgConfig_extract_frameworks)
if(APPLE)
+ run_cmake(FindPkgConfig_extract_frameworks_target)
run_cmake(FindPkgConfig_CMAKE_FRAMEWORK_PATH)
run_cmake(FindPkgConfig_CMAKE_APPBUNDLE_PATH)
endif()
diff --git a/Tests/RunCMake/FindPkgConfig/pc-bletch/lib/pkgconfig/bletch-framework.pc b/Tests/RunCMake/FindPkgConfig/pc-bletch/lib/pkgconfig/bletch-framework.pc
new file mode 100644
index 0000000..cc680ae
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/pc-bletch/lib/pkgconfig/bletch-framework.pc
@@ -0,0 +1,9 @@
+prefix=/opt/bletch
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: Bletch
+Description: Dummy packaget to test variable support
+Version: 1.3
+Libs: -L${libdir} -framework foo -framework bar -lbletch -framework baz
diff --git a/Tests/RunCMake/FindSWIG/CMakeLists.txt b/Tests/RunCMake/FindSWIG/CMakeLists.txt
new file mode 100644
index 0000000..d1b0d2c
--- /dev/null
+++ b/Tests/RunCMake/FindSWIG/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.10)
+project(${RunCMake_TEST} C)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/FindSWIG/RunCMakeTest.cmake b/Tests/RunCMake/FindSWIG/RunCMakeTest.cmake
new file mode 100644
index 0000000..5f5f7f5
--- /dev/null
+++ b/Tests/RunCMake/FindSWIG/RunCMakeTest.cmake
@@ -0,0 +1,4 @@
+include(RunCMake)
+
+run_cmake(components)
+run_cmake(missing-components)
diff --git a/Tests/RunCMake/FindSWIG/components-stdout.txt b/Tests/RunCMake/FindSWIG/components-stdout.txt
new file mode 100644
index 0000000..3977b08
--- /dev/null
+++ b/Tests/RunCMake/FindSWIG/components-stdout.txt
@@ -0,0 +1,6 @@
+-- Found SWIG: [^ ]+ \(found version "[0-9.]+"\) found components: java python missing components: PERL
+-- SWIG_VERSION='[0-9.]+'
+-- SWIG_java_FOUND=TRUE
+-- SWIG_python_FOUND=TRUE
+-- SWIG_PERL_FOUND=
+-- Configuring done
diff --git a/Tests/RunCMake/FindSWIG/components.cmake b/Tests/RunCMake/FindSWIG/components.cmake
new file mode 100644
index 0000000..b79a81e
--- /dev/null
+++ b/Tests/RunCMake/FindSWIG/components.cmake
@@ -0,0 +1,9 @@
+# Note that 'perl' will not be found because it is not lowercase.
+find_package(SWIG REQUIRED
+ COMPONENTS java
+ OPTIONAL_COMPONENTS python PERL)
+
+message(STATUS "SWIG_VERSION='${SWIG_VERSION}'")
+foreach(_lang java python PERL)
+ message(STATUS "SWIG_${_lang}_FOUND=${SWIG_${_lang}_FOUND}")
+endforeach()
diff --git a/Tests/RunCMake/FindSWIG/missing-components-result.txt b/Tests/RunCMake/FindSWIG/missing-components-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/FindSWIG/missing-components-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/FindSWIG/missing-components-stderr.txt b/Tests/RunCMake/FindSWIG/missing-components-stderr.txt
new file mode 100644
index 0000000..c937532
--- /dev/null
+++ b/Tests/RunCMake/FindSWIG/missing-components-stderr.txt
@@ -0,0 +1 @@
+Could NOT find SWIG \(missing: invalid\)
diff --git a/Tests/RunCMake/FindSWIG/missing-components.cmake b/Tests/RunCMake/FindSWIG/missing-components.cmake
new file mode 100644
index 0000000..1d05ae4
--- /dev/null
+++ b/Tests/RunCMake/FindSWIG/missing-components.cmake
@@ -0,0 +1,3 @@
+find_package(SWIG REQUIRED
+ COMPONENTS invalid
+ OPTIONAL_COMPONENTS alsoinvalid)
diff --git a/Tests/RunCMake/Framework/FrameworkMultiConfigPostfix-build-final-check.cmake b/Tests/RunCMake/Framework/FrameworkMultiConfigPostfix-build-final-check.cmake
new file mode 100644
index 0000000..76fe6b8
--- /dev/null
+++ b/Tests/RunCMake/Framework/FrameworkMultiConfigPostfix-build-final-check.cmake
@@ -0,0 +1,45 @@
+include("${RunCMake_TEST_BINARY_DIR}/FrameworkMultiConfigPostfixInfo.cmake")
+
+get_filename_component(framework_location "${framework_dir}" DIRECTORY)
+set(non_existent_debug_framework_dir "${framework_location}/${target_file_name}_debug.framework")
+set(framework_resources "${framework_dir}/Resources")
+set(plist_file "${framework_resources}/Info.plist")
+
+set(symlink_release_path "${framework_dir}/${target_file_name}")
+set(framework_release_path "${framework_dir}/Versions/A/${target_file_name}")
+
+# When using a multi config generator (like Ninja Multi-Config and Xcode),
+# the postfix will be applied to the debug framework library name and the symlink name.
+# For single config generators, the name stays the same as the the release framework.
+if(is_multi_config)
+ set(symlink_debug_path "${framework_dir}/${target_file_name}_debug")
+ set(framework_debug_path "${framework_dir}/Versions/A/${target_file_name}_debug")
+else()
+ set(symlink_debug_path "${framework_dir}/${target_file_name}")
+ set(framework_debug_path "${framework_dir}/Versions/A/${target_file_name}")
+endif()
+
+if(NOT IS_DIRECTORY ${framework_dir})
+ message(SEND_ERROR "Framework dir not found at ${framework_dir}")
+endif()
+
+if(IS_DIRECTORY ${non_existent_debug_framework_dir})
+ message(SEND_ERROR
+ "A framework dir with a debug suffix should not exist at ${non_existent_debug_framework_dir}")
+endif()
+
+if(NOT IS_SYMLINK "${symlink_release_path}")
+ message(SEND_ERROR "Release framework symlink not found at ${symlink_release_path}")
+endif()
+
+if(NOT IS_SYMLINK "${symlink_debug_path}")
+ message(SEND_ERROR "Debug framework symlink not found at ${symlink_debug_path}")
+endif()
+
+if(NOT EXISTS "${framework_release_path}")
+ message(SEND_ERROR "Release framework not found at ${framework_release_path}")
+endif()
+
+if(NOT EXISTS "${framework_debug_path}")
+ message(SEND_ERROR "Debug framework not found at ${framework_debug_path}")
+endif()
diff --git a/Tests/RunCMake/Framework/FrameworkMultiConfigPostfix.cmake b/Tests/RunCMake/Framework/FrameworkMultiConfigPostfix.cmake
new file mode 100644
index 0000000..51e627d
--- /dev/null
+++ b/Tests/RunCMake/Framework/FrameworkMultiConfigPostfix.cmake
@@ -0,0 +1,25 @@
+enable_language(C)
+
+set(CMAKE_FRAMEWORK_MULTI_CONFIG_POSTFIX_DEBUG "_debug")
+
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_BINARY_DIR}/lib)
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_BINARY_DIR}/lib)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_BINARY_DIR}/bin)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_BINARY_DIR}/bin)
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_BINARY_DIR}/lib)
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_BINARY_DIR}/lib)
+
+set(target_name "mylib")
+add_library(${target_name} SHARED foo.c)
+set_property(TARGET ${target_name} PROPERTY FRAMEWORK ON)
+get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+
+string(APPEND content
+ "set(is_multi_config \"${is_multi_config}\")\n"
+ "set(framework_dir \"$<TARGET_BUNDLE_DIR:${target_name}>\")\n"
+ "set(target_file_name ${target_name})\n")
+file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/FrameworkMultiConfigPostfixInfo.cmake
+ CONTENT "${content}")
diff --git a/Tests/RunCMake/Framework/RunCMakeTest.cmake b/Tests/RunCMake/Framework/RunCMakeTest.cmake
index 965fbf4..6ee61a3 100644
--- a/Tests/RunCMake/Framework/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Framework/RunCMakeTest.cmake
@@ -45,3 +45,39 @@ framework_type_test(ios SHARED YES)
framework_type_test(ios STATIC YES)
framework_type_test(osx SHARED YES)
framework_type_test(osx STATIC YES)
+
+function(framework_multi_config_postfix_test)
+ set(configure_name "FrameworkMultiConfigPostfix")
+ set(build_name "${configure_name}-build-intermediate")
+ set(build_name_final "${configure_name}-build-final")
+
+ if(RunCMake_GENERATOR MATCHES "Ninja Multi-Config")
+ set(RunCMake_TEST_OPTIONS
+ "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release;-DCMAKE_CROSS_CONFIGS=all")
+ elseif(RunCMake_GENERATOR MATCHES "Xcode")
+ set(RunCMake_TEST_OPTIONS
+ "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release")
+ else()
+ set(RunCMake_TEST_OPTIONS "-DCMAKE_BUILD_TYPE=Debug")
+ endif()
+
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${configure_name})
+ set(RunCMake_TEST_NO_CLEAN 1)
+
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ run_cmake(${configure_name})
+ unset(RunCMake_TEST_OPTIONS)
+
+ if(RunCMake_GENERATOR MATCHES "Ninja Multi-Config")
+ run_cmake_command(${build_name_final} ${CMAKE_COMMAND} --build . --target all:all)
+ elseif(RunCMake_GENERATOR MATCHES "Xcode")
+ run_cmake_command(${build_name} ${CMAKE_COMMAND} --build . --config Release)
+ run_cmake_command(${build_name} ${CMAKE_COMMAND} --build . --config Debug)
+ run_cmake_command(${build_name_final} ${CMAKE_COMMAND} --build . --config Debug)
+ else()
+ run_cmake_command(${build_name_final} ${CMAKE_COMMAND} --build .)
+ endif()
+endfunction()
+
+framework_multi_config_postfix_test()
diff --git a/Tests/RunCMake/GNUInstallDirs/NoSystem-stderr.txt b/Tests/RunCMake/GNUInstallDirs/NoSystem-stderr.txt
new file mode 100644
index 0000000..36f064c
--- /dev/null
+++ b/Tests/RunCMake/GNUInstallDirs/NoSystem-stderr.txt
@@ -0,0 +1,8 @@
+^CMake Warning \(dev\) at .*/Modules/GNUInstallDirs.cmake:[0-9]+ \(message\):
+ Unable to determine default CMAKE_INSTALL_LIBDIR directory because no
+ target architecture is known. Please enable at least one language before
+ including GNUInstallDirs.
+Call Stack \(most recent call first\):
+ NoSystem.cmake:[0-9]+ \(include\)
+ CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.$
diff --git a/Tests/RunCMake/GNUInstallDirs/NoSystem.cmake b/Tests/RunCMake/GNUInstallDirs/NoSystem.cmake
new file mode 100644
index 0000000..19cf7be
--- /dev/null
+++ b/Tests/RunCMake/GNUInstallDirs/NoSystem.cmake
@@ -0,0 +1,2 @@
+unset(CMAKE_SYSTEM_NAME)
+include(GNUInstallDirs)
diff --git a/Tests/RunCMake/GNUInstallDirs/RunCMakeTest.cmake b/Tests/RunCMake/GNUInstallDirs/RunCMakeTest.cmake
index d671ee0..eb2c1a2 100644
--- a/Tests/RunCMake/GNUInstallDirs/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GNUInstallDirs/RunCMakeTest.cmake
@@ -16,4 +16,7 @@ foreach(case
)
set(RunCMake-stderr-file ${case}${variant}-stderr.txt)
run_cmake(${case})
+ unset(RunCMake-stderr-file)
endforeach()
+
+run_cmake(NoSystem)
diff --git a/Tests/RunCMake/GenerateExportHeader/exportheader_test.cpp b/Tests/RunCMake/GenerateExportHeader/exportheader_test.cpp
index ba77679..dcaa4f2 100644
--- a/Tests/RunCMake/GenerateExportHeader/exportheader_test.cpp
+++ b/Tests/RunCMake/GenerateExportHeader/exportheader_test.cpp
@@ -32,14 +32,14 @@ void compare(const char* refName, const char* testName)
// trailing null to the string that we need to strip before testing for a
// trailing space.
if (refLine.size() && refLine[refLine.size() - 1] == 0) {
- refLine = refLine.substr(0, refLine.size() - 1);
+ refLine.resize(refLine.size() - 1);
}
if (testLine.size() && testLine[testLine.size() - 1] == 0) {
- testLine = testLine.substr(0, testLine.size() - 1);
+ testLine.resize(testLine.size() - 1);
}
// The reference files never have trailing spaces:
if (testLine.size() && testLine[testLine.size() - 1] == ' ') {
- testLine = testLine.substr(0, testLine.size() - 1);
+ testLine.resize(testLine.size() - 1);
}
if (refLine != testLine) {
std::cout << "Ref and test are not the same:\n Ref: \"" << refLine
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_custom_command-result.txt b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_custom_command-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_custom_command-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_custom_command-stderr.txt b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_custom_command-stderr.txt
new file mode 100644
index 0000000..eb15834
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_custom_command-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at DEVICE_LINK-add_custom_command.cmake:[0-9]+ \(add_custom_command\):
+ Error evaluating generator expression:
+
+ \$<DEVICE_LINK>
+
+ \$<DEVICE_LINK:...> may only be used with binary targets to specify link
+ options.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_custom_command.cmake b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_custom_command.cmake
new file mode 100644
index 0000000..01b3784
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_custom_command.cmake
@@ -0,0 +1,4 @@
+add_custom_target(drive)
+add_custom_command(TARGET drive PRE_BUILD
+ COMMAND ${CMAKE_COMMAND} -E echo $<DEVICE_LINK>
+)
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_custom_target-result.txt b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_custom_target-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_custom_target-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_custom_target-stderr.txt b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_custom_target-stderr.txt
new file mode 100644
index 0000000..cdd3043
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_custom_target-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at DEVICE_LINK-add_custom_target.cmake:[0-9]+ \(add_custom_target\):
+ Error evaluating generator expression:
+
+ \$<DEVICE_LINK>
+
+ \$<DEVICE_LINK:...> may only be used with binary targets to specify link
+ options.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_custom_target.cmake b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_custom_target.cmake
new file mode 100644
index 0000000..35728e9
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_custom_target.cmake
@@ -0,0 +1,3 @@
+add_custom_target(drive
+ COMMAND ${CMAKE_COMMAND} -E echo $<DEVICE_LINK>
+)
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_executable-result.txt b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_executable-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_executable-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_executable-stderr.txt b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_executable-stderr.txt
new file mode 100644
index 0000000..56b595c
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_executable-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at DEVICE_LINK-add_executable.cmake:[0-9]+ \(add_executable\):
+ Error evaluating generator expression:
+
+ \$<DEVICE_LINK:empty.c>
+
+ \$<DEVICE_LINK:...> may only be used with binary targets to specify link
+ options.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_executable.cmake b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_executable.cmake
new file mode 100644
index 0000000..899f8f6
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_executable.cmake
@@ -0,0 +1 @@
+add_executable(empty $<DEVICE_LINK:empty.c>)
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_library-result.txt b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_library-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_library-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_library-stderr.txt b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_library-stderr.txt
new file mode 100644
index 0000000..4477e00
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_library-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at DEVICE_LINK-add_library.cmake:[0-9]+ \(add_library\):
+ Error evaluating generator expression:
+
+ \$<DEVICE_LINK:empty.c>
+
+ \$<DEVICE_LINK:...> may only be used with binary targets to specify link
+ options.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_library.cmake b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_library.cmake
new file mode 100644
index 0000000..fc8547b
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_library.cmake
@@ -0,0 +1 @@
+add_library(empty $<DEVICE_LINK:empty.c>)
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_test-result.txt b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_test-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_test-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_test-stderr.txt b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_test-stderr.txt
new file mode 100644
index 0000000..99561fe
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_test-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at DEVICE_LINK-add_test.cmake:[0-9]+ \(add_test\):
+ Error evaluating generator expression:
+
+ \$<DEVICE_LINK>
+
+ \$<DEVICE_LINK:...> may only be used with binary targets to specify link
+ options.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_test.cmake b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_test.cmake
new file mode 100644
index 0000000..87d6ba1
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-add_test.cmake
@@ -0,0 +1,5 @@
+
+include(CTest)
+enable_testing()
+
+add_test(NAME dummy COMMAND ${CMAKE_COMMAND} -E echo $<DEVICE_LINK>)
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-install-result.txt b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-install-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-install-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-install-stderr.txt b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-install-stderr.txt
new file mode 100644
index 0000000..afb3090
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-install-stderr.txt
@@ -0,0 +1,7 @@
+CMake Error:
+ Error evaluating generator expression:
+
+ \$<DEVICE_LINK:empty>
+
+ \$<DEVICE_LINK:...> may only be used with binary targets to specify link
+ options.
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-install.cmake b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-install.cmake
new file mode 100644
index 0000000..4b6dbef
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-install.cmake
@@ -0,0 +1,5 @@
+
+install(FILES
+ $<DEVICE_LINK:empty>
+ DESTINATION src
+)
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-link_depends-result.txt b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-link_depends-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-link_depends-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-link_depends-stderr.txt b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-link_depends-stderr.txt
new file mode 100644
index 0000000..4fa0522
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-link_depends-stderr.txt
@@ -0,0 +1,7 @@
+CMake Error:
+ Error evaluating generator expression:
+
+ \$<DEVICE_LINK:lib>
+
+ \$<DEVICE_LINK:...> may only be used with binary targets to specify link
+ options.
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-link_depends.cmake b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-link_depends.cmake
new file mode 100644
index 0000000..8129514
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-link_depends.cmake
@@ -0,0 +1,7 @@
+
+enable_language(C)
+
+add_library(lib empty.c)
+
+add_executable(empty empty.c)
+set_property(TARGET empty PROPERTY LINK_DEPENDS $<DEVICE_LINK:lib>)
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_compile_definitions-result.txt b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_compile_definitions-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_compile_definitions-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_compile_definitions-stderr.txt b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_compile_definitions-stderr.txt
new file mode 100644
index 0000000..c0185e3
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_compile_definitions-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at DEVICE_LINK-target_compile_definitions.cmake:[0-9]+ \(target_compile_definitions\):
+ Error evaluating generator expression:
+
+ \$<DEVICE_LINK:DEF>
+
+ \$<DEVICE_LINK:...> may only be used with binary targets to specify link
+ options.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_compile_definitions.cmake b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_compile_definitions.cmake
new file mode 100644
index 0000000..aaa8efc
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_compile_definitions.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_compile_definitions(empty PRIVATE $<DEVICE_LINK:DEF>)
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_compile_options-result.txt b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_compile_options-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_compile_options-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_compile_options-stderr.txt b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_compile_options-stderr.txt
new file mode 100644
index 0000000..34ca4f2
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_compile_options-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at DEVICE_LINK-target_compile_options.cmake:[0-9]+ \(target_compile_options\):
+ Error evaluating generator expression:
+
+ \$<DEVICE_LINK:-OPT>
+
+ \$<DEVICE_LINK:...> may only be used with binary targets to specify link
+ options.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_compile_options.cmake b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_compile_options.cmake
new file mode 100644
index 0000000..a9cb7fd
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_compile_options.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_compile_options(empty PRIVATE $<DEVICE_LINK:-OPT>)
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_include_directories-result.txt b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_include_directories-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_include_directories-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_include_directories-stderr.txt b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_include_directories-stderr.txt
new file mode 100644
index 0000000..4d1642d
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_include_directories-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at DEVICE_LINK-target_include_directories.cmake:[0-9]+ \(target_include_directories\):
+ Error evaluating generator expression:
+
+ \$<DEVICE_LINK:/DIR>
+
+ \$<DEVICE_LINK:...> may only be used with binary targets to specify link
+ options.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_include_directories.cmake b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_include_directories.cmake
new file mode 100644
index 0000000..03cc413
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_include_directories.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_include_directories(empty PRIVATE $<DEVICE_LINK:/DIR>)
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_link_directories-result.txt b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_link_directories-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_link_directories-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_link_directories-stderr.txt b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_link_directories-stderr.txt
new file mode 100644
index 0000000..d924916
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_link_directories-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at DEVICE_LINK-target_link_directories.cmake:[0-9]+ \(target_link_directories\):
+ Error evaluating generator expression:
+
+ \$<DEVICE_LINK:/DIR>
+
+ \$<DEVICE_LINK:...> may only be used with binary targets to specify link
+ options.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_link_directories.cmake b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_link_directories.cmake
new file mode 100644
index 0000000..e50d27d
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_link_directories.cmake
@@ -0,0 +1,7 @@
+
+enable_language(C)
+
+add_library(lib empty.c)
+
+add_executable(empty empty.c)
+target_link_directories(empty PRIVATE $<DEVICE_LINK:/DIR>)
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_link_libraries-result.txt b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_link_libraries-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_link_libraries-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_link_libraries-stderr.txt b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_link_libraries-stderr.txt
new file mode 100644
index 0000000..1436fa8
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_link_libraries-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at DEVICE_LINK-target_link_libraries.cmake:[0-9]+ \(target_link_libraries\):
+ Error evaluating generator expression:
+
+ \$<DEVICE_LINK:lib>
+
+ \$<DEVICE_LINK:...> may only be used with binary targets to specify link
+ options.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_link_libraries.cmake b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_link_libraries.cmake
new file mode 100644
index 0000000..971f562
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_link_libraries.cmake
@@ -0,0 +1,7 @@
+
+enable_language(C)
+
+add_library(lib empty.c)
+
+add_executable(empty empty.c)
+target_link_libraries(empty PRIVATE $<DEVICE_LINK:lib>)
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_sources-result.txt b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_sources-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_sources-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_sources-stderr.txt b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_sources-stderr.txt
new file mode 100644
index 0000000..c9b602d
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_sources-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at DEVICE_LINK-target_sources.cmake:[0-9]+ \(target_sources\):
+ Error evaluating generator expression:
+
+ \$<DEVICE_LINK:empty.c>
+
+ \$<DEVICE_LINK:...> may only be used with binary targets to specify link
+ options.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_sources.cmake b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_sources.cmake
new file mode 100644
index 0000000..94bac9e
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/DEVICE_LINK-target_sources.cmake
@@ -0,0 +1,2 @@
+add_library(empty)
+target_sources(empty PRIVATE $<DEVICE_LINK:empty.c>)
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_custom_command-result.txt b/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_custom_command-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_custom_command-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_custom_command-stderr.txt b/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_custom_command-stderr.txt
new file mode 100644
index 0000000..5ad41b9
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_custom_command-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at HOST_LINK-add_custom_command.cmake:[0-9]+ \(add_custom_command\):
+ Error evaluating generator expression:
+
+ \$<HOST_LINK>
+
+ \$<HOST_LINK:...> may only be used with binary targets to specify link
+ options.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_custom_command.cmake b/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_custom_command.cmake
new file mode 100644
index 0000000..4d6e305
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_custom_command.cmake
@@ -0,0 +1,4 @@
+add_custom_target(drive)
+add_custom_command(TARGET drive PRE_BUILD
+ COMMAND ${CMAKE_COMMAND} -E echo $<HOST_LINK>
+)
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_custom_target-result.txt b/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_custom_target-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_custom_target-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_custom_target-stderr.txt b/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_custom_target-stderr.txt
new file mode 100644
index 0000000..c44202a
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_custom_target-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at HOST_LINK-add_custom_target.cmake:[0-9]+ \(add_custom_target\):
+ Error evaluating generator expression:
+
+ \$<HOST_LINK>
+
+ \$<HOST_LINK:...> may only be used with binary targets to specify link
+ options.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_custom_target.cmake b/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_custom_target.cmake
new file mode 100644
index 0000000..eec072a
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_custom_target.cmake
@@ -0,0 +1,3 @@
+add_custom_target(drive
+ COMMAND ${CMAKE_COMMAND} -E echo $<HOST_LINK>
+)
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_executable-result.txt b/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_executable-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_executable-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_executable-stderr.txt b/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_executable-stderr.txt
new file mode 100644
index 0000000..b395515
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_executable-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at HOST_LINK-add_executable.cmake:[0-9]+ \(add_executable\):
+ Error evaluating generator expression:
+
+ \$<HOST_LINK:empty.c>
+
+ \$<HOST_LINK:...> may only be used with binary targets to specify link
+ options.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_executable.cmake b/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_executable.cmake
new file mode 100644
index 0000000..c9f74a5
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_executable.cmake
@@ -0,0 +1 @@
+add_executable(empty $<HOST_LINK:empty.c>)
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_library-result.txt b/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_library-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_library-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_library-stderr.txt b/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_library-stderr.txt
new file mode 100644
index 0000000..4bd27be
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_library-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at HOST_LINK-add_library.cmake:[0-9]+ \(add_library\):
+ Error evaluating generator expression:
+
+ \$<HOST_LINK:empty.c>
+
+ \$<HOST_LINK:...> may only be used with binary targets to specify link
+ options.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_library.cmake b/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_library.cmake
new file mode 100644
index 0000000..44135af
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_library.cmake
@@ -0,0 +1 @@
+add_library(empty $<HOST_LINK:empty.c>)
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_test-result.txt b/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_test-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_test-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_test-stderr.txt b/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_test-stderr.txt
new file mode 100644
index 0000000..012ad21
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_test-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at HOST_LINK-add_test.cmake:[0-9]+ \(add_test\):
+ Error evaluating generator expression:
+
+ \$<HOST_LINK>
+
+ \$<HOST_LINK:...> may only be used with binary targets to specify link
+ options.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_test.cmake b/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_test.cmake
new file mode 100644
index 0000000..4b472af
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-add_test.cmake
@@ -0,0 +1,5 @@
+
+include(CTest)
+enable_testing()
+
+add_test(NAME dummy COMMAND ${CMAKE_COMMAND} -E echo $<HOST_LINK>)
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-install-result.txt b/Tests/RunCMake/GeneratorExpression/HOST_LINK-install-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-install-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-install-stderr.txt b/Tests/RunCMake/GeneratorExpression/HOST_LINK-install-stderr.txt
new file mode 100644
index 0000000..c265ec4
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-install-stderr.txt
@@ -0,0 +1,7 @@
+CMake Error:
+ Error evaluating generator expression:
+
+ \$<HOST_LINK:empty>
+
+ \$<HOST_LINK:...> may only be used with binary targets to specify link
+ options.
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-install.cmake b/Tests/RunCMake/GeneratorExpression/HOST_LINK-install.cmake
new file mode 100644
index 0000000..b4dff68
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-install.cmake
@@ -0,0 +1,5 @@
+
+install(FILES
+ $<HOST_LINK:empty>
+ DESTINATION src
+)
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-link_depends-result.txt b/Tests/RunCMake/GeneratorExpression/HOST_LINK-link_depends-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-link_depends-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-link_depends-stderr.txt b/Tests/RunCMake/GeneratorExpression/HOST_LINK-link_depends-stderr.txt
new file mode 100644
index 0000000..24b8b82
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-link_depends-stderr.txt
@@ -0,0 +1,7 @@
+CMake Error:
+ Error evaluating generator expression:
+
+ \$<HOST_LINK:lib>
+
+ \$<HOST_LINK:...> may only be used with binary targets to specify link
+ options.
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-link_depends.cmake b/Tests/RunCMake/GeneratorExpression/HOST_LINK-link_depends.cmake
new file mode 100644
index 0000000..0402f43
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-link_depends.cmake
@@ -0,0 +1,7 @@
+
+enable_language(C)
+
+add_library(lib empty.c)
+
+add_executable(empty empty.c)
+set_property(TARGET empty PROPERTY LINK_DEPENDS $<HOST_LINK:lib>)
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_compile_definitions-result.txt b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_compile_definitions-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_compile_definitions-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_compile_definitions-stderr.txt b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_compile_definitions-stderr.txt
new file mode 100644
index 0000000..6ab3c14
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_compile_definitions-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at HOST_LINK-target_compile_definitions.cmake:[0-9]+ \(target_compile_definitions\):
+ Error evaluating generator expression:
+
+ \$<HOST_LINK:DEF>
+
+ \$<HOST_LINK:...> may only be used with binary targets to specify link
+ options.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_compile_definitions.cmake b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_compile_definitions.cmake
new file mode 100644
index 0000000..f6c130d
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_compile_definitions.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_compile_definitions(empty PRIVATE $<HOST_LINK:DEF>)
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_compile_options-result.txt b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_compile_options-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_compile_options-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_compile_options-stderr.txt b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_compile_options-stderr.txt
new file mode 100644
index 0000000..0f5bbc3
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_compile_options-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at HOST_LINK-target_compile_options.cmake:[0-9]+ \(target_compile_options\):
+ Error evaluating generator expression:
+
+ \$<HOST_LINK:-OPT>
+
+ \$<HOST_LINK:...> may only be used with binary targets to specify link
+ options.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_compile_options.cmake b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_compile_options.cmake
new file mode 100644
index 0000000..53afea1
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_compile_options.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_compile_options(empty PRIVATE $<HOST_LINK:-OPT>)
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_include_directories-result.txt b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_include_directories-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_include_directories-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_include_directories-stderr.txt b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_include_directories-stderr.txt
new file mode 100644
index 0000000..9a2634a
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_include_directories-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at HOST_LINK-target_include_directories.cmake:[0-9]+ \(target_include_directories\):
+ Error evaluating generator expression:
+
+ \$<HOST_LINK:/DIR>
+
+ \$<HOST_LINK:...> may only be used with binary targets to specify link
+ options.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_include_directories.cmake b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_include_directories.cmake
new file mode 100644
index 0000000..aff1009
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_include_directories.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_include_directories(empty PRIVATE $<HOST_LINK:/DIR>)
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_link_directories-result.txt b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_link_directories-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_link_directories-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_link_directories-stderr.txt b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_link_directories-stderr.txt
new file mode 100644
index 0000000..5225a52
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_link_directories-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at HOST_LINK-target_link_directories.cmake:[0-9]+ \(target_link_directories\):
+ Error evaluating generator expression:
+
+ \$<HOST_LINK:/DIR>
+
+ \$<HOST_LINK:...> may only be used with binary targets to specify link
+ options.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_link_directories.cmake b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_link_directories.cmake
new file mode 100644
index 0000000..97488ee
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_link_directories.cmake
@@ -0,0 +1,7 @@
+
+enable_language(C)
+
+add_library(lib empty.c)
+
+add_executable(empty empty.c)
+target_link_directories(empty PRIVATE $<HOST_LINK:/DIR>)
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_link_libraries-result.txt b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_link_libraries-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_link_libraries-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_link_libraries-stderr.txt b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_link_libraries-stderr.txt
new file mode 100644
index 0000000..6c4441f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_link_libraries-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at HOST_LINK-target_link_libraries.cmake:[0-9]+ \(target_link_libraries\):
+ Error evaluating generator expression:
+
+ \$<HOST_LINK:lib>
+
+ \$<HOST_LINK:...> may only be used with binary targets to specify link
+ options.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_link_libraries.cmake b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_link_libraries.cmake
new file mode 100644
index 0000000..d74c92d
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_link_libraries.cmake
@@ -0,0 +1,7 @@
+
+enable_language(C)
+
+add_library(lib empty.c)
+
+add_executable(empty empty.c)
+target_link_libraries(empty PRIVATE $<HOST_LINK:lib>)
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_sources-result.txt b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_sources-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_sources-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_sources-stderr.txt b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_sources-stderr.txt
new file mode 100644
index 0000000..0e25568
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_sources-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at HOST_LINK-target_sources.cmake:[0-9]+ \(target_sources\):
+ Error evaluating generator expression:
+
+ \$<HOST_LINK:empty.c>
+
+ \$<HOST_LINK:...> may only be used with binary targets to specify link
+ options.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_sources.cmake b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_sources.cmake
new file mode 100644
index 0000000..ea7bf55
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/HOST_LINK-target_sources.cmake
@@ -0,0 +1,2 @@
+add_library(empty)
+target_sources(empty PRIVATE $<HOST_LINK:empty.c>)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_command-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_command-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_command-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_command-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_command-stderr.txt
new file mode 100644
index 0000000..0b0d458
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_command-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANGUAGE-add_custom_command.cmake:2 \(add_custom_command\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANGUAGE>
+
+ \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+ libraries, link directories, link options and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_command.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_command.cmake
new file mode 100644
index 0000000..a378c1c
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_command.cmake
@@ -0,0 +1,4 @@
+add_custom_target(drive)
+add_custom_command(TARGET drive PRE_BUILD
+ COMMAND ${CMAKE_COMMAND} -E echo $<LINK_LANGUAGE>
+)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_target-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_target-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_target-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_target-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_target-stderr.txt
new file mode 100644
index 0000000..92da634
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_target-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANGUAGE-add_custom_target.cmake:1 \(add_custom_target\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANGUAGE>
+
+ \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+ libraries, link directories, link options and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_target.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_target.cmake
new file mode 100644
index 0000000..60b6c75
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_target.cmake
@@ -0,0 +1,3 @@
+add_custom_target(drive
+ COMMAND ${CMAKE_COMMAND} -E echo $<LINK_LANGUAGE>
+)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_executable-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_executable-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_executable-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_executable-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_executable-stderr.txt
new file mode 100644
index 0000000..3bdc8e4
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_executable-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANGUAGE-add_executable.cmake:1 \(add_executable\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANGUAGE>
+
+ \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+ libraries, link directories, link options and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_executable.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_executable.cmake
new file mode 100644
index 0000000..2176b39
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_executable.cmake
@@ -0,0 +1 @@
+add_executable(empty empty.$<LINK_LANGUAGE>)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_library-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_library-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_library-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_library-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_library-stderr.txt
new file mode 100644
index 0000000..1bacdeb
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_library-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANGUAGE-add_library.cmake:1 \(add_library\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANGUAGE>
+
+ \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+ libraries, link directories, link options and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_library.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_library.cmake
new file mode 100644
index 0000000..253f82a
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_library.cmake
@@ -0,0 +1 @@
+add_library(empty empty.$<LINK_LANGUAGE>)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_test-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_test-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_test-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_test-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_test-stderr.txt
new file mode 100644
index 0000000..f22efde
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_test-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANGUAGE-add_test.cmake:5 \(add_test\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANGUAGE>
+
+ \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+ libraries, link directories, link options and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_test.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_test.cmake
new file mode 100644
index 0000000..4fd547d
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_test.cmake
@@ -0,0 +1,5 @@
+
+include(CTest)
+enable_testing()
+
+add_test(NAME dummy COMMAND ${CMAKE_COMMAND} -E echo $<LINK_LANGUAGE>)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-file_generate-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-file_generate-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-file_generate-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-file_generate-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-file_generate-stderr.txt
new file mode 100644
index 0000000..21d26de
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-file_generate-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANGUAGE-file_generate.cmake:3 \(file\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANGUAGE>
+
+ \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+ libraries, link directories, link options and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-file_generate.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-file_generate.cmake
new file mode 100644
index 0000000..519b883
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-file_generate.cmake
@@ -0,0 +1,6 @@
+enable_language(CXX C)
+
+file(GENERATE
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/output.txt
+ CONTENT "LANG_IS_$<LINK_LANGUAGE>\n"
+)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-install-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-install-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-install-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-install-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-install-stderr.txt
new file mode 100644
index 0000000..73afc33
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-install-stderr.txt
@@ -0,0 +1,10 @@
+CMake Error:
+ Error evaluating generator expression:
+
+ \$<LINK_LANGUAGE>
+
+ \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+ libraries, link directories, link options and link depends.
+
+
+CMake Generate step failed. Build files cannot be regenerated correctly.
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-install.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-install.cmake
new file mode 100644
index 0000000..533c0b4
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-install.cmake
@@ -0,0 +1,5 @@
+
+install(FILES
+ empty.$<LINK_LANGUAGE>
+ DESTINATION src
+)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-target_sources-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-target_sources-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-target_sources-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-target_sources-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-target_sources-stderr.txt
new file mode 100644
index 0000000..d8121cc
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-target_sources-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANGUAGE-target_sources.cmake:2 \(target_sources\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANGUAGE>
+
+ \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+ libraries, link directories, link options and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-target_sources.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-target_sources.cmake
new file mode 100644
index 0000000..c134c01
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-target_sources.cmake
@@ -0,0 +1,2 @@
+add_library(empty)
+target_sources(empty PRIVATE empty.$<LINK_LANGUAGE>)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-unknown-lang.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-unknown-lang.cmake
new file mode 100644
index 0000000..0ba472d
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-unknown-lang.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_link_options(empty PRIVATE $<$<LINK_LANGUAGE:CXX>:$<TARGET_EXISTS:too,many,parameters>>)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage1-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage1-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage1-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage1-stderr.txt
new file mode 100644
index 0000000..1e3a83b
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage1-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANGUAGE-wrong-usage1.cmake:4 \(target_compile_definitions\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANGUAGE:C>
+
+ \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+ libraries, link directories, link options and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage1.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage1.cmake
new file mode 100644
index 0000000..90b7ce0
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage1.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_compile_definitions(empty PRIVATE $<$<LINK_LANGUAGE:C>:DEF>)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage2-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage2-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage2-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage2-stderr.txt
new file mode 100644
index 0000000..7fe4310
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage2-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANGUAGE-wrong-usage2.cmake:4 \(target_compile_options\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANGUAGE:C>
+
+ \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+ libraries, link directories, link options and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage2.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage2.cmake
new file mode 100644
index 0000000..e761897
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage2.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_compile_options(empty PRIVATE $<$<LINK_LANGUAGE:C>:-OPT>)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage3-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage3-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage3-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage3-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage3-stderr.txt
new file mode 100644
index 0000000..cb20e99
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage3-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANGUAGE-wrong-usage3.cmake:4 \(target_include_directories\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANGUAGE:C>
+
+ \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+ libraries, link directories, link options and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage3.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage3.cmake
new file mode 100644
index 0000000..96a72a1
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage3.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_include_directories(empty PRIVATE $<$<LINK_LANGUAGE:C>:/DIR>)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage4-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage4-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage4-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage4-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage4-stderr.txt
new file mode 100644
index 0000000..ee36912
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage4-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at LINK_LANGUAGE-wrong-usage4.cmake:7 \(target_link_libraries\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANGUAGE>
+
+ \$<LINK_LANGUAGE> is not supported in link libraries expression.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage4.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage4.cmake
new file mode 100644
index 0000000..3ecaabb
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage4.cmake
@@ -0,0 +1,7 @@
+
+enable_language(C)
+
+add_library(libC empty.c)
+
+add_executable(empty empty.c)
+target_link_libraries(empty PRIVATE lib$<LINK_LANGUAGE>)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_command-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_command-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_command-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_command-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_command-stderr.txt
new file mode 100644
index 0000000..2ff62bc
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_command-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANG_AND_ID-add_custom_command.cmake:2 \(add_custom_command\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANG_AND_ID:LANG,ID>
+
+ \$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets to specify
+ link libraries, link directories, link options, and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_command.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_command.cmake
new file mode 100644
index 0000000..9df9232
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_command.cmake
@@ -0,0 +1,4 @@
+add_custom_target(drive)
+add_custom_command(TARGET drive PRE_BUILD
+ COMMAND ${CMAKE_COMMAND} -E echo $<LINK_LANG_AND_ID:LANG,ID>
+)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_target-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_target-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_target-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_target-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_target-stderr.txt
new file mode 100644
index 0000000..0749c44
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_target-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANG_AND_ID-add_custom_target.cmake:2 \(add_custom_target\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANG_AND_ID:LANG,ID>
+
+ \$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets to specify
+ link libraries, link directories, link options, and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_target.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_target.cmake
new file mode 100644
index 0000000..e5f76bc
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_target.cmake
@@ -0,0 +1,4 @@
+
+add_custom_target(drive
+ COMMAND ${CMAKE_COMMAND} -E echo $<LINK_LANG_AND_ID:LANG,ID>
+)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_executable-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_executable-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_executable-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_executable-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_executable-stderr.txt
new file mode 100644
index 0000000..595312a
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_executable-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANG_AND_ID-add_executable.cmake:1 \(add_executable\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANG_AND_ID:C,MSVC>
+
+ \$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets to specify
+ link libraries, link directories, link options, and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_executable.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_executable.cmake
new file mode 100644
index 0000000..4d6c674
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_executable.cmake
@@ -0,0 +1,5 @@
+add_executable(empty main.c
+ $<$<LINK_LANG_AND_ID:C,MSVC>:empty.c>
+ $<$<LINK_LANG_AND_ID:C,GNU>:empty2.c>
+ $<$<LINK_LANG_AND_ID:C,Clang>:empty3.c>
+ )
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_library-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_library-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_library-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_library-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_library-stderr.txt
new file mode 100644
index 0000000..be46e28
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_library-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANG_AND_ID-add_library.cmake:2 \(add_library\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANG_AND_ID:C,MSVC>
+
+ \$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets to specify
+ link libraries, link directories, link options, and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_library.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_library.cmake
new file mode 100644
index 0000000..a8199cf
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_library.cmake
@@ -0,0 +1,2 @@
+
+add_library(empty empty.$<LINK_LANG_AND_ID:C,MSVC>)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_test-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_test-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_test-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_test-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_test-stderr.txt
new file mode 100644
index 0000000..2a29492
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_test-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANG_AND_ID-add_test.cmake:5 \(add_test\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANG_AND_ID:CXX,GNU>
+
+ \$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets to specify
+ link libraries, link directories, link options, and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_test.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_test.cmake
new file mode 100644
index 0000000..fd700d7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_test.cmake
@@ -0,0 +1,5 @@
+
+include(CTest)
+enable_testing()
+
+add_test(NAME dummy COMMAND ${CMAKE_COMMAND} -E echo $<LINK_LANG_AND_ID:CXX,GNU>)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-file_generate-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-file_generate-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-file_generate-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-file_generate-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-file_generate-stderr.txt
new file mode 100644
index 0000000..e57b55c
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-file_generate-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANG_AND_ID-file_generate.cmake:3 \(file\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANG_AND_ID:C,GNU>
+
+ \$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets to specify
+ link libraries, link directories, link options, and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-file_generate.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-file_generate.cmake
new file mode 100644
index 0000000..67c1bda
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-file_generate.cmake
@@ -0,0 +1,6 @@
+enable_language(CXX C)
+
+file(GENERATE
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/output.txt
+ CONTENT "LANG_IS_$<$<LINK_LANG_AND_ID:C,GNU>:C>\n"
+)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-install-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-install-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-install-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-install-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-install-stderr.txt
new file mode 100644
index 0000000..965f974
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-install-stderr.txt
@@ -0,0 +1,10 @@
+CMake Error:
+ Error evaluating generator expression:
+
+ \$<LINK_LANG_AND_ID:C,MSVC>
+
+ \$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets to specify
+ link libraries, link directories, link options, and link depends.
+
+
+CMake Generate step failed. Build files cannot be regenerated correctly.
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-install.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-install.cmake
new file mode 100644
index 0000000..b8f9323
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-install.cmake
@@ -0,0 +1,5 @@
+
+install(FILES
+ empty.$<LINK_LANG_AND_ID:C,MSVC>
+ DESTINATION src
+)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-target_sources-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-target_sources-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-target_sources-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-target_sources-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-target_sources-stderr.txt
new file mode 100644
index 0000000..e86602a
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-target_sources-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at LINK_LANG_AND_ID-target_sources.cmake:2 \(target_sources\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANG_AND_ID>
+
+ \$<LINK_LANG_AND_ID> expression requires at least two parameters.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-target_sources.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-target_sources.cmake
new file mode 100644
index 0000000..da5faf4
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-target_sources.cmake
@@ -0,0 +1,2 @@
+add_library(empty)
+target_sources(empty PRIVATE empty.$<LINK_LANG_AND_ID>)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-unknown-lang.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-unknown-lang.cmake
new file mode 100644
index 0000000..99dd337
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-unknown-lang.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_link_options(empty PRIVATE $<$<LINK_LANG_AND_ID:CXX,GNU>:$<TARGET_EXISTS:too,many,parameters>>)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage1-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage1-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage1-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage1-stderr.txt
new file mode 100644
index 0000000..95611c3
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage1-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANG_AND_ID-wrong-usage1.cmake:4 \(target_compile_definitions\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANG_AND_ID:C,GNU>
+
+ \$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets to specify
+ link libraries, link directories, link options, and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage1.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage1.cmake
new file mode 100644
index 0000000..e58e3b44
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage1.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_compile_definitions(empty PRIVATE $<$<LINK_LANG_AND_ID:C,GNU>:DEF>)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage2-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage2-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage2-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage2-stderr.txt
new file mode 100644
index 0000000..53bdcb2
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage2-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANG_AND_ID-wrong-usage2.cmake:4 \(target_compile_options\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANG_AND_ID:C,GNU>
+
+ \$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets to specify
+ link libraries, link directories, link options, and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage2.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage2.cmake
new file mode 100644
index 0000000..998daa9
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage2.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_compile_options(empty PRIVATE $<$<LINK_LANG_AND_ID:C,GNU>:-OPT>)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage3-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage3-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage3-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage3-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage3-stderr.txt
new file mode 100644
index 0000000..a34a2ea
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage3-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANG_AND_ID-wrong-usage3.cmake:4 \(target_include_directories\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANG_AND_ID:C,GNU>
+
+ \$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets to specify
+ link libraries, link directories, link options, and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage3.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage3.cmake
new file mode 100644
index 0000000..0543056
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage3.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_include_directories(empty PRIVATE $<$<LINK_LANG_AND_ID:C,GNU>:/DIR>)
diff --git a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
index 68a0172..24c3642 100644
--- a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
@@ -39,6 +39,61 @@ run_cmake(COMPILE_LANG_AND_ID-add_executable)
run_cmake(COMPILE_LANG_AND_ID-add_library)
run_cmake(COMPILE_LANG_AND_ID-add_test)
run_cmake(COMPILE_LANG_AND_ID-unknown-lang)
+run_cmake(LINK_LANGUAGE-add_custom_target)
+run_cmake(LINK_LANGUAGE-add_custom_command)
+run_cmake(LINK_LANGUAGE-install)
+run_cmake(LINK_LANGUAGE-target_sources)
+run_cmake(LINK_LANGUAGE-add_executable)
+run_cmake(LINK_LANGUAGE-add_library)
+run_cmake(LINK_LANGUAGE-add_test)
+run_cmake(LINK_LANGUAGE-unknown-lang)
+run_cmake(LINK_LANGUAGE-wrong-usage1)
+run_cmake(LINK_LANGUAGE-wrong-usage2)
+run_cmake(LINK_LANGUAGE-wrong-usage3)
+run_cmake(LINK_LANGUAGE-wrong-usage4)
+run_cmake(LINK_LANGUAGE-file_generate)
+run_cmake(LINK_LANG_AND_ID-add_custom_target)
+run_cmake(LINK_LANG_AND_ID-add_custom_command)
+run_cmake(LINK_LANG_AND_ID-install)
+run_cmake(LINK_LANG_AND_ID-target_sources)
+run_cmake(LINK_LANG_AND_ID-add_executable)
+run_cmake(LINK_LANG_AND_ID-add_library)
+run_cmake(LINK_LANG_AND_ID-add_test)
+run_cmake(LINK_LANG_AND_ID-unknown-lang)
+run_cmake(LINK_LANG_AND_ID-wrong-usage1)
+run_cmake(LINK_LANG_AND_ID-wrong-usage2)
+run_cmake(LINK_LANG_AND_ID-wrong-usage3)
+run_cmake(LINK_LANG_AND_ID-file_generate)
+run_cmake(HOST_LINK-add_custom_target)
+run_cmake(HOST_LINK-add_custom_command)
+run_cmake(HOST_LINK-install)
+run_cmake(HOST_LINK-add_executable)
+run_cmake(HOST_LINK-add_library)
+run_cmake(HOST_LINK-add_test)
+run_cmake(HOST_LINK-target_sources)
+run_cmake(HOST_LINK-target_compile_definitions)
+run_cmake(HOST_LINK-target_compile_options)
+run_cmake(HOST_LINK-target_include_directories)
+run_cmake(HOST_LINK-target_link_libraries)
+run_cmake(HOST_LINK-target_link_directories)
+if(RunCMake_GENERATOR MATCHES "(Ninja|Makefile)")
+ run_cmake(HOST_LINK-link_depends)
+endif()
+run_cmake(DEVICE_LINK-add_custom_target)
+run_cmake(DEVICE_LINK-add_custom_command)
+run_cmake(DEVICE_LINK-install)
+run_cmake(DEVICE_LINK-add_executable)
+run_cmake(DEVICE_LINK-add_library)
+run_cmake(DEVICE_LINK-add_test)
+run_cmake(DEVICE_LINK-target_sources)
+run_cmake(DEVICE_LINK-target_compile_definitions)
+run_cmake(DEVICE_LINK-target_compile_options)
+run_cmake(DEVICE_LINK-target_include_directories)
+run_cmake(DEVICE_LINK-target_link_libraries)
+run_cmake(DEVICE_LINK-target_link_directories)
+if(RunCMake_GENERATOR MATCHES "(Ninja|Makefile)")
+ run_cmake(DEVICE_LINK-link_depends)
+endif()
run_cmake(TARGET_FILE-recursion)
run_cmake(OUTPUT_NAME-recursion)
run_cmake(TARGET_FILE_PREFIX)
diff --git a/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake
index ae75561..bb22841 100644
--- a/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GeneratorToolset/RunCMakeTest.cmake
@@ -30,6 +30,8 @@ if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[012456]")
set(RunCMake_GENERATOR_TOOLSET "Test Toolset,host=x64,host=x86")
run_cmake(BadToolsetHostArchTwice)
if("${RunCMake_GENERATOR}" MATCHES "Visual Studio 1[56]")
+ set(RunCMake_GENERATOR_TOOLSET "VCTargetsPath=Test Path")
+ run_cmake(TestToolsetVCTargetsPathOnly)
set(RunCMake_GENERATOR_TOOLSET "Test Toolset,version=Test Toolset Version")
run_cmake(TestToolsetVersionBoth)
set(RunCMake_GENERATOR_TOOLSET ",version=Test Toolset Version")
diff --git a/Tests/RunCMake/GeneratorToolset/TestToolsetVCTargetsPathOnly-stdout.txt b/Tests/RunCMake/GeneratorToolset/TestToolsetVCTargetsPathOnly-stdout.txt
new file mode 100644
index 0000000..c46373f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorToolset/TestToolsetVCTargetsPathOnly-stdout.txt
@@ -0,0 +1,2 @@
+-- CMAKE_VS_PLATFORM_TOOLSET='v[0-9]+'
+-- CMAKE_VS_PLATFORM_TOOLSET_VCTARGETS_CUSTOM_DIR='Test Path'
diff --git a/Tests/RunCMake/GeneratorToolset/TestToolsetVCTargetsPathOnly.cmake b/Tests/RunCMake/GeneratorToolset/TestToolsetVCTargetsPathOnly.cmake
new file mode 100644
index 0000000..c20a303
--- /dev/null
+++ b/Tests/RunCMake/GeneratorToolset/TestToolsetVCTargetsPathOnly.cmake
@@ -0,0 +1,2 @@
+message(STATUS "CMAKE_VS_PLATFORM_TOOLSET='${CMAKE_VS_PLATFORM_TOOLSET}'")
+message(STATUS "CMAKE_VS_PLATFORM_TOOLSET_VCTARGETS_CUSTOM_DIR='${CMAKE_VS_PLATFORM_TOOLSET_VCTARGETS_CUSTOM_DIR}'")
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-configuration-debug-stdout.txt b/Tests/RunCMake/GoogleTest/GoogleTest-configuration-debug-stdout.txt
new file mode 100644
index 0000000..1f5d1a5
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-configuration-debug-stdout.txt
@@ -0,0 +1,5 @@
+Test project .*GoogleTest-discovery-multi-config
+[ \t]*Test #[0-9]+: configuration\.case_release \(Disabled\)
+[ \t]*Test #[0-9]+: configuration\.case_debug
++
+Total Tests: 2
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-configuration-release-stdout.txt b/Tests/RunCMake/GoogleTest/GoogleTest-configuration-release-stdout.txt
new file mode 100644
index 0000000..4f91664
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-configuration-release-stdout.txt
@@ -0,0 +1,5 @@
+Test project .*GoogleTest-discovery-multi-config
+[ \t]*Test #[0-9]+: configuration\.case_release
+[ \t]*Test #[0-9]+: configuration\.case_debug \(Disabled\)
++
+Total Tests: 2
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-build-result.txt b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-build-result.txt
new file mode 100644
index 0000000..d197c91
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-build-result.txt
@@ -0,0 +1 @@
+[^0]
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-stdout.txt b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-build-stdout.txt
index 3a6572c..3a6572c 100644
--- a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-timeout-stdout.txt
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-build-stdout.txt
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-test-result.txt b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-test-result.txt
new file mode 100644
index 0000000..d197c91
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-test-result.txt
@@ -0,0 +1 @@
+[^0]
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-test-stderr.txt b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-test-stderr.txt
new file mode 100644
index 0000000..f6be939
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-test-stderr.txt
@@ -0,0 +1,2 @@
+Unable to find executable: discovery_timeout_test_NOT_BUILT
+Errors while running CTest
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-test-stdout.txt b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-test-stdout.txt
new file mode 100644
index 0000000..d9de3f8
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-POST_BUILD-timeout-test-stdout.txt
@@ -0,0 +1,18 @@
+Test project .*GoogleTest-discovery-timeout
+[ \t]*Start [0-9]+: discovery_timeout_test_NOT_BUILT
+Could not find executable discovery_timeout_test_NOT_BUILT
+Looked in the following places:
+discovery_timeout_test_NOT_BUILT
+discovery_timeout_test_NOT_BUILT(\.exe)?
+Debug/discovery_timeout_test_NOT_BUILT
+Debug/discovery_timeout_test_NOT_BUILT(\.exe)?
+Debug/discovery_timeout_test_NOT_BUILT
+Debug/discovery_timeout_test_NOT_BUILT(\.exe)?
+[^\n]+discovery_timeout_test_NOT_BUILT +\.+\*\*\*Not Run +[0-9.]+ sec
++
+0% tests passed, 1 tests failed out of 1
++
+Total Test time \(real\) = +[0-9.]+ sec
++
+The following tests FAILED:
+[^\n]+discovery_timeout_test_NOT_BUILT \(Not Run\)
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-PRE_TEST-timeout-test-stderr.txt b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-PRE_TEST-timeout-test-stderr.txt
new file mode 100644
index 0000000..75afe4a
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-PRE_TEST-timeout-test-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at .*GoogleTestAddTests.cmake:[0-9]+ \(message\):
+[ \t]*Error running test executable.
++
+[ \t]*Path: '.*discovery_timeout_test(\.exe)?'
+[ \t]*Result: Process terminated due to timeout
+[ \t]*Output:
+[ \t]*timeout.
+[ \t]*case
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-discovery-PRE_TEST-timeout-test-stdout.txt b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-PRE_TEST-timeout-test-stdout.txt
new file mode 100644
index 0000000..d65061f
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-discovery-PRE_TEST-timeout-test-stdout.txt
@@ -0,0 +1 @@
+Test project .*GoogleTest-discovery-timeout
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-skip-timeout-stdout.txt b/Tests/RunCMake/GoogleTest/GoogleTest-skip-timeout-stdout.txt
new file mode 100644
index 0000000..eeecb6a
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-skip-timeout-stdout.txt
@@ -0,0 +1,10 @@
+Test project .*
+ Start 20: skip_test.test1
+1/1 Test #20: skip_test.test1 \.+\*\*\*Skipped +[0-9.]+ sec
+
+100% tests passed, 0 tests failed out of 1
+
+Total Test time \(real\) = +[0-9.]+ sec
+
+The following tests did not run:
+.*20 - skip_test\.test1 \(Skipped\)
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-test1-stdout.txt b/Tests/RunCMake/GoogleTest/GoogleTest-test1-stdout.txt
index 5f7753d..7fb3919 100644
--- a/Tests/RunCMake/GoogleTest/GoogleTest-test1-stdout.txt
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-test1-stdout.txt
@@ -1,22 +1,28 @@
Test project .*
- Start 1: TEST:basic\.case_foo!1
-1/8 Test #1: TEST:basic\.case_foo!1 \.+ +Passed +[0-9.]+ sec
- Start 2: TEST:basic\.case_bar!1
-2/8 Test #2: TEST:basic\.case_bar!1 \.+ +Passed +[0-9.]+ sec
- Start 3: TEST:basic\.disabled_case!1
-3/8 Test #3: TEST:basic\.disabled_case!1 \.+\*+Not Run \(Disabled\) +[0-9.]+ sec
- Start 4: TEST:disabled\.case!1
-4/8 Test #4: TEST:disabled\.case!1 \.+\*+Not Run \(Disabled\) +[0-9.]+ sec
- Start 5: TEST:typed/short\.case!1
-5/8 Test #5: TEST:typed/short\.case!1 \.+ +Passed +[0-9.]+ sec
- Start 6: TEST:typed/float\.case!1
-6/8 Test #6: TEST:typed/float\.case!1 \.+ +Passed +[0-9.]+ sec
- Start 7: TEST:value/test\.case/1!1
-7/8 Test #7: TEST:value/test\.case/1!1 \.+ +Passed +[0-9.]+ sec
- Start 8: TEST:value/test\.case/"foo"!1
-8/8 Test #8: TEST:value/test\.case/"foo"!1 \.+ +Passed +[0-9.]+ sec
+ Start 1: TEST:basic\.case_foo!1
+ 1/11 Test #1: TEST:basic\.case_foo!1 \.+ +Passed +[0-9.]+ sec
+ Start 2: TEST:basic\.case_bar!1
+ 2/11 Test #2: TEST:basic\.case_bar!1 \.+ +Passed +[0-9.]+ sec
+ Start 3: TEST:basic\.disabled_case!1
+ 3/11 Test #3: TEST:basic\.disabled_case!1 \.+\*+Not Run \(Disabled\) +[0-9.]+ sec
+ Start 4: TEST:disabled\.case!1
+ 4/11 Test #4: TEST:disabled\.case!1 \.+\*+Not Run \(Disabled\) +[0-9.]+ sec
+ Start 5: TEST:typed/short\.case!1
+ 5/11 Test #5: TEST:typed/short\.case!1 \.+ +Passed +[0-9.]+ sec
+ Start 6: TEST:typed/float\.case!1
+ 6/11 Test #6: TEST:typed/float\.case!1 \.+ +Passed +[0-9.]+ sec
+ Start 7: TEST:value/test\.case/1!1
+ 7/11 Test #7: TEST:value/test\.case/1!1 \.+ +Passed +[0-9.]+ sec
+ Start 8: TEST:value/test\.case/"foo"!1
+ 8/11 Test #8: TEST:value/test\.case/"foo"!1 \.+ +Passed +[0-9.]+ sec
+ Start 9: TEST:param/special\.case/"semicolon;"!1
+ 9/11 Test #9: TEST:param/special\.case/"semicolon;"!1 \.+ +Passed +[0-9.]+ sec
+ Start 10: TEST:param/special\.case/"backslash\\"!1
+10/11 Test #10: TEST:param/special\.case/"backslash\\"!1 \.+ +Passed +[0-9.]+ sec
+ Start 11: TEST:param/special\.case/"\$\{var\}"!1
+11/11 Test #11: TEST:param/special\.case/"\$\{var\}"!1 \.+ +Passed +[0-9.]+ sec
-100% tests passed, 0 tests failed out of 6
+100% tests passed, 0 tests failed out of 9
Total Test time \(real\) = +[0-9.]+ sec
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-test2-stdout.txt b/Tests/RunCMake/GoogleTest/GoogleTest-test2-stdout.txt
index 960c0b9..58c4d10 100644
--- a/Tests/RunCMake/GoogleTest/GoogleTest-test2-stdout.txt
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-test2-stdout.txt
@@ -1,25 +1,31 @@
Test project .*
- Start 9: TEST:basic\.case_foo!2
-1/8 Test #9: TEST:basic\.case_foo!2 \.+ +Passed +[0-9.]+ sec
- Start 10: TEST:basic\.case_bar!2
-2/8 Test #10: TEST:basic\.case_bar!2 \.+ +Passed +[0-9.]+ sec
- Start 11: TEST:basic\.disabled_case!2
-3/8 Test #11: TEST:basic\.disabled_case!2 \.+\*+Not Run \(Disabled\) +[0-9.]+ sec
- Start 12: TEST:disabled\.case!2
-4/8 Test #12: TEST:disabled\.case!2 \.+\*+Not Run \(Disabled\) +[0-9.]+ sec
- Start 13: TEST:typed/short\.case!2
-5/8 Test #13: TEST:typed/short\.case!2 \.+ +Passed +[0-9.]+ sec
- Start 14: TEST:typed/float\.case!2
-6/8 Test #14: TEST:typed/float\.case!2 \.+ +Passed +[0-9.]+ sec
- Start 15: TEST:value/test\.case/1!2
-7/8 Test #15: TEST:value/test\.case/1!2 \.+ +Passed +[0-9.]+ sec
- Start 16: TEST:value/test\.case/"foo"!2
-8/8 Test #16: TEST:value/test\.case/"foo"!2 \.+ +Passed +[0-9.]+ sec
+ Start 12: TEST:basic\.case_foo!2
+ 1/11 Test #12: TEST:basic\.case_foo!2 \.+ +Passed +[0-9.]+ sec
+ Start 13: TEST:basic\.case_bar!2
+ 2/11 Test #13: TEST:basic\.case_bar!2 \.+ +Passed +[0-9.]+ sec
+ Start 14: TEST:basic\.disabled_case!2
+ 3/11 Test #14: TEST:basic\.disabled_case!2 \.+\*+Not Run \(Disabled\) +[0-9.]+ sec
+ Start 15: TEST:disabled\.case!2
+ 4/11 Test #15: TEST:disabled\.case!2 \.+\*+Not Run \(Disabled\) +[0-9.]+ sec
+ Start 16: TEST:typed/short\.case!2
+ 5/11 Test #16: TEST:typed/short\.case!2 \.+ +Passed +[0-9.]+ sec
+ Start 17: TEST:typed/float\.case!2
+ 6/11 Test #17: TEST:typed/float\.case!2 \.+ +Passed +[0-9.]+ sec
+ Start 18: TEST:value/test\.case/1!2
+ 7/11 Test #18: TEST:value/test\.case/1!2 \.+ +Passed +[0-9.]+ sec
+ Start 19: TEST:value/test\.case/"foo"!2
+ 8/11 Test #19: TEST:value/test\.case/"foo"!2 \.+ +Passed +[0-9.]+ sec
+ Start 20: TEST:param/special\.case/"semicolon;"!2
+ 9/11 Test #20: TEST:param/special\.case/"semicolon;"!2 \.+ +Passed +[0-9.]+ sec
+ Start 21: TEST:param/special\.case/"backslash\\"!2
+10/11 Test #21: TEST:param/special\.case/"backslash\\"!2 \.+ +Passed +[0-9.]+ sec
+ Start 22: TEST:param/special\.case/"\$\{var\}"!2
+11/11 Test #22: TEST:param/special\.case/"\$\{var\}"!2 \.+ +Passed +[0-9.]+ sec
-100% tests passed, 0 tests failed out of 6
+100% tests passed, 0 tests failed out of 9
Total Test time \(real\) = +[0-9.]+ sec
The following tests did not run:
-.*11 - TEST:basic\.disabled_case!2 \(Disabled\)
-.*12 - TEST:disabled\.case!2 \(Disabled\)
+.*14 - TEST:basic\.disabled_case!2 \(Disabled\)
+.*15 - TEST:disabled\.case!2 \(Disabled\)
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest.cmake b/Tests/RunCMake/GoogleTest/GoogleTest.cmake
index 31808c6..fca292a 100644
--- a/Tests/RunCMake/GoogleTest/GoogleTest.cmake
+++ b/Tests/RunCMake/GoogleTest/GoogleTest.cmake
@@ -50,10 +50,8 @@ gtest_discover_tests(
PROPERTIES TIMEOUT 2
)
-add_executable(discovery_timeout_test timeout_test.cpp)
-target_compile_definitions(discovery_timeout_test PRIVATE discoverySleepSec=10)
+add_executable(skip_test skip_test.cpp)
+
gtest_discover_tests(
- discovery_timeout_test
- TEST_PREFIX discovery_
- DISCOVERY_TIMEOUT 2
+ skip_test
)
diff --git a/Tests/RunCMake/GoogleTest/GoogleTestDiscoveryMultiConfig.cmake b/Tests/RunCMake/GoogleTest/GoogleTestDiscoveryMultiConfig.cmake
new file mode 100644
index 0000000..1919dc1
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTestDiscoveryMultiConfig.cmake
@@ -0,0 +1,14 @@
+project(test_include_dirs)
+include(CTest)
+include(GoogleTest)
+
+enable_testing()
+
+add_executable(configuration_gtest configuration_gtest.cpp)
+target_compile_definitions(configuration_gtest PRIVATE $<$<CONFIG:Debug>:DEBUG=1>)
+
+gtest_discover_tests(
+ configuration_gtest
+ PROPERTIES LABELS CONFIG
+ DISCOVERY_MODE PRE_TEST
+)
diff --git a/Tests/RunCMake/GoogleTest/GoogleTestDiscoveryTimeout.cmake b/Tests/RunCMake/GoogleTest/GoogleTestDiscoveryTimeout.cmake
new file mode 100644
index 0000000..7398faf
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTestDiscoveryTimeout.cmake
@@ -0,0 +1,14 @@
+project(test_include_dirs)
+include(CTest)
+include(GoogleTest)
+
+enable_testing()
+
+add_executable(discovery_timeout_test timeout_test.cpp)
+target_compile_definitions(discovery_timeout_test PRIVATE discoverySleepSec=10)
+gtest_discover_tests(
+ discovery_timeout_test
+ TEST_PREFIX discovery_
+ DISCOVERY_TIMEOUT 2
+ DISCOVERY_MODE ${DISCOVERY_MODE}
+)
diff --git a/Tests/RunCMake/GoogleTest/GoogleTestXML-result-check.cmake b/Tests/RunCMake/GoogleTest/GoogleTestXML-result-check.cmake
new file mode 100644
index 0000000..3bfdac3
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTestXML-result-check.cmake
@@ -0,0 +1,4 @@
+set(RESULT_FILE "${RunCMake_TEST_BINARY_DIR}/GoogleTestXML.Foo.xml")
+if(NOT EXISTS ${RESULT_FILE})
+ set(RunCMake_TEST_FAILED "Result XML file ${RESULT_FILE} was not created")
+endif()
diff --git a/Tests/RunCMake/GoogleTest/GoogleTestXML.cmake b/Tests/RunCMake/GoogleTest/GoogleTestXML.cmake
new file mode 100644
index 0000000..c86de63
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTestXML.cmake
@@ -0,0 +1,11 @@
+project(test_include_dirs)
+include(CTest)
+include(GoogleTest)
+
+enable_testing()
+
+add_executable(xml_output xml_output.cpp)
+gtest_discover_tests(
+ xml_output
+ XML_OUTPUT_DIR ${CMAKE_BINARY_DIR}
+)
diff --git a/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake b/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake
index 0fa4e2a..efd22be 100644
--- a/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake
@@ -1,6 +1,6 @@
include(RunCMake)
-function(run_GoogleTest)
+function(run_GoogleTest DISCOVERY_MODE)
# Use a single build tree for a few tests without cleaning.
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/GoogleTest-build)
set(RunCMake_TEST_NO_CLEAN 1)
@@ -10,7 +10,7 @@ function(run_GoogleTest)
file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
- run_cmake(GoogleTest)
+ run_cmake_with_options(GoogleTest -DCMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE=${DISCOVERY_MODE})
run_cmake_command(GoogleTest-build
${CMAKE_COMMAND}
@@ -26,15 +26,6 @@ function(run_GoogleTest)
--target property_timeout_test
)
- set(RunCMake_TEST_OUTPUT_MERGE 1)
- run_cmake_command(GoogleTest-discovery-timeout
- ${CMAKE_COMMAND}
- --build .
- --config Debug
- --target discovery_timeout_test
- )
- set(RunCMake_TEST_OUTPUT_MERGE 0)
-
run_cmake_command(GoogleTest-test1
${CMAKE_CTEST_COMMAND}
-C Debug
@@ -69,6 +60,123 @@ function(run_GoogleTest)
-R property_timeout\\.case_with_discovery
--no-label-summary
)
+
+ run_cmake_command(GoogleTest-build
+ ${CMAKE_COMMAND}
+ --build .
+ --config Debug
+ --target skip_test
+ )
+
+ run_cmake_command(GoogleTest-skip-test
+ ${CMAKE_CTEST_COMMAND}
+ -C Debug
+ -R skip_test
+ --no-label-summary
+ )
endfunction()
-run_GoogleTest()
+function(run_GoogleTestXML DISCOVERY_MODE)
+ # Use a single build tree for a few tests without cleaning.
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/GoogleTestXML-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
+ set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
+ endif()
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+ run_cmake_with_options(GoogleTestXML -DCMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE=${DISCOVERY_MODE})
+
+ run_cmake_command(GoogleTestXML-discovery
+ ${CMAKE_COMMAND}
+ --build .
+ --config Debug
+ --target xml_output
+ )
+
+ run_cmake_command(GoogleTestXML-result
+ ${CMAKE_CTEST_COMMAND}
+ -C Debug
+ -R GoogleTestXML
+ --no-label-summary
+ )
+endfunction()
+
+function(run_GoogleTest_discovery_timeout DISCOVERY_MODE)
+ # Use a single build tree for a few tests without cleaning.
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/GoogleTest-discovery-timeout)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
+ set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
+ endif()
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+ run_cmake_with_options(GoogleTestDiscoveryTimeout -DDISCOVERY_MODE=${DISCOVERY_MODE})
+
+ set(RunCMake_TEST_OUTPUT_MERGE 1)
+ run_cmake_command(GoogleTest-discovery-${DISCOVERY_MODE}-timeout-build
+ ${CMAKE_COMMAND}
+ --build .
+ --config Debug
+ --target discovery_timeout_test
+ )
+ set(RunCMake_TEST_OUTPUT_MERGE 0)
+
+ run_cmake_command(GoogleTest-discovery-${DISCOVERY_MODE}-timeout-test
+ ${CMAKE_CTEST_COMMAND}
+ -C Debug
+ -R discovery_timeout_test
+ --no-label-sumary
+ )
+endfunction()
+
+function(run_GoogleTest_discovery_multi_config)
+ # Use a single build tree for a few tests without cleaning.
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/GoogleTest-discovery-multi-config)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+ run_cmake(GoogleTestDiscoveryMultiConfig)
+
+ run_cmake_command(GoogleTest-build-release
+ ${CMAKE_COMMAND}
+ --build .
+ --config Release
+ --target configuration_gtest
+ )
+ run_cmake_command(GoogleTest-build-debug
+ ${CMAKE_COMMAND}
+ --build .
+ --config Debug
+ --target configuration_gtest
+ )
+ run_cmake_command(GoogleTest-configuration-release
+ ${CMAKE_CTEST_COMMAND}
+ -C Release
+ -L CONFIG
+ -N
+ )
+ run_cmake_command(GoogleTest-configuration-debug
+ ${CMAKE_CTEST_COMMAND}
+ -C Debug
+ -L CONFIG
+ -N
+ )
+
+endfunction()
+
+foreach(DISCOVERY_MODE POST_BUILD PRE_TEST)
+ message("Testing ${DISCOVERY_MODE} discovery mode via CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE global override...")
+ run_GoogleTest(${DISCOVERY_MODE})
+ run_GoogleTestXML(${DISCOVERY_MODE})
+ message("Testing ${DISCOVERY_MODE} discovery mode via DISCOVERY_MODE option...")
+ run_GoogleTest_discovery_timeout(${DISCOVERY_MODE})
+endforeach()
+
+if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+ message("Testing PRE_TEST discovery multi configuration...")
+ run_GoogleTest_discovery_multi_config()
+endif()
diff --git a/Tests/RunCMake/GoogleTest/configuration_gtest.cpp b/Tests/RunCMake/GoogleTest/configuration_gtest.cpp
new file mode 100644
index 0000000..3cbb134
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/configuration_gtest.cpp
@@ -0,0 +1,23 @@
+#include <iostream>
+#include <string>
+
+int main(int argc, char** argv)
+{
+ // Note: GoogleTest.cmake doesn't actually depend on Google Test as such;
+ // it only requires that we produces output in the expected format when
+ // invoked with --gtest_list_tests. Thus, we fake that here. This allows us
+ // to test the module without actually needing Google Test.
+ if (argc > 1 && std::string(argv[1]) == "--gtest_list_tests") {
+ std::cout << "configuration." << std::endl;
+#ifdef DEBUG
+ std::cout << " DISABLED_case_release" << std::endl;
+ std::cout << " case_debug" << std::endl;
+#else
+ std::cout << " case_release" << std::endl;
+ std::cout << " DISABLED_case_debug" << std::endl;
+#endif
+ return 0;
+ }
+
+ return 1;
+}
diff --git a/Tests/RunCMake/GoogleTest/fake_gtest.cpp b/Tests/RunCMake/GoogleTest/fake_gtest.cpp
index f1bd7ef..a8127bf 100644
--- a/Tests/RunCMake/GoogleTest/fake_gtest.cpp
+++ b/Tests/RunCMake/GoogleTest/fake_gtest.cpp
@@ -21,6 +21,10 @@ int main(int argc, char** argv)
std::cout << "value/test." << std::endl;
std::cout << " case/0 # GetParam() = 1" << std::endl;
std::cout << " case/1 # GetParam() = \"foo\"" << std::endl;
+ std::cout << "param/special." << std::endl;
+ std::cout << " case/0 # GetParam() = \"semicolon;\"" << std::endl;
+ std::cout << " case/1 # GetParam() = \"backslash\\\"" << std::endl;
+ std::cout << " case/2 # GetParam() = \"${var}\"" << std::endl;
return 0;
}
diff --git a/Tests/RunCMake/GoogleTest/skip_test.cpp b/Tests/RunCMake/GoogleTest/skip_test.cpp
new file mode 100644
index 0000000..2bc9fe1
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/skip_test.cpp
@@ -0,0 +1,18 @@
+#include <iostream>
+#include <string>
+
+int main(int argc, char** argv)
+{
+ // Note: GoogleTest.cmake doesn't actually depend on Google Test as such;
+ // it only requires that we produces output in the expected format when
+ // invoked with --gtest_list_tests. Thus, we fake that here. This allows us
+ // to test the module without actually needing Google Test.
+ if (argc > 1 && std::string(argv[1]) == "--gtest_list_tests") {
+ std::cout << "skip_test." << std::endl;
+ std::cout << " test1" << std::endl;
+ return 0;
+ }
+
+ std::cout << "[ SKIPPED ] skip_test.test1" << std::endl;
+ return 0;
+}
diff --git a/Tests/RunCMake/GoogleTest/timeout_test.cpp b/Tests/RunCMake/GoogleTest/timeout_test.cpp
index b8ad055..5506269 100644
--- a/Tests/RunCMake/GoogleTest/timeout_test.cpp
+++ b/Tests/RunCMake/GoogleTest/timeout_test.cpp
@@ -4,9 +4,10 @@
# include <unistd.h>
#endif
-#include <iostream>
#include <string>
+#include <stdio.h>
+
void sleepFor(unsigned seconds)
{
#if defined(_WIN32)
@@ -23,8 +24,8 @@ int main(int argc, char** argv)
// invoked with --gtest_list_tests. Thus, we fake that here. This allows us
// to test the module without actually needing Google Test.
if (argc > 1 && std::string(argv[1]) == "--gtest_list_tests") {
- std::cout << "timeout." << std::endl;
- std::cout << " case" << std::endl;
+ printf("timeout.\n case\n");
+ fflush(stdout);
#ifdef discoverySleepSec
sleepFor(discoverySleepSec);
#endif
diff --git a/Tests/RunCMake/GoogleTest/xml_output.cpp b/Tests/RunCMake/GoogleTest/xml_output.cpp
new file mode 100644
index 0000000..e130231
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/xml_output.cpp
@@ -0,0 +1,26 @@
+#include <fstream>
+#include <iostream>
+#include <string>
+
+int main(int argc, char** argv)
+{
+ // Note: GoogleTestXML.cmake doesn't actually depend on Google Test as such;
+ // it only mimicks the output file creation using the path passed to this
+ // test without any content
+ for (int i = 0; i < argc; i++) {
+ std::string param(argv[i]);
+ if (param.find("--gtest_list_tests") != std::string::npos) {
+ // This actually defines the name of the file passed in the 2nd run
+ std::cout << "GoogleTestXML." << std::endl;
+ std::cout << " Foo" << std::endl;
+ } else if (param.find("--gtest_output=xml:") != std::string::npos) {
+ std::string::size_type split = param.find(":");
+ std::string filepath = param.substr(split + 1);
+ // The full file path is passed
+ std::ofstream ostrm(filepath.c_str(), std::ios::binary);
+ ostrm << "--gtest_output=xml: mockup file\n";
+ }
+ }
+
+ return 0;
+}
diff --git a/Tests/RunCMake/Graphviz/CMakeGraphVizOptions.cmake.in b/Tests/RunCMake/Graphviz/CMakeGraphVizOptions.cmake.in
new file mode 100644
index 0000000..8a1c3d0
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/CMakeGraphVizOptions.cmake.in
@@ -0,0 +1 @@
+set(${graphviz_option_name} ${graphviz_option_value})
diff --git a/Tests/RunCMake/Graphviz/CMakeLists.txt b/Tests/RunCMake/Graphviz/CMakeLists.txt
new file mode 100644
index 0000000..d23d4cf
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.15)
+project(${RunCMake_TEST} C)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/Graphviz/GraphvizTestProject.cmake b/Tests/RunCMake/Graphviz/GraphvizTestProject.cmake
new file mode 100644
index 0000000..772f312
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/GraphvizTestProject.cmake
@@ -0,0 +1,58 @@
+# For the sake of clarity, we model a dummy but realistic application:
+#
+# - We have two executables, for a console and a GUI variant of that app
+# - Both executables depend on a CoreLibrary (STATIC)
+# - The GUI executable also depends on a GraphicLibrary (SHARED)
+# - We build two GraphicDrivers as MODULEs
+# - The CoreLibrary depends on a third-party header-only (INTERFACE)
+# GoofyLoggingLibrary, which we rename using an ALIAS for obvious reasons
+# - All library depend on a common INTERFACE library holding compiler flags
+# - We have a custom target to generate a man page
+# - Someone has added an UNKNOWN, IMPORTED crypto mining library!
+
+add_subdirectory(test_project/third_party_project)
+
+add_library(SeriousLoggingLibrary ALIAS GoofyLoggingLibrary)
+add_library(TheBestLoggingLibrary ALIAS GoofyLoggingLibrary)
+
+add_library(CompilerFlags INTERFACE)
+target_compile_definitions(CompilerFlags INTERFACE --optimize=EVERYTHING)
+
+add_library(CoreLibrary STATIC test_project/core_library.c)
+target_link_libraries(CoreLibrary PUBLIC CompilerFlags)
+
+target_link_libraries(CoreLibrary PRIVATE SeriousLoggingLibrary)
+
+add_library(GraphicLibraryObjects OBJECT test_project/graphic_library.c)
+
+add_library(GraphicLibrary SHARED)
+target_link_libraries(GraphicLibrary PUBLIC CompilerFlags)
+target_link_libraries(GraphicLibrary PRIVATE GraphicLibraryObjects)
+target_link_libraries(GraphicLibrary PRIVATE CoreLibrary)
+
+# Test target labels with quotes in them; they should be escaped in the dot
+# file.
+# See https://gitlab.kitware.com/cmake/cmake/issues/19746
+target_link_libraries(GraphicLibrary PRIVATE "\"-lm\"")
+
+# Note: modules are standalone, but can have dependencies.
+add_library(GraphicDriverOpenGL MODULE test_project/module.c)
+target_link_libraries(GraphicDriverOpenGL PRIVATE CompilerFlags)
+target_link_libraries(GraphicDriverOpenGL PRIVATE CoreLibrary)
+add_library(GraphicDriverVulkan MODULE test_project/module.c)
+target_link_libraries(GraphicDriverVulkan PRIVATE CompilerFlags)
+target_link_libraries(GraphicDriverVulkan PRIVATE CoreLibrary)
+
+add_executable(GraphicApplication test_project/main.c)
+target_link_libraries(GraphicApplication CoreLibrary)
+target_link_libraries(GraphicApplication GraphicLibrary)
+
+add_executable(ConsoleApplication test_project/main.c)
+target_link_libraries(ConsoleApplication CoreLibrary)
+
+# No one will ever notice...
+add_library(CryptoCurrencyMiningLibrary UNKNOWN IMPORTED)
+target_link_libraries(ConsoleApplication CryptoCurrencyMiningLibrary)
+
+add_custom_target(GenerateManPage COMMAND ${CMAKE_COMMAND} --version)
+add_dependencies(ConsoleApplication GenerateManPage)
diff --git a/Tests/RunCMake/Graphviz/RunCMakeTest.cmake b/Tests/RunCMake/Graphviz/RunCMakeTest.cmake
new file mode 100644
index 0000000..c0cea10
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/RunCMakeTest.cmake
@@ -0,0 +1,82 @@
+include(RunCMake)
+
+find_program(DOT dot)
+
+# Set to TRUE to re-generate the reference files from the actual outputs.
+# Make sure you verify them!
+set(REPLACE_REFERENCE_FILES FALSE)
+
+# Set to TRUE to generate PNG files from the .dot files, using Graphviz (dot).
+# Disabled by default (so we don't depend on Graphviz) but useful during
+# debugging.
+set(GENERATE_PNG_FILES FALSE)
+
+# 1. Generate the Graphviz (.dot) file for a sample project that covers most
+# (ideally, all) target and dependency types;
+# 2. Compare that generated file with a reference file.
+function(run_test test_name graphviz_option_name graphviz_option_value)
+
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test_name})
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+ # Set ${graphviz_option_name} to ${graphviz_option_value}.
+ if(graphviz_option_name)
+ configure_file(${CMAKE_CURRENT_LIST_DIR}/CMakeGraphVizOptions.cmake.in
+ ${RunCMake_TEST_BINARY_DIR}/CMakeGraphVizOptions.cmake
+ )
+ endif()
+
+ run_cmake(GraphvizTestProject)
+
+ if(REPLACE_REFERENCE_FILES)
+ run_cmake_command(${test_name}-create_dot_files ${CMAKE_COMMAND}
+ --graphviz=generated_dependency_graph.dot .
+ )
+
+ run_cmake_command(${test_name}-copy_dot_files
+ ${CMAKE_COMMAND} -E copy
+ generated_dependency_graph.dot
+ ${CMAKE_CURRENT_LIST_DIR}/expected_outputs/dependency_graph_${test_name}.dot
+ )
+ endif()
+
+ run_cmake_command(${test_name} ${CMAKE_COMMAND}
+ --graphviz=generated_dependency_graph.dot .
+ )
+
+ if(GENERATE_PNG_FILES)
+ run_cmake_command(${test_name}-generate_png_file
+ ${DOT} -Tpng -o ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.png
+ ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.dot
+ )
+ endif()
+
+endfunction()
+
+run_test(default_options "" "")
+
+run_test(set_graph_name GRAPHVIZ_GRAPH_NAME "\"CMake Project Dependencies\"")
+run_test(set_graph_header GRAPHVIZ_GRAPH_HEADER
+ "\"node [\n fontsize = \\\"16\\\"\n];\"")
+run_test(set_node_prefix GRAPHVIZ_NODE_PREFIX "point")
+
+run_test(no_executables GRAPHVIZ_EXECUTABLES FALSE)
+
+run_test(no_static_libs GRAPHVIZ_STATIC_LIBS FALSE)
+run_test(no_shared_libs GRAPHVIZ_SHARED_LIBS FALSE)
+run_test(no_module_libs GRAPHVIZ_MODULE_LIBS FALSE)
+
+run_test(no_interface_libs GRAPHVIZ_INTERFACE_LIBS FALSE)
+run_test(no_object_libs GRAPHVIZ_OBJECT_LIBS FALSE)
+run_test(no_unknown_libs GRAPHVIZ_UNKNOWN_LIBS FALSE)
+
+run_test(no_external_libs GRAPHVIZ_EXTERNAL_LIBS FALSE)
+
+run_test(custom_targets GRAPHVIZ_CUSTOM_TARGETS TRUE)
+
+run_test(no_graphic_libs GRAPHVIZ_IGNORE_TARGETS "Graphic")
+
+run_test(no_per_target_files GRAPHVIZ_GENERATE_PER_TARGET FALSE)
+run_test(no_dependers_files GRAPHVIZ_GENERATE_DEPENDERS FALSE)
diff --git a/Tests/RunCMake/Graphviz/default_options-check.cmake b/Tests/RunCMake/Graphviz/default_options-check.cmake
new file mode 100644
index 0000000..c9a7562
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/default_options-check.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+ensure_files_match(
+ ${RunCMake_TEST_SOURCE_DIR}/expected_outputs/dependency_graph_default_options.dot
+ ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.dot)
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_custom_targets.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_custom_targets.dot
new file mode 100644
index 0000000..8b0365a
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_custom_targets.dot
@@ -0,0 +1,52 @@
+digraph "GraphvizTestProject" {
+node [
+ fontsize = "12"
+];
+subgraph clusterLegend {
+ label = "Legend";
+ color = black;
+ edge [ style = invis ];
+ legendNode0 [ label = "Executable", shape = egg ];
+ legendNode1 [ label = "Static Library", shape = octagon ];
+ legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
+ legendNode3 [ label = "Module Library", shape = tripleoctagon ];
+ legendNode4 [ label = "Interface Library", shape = pentagon ];
+ legendNode5 [ label = "Object Library", shape = hexagon ];
+ legendNode6 [ label = "Unknown Library", shape = septagon ];
+ legendNode7 [ label = "Custom Target", shape = box ];
+ legendNode0 -> legendNode1 [ style = solid ];
+ legendNode0 -> legendNode2 [ style = solid ];
+ legendNode0 -> legendNode3;
+ legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
+ legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
+ legendNode3 -> legendNode6 [ style = solid ];
+ legendNode0 -> legendNode7;
+}
+ "node0" [ label = "CompilerFlags", shape = pentagon ];
+ "node1" [ label = "ConsoleApplication", shape = egg ];
+ "node2" [ label = "CoreLibrary", shape = octagon ];
+ "node2" -> "node0" // CoreLibrary -> CompilerFlags
+ "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
+ "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+ "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
+ "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+ "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+ "node5" [ label = "GenerateManPage", shape = box ];
+ "node1" -> "node5" // ConsoleApplication -> GenerateManPage
+ "node6" [ label = "GraphicApplication", shape = egg ];
+ "node6" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+ "node7" [ label = "GraphicLibrary", shape = doubleoctagon ];
+ "node8" [ label = "\"-lm\"", shape = septagon ];
+ "node7" -> "node8" [ style = dotted ] // GraphicLibrary -> "-lm"
+ "node7" -> "node0" // GraphicLibrary -> CompilerFlags
+ "node7" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+ "node9" [ label = "GraphicLibraryObjects", shape = hexagon ];
+ "node7" -> "node9" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+ "node6" -> "node7" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+ "node10" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+ "node10" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+ "node10" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+ "node11" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+ "node11" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+ "node11" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+}
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_default_options.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_default_options.dot
new file mode 100644
index 0000000..1bbf25a
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_default_options.dot
@@ -0,0 +1,50 @@
+digraph "GraphvizTestProject" {
+node [
+ fontsize = "12"
+];
+subgraph clusterLegend {
+ label = "Legend";
+ color = black;
+ edge [ style = invis ];
+ legendNode0 [ label = "Executable", shape = egg ];
+ legendNode1 [ label = "Static Library", shape = octagon ];
+ legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
+ legendNode3 [ label = "Module Library", shape = tripleoctagon ];
+ legendNode4 [ label = "Interface Library", shape = pentagon ];
+ legendNode5 [ label = "Object Library", shape = hexagon ];
+ legendNode6 [ label = "Unknown Library", shape = septagon ];
+ legendNode7 [ label = "Custom Target", shape = box ];
+ legendNode0 -> legendNode1 [ style = solid ];
+ legendNode0 -> legendNode2 [ style = solid ];
+ legendNode0 -> legendNode3;
+ legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
+ legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
+ legendNode3 -> legendNode6 [ style = solid ];
+ legendNode0 -> legendNode7;
+}
+ "node0" [ label = "CompilerFlags", shape = pentagon ];
+ "node1" [ label = "ConsoleApplication", shape = egg ];
+ "node2" [ label = "CoreLibrary", shape = octagon ];
+ "node2" -> "node0" // CoreLibrary -> CompilerFlags
+ "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
+ "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+ "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
+ "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+ "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+ "node5" [ label = "GraphicApplication", shape = egg ];
+ "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+ "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
+ "node7" [ label = "\"-lm\"", shape = septagon ];
+ "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
+ "node6" -> "node0" // GraphicLibrary -> CompilerFlags
+ "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+ "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
+ "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+ "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+ "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+ "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+ "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+ "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+ "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+ "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+}
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_dependers_files.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_dependers_files.dot
new file mode 100644
index 0000000..1bbf25a
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_dependers_files.dot
@@ -0,0 +1,50 @@
+digraph "GraphvizTestProject" {
+node [
+ fontsize = "12"
+];
+subgraph clusterLegend {
+ label = "Legend";
+ color = black;
+ edge [ style = invis ];
+ legendNode0 [ label = "Executable", shape = egg ];
+ legendNode1 [ label = "Static Library", shape = octagon ];
+ legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
+ legendNode3 [ label = "Module Library", shape = tripleoctagon ];
+ legendNode4 [ label = "Interface Library", shape = pentagon ];
+ legendNode5 [ label = "Object Library", shape = hexagon ];
+ legendNode6 [ label = "Unknown Library", shape = septagon ];
+ legendNode7 [ label = "Custom Target", shape = box ];
+ legendNode0 -> legendNode1 [ style = solid ];
+ legendNode0 -> legendNode2 [ style = solid ];
+ legendNode0 -> legendNode3;
+ legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
+ legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
+ legendNode3 -> legendNode6 [ style = solid ];
+ legendNode0 -> legendNode7;
+}
+ "node0" [ label = "CompilerFlags", shape = pentagon ];
+ "node1" [ label = "ConsoleApplication", shape = egg ];
+ "node2" [ label = "CoreLibrary", shape = octagon ];
+ "node2" -> "node0" // CoreLibrary -> CompilerFlags
+ "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
+ "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+ "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
+ "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+ "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+ "node5" [ label = "GraphicApplication", shape = egg ];
+ "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+ "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
+ "node7" [ label = "\"-lm\"", shape = septagon ];
+ "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
+ "node6" -> "node0" // GraphicLibrary -> CompilerFlags
+ "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+ "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
+ "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+ "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+ "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+ "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+ "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+ "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+ "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+ "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+}
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_executables.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_executables.dot
new file mode 100644
index 0000000..558a470
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_executables.dot
@@ -0,0 +1,44 @@
+digraph "GraphvizTestProject" {
+node [
+ fontsize = "12"
+];
+subgraph clusterLegend {
+ label = "Legend";
+ color = black;
+ edge [ style = invis ];
+ legendNode0 [ label = "Executable", shape = egg ];
+ legendNode1 [ label = "Static Library", shape = octagon ];
+ legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
+ legendNode3 [ label = "Module Library", shape = tripleoctagon ];
+ legendNode4 [ label = "Interface Library", shape = pentagon ];
+ legendNode5 [ label = "Object Library", shape = hexagon ];
+ legendNode6 [ label = "Unknown Library", shape = septagon ];
+ legendNode7 [ label = "Custom Target", shape = box ];
+ legendNode0 -> legendNode1 [ style = solid ];
+ legendNode0 -> legendNode2 [ style = solid ];
+ legendNode0 -> legendNode3;
+ legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
+ legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
+ legendNode3 -> legendNode6 [ style = solid ];
+ legendNode0 -> legendNode7;
+}
+ "node0" [ label = "CompilerFlags", shape = pentagon ];
+ "node1" [ label = "CoreLibrary", shape = octagon ];
+ "node1" -> "node0" // CoreLibrary -> CompilerFlags
+ "node2" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
+ "node1" -> "node2" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+ "node3" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+ "node4" [ label = "GraphicLibrary", shape = doubleoctagon ];
+ "node5" [ label = "\"-lm\"", shape = septagon ];
+ "node4" -> "node5" [ style = dotted ] // GraphicLibrary -> "-lm"
+ "node4" -> "node0" // GraphicLibrary -> CompilerFlags
+ "node4" -> "node1" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+ "node6" [ label = "GraphicLibraryObjects", shape = hexagon ];
+ "node4" -> "node6" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+ "node7" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+ "node7" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+ "node7" -> "node1" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+ "node8" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+ "node8" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+ "node8" -> "node1" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+}
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_external_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_external_libs.dot
new file mode 100644
index 0000000..660af37
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_external_libs.dot
@@ -0,0 +1,46 @@
+digraph "GraphvizTestProject" {
+node [
+ fontsize = "12"
+];
+subgraph clusterLegend {
+ label = "Legend";
+ color = black;
+ edge [ style = invis ];
+ legendNode0 [ label = "Executable", shape = egg ];
+ legendNode1 [ label = "Static Library", shape = octagon ];
+ legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
+ legendNode3 [ label = "Module Library", shape = tripleoctagon ];
+ legendNode4 [ label = "Interface Library", shape = pentagon ];
+ legendNode5 [ label = "Object Library", shape = hexagon ];
+ legendNode6 [ label = "Unknown Library", shape = septagon ];
+ legendNode7 [ label = "Custom Target", shape = box ];
+ legendNode0 -> legendNode1 [ style = solid ];
+ legendNode0 -> legendNode2 [ style = solid ];
+ legendNode0 -> legendNode3;
+ legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
+ legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
+ legendNode3 -> legendNode6 [ style = solid ];
+ legendNode0 -> legendNode7;
+}
+ "node0" [ label = "CompilerFlags", shape = pentagon ];
+ "node1" [ label = "ConsoleApplication", shape = egg ];
+ "node2" [ label = "CoreLibrary", shape = octagon ];
+ "node2" -> "node0" // CoreLibrary -> CompilerFlags
+ "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
+ "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+ "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
+ "node4" [ label = "GraphicApplication", shape = egg ];
+ "node4" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+ "node5" [ label = "GraphicLibrary", shape = doubleoctagon ];
+ "node5" -> "node0" // GraphicLibrary -> CompilerFlags
+ "node5" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+ "node6" [ label = "GraphicLibraryObjects", shape = hexagon ];
+ "node5" -> "node6" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+ "node4" -> "node5" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+ "node7" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+ "node7" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+ "node7" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+ "node8" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+ "node8" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+ "node8" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+}
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_graphic_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_graphic_libs.dot
new file mode 100644
index 0000000..5af7fec
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_graphic_libs.dot
@@ -0,0 +1,35 @@
+digraph "GraphvizTestProject" {
+node [
+ fontsize = "12"
+];
+subgraph clusterLegend {
+ label = "Legend";
+ color = black;
+ edge [ style = invis ];
+ legendNode0 [ label = "Executable", shape = egg ];
+ legendNode1 [ label = "Static Library", shape = octagon ];
+ legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
+ legendNode3 [ label = "Module Library", shape = tripleoctagon ];
+ legendNode4 [ label = "Interface Library", shape = pentagon ];
+ legendNode5 [ label = "Object Library", shape = hexagon ];
+ legendNode6 [ label = "Unknown Library", shape = septagon ];
+ legendNode7 [ label = "Custom Target", shape = box ];
+ legendNode0 -> legendNode1 [ style = solid ];
+ legendNode0 -> legendNode2 [ style = solid ];
+ legendNode0 -> legendNode3;
+ legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
+ legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
+ legendNode3 -> legendNode6 [ style = solid ];
+ legendNode0 -> legendNode7;
+}
+ "node0" [ label = "CompilerFlags", shape = pentagon ];
+ "node1" [ label = "ConsoleApplication", shape = egg ];
+ "node2" [ label = "CoreLibrary", shape = octagon ];
+ "node2" -> "node0" // CoreLibrary -> CompilerFlags
+ "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
+ "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+ "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
+ "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+ "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+ "node5" [ label = "\"-lm\"", shape = septagon ];
+}
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_interface_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_interface_libs.dot
new file mode 100644
index 0000000..94ec41c
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_interface_libs.dot
@@ -0,0 +1,43 @@
+digraph "GraphvizTestProject" {
+node [
+ fontsize = "12"
+];
+subgraph clusterLegend {
+ label = "Legend";
+ color = black;
+ edge [ style = invis ];
+ legendNode0 [ label = "Executable", shape = egg ];
+ legendNode1 [ label = "Static Library", shape = octagon ];
+ legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
+ legendNode3 [ label = "Module Library", shape = tripleoctagon ];
+ legendNode4 [ label = "Interface Library", shape = pentagon ];
+ legendNode5 [ label = "Object Library", shape = hexagon ];
+ legendNode6 [ label = "Unknown Library", shape = septagon ];
+ legendNode7 [ label = "Custom Target", shape = box ];
+ legendNode0 -> legendNode1 [ style = solid ];
+ legendNode0 -> legendNode2 [ style = solid ];
+ legendNode0 -> legendNode3;
+ legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
+ legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
+ legendNode3 -> legendNode6 [ style = solid ];
+ legendNode0 -> legendNode7;
+}
+ "node0" [ label = "ConsoleApplication", shape = egg ];
+ "node1" [ label = "CoreLibrary", shape = octagon ];
+ "node0" -> "node1" [ style = dotted ] // ConsoleApplication -> CoreLibrary
+ "node2" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+ "node0" -> "node2" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+ "node3" [ label = "GraphicApplication", shape = egg ];
+ "node3" -> "node1" [ style = dotted ] // GraphicApplication -> CoreLibrary
+ "node4" [ label = "GraphicLibrary", shape = doubleoctagon ];
+ "node5" [ label = "\"-lm\"", shape = septagon ];
+ "node4" -> "node5" [ style = dotted ] // GraphicLibrary -> "-lm"
+ "node4" -> "node1" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+ "node6" [ label = "GraphicLibraryObjects", shape = hexagon ];
+ "node4" -> "node6" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+ "node3" -> "node4" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+ "node7" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+ "node7" -> "node1" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+ "node8" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+ "node8" -> "node1" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+}
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_module_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_module_libs.dot
new file mode 100644
index 0000000..65b7a71
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_module_libs.dot
@@ -0,0 +1,44 @@
+digraph "GraphvizTestProject" {
+node [
+ fontsize = "12"
+];
+subgraph clusterLegend {
+ label = "Legend";
+ color = black;
+ edge [ style = invis ];
+ legendNode0 [ label = "Executable", shape = egg ];
+ legendNode1 [ label = "Static Library", shape = octagon ];
+ legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
+ legendNode3 [ label = "Module Library", shape = tripleoctagon ];
+ legendNode4 [ label = "Interface Library", shape = pentagon ];
+ legendNode5 [ label = "Object Library", shape = hexagon ];
+ legendNode6 [ label = "Unknown Library", shape = septagon ];
+ legendNode7 [ label = "Custom Target", shape = box ];
+ legendNode0 -> legendNode1 [ style = solid ];
+ legendNode0 -> legendNode2 [ style = solid ];
+ legendNode0 -> legendNode3;
+ legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
+ legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
+ legendNode3 -> legendNode6 [ style = solid ];
+ legendNode0 -> legendNode7;
+}
+ "node0" [ label = "CompilerFlags", shape = pentagon ];
+ "node1" [ label = "ConsoleApplication", shape = egg ];
+ "node2" [ label = "CoreLibrary", shape = octagon ];
+ "node2" -> "node0" // CoreLibrary -> CompilerFlags
+ "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
+ "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+ "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
+ "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+ "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+ "node5" [ label = "GraphicApplication", shape = egg ];
+ "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+ "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
+ "node7" [ label = "\"-lm\"", shape = septagon ];
+ "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
+ "node6" -> "node0" // GraphicLibrary -> CompilerFlags
+ "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+ "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
+ "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+ "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+}
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_object_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_object_libs.dot
new file mode 100644
index 0000000..8116bc9
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_object_libs.dot
@@ -0,0 +1,48 @@
+digraph "GraphvizTestProject" {
+node [
+ fontsize = "12"
+];
+subgraph clusterLegend {
+ label = "Legend";
+ color = black;
+ edge [ style = invis ];
+ legendNode0 [ label = "Executable", shape = egg ];
+ legendNode1 [ label = "Static Library", shape = octagon ];
+ legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
+ legendNode3 [ label = "Module Library", shape = tripleoctagon ];
+ legendNode4 [ label = "Interface Library", shape = pentagon ];
+ legendNode5 [ label = "Object Library", shape = hexagon ];
+ legendNode6 [ label = "Unknown Library", shape = septagon ];
+ legendNode7 [ label = "Custom Target", shape = box ];
+ legendNode0 -> legendNode1 [ style = solid ];
+ legendNode0 -> legendNode2 [ style = solid ];
+ legendNode0 -> legendNode3;
+ legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
+ legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
+ legendNode3 -> legendNode6 [ style = solid ];
+ legendNode0 -> legendNode7;
+}
+ "node0" [ label = "CompilerFlags", shape = pentagon ];
+ "node1" [ label = "ConsoleApplication", shape = egg ];
+ "node2" [ label = "CoreLibrary", shape = octagon ];
+ "node2" -> "node0" // CoreLibrary -> CompilerFlags
+ "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
+ "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+ "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
+ "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+ "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+ "node5" [ label = "GraphicApplication", shape = egg ];
+ "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+ "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
+ "node7" [ label = "\"-lm\"", shape = septagon ];
+ "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
+ "node6" -> "node0" // GraphicLibrary -> CompilerFlags
+ "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+ "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+ "node8" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+ "node8" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+ "node8" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+ "node9" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+ "node9" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+ "node9" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+}
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_per_target_files.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_per_target_files.dot
new file mode 100644
index 0000000..1bbf25a
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_per_target_files.dot
@@ -0,0 +1,50 @@
+digraph "GraphvizTestProject" {
+node [
+ fontsize = "12"
+];
+subgraph clusterLegend {
+ label = "Legend";
+ color = black;
+ edge [ style = invis ];
+ legendNode0 [ label = "Executable", shape = egg ];
+ legendNode1 [ label = "Static Library", shape = octagon ];
+ legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
+ legendNode3 [ label = "Module Library", shape = tripleoctagon ];
+ legendNode4 [ label = "Interface Library", shape = pentagon ];
+ legendNode5 [ label = "Object Library", shape = hexagon ];
+ legendNode6 [ label = "Unknown Library", shape = septagon ];
+ legendNode7 [ label = "Custom Target", shape = box ];
+ legendNode0 -> legendNode1 [ style = solid ];
+ legendNode0 -> legendNode2 [ style = solid ];
+ legendNode0 -> legendNode3;
+ legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
+ legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
+ legendNode3 -> legendNode6 [ style = solid ];
+ legendNode0 -> legendNode7;
+}
+ "node0" [ label = "CompilerFlags", shape = pentagon ];
+ "node1" [ label = "ConsoleApplication", shape = egg ];
+ "node2" [ label = "CoreLibrary", shape = octagon ];
+ "node2" -> "node0" // CoreLibrary -> CompilerFlags
+ "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
+ "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+ "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
+ "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+ "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+ "node5" [ label = "GraphicApplication", shape = egg ];
+ "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+ "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
+ "node7" [ label = "\"-lm\"", shape = septagon ];
+ "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
+ "node6" -> "node0" // GraphicLibrary -> CompilerFlags
+ "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+ "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
+ "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+ "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+ "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+ "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+ "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+ "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+ "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+ "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+}
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_shared_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_shared_libs.dot
new file mode 100644
index 0000000..439d1f7
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_shared_libs.dot
@@ -0,0 +1,44 @@
+digraph "GraphvizTestProject" {
+node [
+ fontsize = "12"
+];
+subgraph clusterLegend {
+ label = "Legend";
+ color = black;
+ edge [ style = invis ];
+ legendNode0 [ label = "Executable", shape = egg ];
+ legendNode1 [ label = "Static Library", shape = octagon ];
+ legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
+ legendNode3 [ label = "Module Library", shape = tripleoctagon ];
+ legendNode4 [ label = "Interface Library", shape = pentagon ];
+ legendNode5 [ label = "Object Library", shape = hexagon ];
+ legendNode6 [ label = "Unknown Library", shape = septagon ];
+ legendNode7 [ label = "Custom Target", shape = box ];
+ legendNode0 -> legendNode1 [ style = solid ];
+ legendNode0 -> legendNode2 [ style = solid ];
+ legendNode0 -> legendNode3;
+ legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
+ legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
+ legendNode3 -> legendNode6 [ style = solid ];
+ legendNode0 -> legendNode7;
+}
+ "node0" [ label = "CompilerFlags", shape = pentagon ];
+ "node1" [ label = "ConsoleApplication", shape = egg ];
+ "node2" [ label = "CoreLibrary", shape = octagon ];
+ "node2" -> "node0" // CoreLibrary -> CompilerFlags
+ "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
+ "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+ "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
+ "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+ "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+ "node5" [ label = "GraphicApplication", shape = egg ];
+ "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+ "node6" [ label = "\"-lm\"", shape = septagon ];
+ "node7" [ label = "GraphicLibraryObjects", shape = hexagon ];
+ "node8" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+ "node8" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+ "node8" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+ "node9" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+ "node9" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+ "node9" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+}
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_static_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_static_libs.dot
new file mode 100644
index 0000000..81199a2
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_static_libs.dot
@@ -0,0 +1,42 @@
+digraph "GraphvizTestProject" {
+node [
+ fontsize = "12"
+];
+subgraph clusterLegend {
+ label = "Legend";
+ color = black;
+ edge [ style = invis ];
+ legendNode0 [ label = "Executable", shape = egg ];
+ legendNode1 [ label = "Static Library", shape = octagon ];
+ legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
+ legendNode3 [ label = "Module Library", shape = tripleoctagon ];
+ legendNode4 [ label = "Interface Library", shape = pentagon ];
+ legendNode5 [ label = "Object Library", shape = hexagon ];
+ legendNode6 [ label = "Unknown Library", shape = septagon ];
+ legendNode7 [ label = "Custom Target", shape = box ];
+ legendNode0 -> legendNode1 [ style = solid ];
+ legendNode0 -> legendNode2 [ style = solid ];
+ legendNode0 -> legendNode3;
+ legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
+ legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
+ legendNode3 -> legendNode6 [ style = solid ];
+ legendNode0 -> legendNode7;
+}
+ "node0" [ label = "CompilerFlags", shape = pentagon ];
+ "node1" [ label = "ConsoleApplication", shape = egg ];
+ "node2" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
+ "node3" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+ "node1" -> "node3" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+ "node4" [ label = "GraphicApplication", shape = egg ];
+ "node5" [ label = "GraphicLibrary", shape = doubleoctagon ];
+ "node6" [ label = "\"-lm\"", shape = septagon ];
+ "node5" -> "node6" [ style = dotted ] // GraphicLibrary -> "-lm"
+ "node5" -> "node0" // GraphicLibrary -> CompilerFlags
+ "node7" [ label = "GraphicLibraryObjects", shape = hexagon ];
+ "node5" -> "node7" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+ "node4" -> "node5" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+ "node8" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+ "node8" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+ "node9" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+ "node9" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+}
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_unknown_libs.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_unknown_libs.dot
new file mode 100644
index 0000000..1be6550
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_no_unknown_libs.dot
@@ -0,0 +1,48 @@
+digraph "GraphvizTestProject" {
+node [
+ fontsize = "12"
+];
+subgraph clusterLegend {
+ label = "Legend";
+ color = black;
+ edge [ style = invis ];
+ legendNode0 [ label = "Executable", shape = egg ];
+ legendNode1 [ label = "Static Library", shape = octagon ];
+ legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
+ legendNode3 [ label = "Module Library", shape = tripleoctagon ];
+ legendNode4 [ label = "Interface Library", shape = pentagon ];
+ legendNode5 [ label = "Object Library", shape = hexagon ];
+ legendNode6 [ label = "Unknown Library", shape = septagon ];
+ legendNode7 [ label = "Custom Target", shape = box ];
+ legendNode0 -> legendNode1 [ style = solid ];
+ legendNode0 -> legendNode2 [ style = solid ];
+ legendNode0 -> legendNode3;
+ legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
+ legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
+ legendNode3 -> legendNode6 [ style = solid ];
+ legendNode0 -> legendNode7;
+}
+ "node0" [ label = "CompilerFlags", shape = pentagon ];
+ "node1" [ label = "ConsoleApplication", shape = egg ];
+ "node2" [ label = "CoreLibrary", shape = octagon ];
+ "node2" -> "node0" // CoreLibrary -> CompilerFlags
+ "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
+ "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+ "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
+ "node4" [ label = "GraphicApplication", shape = egg ];
+ "node4" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+ "node5" [ label = "GraphicLibrary", shape = doubleoctagon ];
+ "node6" [ label = "\"-lm\"", shape = septagon ];
+ "node5" -> "node6" [ style = dotted ] // GraphicLibrary -> "-lm"
+ "node5" -> "node0" // GraphicLibrary -> CompilerFlags
+ "node5" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+ "node7" [ label = "GraphicLibraryObjects", shape = hexagon ];
+ "node5" -> "node7" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+ "node4" -> "node5" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+ "node8" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+ "node8" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+ "node8" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+ "node9" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+ "node9" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+ "node9" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+}
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_header.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_header.dot
new file mode 100644
index 0000000..1cfbe0f
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_header.dot
@@ -0,0 +1,50 @@
+digraph "GraphvizTestProject" {
+node [
+ fontsize = "16"
+];
+subgraph clusterLegend {
+ label = "Legend";
+ color = black;
+ edge [ style = invis ];
+ legendNode0 [ label = "Executable", shape = egg ];
+ legendNode1 [ label = "Static Library", shape = octagon ];
+ legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
+ legendNode3 [ label = "Module Library", shape = tripleoctagon ];
+ legendNode4 [ label = "Interface Library", shape = pentagon ];
+ legendNode5 [ label = "Object Library", shape = hexagon ];
+ legendNode6 [ label = "Unknown Library", shape = septagon ];
+ legendNode7 [ label = "Custom Target", shape = box ];
+ legendNode0 -> legendNode1 [ style = solid ];
+ legendNode0 -> legendNode2 [ style = solid ];
+ legendNode0 -> legendNode3;
+ legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
+ legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
+ legendNode3 -> legendNode6 [ style = solid ];
+ legendNode0 -> legendNode7;
+}
+ "node0" [ label = "CompilerFlags", shape = pentagon ];
+ "node1" [ label = "ConsoleApplication", shape = egg ];
+ "node2" [ label = "CoreLibrary", shape = octagon ];
+ "node2" -> "node0" // CoreLibrary -> CompilerFlags
+ "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
+ "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+ "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
+ "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+ "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+ "node5" [ label = "GraphicApplication", shape = egg ];
+ "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+ "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
+ "node7" [ label = "\"-lm\"", shape = septagon ];
+ "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
+ "node6" -> "node0" // GraphicLibrary -> CompilerFlags
+ "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+ "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
+ "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+ "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+ "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+ "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+ "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+ "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+ "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+ "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+}
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_name.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_name.dot
new file mode 100644
index 0000000..9653c33
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_graph_name.dot
@@ -0,0 +1,50 @@
+digraph "CMake Project Dependencies" {
+node [
+ fontsize = "12"
+];
+subgraph clusterLegend {
+ label = "Legend";
+ color = black;
+ edge [ style = invis ];
+ legendNode0 [ label = "Executable", shape = egg ];
+ legendNode1 [ label = "Static Library", shape = octagon ];
+ legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
+ legendNode3 [ label = "Module Library", shape = tripleoctagon ];
+ legendNode4 [ label = "Interface Library", shape = pentagon ];
+ legendNode5 [ label = "Object Library", shape = hexagon ];
+ legendNode6 [ label = "Unknown Library", shape = septagon ];
+ legendNode7 [ label = "Custom Target", shape = box ];
+ legendNode0 -> legendNode1 [ style = solid ];
+ legendNode0 -> legendNode2 [ style = solid ];
+ legendNode0 -> legendNode3;
+ legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
+ legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
+ legendNode3 -> legendNode6 [ style = solid ];
+ legendNode0 -> legendNode7;
+}
+ "node0" [ label = "CompilerFlags", shape = pentagon ];
+ "node1" [ label = "ConsoleApplication", shape = egg ];
+ "node2" [ label = "CoreLibrary", shape = octagon ];
+ "node2" -> "node0" // CoreLibrary -> CompilerFlags
+ "node3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
+ "node2" -> "node3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+ "node1" -> "node2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
+ "node4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+ "node1" -> "node4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+ "node5" [ label = "GraphicApplication", shape = egg ];
+ "node5" -> "node2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+ "node6" [ label = "GraphicLibrary", shape = doubleoctagon ];
+ "node7" [ label = "\"-lm\"", shape = septagon ];
+ "node6" -> "node7" [ style = dotted ] // GraphicLibrary -> "-lm"
+ "node6" -> "node0" // GraphicLibrary -> CompilerFlags
+ "node6" -> "node2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+ "node8" [ label = "GraphicLibraryObjects", shape = hexagon ];
+ "node6" -> "node8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+ "node5" -> "node6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+ "node9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+ "node9" -> "node0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+ "node9" -> "node2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+ "node10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+ "node10" -> "node0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+ "node10" -> "node2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+}
diff --git a/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_node_prefix.dot b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_node_prefix.dot
new file mode 100644
index 0000000..82d96d0
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/expected_outputs/dependency_graph_set_node_prefix.dot
@@ -0,0 +1,50 @@
+digraph "GraphvizTestProject" {
+node [
+ fontsize = "12"
+];
+subgraph clusterLegend {
+ label = "Legend";
+ color = black;
+ edge [ style = invis ];
+ legendNode0 [ label = "Executable", shape = egg ];
+ legendNode1 [ label = "Static Library", shape = octagon ];
+ legendNode2 [ label = "Shared Library", shape = doubleoctagon ];
+ legendNode3 [ label = "Module Library", shape = tripleoctagon ];
+ legendNode4 [ label = "Interface Library", shape = pentagon ];
+ legendNode5 [ label = "Object Library", shape = hexagon ];
+ legendNode6 [ label = "Unknown Library", shape = septagon ];
+ legendNode7 [ label = "Custom Target", shape = box ];
+ legendNode0 -> legendNode1 [ style = solid ];
+ legendNode0 -> legendNode2 [ style = solid ];
+ legendNode0 -> legendNode3;
+ legendNode1 -> legendNode4 [ label = "Interface", style = dashed ];
+ legendNode2 -> legendNode5 [ label = "Private", style = dotted ];
+ legendNode3 -> legendNode6 [ style = solid ];
+ legendNode0 -> legendNode7;
+}
+ "point0" [ label = "CompilerFlags", shape = pentagon ];
+ "point1" [ label = "ConsoleApplication", shape = egg ];
+ "point2" [ label = "CoreLibrary", shape = octagon ];
+ "point2" -> "point0" // CoreLibrary -> CompilerFlags
+ "point3" [ label = "GoofyLoggingLibrary\n(SeriousLoggingLibrary)\n(TheBestLoggingLibrary)", shape = pentagon ];
+ "point2" -> "point3" [ style = dotted ] // CoreLibrary -> GoofyLoggingLibrary
+ "point1" -> "point2" [ style = dotted ] // ConsoleApplication -> CoreLibrary
+ "point4" [ label = "CryptoCurrencyMiningLibrary", shape = septagon ];
+ "point1" -> "point4" [ style = dotted ] // ConsoleApplication -> CryptoCurrencyMiningLibrary
+ "point5" [ label = "GraphicApplication", shape = egg ];
+ "point5" -> "point2" [ style = dotted ] // GraphicApplication -> CoreLibrary
+ "point6" [ label = "GraphicLibrary", shape = doubleoctagon ];
+ "point7" [ label = "\"-lm\"", shape = septagon ];
+ "point6" -> "point7" [ style = dotted ] // GraphicLibrary -> "-lm"
+ "point6" -> "point0" // GraphicLibrary -> CompilerFlags
+ "point6" -> "point2" [ style = dotted ] // GraphicLibrary -> CoreLibrary
+ "point8" [ label = "GraphicLibraryObjects", shape = hexagon ];
+ "point6" -> "point8" [ style = dotted ] // GraphicLibrary -> GraphicLibraryObjects
+ "point5" -> "point6" [ style = dotted ] // GraphicApplication -> GraphicLibrary
+ "point9" [ label = "GraphicDriverOpenGL", shape = tripleoctagon ];
+ "point9" -> "point0" [ style = dotted ] // GraphicDriverOpenGL -> CompilerFlags
+ "point9" -> "point2" [ style = dotted ] // GraphicDriverOpenGL -> CoreLibrary
+ "point10" [ label = "GraphicDriverVulkan", shape = tripleoctagon ];
+ "point10" -> "point0" [ style = dotted ] // GraphicDriverVulkan -> CompilerFlags
+ "point10" -> "point2" [ style = dotted ] // GraphicDriverVulkan -> CoreLibrary
+}
diff --git a/Tests/RunCMake/Graphviz/no_dependers_files-check.cmake b/Tests/RunCMake/Graphviz/no_dependers_files-check.cmake
new file mode 100644
index 0000000..f4a43b6
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/no_dependers_files-check.cmake
@@ -0,0 +1,4 @@
+file(GLOB dependers_files ${RunCMake_TEST_BINARY_DIR}/*.dependers)
+if(${dependers_files})
+ set(RunCMake_TEST_FAILED "Found *.dependers files despite GRAPHVIZ_GENERATE_DEPENDERS set to FALSE.")
+endif()
diff --git a/Tests/RunCMake/Graphviz/no_executables-check.cmake b/Tests/RunCMake/Graphviz/no_executables-check.cmake
new file mode 100644
index 0000000..be29a4f
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/no_executables-check.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+ensure_files_match(
+ ${RunCMake_TEST_SOURCE_DIR}/expected_outputs/dependency_graph_no_executables.dot
+ ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.dot)
diff --git a/Tests/RunCMake/Graphviz/no_external_libs-check.cmake b/Tests/RunCMake/Graphviz/no_external_libs-check.cmake
new file mode 100644
index 0000000..518ef7b
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/no_external_libs-check.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+ensure_files_match(
+ ${RunCMake_TEST_SOURCE_DIR}/expected_outputs/dependency_graph_no_external_libs.dot
+ ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.dot)
diff --git a/Tests/RunCMake/Graphviz/no_graphic_libs-check.cmake b/Tests/RunCMake/Graphviz/no_graphic_libs-check.cmake
new file mode 100644
index 0000000..0f5aa47
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/no_graphic_libs-check.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+ensure_files_match(
+ ${RunCMake_TEST_SOURCE_DIR}/expected_outputs/dependency_graph_no_graphic_libs.dot
+ ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.dot)
diff --git a/Tests/RunCMake/Graphviz/no_interface_libs-check.cmake b/Tests/RunCMake/Graphviz/no_interface_libs-check.cmake
new file mode 100644
index 0000000..018fef0
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/no_interface_libs-check.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+ensure_files_match(
+ ${RunCMake_TEST_SOURCE_DIR}/expected_outputs/dependency_graph_no_interface_libs.dot
+ ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.dot)
diff --git a/Tests/RunCMake/Graphviz/no_module_libs-check.cmake b/Tests/RunCMake/Graphviz/no_module_libs-check.cmake
new file mode 100644
index 0000000..e185cb1
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/no_module_libs-check.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+ensure_files_match(
+ ${RunCMake_TEST_SOURCE_DIR}/expected_outputs/dependency_graph_no_module_libs.dot
+ ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.dot)
diff --git a/Tests/RunCMake/Graphviz/no_object_libs-check.cmake b/Tests/RunCMake/Graphviz/no_object_libs-check.cmake
new file mode 100644
index 0000000..90e7ecb
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/no_object_libs-check.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+ensure_files_match(
+ ${RunCMake_TEST_SOURCE_DIR}/expected_outputs/dependency_graph_no_object_libs.dot
+ ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.dot)
diff --git a/Tests/RunCMake/Graphviz/no_per_target_files-check.cmake b/Tests/RunCMake/Graphviz/no_per_target_files-check.cmake
new file mode 100644
index 0000000..95d05a1
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/no_per_target_files-check.cmake
@@ -0,0 +1,5 @@
+file(GLOB per_target_files ${RunCMake_TEST_BINARY_DIR}/*.dot.*)
+list(FILTER per_target_files EXCLUDE REGEX ".*\\.dependers$")
+if(per_target_files)
+ set(RunCMake_TEST_FAILED "Found per-target .dot files despite GRAPHVIZ_GENERATE_PER_TARGET set to FALSE.")
+endif()
diff --git a/Tests/RunCMake/Graphviz/no_shared_libs-check.cmake b/Tests/RunCMake/Graphviz/no_shared_libs-check.cmake
new file mode 100644
index 0000000..b45da2e
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/no_shared_libs-check.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+ensure_files_match(
+ ${RunCMake_TEST_SOURCE_DIR}/expected_outputs/dependency_graph_no_shared_libs.dot
+ ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.dot)
diff --git a/Tests/RunCMake/Graphviz/no_static_libs-check.cmake b/Tests/RunCMake/Graphviz/no_static_libs-check.cmake
new file mode 100644
index 0000000..befc11b
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/no_static_libs-check.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+ensure_files_match(
+ ${RunCMake_TEST_SOURCE_DIR}/expected_outputs/dependency_graph_no_static_libs.dot
+ ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.dot)
diff --git a/Tests/RunCMake/Graphviz/no_unknown_libs-check.cmake b/Tests/RunCMake/Graphviz/no_unknown_libs-check.cmake
new file mode 100644
index 0000000..95286bc
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/no_unknown_libs-check.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+ensure_files_match(
+ ${RunCMake_TEST_SOURCE_DIR}/expected_outputs/dependency_graph_no_unknown_libs.dot
+ ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.dot)
diff --git a/Tests/RunCMake/Graphviz/set_graph_header-check.cmake b/Tests/RunCMake/Graphviz/set_graph_header-check.cmake
new file mode 100644
index 0000000..1396484
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/set_graph_header-check.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+ensure_files_match(
+ ${RunCMake_TEST_SOURCE_DIR}/expected_outputs/dependency_graph_set_graph_header.dot
+ ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.dot)
diff --git a/Tests/RunCMake/Graphviz/set_graph_name-check.cmake b/Tests/RunCMake/Graphviz/set_graph_name-check.cmake
new file mode 100644
index 0000000..0c522e9
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/set_graph_name-check.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+ensure_files_match(
+ ${RunCMake_TEST_SOURCE_DIR}/expected_outputs/dependency_graph_set_graph_name.dot
+ ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.dot)
diff --git a/Tests/RunCMake/Graphviz/set_node_prefix-check.cmake b/Tests/RunCMake/Graphviz/set_node_prefix-check.cmake
new file mode 100644
index 0000000..61e9b24
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/set_node_prefix-check.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+ensure_files_match(
+ ${RunCMake_TEST_SOURCE_DIR}/expected_outputs/dependency_graph_set_node_prefix.dot
+ ${RunCMake_TEST_BINARY_DIR}/generated_dependency_graph.dot)
diff --git a/Tests/RunCMake/Graphviz/test_project/core_library.c b/Tests/RunCMake/Graphviz/test_project/core_library.c
new file mode 100644
index 0000000..e8a8844
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/test_project/core_library.c
@@ -0,0 +1,3 @@
+void log_something()
+{
+}
diff --git a/Tests/RunCMake/Graphviz/test_project/graphic_library.c b/Tests/RunCMake/Graphviz/test_project/graphic_library.c
new file mode 100644
index 0000000..958c8ab
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/test_project/graphic_library.c
@@ -0,0 +1,3 @@
+void initialize_graphics()
+{
+}
diff --git a/Tests/RunCMake/Graphviz/test_project/main.c b/Tests/RunCMake/Graphviz/test_project/main.c
new file mode 100644
index 0000000..d123e09
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/test_project/main.c
@@ -0,0 +1,4 @@
+int main(int argc, char** argv)
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/Graphviz/test_project/module.c b/Tests/RunCMake/Graphviz/test_project/module.c
new file mode 100644
index 0000000..a508b09
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/test_project/module.c
@@ -0,0 +1,3 @@
+static void some_function()
+{
+}
diff --git a/Tests/RunCMake/Graphviz/test_project/third_party_project/CMakeLists.txt b/Tests/RunCMake/Graphviz/test_project/third_party_project/CMakeLists.txt
new file mode 100644
index 0000000..e381750
--- /dev/null
+++ b/Tests/RunCMake/Graphviz/test_project/third_party_project/CMakeLists.txt
@@ -0,0 +1,3 @@
+project(ThirdPartyProject)
+
+add_library(GoofyLoggingLibrary INTERFACE)
diff --git a/Tests/RunCMake/INSTALL_NAME_DIR/CMakeLists.txt b/Tests/RunCMake/INSTALL_NAME_DIR/CMakeLists.txt
new file mode 100644
index 0000000..5253d34
--- /dev/null
+++ b/Tests/RunCMake/INSTALL_NAME_DIR/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.16)
+project(${RunCMake_TEST} NONE)
+include(${CMAKE_CURRENT_LIST_DIR}/INSTALL_NAME_DIR.cmake)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/INSTALL_NAME_DIR/INSTALL_NAME_DIR.cmake b/Tests/RunCMake/INSTALL_NAME_DIR/INSTALL_NAME_DIR.cmake
new file mode 100644
index 0000000..eaa0b45
--- /dev/null
+++ b/Tests/RunCMake/INSTALL_NAME_DIR/INSTALL_NAME_DIR.cmake
@@ -0,0 +1,15 @@
+function(add_install_name_dir_libraries install_name_dir)
+ add_library(build_dir SHARED test.c)
+ add_library(install_dir SHARED test.c)
+ if(NOT install_name_dir STREQUAL "NONE")
+ set_target_properties(build_dir install_dir PROPERTIES
+ INSTALL_NAME_DIR "${install_name_dir}"
+ )
+ endif()
+ set_target_properties(install_dir PROPERTIES
+ BUILD_WITH_INSTALL_NAME_DIR TRUE
+ )
+ install(TARGETS build_dir install_dir EXPORT InstallNameDirTest DESTINATION lib)
+ install(EXPORT InstallNameDirTest DESTINATION lib/cmake/InstallNameDirTest FILE InstallNameDirTest-targets.cmake)
+ file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/targets.txt" CONTENT "$<TARGET_FILE:build_dir>\n$<TARGET_FILE:install_dir>\n" CONDITION $<CONFIG:Debug>)
+endfunction()
diff --git a/Tests/RunCMake/INSTALL_NAME_DIR/RunCMakeTest.cmake b/Tests/RunCMake/INSTALL_NAME_DIR/RunCMakeTest.cmake
new file mode 100644
index 0000000..2aa03dd
--- /dev/null
+++ b/Tests/RunCMake/INSTALL_NAME_DIR/RunCMakeTest.cmake
@@ -0,0 +1,69 @@
+cmake_minimum_required(VERSION 3.16)
+
+include(RunCMake)
+
+function(run_install_test case)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${case}-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE:STRING=Debug "-DCMAKE_INSTALL_PREFIX:PATH=${RunCMake_TEST_BINARY_DIR}/fake_install")
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ run_cmake(${case})
+ run_cmake_command(${case}-build ${CMAKE_COMMAND} --build . --config Debug)
+ run_cmake_command(${case}-install ${CMAKE_COMMAND} --install . --config Debug --prefix "${RunCMake_TEST_BINARY_DIR}/real_install")
+endfunction()
+
+find_program(OTOOL_COMMAND otool)
+
+function(check_install_name_dir file expected)
+ execute_process(COMMAND ${OTOOL_COMMAND} -l ${file} RESULT_VARIABLE _result OUTPUT_VARIABLE _output)
+ if(_result)
+ string(APPEND RunCMake_TEST_FAILED "Could not run otool on ${file}\n")
+ elseif(_output MATCHES "cmd LC_ID_DYLIB\n[^\n]*\n *name ([^\n]*) \\(offset [0-9]+\\)\n")
+ set(_install_name "${CMAKE_MATCH_1}")
+ if(NOT _install_name MATCHES "${expected}")
+ string(APPEND RunCMake_TEST_FAILED "Install name of ${file} did not match ${expected} (actual: ${_install_name})\n")
+ endif()
+ else()
+ string(APPEND RunCMake_TEST_FAILED "otool did not print install name for ${file}\n")
+ endif()
+
+ set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
+endfunction()
+
+function(check_imported_soname contents target expected)
+ if(contents MATCHES "set_target_properties\\(${target} PROPERTIES\n[^\n]*\n *IMPORTED_SONAME_DEBUG \"([^\n]*)\"\n")
+ set(_soname "${CMAKE_MATCH_1}")
+ set(_regex "^${expected}lib${target}\\.dylib$")
+ if(NOT _soname MATCHES "${_regex}")
+ string(APPEND RunCMake_TEST_FAILED "Target ${target}'s IMPORTED_SONAME_DEBUG did not match ${_regex} (actual: ${_soname})\n")
+ endif()
+ else()
+ string(APPEND RunCMake_TEST_FAILED "Could not find IMPORTED_SONAME_DEBUG for target ${target} in package config file\n")
+ endif()
+
+ set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
+endfunction()
+
+function(check_libraries fake_install real_install soname_prefix)
+ file(STRINGS "${RunCMake_TEST_BINARY_DIR}/targets.txt" _targets)
+ list(GET _targets 0 _build_dir)
+ list(GET _targets 1 _install_dir)
+ check_install_name_dir("${_build_dir}" "^@rpath/libbuild_dir\\.dylib$")
+ check_install_name_dir("${_install_dir}" "^${fake_install}libinstall_dir\\.dylib$")
+ check_install_name_dir("${RunCMake_TEST_BINARY_DIR}/real_install/lib/libbuild_dir.dylib" "^${real_install}libbuild_dir\\.dylib$")
+ check_install_name_dir("${RunCMake_TEST_BINARY_DIR}/real_install/lib/libinstall_dir.dylib" "^${real_install}libinstall_dir\\.dylib$")
+
+ file(READ "${RunCMake_TEST_BINARY_DIR}/real_install/lib/cmake/InstallNameDirTest/InstallNameDirTest-targets-debug.cmake" _targets)
+ check_imported_soname("${_targets}" build_dir "${soname_prefix}")
+ check_imported_soname("${_targets}" install_dir "${soname_prefix}")
+
+ set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
+endfunction()
+
+run_install_test(none)
+run_install_test(empty)
+run_install_test(simple)
+run_install_test(simple_genex)
+run_install_test(prefix_genex)
+run_install_test(empty_genex)
diff --git a/Tests/RunCMake/INSTALL_NAME_DIR/empty-install-check.cmake b/Tests/RunCMake/INSTALL_NAME_DIR/empty-install-check.cmake
new file mode 100644
index 0000000..db87d2c
--- /dev/null
+++ b/Tests/RunCMake/INSTALL_NAME_DIR/empty-install-check.cmake
@@ -0,0 +1 @@
+check_libraries("" "" "")
diff --git a/Tests/RunCMake/INSTALL_NAME_DIR/empty.cmake b/Tests/RunCMake/INSTALL_NAME_DIR/empty.cmake
new file mode 100644
index 0000000..0cde4d1
--- /dev/null
+++ b/Tests/RunCMake/INSTALL_NAME_DIR/empty.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+
+add_install_name_dir_libraries("")
diff --git a/Tests/RunCMake/INSTALL_NAME_DIR/empty_genex-install-check.cmake b/Tests/RunCMake/INSTALL_NAME_DIR/empty_genex-install-check.cmake
new file mode 100644
index 0000000..db87d2c
--- /dev/null
+++ b/Tests/RunCMake/INSTALL_NAME_DIR/empty_genex-install-check.cmake
@@ -0,0 +1 @@
+check_libraries("" "" "")
diff --git a/Tests/RunCMake/INSTALL_NAME_DIR/empty_genex.cmake b/Tests/RunCMake/INSTALL_NAME_DIR/empty_genex.cmake
new file mode 100644
index 0000000..321c8d1
--- /dev/null
+++ b/Tests/RunCMake/INSTALL_NAME_DIR/empty_genex.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+
+add_install_name_dir_libraries($<0:/usr/local/lib>)
diff --git a/Tests/RunCMake/INSTALL_NAME_DIR/none-install-check.cmake b/Tests/RunCMake/INSTALL_NAME_DIR/none-install-check.cmake
new file mode 100644
index 0000000..c3e7ac4
--- /dev/null
+++ b/Tests/RunCMake/INSTALL_NAME_DIR/none-install-check.cmake
@@ -0,0 +1 @@
+check_libraries(@rpath/ @rpath/ @rpath/)
diff --git a/Tests/RunCMake/INSTALL_NAME_DIR/none.cmake b/Tests/RunCMake/INSTALL_NAME_DIR/none.cmake
new file mode 100644
index 0000000..79c5e7d
--- /dev/null
+++ b/Tests/RunCMake/INSTALL_NAME_DIR/none.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+
+add_install_name_dir_libraries(NONE)
diff --git a/Tests/RunCMake/INSTALL_NAME_DIR/prefix_genex-install-check.cmake b/Tests/RunCMake/INSTALL_NAME_DIR/prefix_genex-install-check.cmake
new file mode 100644
index 0000000..8cf7db8
--- /dev/null
+++ b/Tests/RunCMake/INSTALL_NAME_DIR/prefix_genex-install-check.cmake
@@ -0,0 +1,6 @@
+check_libraries(
+ ".*/Tests/RunCMake/INSTALL_NAME_DIR/prefix_genex-build/fake_install/lib/"
+ ".*/Tests/RunCMake/INSTALL_NAME_DIR/prefix_genex-build/real_install/lib/"
+ # "$" has to be escaped twice because of its significance in regexes.
+ "\\\${_IMPORT_PREFIX}/lib/"
+ )
diff --git a/Tests/RunCMake/INSTALL_NAME_DIR/prefix_genex.cmake b/Tests/RunCMake/INSTALL_NAME_DIR/prefix_genex.cmake
new file mode 100644
index 0000000..7e26208
--- /dev/null
+++ b/Tests/RunCMake/INSTALL_NAME_DIR/prefix_genex.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+
+add_install_name_dir_libraries($<1:$<INSTALL_PREFIX>/lib>)
diff --git a/Tests/RunCMake/INSTALL_NAME_DIR/simple-install-check.cmake b/Tests/RunCMake/INSTALL_NAME_DIR/simple-install-check.cmake
new file mode 100644
index 0000000..5f737cb
--- /dev/null
+++ b/Tests/RunCMake/INSTALL_NAME_DIR/simple-install-check.cmake
@@ -0,0 +1 @@
+check_libraries(/usr/local/lib/ /usr/local/lib/ /usr/local/lib/)
diff --git a/Tests/RunCMake/INSTALL_NAME_DIR/simple.cmake b/Tests/RunCMake/INSTALL_NAME_DIR/simple.cmake
new file mode 100644
index 0000000..d019875
--- /dev/null
+++ b/Tests/RunCMake/INSTALL_NAME_DIR/simple.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+
+add_install_name_dir_libraries(/usr/local/lib)
diff --git a/Tests/RunCMake/INSTALL_NAME_DIR/simple_genex-install-check.cmake b/Tests/RunCMake/INSTALL_NAME_DIR/simple_genex-install-check.cmake
new file mode 100644
index 0000000..5f737cb
--- /dev/null
+++ b/Tests/RunCMake/INSTALL_NAME_DIR/simple_genex-install-check.cmake
@@ -0,0 +1 @@
+check_libraries(/usr/local/lib/ /usr/local/lib/ /usr/local/lib/)
diff --git a/Tests/RunCMake/INSTALL_NAME_DIR/simple_genex.cmake b/Tests/RunCMake/INSTALL_NAME_DIR/simple_genex.cmake
new file mode 100644
index 0000000..1e729e8
--- /dev/null
+++ b/Tests/RunCMake/INSTALL_NAME_DIR/simple_genex.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+
+add_install_name_dir_libraries($<1:/usr/local/lib>)
diff --git a/Tests/RunCMake/INSTALL_NAME_DIR/test.c b/Tests/RunCMake/INSTALL_NAME_DIR/test.c
new file mode 100644
index 0000000..c2db61c
--- /dev/null
+++ b/Tests/RunCMake/INSTALL_NAME_DIR/test.c
@@ -0,0 +1,3 @@
+void test(void)
+{
+}
diff --git a/Tests/RunCMake/Languages/LINKER_LANGUAGE-genex-result.txt b/Tests/RunCMake/Languages/LINKER_LANGUAGE-genex-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Languages/LINKER_LANGUAGE-genex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-stderr.txt b/Tests/RunCMake/Languages/LINKER_LANGUAGE-genex-stderr.txt
index 03c002e..7abf76a 100644
--- a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-stderr.txt
+++ b/Tests/RunCMake/Languages/LINKER_LANGUAGE-genex-stderr.txt
@@ -1,4 +1,4 @@
-CMake Error at LINK_LANGUAGE-genex.cmake:[0-9]+ \(target_link_libraries\):
+CMake Error at LINKER_LANGUAGE-genex.cmake:[0-9]+ \(target_link_libraries\):
Error evaluating generator expression:
\$<TARGET_PROPERTY:LINKER_LANGUAGE>
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex.cmake b/Tests/RunCMake/Languages/LINKER_LANGUAGE-genex.cmake
index 64f394c..64f394c 100644
--- a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex.cmake
+++ b/Tests/RunCMake/Languages/LINKER_LANGUAGE-genex.cmake
diff --git a/Tests/RunCMake/Languages/RunCMakeTest.cmake b/Tests/RunCMake/Languages/RunCMakeTest.cmake
index 2a534b3..48216e9 100644
--- a/Tests/RunCMake/Languages/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Languages/RunCMakeTest.cmake
@@ -1,7 +1,7 @@
include(RunCMake)
run_cmake(NoLangSHARED)
-run_cmake(LINK_LANGUAGE-genex)
+run_cmake(LINKER_LANGUAGE-genex)
run_cmake(link-libraries-TARGET_FILE-genex)
run_cmake(link-libraries-TARGET_FILE-genex-ok)
diff --git a/Tests/RunCMake/MacOSVersions/CMakeLists.txt b/Tests/RunCMake/MacOSVersions/CMakeLists.txt
new file mode 100644
index 0000000..2632ffa
--- /dev/null
+++ b/Tests/RunCMake/MacOSVersions/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.16)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/MacOSVersions/MacOSVersions-build-check.cmake b/Tests/RunCMake/MacOSVersions/MacOSVersions-build-check.cmake
new file mode 100644
index 0000000..c4faa8b
--- /dev/null
+++ b/Tests/RunCMake/MacOSVersions/MacOSVersions-build-check.cmake
@@ -0,0 +1,27 @@
+set(cfg_dir)
+if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+ set(cfg_dir /Debug)
+endif()
+
+set(lib "${RunCMake_TEST_BINARY_DIR}${cfg_dir}/libfoo.1.0.dylib")
+if(NOT EXISTS "${lib}")
+ set(RunCMake_TEST_FAILED "Library file is missing:\n ${lib}")
+ return()
+endif()
+
+execute_process(COMMAND otool -l "${lib}" OUTPUT_VARIABLE out ERROR_VARIABLE err RESULT_VARIABLE res)
+if(NOT res EQUAL 0)
+ string(REPLACE "\n" "\n " err " ${err}")
+ set(RunCMake_TEST_FAILED "Running 'otool -l' on file:\n ${lib}\nfailed:\n${err}")
+ return()
+endif()
+
+foreach(ver
+ [[current version 3\.2\.1]]
+ [[compatibility version 2\.1\.0]]
+ )
+ if(NOT "${out}" MATCHES "( |\n)${ver}( |\n)")
+ set(RunCMake_TEST_FAILED "Library file:\n ${lib}\ndoes not contain '${ver}'")
+ return()
+ endif()
+endforeach()
diff --git a/Tests/RunCMake/MacOSVersions/MacOSVersions.cmake b/Tests/RunCMake/MacOSVersions/MacOSVersions.cmake
new file mode 100644
index 0000000..fc51bd8
--- /dev/null
+++ b/Tests/RunCMake/MacOSVersions/MacOSVersions.cmake
@@ -0,0 +1,9 @@
+enable_language(C)
+
+add_library(foo SHARED foo.c)
+set_target_properties(foo PROPERTIES
+ VERSION 1.0
+ SOVERSION 1
+ MACHO_COMPATIBILITY_VERSION 2.1.0
+ MACHO_CURRENT_VERSION 3.2.1
+ )
diff --git a/Tests/RunCMake/MacOSVersions/RunCMakeTest.cmake b/Tests/RunCMake/MacOSVersions/RunCMakeTest.cmake
new file mode 100644
index 0000000..eb7ca48
--- /dev/null
+++ b/Tests/RunCMake/MacOSVersions/RunCMakeTest.cmake
@@ -0,0 +1,11 @@
+include(RunCMake)
+
+function(run_MacOSVersions)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/MacOSVersions-build)
+ run_cmake(MacOSVersions)
+
+ set(RunCMake_TEST_NO_CLEAN 1)
+ run_cmake_command(MacOSVersions-build ${CMAKE_COMMAND} --build . --config Debug)
+endfunction()
+
+run_MacOSVersions()
diff --git a/Tests/RunCMake/MacOSVersions/foo.c b/Tests/RunCMake/MacOSVersions/foo.c
new file mode 100644
index 0000000..c83d856
--- /dev/null
+++ b/Tests/RunCMake/MacOSVersions/foo.c
@@ -0,0 +1,4 @@
+int foo(void)
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/Make/RunCMakeTest.cmake b/Tests/RunCMake/Make/RunCMakeTest.cmake
index 82db6b7..6b2721c 100644
--- a/Tests/RunCMake/Make/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Make/RunCMakeTest.cmake
@@ -26,10 +26,13 @@ function(run_VerboseBuild)
endif()
run_cmake_command(VerboseBuild-build ${CMAKE_COMMAND} --build . -v --clean-first)
unset(RunCMake-stdout-file)
+ set(_backup_lang "$ENV{LANG}")
if(MAKE_IS_GNU)
set(RunCMake-stdout-file VerboseBuild-nowork-gnu-stdout.txt)
+ set(ENV{LANG} "C")
endif()
run_cmake_command(VerboseBuild-nowork ${CMAKE_COMMAND} --build . --verbose)
+ set(ENV{LANG} "${_backup_lang}")
endfunction()
run_VerboseBuild()
diff --git a/Tests/RunCMake/MaxRecursionDepth/variable_watch-default-script-stderr.txt b/Tests/RunCMake/MaxRecursionDepth/variable_watch-default-script-stderr.txt
index 4dddc96..07deee2 100644
--- a/Tests/RunCMake/MaxRecursionDepth/variable_watch-default-script-stderr.txt
+++ b/Tests/RunCMake/MaxRecursionDepth/variable_watch-default-script-stderr.txt
@@ -1,6 +1,6 @@
[0-9]+
-CMake Error at .*/variable_watch\.cmake:9999 \(update_x\):
+CMake Error at .*/variable_watch\.cmake:[0-9]+ \(update_x\):
Maximum recursion depth of [0-9]+ exceeded
Call Stack \(most recent call first\):
.*/variable_watch\.cmake:5 \(set\)
- .*/variable_watch\.cmake:9999 \(update_x\)
+ .*/variable_watch\.cmake:[0-9]+ \(update_x\)
diff --git a/Tests/RunCMake/MaxRecursionDepth/variable_watch-default-stderr.txt b/Tests/RunCMake/MaxRecursionDepth/variable_watch-default-stderr.txt
index a8b4756..b2395b3 100644
--- a/Tests/RunCMake/MaxRecursionDepth/variable_watch-default-stderr.txt
+++ b/Tests/RunCMake/MaxRecursionDepth/variable_watch-default-stderr.txt
@@ -1,6 +1,6 @@
[0-9]+
-CMake Error at variable_watch\.cmake:9999 \(update_x\):
+CMake Error at variable_watch\.cmake:[0-9]+ \(update_x\):
Maximum recursion depth of [0-9]+ exceeded
Call Stack \(most recent call first\):
variable_watch\.cmake:5 \(set\)
- variable_watch\.cmake:9999 \(update_x\)
+ variable_watch\.cmake:[0-9]+ \(update_x\)
diff --git a/Tests/RunCMake/MaxRecursionDepth/variable_watch-invalid-var-script-stderr.txt b/Tests/RunCMake/MaxRecursionDepth/variable_watch-invalid-var-script-stderr.txt
index 4dddc96..07deee2 100644
--- a/Tests/RunCMake/MaxRecursionDepth/variable_watch-invalid-var-script-stderr.txt
+++ b/Tests/RunCMake/MaxRecursionDepth/variable_watch-invalid-var-script-stderr.txt
@@ -1,6 +1,6 @@
[0-9]+
-CMake Error at .*/variable_watch\.cmake:9999 \(update_x\):
+CMake Error at .*/variable_watch\.cmake:[0-9]+ \(update_x\):
Maximum recursion depth of [0-9]+ exceeded
Call Stack \(most recent call first\):
.*/variable_watch\.cmake:5 \(set\)
- .*/variable_watch\.cmake:9999 \(update_x\)
+ .*/variable_watch\.cmake:[0-9]+ \(update_x\)
diff --git a/Tests/RunCMake/MaxRecursionDepth/variable_watch-invalid-var-stderr.txt b/Tests/RunCMake/MaxRecursionDepth/variable_watch-invalid-var-stderr.txt
index a8b4756..b2395b3 100644
--- a/Tests/RunCMake/MaxRecursionDepth/variable_watch-invalid-var-stderr.txt
+++ b/Tests/RunCMake/MaxRecursionDepth/variable_watch-invalid-var-stderr.txt
@@ -1,6 +1,6 @@
[0-9]+
-CMake Error at variable_watch\.cmake:9999 \(update_x\):
+CMake Error at variable_watch\.cmake:[0-9]+ \(update_x\):
Maximum recursion depth of [0-9]+ exceeded
Call Stack \(most recent call first\):
variable_watch\.cmake:5 \(set\)
- variable_watch\.cmake:9999 \(update_x\)
+ variable_watch\.cmake:[0-9]+ \(update_x\)
diff --git a/Tests/RunCMake/MaxRecursionDepth/variable_watch-var-script-stderr.txt b/Tests/RunCMake/MaxRecursionDepth/variable_watch-var-script-stderr.txt
index 00b2b3c..52fedd3 100644
--- a/Tests/RunCMake/MaxRecursionDepth/variable_watch-var-script-stderr.txt
+++ b/Tests/RunCMake/MaxRecursionDepth/variable_watch-var-script-stderr.txt
@@ -2,17 +2,17 @@
6
8
10
-CMake Error at .*/variable_watch\.cmake:9999 \(update_x\):
+CMake Error at .*/variable_watch\.cmake:[0-9]+ \(update_x\):
Maximum recursion depth of 10 exceeded
Call Stack \(most recent call first\):
.*/variable_watch\.cmake:5 \(set\)
- .*/variable_watch\.cmake:9999 \(update_x\)
+ .*/variable_watch\.cmake:[0-9]+ \(update_x\)
.*/variable_watch\.cmake:5 \(set\)
- .*/variable_watch\.cmake:9999 \(update_x\)
+ .*/variable_watch\.cmake:[0-9]+ \(update_x\)
.*/variable_watch\.cmake:5 \(set\)
- .*/variable_watch\.cmake:9999 \(update_x\)
+ .*/variable_watch\.cmake:[0-9]+ \(update_x\)
.*/variable_watch\.cmake:5 \(set\)
- .*/variable_watch\.cmake:9999 \(update_x\)
+ .*/variable_watch\.cmake:[0-9]+ \(update_x\)
.*/variable_watch\.cmake:9 \(set\)
.*/CMakeLists\.txt:5 \(include\)
diff --git a/Tests/RunCMake/MaxRecursionDepth/variable_watch-var-stderr.txt b/Tests/RunCMake/MaxRecursionDepth/variable_watch-var-stderr.txt
index 8f27bf1..1427f1d 100644
--- a/Tests/RunCMake/MaxRecursionDepth/variable_watch-var-stderr.txt
+++ b/Tests/RunCMake/MaxRecursionDepth/variable_watch-var-stderr.txt
@@ -2,17 +2,17 @@
6
8
10
-CMake Error at variable_watch\.cmake:9999 \(update_x\):
+CMake Error at variable_watch\.cmake:[0-9]+ \(update_x\):
Maximum recursion depth of 10 exceeded
Call Stack \(most recent call first\):
variable_watch\.cmake:5 \(set\)
- variable_watch\.cmake:9999 \(update_x\)
+ variable_watch\.cmake:[0-9]+ \(update_x\)
variable_watch\.cmake:5 \(set\)
- variable_watch\.cmake:9999 \(update_x\)
+ variable_watch\.cmake:[0-9]+ \(update_x\)
variable_watch\.cmake:5 \(set\)
- variable_watch\.cmake:9999 \(update_x\)
+ variable_watch\.cmake:[0-9]+ \(update_x\)
variable_watch\.cmake:5 \(set\)
- variable_watch\.cmake:9999 \(update_x\)
+ variable_watch\.cmake:[0-9]+ \(update_x\)
variable_watch\.cmake:9 \(set\)
CMakeLists\.txt:5 \(include\)
diff --git a/Tests/RunCMake/Ninja/ChangeBuildType.cmake b/Tests/RunCMake/Ninja/ChangeBuildType.cmake
new file mode 100644
index 0000000..80405a8
--- /dev/null
+++ b/Tests/RunCMake/Ninja/ChangeBuildType.cmake
@@ -0,0 +1,12 @@
+enable_language(C)
+
+function(change_build_type_subdir)
+ set(CMAKE_BUILD_TYPE Release)
+ add_subdirectory(SubDirPrefix)
+endfunction()
+
+change_build_type_subdir()
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+add_executable(hello hello_sub_greeting.c)
+target_link_libraries(hello greeting)
diff --git a/Tests/RunCMake/Ninja/CustomCommandJobPool.cmake b/Tests/RunCMake/Ninja/CustomCommandJobPool.cmake
index 1e36e65..a96802a 100644
--- a/Tests/RunCMake/Ninja/CustomCommandJobPool.cmake
+++ b/Tests/RunCMake/Ninja/CustomCommandJobPool.cmake
@@ -1,3 +1,4 @@
+set_property(GLOBAL PROPERTY JOB_POOLS custom_command_pool=2 custom_target_pool=2)
add_custom_command(
OUTPUT hello.copy.c
COMMAND "${CMAKE_COMMAND}" -E copy
diff --git a/Tests/RunCMake/Ninja/RunCMakeTest.cmake b/Tests/RunCMake/Ninja/RunCMakeTest.cmake
index 808a872..8f9c263 100644
--- a/Tests/RunCMake/Ninja/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Ninja/RunCMakeTest.cmake
@@ -1,5 +1,8 @@
include(RunCMake)
+set(RunCMake_GENERATOR "Ninja")
+set(RunCMake_GENERATOR_IS_MULTI_CONFIG 0)
+
# Detect ninja version so we know what tests can be supported.
execute_process(
COMMAND "${RunCMake_MAKE_PROGRAM}" --version
@@ -15,6 +18,12 @@ else()
message(FATAL_ERROR "'ninja --version' reported:\n${ninja_out}")
endif()
+if(CMAKE_HOST_WIN32)
+ run_cmake(SelectCompilerWindows)
+else()
+ run_cmake(SelectCompilerUNIX)
+endif()
+
function(run_NinjaToolMissing)
set(RunCMake_MAKE_PROGRAM ninja-tool-missing)
run_cmake(NinjaToolMissing)
@@ -304,3 +313,12 @@ function (run_PreventConfigureFileDupBuildRule)
run_ninja("${RunCMake_TEST_BINARY_DIR}" -w dupbuild=err)
endfunction()
run_PreventConfigureFileDupBuildRule()
+
+function (run_ChangeBuildType)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/ChangeBuildType-build)
+ set(RunCMake_TEST_OPTIONS "-DCMAKE_BUILD_TYPE:STRING=Debug")
+ run_cmake(ChangeBuildType)
+ unset(RunCMake_TEST_OPTIONS)
+ run_ninja("${RunCMake_TEST_BINARY_DIR}" -w dupbuild=err)
+endfunction()
+run_ChangeBuildType()
diff --git a/Tests/RunCMake/Ninja/SelectCompiler/1/gcc b/Tests/RunCMake/Ninja/SelectCompiler/1/gcc
new file mode 100755
index 0000000..151dfa6
--- /dev/null
+++ b/Tests/RunCMake/Ninja/SelectCompiler/1/gcc
@@ -0,0 +1,2 @@
+#!/bin/sh
+false
diff --git a/Tests/RunCMake/Ninja/SelectCompiler/2/cc b/Tests/RunCMake/Ninja/SelectCompiler/2/cc
new file mode 100755
index 0000000..151dfa6
--- /dev/null
+++ b/Tests/RunCMake/Ninja/SelectCompiler/2/cc
@@ -0,0 +1,2 @@
+#!/bin/sh
+false
diff --git a/Tests/RunCMake/Ninja/SelectCompilerUNIX-result.txt b/Tests/RunCMake/Ninja/SelectCompilerUNIX-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Ninja/SelectCompilerUNIX-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Ninja/SelectCompilerUNIX-stderr.txt b/Tests/RunCMake/Ninja/SelectCompilerUNIX-stderr.txt
new file mode 100644
index 0000000..a2baa48
--- /dev/null
+++ b/Tests/RunCMake/Ninja/SelectCompilerUNIX-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Error at .*/Modules/CMakeTestCCompiler.cmake:[0-9]+ \(message\):
+ The C compiler
+
+ "[^"]*/Tests/RunCMake/Ninja/SelectCompiler/2/cc"
+
+ is not able to compile a simple test program.
diff --git a/Tests/RunCMake/Ninja/SelectCompilerUNIX.cmake b/Tests/RunCMake/Ninja/SelectCompilerUNIX.cmake
new file mode 100644
index 0000000..02c8439
--- /dev/null
+++ b/Tests/RunCMake/Ninja/SelectCompilerUNIX.cmake
@@ -0,0 +1,3 @@
+set(ENV{PATH} "${CMAKE_CURRENT_SOURCE_DIR}/SelectCompiler/1:${CMAKE_CURRENT_SOURCE_DIR}/SelectCompiler/2:$ENV{PATH}")
+unset(ENV{CC})
+enable_language(C)
diff --git a/Tests/RunCMake/Ninja/SelectCompilerWindows-result.txt b/Tests/RunCMake/Ninja/SelectCompilerWindows-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Ninja/SelectCompilerWindows-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Ninja/SelectCompilerWindows-stderr.txt b/Tests/RunCMake/Ninja/SelectCompilerWindows-stderr.txt
new file mode 100644
index 0000000..e4b506e
--- /dev/null
+++ b/Tests/RunCMake/Ninja/SelectCompilerWindows-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Error at .*/Modules/CMakeTestCCompiler.cmake:[0-9]+ \(message\):
+ The C compiler
+
+ "[^"]*/Tests/RunCMake/Ninja/SelectCompiler/1/gcc"
+
+ is not able to compile a simple test program.
diff --git a/Tests/RunCMake/Ninja/SelectCompilerWindows.cmake b/Tests/RunCMake/Ninja/SelectCompilerWindows.cmake
new file mode 100644
index 0000000..f5a7e2b
--- /dev/null
+++ b/Tests/RunCMake/Ninja/SelectCompilerWindows.cmake
@@ -0,0 +1,3 @@
+set(ENV{PATH} "${CMAKE_CURRENT_SOURCE_DIR}/SelectCompiler/1;${CMAKE_CURRENT_SOURCE_DIR}/SelectCompiler/2;$ENV{PATH}")
+unset(ENV{CC})
+enable_language(C)
diff --git a/Tests/RunCMake/NinjaMultiConfig/AdditionalCleanFiles-all-clean-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/AdditionalCleanFiles-all-clean-ninja-check.cmake
new file mode 100644
index 0000000..012dc2f
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/AdditionalCleanFiles-all-clean-ninja-check.cmake
@@ -0,0 +1,4 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ # Intentionally empty
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/AdditionalCleanFiles-check.cmake b/Tests/RunCMake/NinjaMultiConfig/AdditionalCleanFiles-check.cmake
new file mode 100644
index 0000000..77412f1
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/AdditionalCleanFiles-check.cmake
@@ -0,0 +1,8 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${RunCMake_TEST_BINARY_DIR}/global.txt
+ ${RunCMake_TEST_BINARY_DIR}/Debug.txt
+ ${RunCMake_TEST_BINARY_DIR}/Release.txt
+ ${RunCMake_TEST_BINARY_DIR}/MinSizeRel.txt
+ ${RunCMake_TEST_BINARY_DIR}/RelWithDebInfo.txt
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/AdditionalCleanFiles-release-clean-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/AdditionalCleanFiles-release-clean-build-check.cmake
new file mode 100644
index 0000000..f211223
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/AdditionalCleanFiles-release-clean-build-check.cmake
@@ -0,0 +1,6 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${RunCMake_TEST_BINARY_DIR}/Debug.txt
+ ${RunCMake_TEST_BINARY_DIR}/MinSizeRel.txt
+ ${RunCMake_TEST_BINARY_DIR}/RelWithDebInfo.txt
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/AdditionalCleanFiles.cmake b/Tests/RunCMake/NinjaMultiConfig/AdditionalCleanFiles.cmake
new file mode 100644
index 0000000..983a494
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/AdditionalCleanFiles.cmake
@@ -0,0 +1,3 @@
+file(GENERATE OUTPUT $<CONFIG>.txt CONTENT "$<CONFIG>\n")
+file(TOUCH ${CMAKE_BINARY_DIR}/global.txt)
+set_directory_properties(PROPERTIES ADDITIONAL_CLEAN_FILES "$<CONFIG>.txt;global.txt")
diff --git a/Tests/RunCMake/NinjaMultiConfig/AutoMocExecutable.cmake b/Tests/RunCMake/NinjaMultiConfig/AutoMocExecutable.cmake
new file mode 100644
index 0000000..950e18e
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/AutoMocExecutable.cmake
@@ -0,0 +1,10 @@
+enable_language(C)
+
+add_executable(badmoc badmoc.c)
+target_compile_definitions(badmoc PRIVATE "CONFIG=\"$<CONFIG>\"")
+
+add_executable(exe main.c)
+set_target_properties(exe PROPERTIES
+ AUTOMOC ON
+ AUTOMOC_EXECUTABLE $<TARGET_FILE:badmoc>
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/CMakeLists.txt b/Tests/RunCMake/NinjaMultiConfig/CMakeLists.txt
new file mode 100644
index 0000000..2632ffa
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.16)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/NinjaMultiConfig/Clean-release-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/Clean-release-build-check.cmake
new file mode 100644
index 0000000..cfe6984
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Clean-release-build-check.cmake
@@ -0,0 +1,16 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${TARGET_FILE_mylib_Release}
+ ${TARGET_LINKER_FILE_mylib_Release}
+ ${TARGET_SONAME_FILE_mylib_Release}
+ ${TARGET_OBJECT_FILES_mylib_Release}
+
+ ${TARGET_OBJECT_FILES_myobj_Release}
+
+ ${TARGET_FILE_exeall_Release}
+ ${TARGET_EXE_FILE_exeall_Release}
+ ${TARGET_OBJECT_FILES_exeall_Release}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_exenotall_Release}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/Clean-release-clean-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/Clean-release-clean-build-check.cmake
new file mode 100644
index 0000000..06b3fb6
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Clean-release-clean-build-check.cmake
@@ -0,0 +1,7 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_exeall_Release}
+ ${TARGET_OBJECT_FILES_exenotall_Release}
+ ${TARGET_OBJECT_FILES_mylib_Release}
+ ${TARGET_OBJECT_FILES_myobj_Release}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/Clean-release-notall-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/Clean-release-notall-ninja-check.cmake
new file mode 100644
index 0000000..42d6a78
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Clean-release-notall-ninja-check.cmake
@@ -0,0 +1,16 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${TARGET_FILE_mylib_Release}
+ ${TARGET_LINKER_FILE_mylib_Release}
+ ${TARGET_SONAME_FILE_mylib_Release}
+ ${TARGET_OBJECT_FILES_mylib_Release}
+
+ ${TARGET_OBJECT_FILES_myobj_Release}
+
+ ${TARGET_FILE_exeall_Release}
+ ${TARGET_EXE_FILE_exeall_Release}
+ ${TARGET_OBJECT_FILES_exeall_Release}
+
+ ${TARGET_FILE_exenotall_Release}
+ ${TARGET_OBJECT_FILES_exenotall_Release}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/Clean.cmake b/Tests/RunCMake/NinjaMultiConfig/Clean.cmake
new file mode 100644
index 0000000..2258d2b
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Clean.cmake
@@ -0,0 +1,17 @@
+enable_language(C)
+
+add_executable(exeall main.c)
+set_target_properties(exeall PROPERTIES VERSION 1.0.0)
+add_executable(exenotall main.c)
+set_target_properties(exenotall PROPERTIES EXCLUDE_FROM_ALL TRUE)
+
+add_library(mylib SHARED simplelib.c)
+set_target_properties(mylib PROPERTIES
+ VERSION 1.0.0
+ SOVERSION 1
+ )
+
+add_library(myobj OBJECT simplelib.c)
+
+include(${CMAKE_CURRENT_LIST_DIR}/Common.cmake)
+generate_output_files(exeall exenotall mylib myobj)
diff --git a/Tests/RunCMake/NinjaMultiConfig/Common.cmake b/Tests/RunCMake/NinjaMultiConfig/Common.cmake
new file mode 100644
index 0000000..6c0d82a
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Common.cmake
@@ -0,0 +1,62 @@
+function(generate_output_files)
+ set(content)
+ foreach(tgt IN LISTS ARGN)
+ get_property(type TARGET ${tgt} PROPERTY TYPE)
+
+ if(NOT type STREQUAL "OBJECT_LIBRARY")
+ set(file " [==[$<TARGET_FILE:${tgt}>]==]")
+ set(filename " [==[$<TARGET_FILE_NAME:${tgt}>]==]")
+ else()
+ set(file)
+ set(filename)
+ endif()
+ string(APPEND content "set(TARGET_FILE_${tgt}_$<CONFIG>${file})\n")
+ string(APPEND content "set(TARGET_FILE_NAME_${tgt}_$<CONFIG>${filename})\n")
+
+ if(type MATCHES "^(STATIC|MODULE|SHARED)_LIBRARY$")
+ set(linker_file " [==[$<TARGET_LINKER_FILE:${tgt}>]==]")
+ set(linker_filename " [==[$<TARGET_LINKER_FILE_NAME:${tgt}>]==]")
+ else()
+ set(linker_file)
+ set(linker_filename)
+ endif()
+ string(APPEND content "set(TARGET_LINKER_FILE_${tgt}_$<CONFIG>${linker_file})\n")
+ string(APPEND content "set(TARGET_LINKER_FILE_NAME_${tgt}_$<CONFIG>${linker_filename})\n")
+
+ if(NOT WIN32 AND NOT CYGWIN AND type MATCHES "^(SHARED_LIBRARY)$")
+ set(soname_file " [==[$<TARGET_SONAME_FILE:${tgt}>]==]")
+ set(soname_filename " [==[$<TARGET_SONAME_FILE_NAME:${tgt}>]==]")
+ else()
+ set(soname_file)
+ set(soname_filename)
+ endif()
+ string(APPEND content "set(TARGET_SONAME_FILE_${tgt}_$<CONFIG>${soname_file})\n")
+ string(APPEND content "set(TARGET_SONAME_FILE_NAME_${tgt}_$<CONFIG>${soname_filename})\n")
+
+ if(type MATCHES "^(EXECUTABLE)$")
+ set(exe_file " [==[$<TARGET_FILE_DIR:${tgt}>/$<TARGET_FILE_PREFIX:${tgt}>$<TARGET_FILE_BASE_NAME:${tgt}>$<TARGET_FILE_SUFFIX:${tgt}>]==]")
+ set(exe_filename " [==[$<TARGET_FILE_PREFIX:${tgt}>$<TARGET_FILE_BASE_NAME:${tgt}>$<TARGET_FILE_SUFFIX:${tgt}>]==]")
+
+ if(WIN32)
+ set(exe_lib_file " [==[$<TARGET_FILE_DIR:${tgt}>/$<TARGET_FILE_PREFIX:${tgt}>$<TARGET_FILE_BASE_NAME:${tgt}>.lib]==]")
+ string(APPEND content "set(TARGET_EXE_LIB_FILE_${tgt}_$<CONFIG>${exe_lib_file})\n")
+ endif()
+ else()
+ set(exe_file)
+ set(exe_filename)
+ endif()
+ string(APPEND content "set(TARGET_EXE_FILE_${tgt}_$<CONFIG>${exe_file})\n")
+ string(APPEND content "set(TARGET_EXE_FILE_NAME_${tgt}_$<CONFIG>${exe_filename})\n")
+
+ string(APPEND content "set(TARGET_OBJECT_FILES_${tgt}_$<CONFIG> [==[$<TARGET_OBJECTS:${tgt}>]==])\n")
+ endforeach()
+
+ file(GENERATE OUTPUT "${CMAKE_BINARY_DIR}/target_files_$<CONFIG>.cmake" CONTENT "${content}")
+
+ set(content)
+ foreach(config IN LISTS CMAKE_CONFIGURATION_TYPES)
+ string(APPEND content "include(\${CMAKE_CURRENT_LIST_DIR}/target_files_${config}.cmake)\n")
+ endforeach()
+
+ file(WRITE "${CMAKE_BINARY_DIR}/target_files.cmake" "${content}")
+endfunction()
diff --git a/Tests/RunCMake/NinjaMultiConfig/CudaSimple-all-clean-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/CudaSimple-all-clean-build-check.cmake
new file mode 100644
index 0000000..45f684b
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CudaSimple-all-clean-build-check.cmake
@@ -0,0 +1,21 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simplecudaexe_Debug}
+ ${TARGET_OBJECT_FILES_simplecudashared_Debug}
+ ${TARGET_OBJECT_FILES_simplecudaobj_Debug}
+
+ ${TARGET_OBJECT_FILES_simplecudaexe_Release}
+ ${TARGET_OBJECT_FILES_simplecudashared_Release}
+ ${TARGET_OBJECT_FILES_simplecudaobj_Release}
+
+ ${TARGET_OBJECT_FILES_simplecudaexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplecudashared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplecudaobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simplecudaexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simplecudashared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simplecudaobj_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/CudaSimple-debug-target-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/CudaSimple-debug-target-build-check.cmake
new file mode 100644
index 0000000..39db5ff
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CudaSimple-debug-target-build-check.cmake
@@ -0,0 +1,28 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simplecudaexe_Debug}
+ ${TARGET_EXE_LIB_FILE_simplecudaexe_Debug}
+ ${TARGET_OBJECT_FILES_simplecudaexe_Debug}
+
+ ${TARGET_FILE_simplecudashared_Debug}
+ ${TARGET_LINKER_FILE_simplecudashared_Debug}
+ ${TARGET_OBJECT_FILES_simplecudashared_Debug}
+
+ ${TARGET_OBJECT_FILES_simplecudaobj_Debug}
+
+ EXCLUDE
+
+ ${TARGET_OBJECT_FILES_simplecudaexe_Release}
+ ${TARGET_OBJECT_FILES_simplecudashared_Release}
+ ${TARGET_OBJECT_FILES_simplecudaobj_Release}
+
+ ${TARGET_OBJECT_FILES_simplecudaexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplecudashared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplecudaobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simplecudaexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simplecudashared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simplecudaobj_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/CudaSimple.cmake b/Tests/RunCMake/NinjaMultiConfig/CudaSimple.cmake
new file mode 100644
index 0000000..00d8a1b
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CudaSimple.cmake
@@ -0,0 +1,22 @@
+cmake_policy(SET CMP0104 NEW)
+enable_language(CUDA)
+file(TOUCH ${CMAKE_BINARY_DIR}/empty.cmake)
+
+add_library(simplecudaobj OBJECT simplelib.cu)
+set_target_properties(simplecudaobj
+ PROPERTIES
+ POSITION_INDEPENDENT_CODE ON)
+
+add_library(simplecudashared SHARED )
+target_link_libraries(simplecudashared PRIVATE simplecudaobj)
+set_target_properties(simplecudaobj simplecudashared
+ PROPERTIES
+ CUDA_SEPARABLE_COMPILATION ON)
+
+add_executable(simplecudaexe main.cu )
+target_link_libraries(simplecudaexe PRIVATE simplecudashared)
+
+include(${CMAKE_CURRENT_LIST_DIR}/Common.cmake)
+generate_output_files(simplecudaexe simplecudashared simplecudaobj)
+
+file(APPEND "${CMAKE_BINARY_DIR}/target_files.cmake" "set(GENERATED_FILES [==[${CMAKE_BINARY_DIR}/empty.cmake]==])\n")
diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfile-check.cmake b/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfile-check.cmake
new file mode 100644
index 0000000..c595b10
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfile-check.cmake
@@ -0,0 +1,5 @@
+set(log "${RunCMake_BINARY_DIR}/CustomCommandDepfile-build/CMakeFiles/impl-Debug.ninja")
+file(READ "${log}" build_file)
+if(NOT "${build_file}" MATCHES "depfile = test\\.d")
+ set(RunCMake_TEST_FAILED "Log file:\n ${log}\ndoes not have expected line: depfile = test.d")
+endif()
diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfile.cmake b/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfile.cmake
new file mode 100644
index 0000000..1a42670
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandDepfile.cmake
@@ -0,0 +1,9 @@
+add_custom_command(
+ OUTPUT main.copy.c
+ COMMAND "${CMAKE_COMMAND}" -E copy
+ "${CMAKE_CURRENT_SOURCE_DIR}/main.c"
+ main.copy.c
+ WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
+ DEPFILE "test.d"
+ )
+add_custom_target(copy ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/main.copy.c")
diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-debug-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-debug-build-check.cmake
new file mode 100644
index 0000000..2abdb43
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-debug-build-check.cmake
@@ -0,0 +1,38 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${CONFIG_FILES}
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_generator_Debug}
+ ${TARGET_OBJECT_FILES_generator_Debug}
+
+ ${TARGET_FILE_generated_Debug}
+ ${TARGET_OBJECT_FILES_generated_Debug}
+
+ ${TARGET_FILE_generatorlib_Debug}
+ ${TARGET_LINKER_FILE_generatorlib_Debug}
+ ${TARGET_OBJECT_FILES_generatorlib_Debug}
+
+ ${TARGET_OBJECT_FILES_generatorobj_Debug}
+
+ ${TARGET_OBJECT_FILES_emptyobj_Debug}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_generator_Release}
+ ${TARGET_OBJECT_FILES_generated_Release}
+ ${TARGET_OBJECT_FILES_generatorlib_Release}
+ ${TARGET_OBJECT_FILES_generatorobj_Release}
+ ${TARGET_OBJECT_FILES_emptyobj_Release}
+
+ ${TARGET_OBJECT_FILES_generator_MinSizeRel}
+ ${TARGET_OBJECT_FILES_generated_MinSizeRel}
+ ${TARGET_OBJECT_FILES_generatorlib_MinSizeRel}
+ ${TARGET_OBJECT_FILES_generatorobj_MinSizeRel}
+ ${TARGET_OBJECT_FILES_emptyobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_generator_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_generated_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_generatorlib_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_generatorobj_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_emptyobj_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-debug-clean-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-debug-clean-ninja-check.cmake
new file mode 100644
index 0000000..aff42c3
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-debug-clean-ninja-check.cmake
@@ -0,0 +1,37 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${CONFIG_FILES}
+
+ ${TARGET_FILE_generator_Release}
+ ${TARGET_OBJECT_FILES_generator_Release}
+
+ ${TARGET_FILE_generated_Release}
+ ${TARGET_OBJECT_FILES_generated_Release}
+
+ ${TARGET_FILE_generatorlib_Release}
+ ${TARGET_LINKER_FILE_generatorlib_Release}
+ ${TARGET_OBJECT_FILES_generatorlib_Release}
+
+ ${TARGET_OBJECT_FILES_generatorobj_Release}
+
+ ${TARGET_OBJECT_FILES_emptyobj_Release}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_generator_Debug}
+ ${TARGET_OBJECT_FILES_generated_Debug}
+ ${TARGET_OBJECT_FILES_generatorlib_Debug}
+ ${TARGET_OBJECT_FILES_generatorobj_Debug}
+ ${TARGET_OBJECT_FILES_emptyobj_Debug}
+
+ ${TARGET_OBJECT_FILES_generator_MinSizeRel}
+ ${TARGET_OBJECT_FILES_generated_MinSizeRel}
+ ${TARGET_OBJECT_FILES_generatorlib_MinSizeRel}
+ ${TARGET_OBJECT_FILES_generatorobj_MinSizeRel}
+ ${TARGET_OBJECT_FILES_emptyobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_generator_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_generated_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_generatorlib_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_generatorobj_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_emptyobj_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-debug-generated-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-debug-generated-stdout.txt
new file mode 100644
index 0000000..765d486
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-debug-generated-stdout.txt
@@ -0,0 +1,12 @@
+^Generator genex config definition: Debug
+Generator genex config include dir: Debug
+Generator library genex config definition: Debug
+Generator library genex config include dir: Debug
+Generator object genex config definition: Debug
+Generator object genex config include dir: Debug
+Generated genex config definition: Debug
+Generated genex config include dir: Debug
+Generated library genex config definition: Debug
+Generated library genex config include dir: Debug
+Generated object genex config definition: Debug
+Generated object genex config include dir: Debug$
diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-debug-in-release-graph-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-debug-in-release-graph-build-check.cmake
new file mode 100644
index 0000000..167f5b9
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-debug-in-release-graph-build-check.cmake
@@ -0,0 +1,43 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${CONFIG_FILES}
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_generated_Debug}
+ ${TARGET_OBJECT_FILES_generated_Debug}
+
+ ${TARGET_FILE_generatorlib_Debug}
+ ${TARGET_LINKER_FILE_generatorlib_Debug}
+ ${TARGET_OBJECT_FILES_generatorlib_Debug}
+
+ ${TARGET_OBJECT_FILES_generatorobj_Debug}
+
+ ${TARGET_OBJECT_FILES_emptyobj_Debug}
+
+ ${TARGET_FILE_generator_Release}
+ ${TARGET_OBJECT_FILES_generator_Release}
+
+ ${TARGET_FILE_generatorlib_Release}
+ ${TARGET_LINKER_FILE_generatorlib_Release}
+ ${TARGET_OBJECT_FILES_generatorlib_Release}
+
+ ${TARGET_OBJECT_FILES_generatorobj_Release}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_generator_Debug}
+
+ ${TARGET_OBJECT_FILES_generated_Release}
+ ${TARGET_OBJECT_FILES_emptyobj_Release}
+
+ ${TARGET_OBJECT_FILES_generator_MinSizeRel}
+ ${TARGET_OBJECT_FILES_generated_MinSizeRel}
+ ${TARGET_OBJECT_FILES_generatorlib_MinSizeRel}
+ ${TARGET_OBJECT_FILES_generatorobj_MinSizeRel}
+ ${TARGET_OBJECT_FILES_emptyobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_generator_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_generated_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_generatorlib_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_generatorobj_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_emptyobj_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-debug-in-release-graph-clean-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-debug-in-release-graph-clean-ninja-check.cmake
new file mode 100644
index 0000000..1e4cbe1
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-debug-in-release-graph-clean-ninja-check.cmake
@@ -0,0 +1,35 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${CONFIG_FILES}
+
+ ${TARGET_FILE_generator_Release}
+ ${TARGET_OBJECT_FILES_generator_Release}
+
+ ${TARGET_FILE_generatorlib_Release}
+ ${TARGET_LINKER_FILE_generatorlib_Release}
+ ${TARGET_OBJECT_FILES_generatorlib_Release}
+
+ ${TARGET_OBJECT_FILES_generatorobj_Release}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_generator_Debug}
+ ${TARGET_OBJECT_FILES_generated_Debug}
+ ${TARGET_OBJECT_FILES_generatorlib_Debug}
+ ${TARGET_OBJECT_FILES_generatorobj_Debug}
+ ${TARGET_OBJECT_FILES_emptyobj_Debug}
+
+ ${TARGET_OBJECT_FILES_generated_Release}
+ ${TARGET_OBJECT_FILES_emptyobj_Release}
+
+ ${TARGET_OBJECT_FILES_generator_MinSizeRel}
+ ${TARGET_OBJECT_FILES_generated_MinSizeRel}
+ ${TARGET_OBJECT_FILES_generatorlib_MinSizeRel}
+ ${TARGET_OBJECT_FILES_generatorobj_MinSizeRel}
+ ${TARGET_OBJECT_FILES_emptyobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_generator_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_generated_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_generatorlib_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_generatorobj_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_emptyobj_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-debug-in-release-graph-generated-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-debug-in-release-graph-generated-stdout.txt
new file mode 100644
index 0000000..1c9abef
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-debug-in-release-graph-generated-stdout.txt
@@ -0,0 +1,12 @@
+^Generator genex config definition: Release
+Generator genex config include dir: Release
+Generator library genex config definition: Release
+Generator library genex config include dir: Release
+Generator object genex config definition: Release
+Generator object genex config include dir: Release
+Generated genex config definition: Debug
+Generated genex config include dir: Debug
+Generated library genex config definition: Debug
+Generated library genex config include dir: Debug
+Generated object genex config definition: Debug
+Generated object genex config include dir: Debug$
diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-release-clean-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-release-clean-build-check.cmake
new file mode 100644
index 0000000..8ba6d68
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-release-clean-build-check.cmake
@@ -0,0 +1,29 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${CONFIG_FILES}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_generator_Debug}
+ ${TARGET_OBJECT_FILES_generated_Debug}
+ ${TARGET_OBJECT_FILES_generatorlib_Debug}
+ ${TARGET_OBJECT_FILES_generatorobj_Debug}
+ ${TARGET_OBJECT_FILES_emptyobj_Debug}
+
+ ${TARGET_OBJECT_FILES_generator_Release}
+ ${TARGET_OBJECT_FILES_generated_Release}
+ ${TARGET_OBJECT_FILES_generatorlib_Release}
+ ${TARGET_OBJECT_FILES_generatorobj_Release}
+ ${TARGET_OBJECT_FILES_emptyobj_Release}
+
+ ${TARGET_OBJECT_FILES_generator_MinSizeRel}
+ ${TARGET_OBJECT_FILES_generated_MinSizeRel}
+ ${TARGET_OBJECT_FILES_generatorlib_MinSizeRel}
+ ${TARGET_OBJECT_FILES_generatorobj_MinSizeRel}
+ ${TARGET_OBJECT_FILES_emptyobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_generator_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_generated_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_generatorlib_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_generatorobj_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_emptyobj_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-release-generated-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-release-generated-stdout.txt
new file mode 100644
index 0000000..576ec51
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-release-generated-stdout.txt
@@ -0,0 +1,12 @@
+^Generator genex config definition: Release
+Generator genex config include dir: Release
+Generator library genex config definition: Release
+Generator library genex config include dir: Release
+Generator object genex config definition: Release
+Generator object genex config include dir: Release
+Generated genex config definition: Release
+Generated genex config include dir: Release
+Generated library genex config definition: Release
+Generated library genex config include dir: Release
+Generated object genex config definition: Release
+Generated object genex config include dir: Release$
diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-release-in-debug-graph-generated-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-release-in-debug-graph-generated-stdout.txt
new file mode 100644
index 0000000..25392af
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-release-in-debug-graph-generated-stdout.txt
@@ -0,0 +1,12 @@
+^Generator genex config definition: Debug
+Generator genex config include dir: Debug
+Generator library genex config definition: Debug
+Generator library genex config include dir: Debug
+Generator object genex config definition: Debug
+Generator object genex config include dir: Debug
+Generated genex config definition: Release
+Generated genex config include dir: Release
+Generated library genex config definition: Release
+Generated library genex config include dir: Release
+Generated object genex config definition: Release
+Generated object genex config include dir: Release$
diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-release-in-debug-graph-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-release-in-debug-graph-ninja-check.cmake
new file mode 100644
index 0000000..faf392e
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-release-in-debug-graph-ninja-check.cmake
@@ -0,0 +1,44 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${CONFIG_FILES}
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_generator_Debug}
+ ${TARGET_OBJECT_FILES_generator_Debug}
+
+ ${TARGET_FILE_generatorlib_Debug}
+ ${TARGET_LINKER_FILE_generatorlib_Debug}
+ ${TARGET_OBJECT_FILES_generatorlib_Debug}
+
+ ${TARGET_OBJECT_FILES_generatorobj_Debug}
+
+ ${TARGET_FILE_generator_Release}
+ ${TARGET_OBJECT_FILES_generator_Release}
+
+ ${TARGET_FILE_generated_Release}
+ ${TARGET_OBJECT_FILES_generated_Release}
+
+ ${TARGET_FILE_generatorlib_Release}
+ ${TARGET_LINKER_FILE_generatorlib_Release}
+ ${TARGET_OBJECT_FILES_generatorlib_Release}
+
+ ${TARGET_OBJECT_FILES_generatorobj_Release}
+
+ ${TARGET_OBJECT_FILES_emptyobj_Release}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_generated_Debug}
+ ${TARGET_OBJECT_FILES_emptyobj_Debug}
+
+ ${TARGET_OBJECT_FILES_generator_MinSizeRel}
+ ${TARGET_OBJECT_FILES_generated_MinSizeRel}
+ ${TARGET_OBJECT_FILES_generatorlib_MinSizeRel}
+ ${TARGET_OBJECT_FILES_generatorobj_MinSizeRel}
+ ${TARGET_OBJECT_FILES_emptyobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_generator_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_generated_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_generatorlib_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_generatorobj_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_emptyobj_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-release-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-release-ninja-check.cmake
new file mode 100644
index 0000000..b51a6a7
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator-release-ninja-check.cmake
@@ -0,0 +1,46 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${CONFIG_FILES}
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_generator_Debug}
+ ${TARGET_OBJECT_FILES_generator_Debug}
+
+ ${TARGET_FILE_generated_Debug}
+ ${TARGET_OBJECT_FILES_generated_Debug}
+
+ ${TARGET_FILE_generatorlib_Debug}
+ ${TARGET_LINKER_FILE_generatorlib_Debug}
+ ${TARGET_OBJECT_FILES_generatorlib_Debug}
+
+ ${TARGET_OBJECT_FILES_generatorobj_Debug}
+
+ ${TARGET_OBJECT_FILES_emptyobj_Debug}
+
+ ${TARGET_FILE_generator_Release}
+ ${TARGET_OBJECT_FILES_generator_Release}
+
+ ${TARGET_FILE_generated_Release}
+ ${TARGET_OBJECT_FILES_generated_Release}
+
+ ${TARGET_FILE_generatorlib_Release}
+ ${TARGET_LINKER_FILE_generatorlib_Release}
+ ${TARGET_OBJECT_FILES_generatorlib_Release}
+
+ ${TARGET_OBJECT_FILES_generatorobj_Release}
+
+ ${TARGET_OBJECT_FILES_emptyobj_Release}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_generator_MinSizeRel}
+ ${TARGET_OBJECT_FILES_generated_MinSizeRel}
+ ${TARGET_OBJECT_FILES_generatorlib_MinSizeRel}
+ ${TARGET_OBJECT_FILES_generatorobj_MinSizeRel}
+ ${TARGET_OBJECT_FILES_emptyobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_generator_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_generated_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_generatorlib_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_generatorobj_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_emptyobj_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator.cmake b/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator.cmake
new file mode 100644
index 0000000..f4aca5e
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandGenerator.cmake
@@ -0,0 +1,56 @@
+enable_language(C)
+
+add_library(generatorlib STATIC generatorlib.c)
+add_library(generatorobj OBJECT generatorobj.c)
+add_library(emptyobj OBJECT empty.c)
+add_library(emptyobj2 OBJECT empty.c)
+
+add_executable(generator generator.c $<TARGET_OBJECTS:generatorobj>)
+target_link_libraries(generator PRIVATE generatorlib)
+
+add_custom_command(OUTPUT generated.c COMMAND generator generated.c)
+add_executable(generated ${CMAKE_BINARY_DIR}/generated.c $<TARGET_OBJECTS:generatorobj> $<TARGET_OBJECTS:emptyobj>)
+target_link_libraries(generated PRIVATE generatorlib)
+
+file(GENERATE OUTPUT include/genex/$<CONFIG>/genex_config.h CONTENT
+"#ifndef GENEX_CONFIG_H
+#define GENEX_CONFIG_H
+
+#define GENEX_CONFIG_INCLUDE_DIR \"$<CONFIG>\"
+
+#endif /* GENEX_CONFIG_H */
+")
+file(GENERATE OUTPUT include/intdir/$<CONFIG>/intdir_config.h CONTENT
+"#ifndef INTDIR_CONFIG_H
+#define INTDIR_CONFIG_H
+
+#define INTDIR_CONFIG_INCLUDE_DIR \"$<CONFIG>\"
+
+#endif /* INTDIR_CONFIG_H */
+")
+
+foreach(g generatorlib generatorobj generator generated)
+ target_compile_definitions(${g} PRIVATE
+ "GENEX_CONFIG_DEFINITION=\"$<CONFIG>\""
+ # FIXME Get this working
+ # "INTDIR_CONFIG_DEFINITION=\"${CMAKE_CFG_INTDIR}\""
+ )
+ target_include_directories(${g} PRIVATE
+ "${CMAKE_BINARY_DIR}/include/genex/$<CONFIG>"
+ # FIXME Get this working
+ # "${CMAKE_BINARY_DIR}/include/intdir/${CMAKE_CFG_INTDIR}"
+ )
+endforeach()
+
+include(${CMAKE_CURRENT_LIST_DIR}/Common.cmake)
+generate_output_files(generatorlib generatorobj emptyobj generator generated)
+
+file(APPEND "${CMAKE_BINARY_DIR}/target_files.cmake" "set(GENERATED_FILES [==[${CMAKE_BINARY_DIR}/generated.c]==])\n")
+set(genfiles)
+foreach(cfg Debug Release MinSizeRel RelWithDebInfo)
+ list(APPEND genfiles
+ ${CMAKE_BINARY_DIR}/include/genex/${cfg}/genex_config.h
+ ${CMAKE_BINARY_DIR}/include/intdir/${cfg}/intdir_config.h
+ )
+endforeach()
+file(APPEND "${CMAKE_BINARY_DIR}/target_files.cmake" "set(CONFIG_FILES [==[${genfiles}]==])\n")
diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-debug-command-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-debug-command-ninja-check.cmake
new file mode 100644
index 0000000..f5c4020
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-debug-command-ninja-check.cmake
@@ -0,0 +1,6 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${TARGET_DEPENDS_SubdirCommand}
+ ${TARGET_DEPENDS_TopCommand}
+ )
+check_file_contents("${TARGET_DEPENDS_TopCommand}" "^Genex config: Debug\nINTDIR config: Debug\n$")
diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-debug-in-release-graph-postbuild-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-debug-in-release-graph-postbuild-build-check.cmake
new file mode 100644
index 0000000..05861b2
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-debug-in-release-graph-postbuild-build-check.cmake
@@ -0,0 +1,8 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${TARGET_DEPENDS_SubdirCommand}
+ ${TARGET_DEPENDS_TopCommand}
+ ${TARGET_BYPRODUCTS_SubdirTarget}
+ ${TARGET_BYPRODUCTS_TopTarget}
+ ${TARGET_FILE_SubdirPostBuild_Debug}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-debug-target-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-debug-target-build-check.cmake
new file mode 100644
index 0000000..52895b2
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-debug-target-build-check.cmake
@@ -0,0 +1,8 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${TARGET_DEPENDS_SubdirCommand}
+ ${TARGET_DEPENDS_TopCommand}
+ ${TARGET_BYPRODUCTS_SubdirTarget}
+ ${TARGET_BYPRODUCTS_TopTarget}
+ )
+check_file_contents("${TARGET_BYPRODUCTS_TopTarget}" "^Genex config: Debug\nINTDIR config: Debug\n$")
diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-debug-targetpostbuild-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-debug-targetpostbuild-build-check.cmake
new file mode 100644
index 0000000..80439ea
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-debug-targetpostbuild-build-check.cmake
@@ -0,0 +1,12 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${TARGET_DEPENDS_SubdirCommand}
+ ${TARGET_DEPENDS_TopCommand}
+ ${TARGET_BYPRODUCTS_SubdirTarget}
+ ${TARGET_BYPRODUCTS_TopTarget}
+ ${TARGET_FILE_SubdirPostBuild_Debug}
+ ${TARGET_FILE_SubdirPostBuild_Release}
+ ${TARGET_BYPRODUCTS_SubdirPostBuild}
+ ${TARGET_BYPRODUCTS_TopTargetPostBuild}
+ )
+check_file_contents("${TARGET_BYPRODUCTS_TopTargetPostBuild}" "^Genex config: Debug\nINTDIR config: Debug\n$")
diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-minsizerel-command-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-minsizerel-command-ninja-check.cmake
new file mode 100644
index 0000000..2813f02
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-minsizerel-command-ninja-check.cmake
@@ -0,0 +1,5 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${TARGET_DEPENDS_SubdirCommand}
+ )
+check_file_contents("${TARGET_DEPENDS_SubdirCommand}" "^Genex config: MinSizeRel\nINTDIR config: MinSizeRel\n$")
diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-release-command-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-release-command-build-check.cmake
new file mode 100644
index 0000000..2da9735
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-release-command-build-check.cmake
@@ -0,0 +1,5 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${TARGET_DEPENDS_SubdirCommand}
+ )
+check_file_contents("${TARGET_DEPENDS_SubdirCommand}" "^Genex config: Release\nINTDIR config: Release\n$")
diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-release-postbuild-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-release-postbuild-ninja-check.cmake
new file mode 100644
index 0000000..0916b90
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-release-postbuild-ninja-check.cmake
@@ -0,0 +1,11 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${TARGET_DEPENDS_SubdirCommand}
+ ${TARGET_DEPENDS_TopCommand}
+ ${TARGET_BYPRODUCTS_SubdirTarget}
+ ${TARGET_BYPRODUCTS_TopTarget}
+ ${TARGET_FILE_SubdirPostBuild_Debug}
+ ${TARGET_FILE_SubdirPostBuild_Release}
+ ${TARGET_BYPRODUCTS_SubdirPostBuild}
+ )
+check_file_contents("${TARGET_BYPRODUCTS_SubdirPostBuild}" "^Genex config: Release\nINTDIR config: Release\n$")
diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-release-target-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-release-target-ninja-check.cmake
new file mode 100644
index 0000000..87e78b4
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-release-target-ninja-check.cmake
@@ -0,0 +1,7 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${TARGET_DEPENDS_SubdirCommand}
+ ${TARGET_DEPENDS_TopCommand}
+ ${TARGET_BYPRODUCTS_SubdirTarget}
+ )
+check_file_contents("${TARGET_BYPRODUCTS_SubdirTarget}" "^Genex config: Release\nINTDIR config: Release\n$")
diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-release-targetpostbuild-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-release-targetpostbuild-ninja-check.cmake
new file mode 100644
index 0000000..f67d5be
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets-release-targetpostbuild-ninja-check.cmake
@@ -0,0 +1,13 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${TARGET_DEPENDS_SubdirCommand}
+ ${TARGET_DEPENDS_TopCommand}
+ ${TARGET_BYPRODUCTS_SubdirTarget}
+ ${TARGET_BYPRODUCTS_TopTarget}
+ ${TARGET_FILE_SubdirPostBuild_Debug}
+ ${TARGET_FILE_SubdirPostBuild_Release}
+ ${TARGET_BYPRODUCTS_SubdirPostBuild}
+ ${TARGET_BYPRODUCTS_TopTargetPostBuild}
+ ${TARGET_BYPRODUCTS_SubdirTargetPostBuild}
+ )
+check_file_contents("${TARGET_BYPRODUCTS_SubdirTargetPostBuild}" "^Genex config: Release\nINTDIR config: Release\n$")
diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets.cmake b/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets.cmake
new file mode 100644
index 0000000..b2b24e8
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargets.cmake
@@ -0,0 +1,39 @@
+enable_language(C)
+
+file(REMOVE "${CMAKE_BINARY_DIR}/target_files_custom.cmake")
+
+function(get_write_file_command var filename)
+ set(${var} ${CMAKE_COMMAND} -DOUTPUT_FILE=${filename} -DGENEX_CONFIG=$<CONFIG> -DINTDIR_CONFIG=${CMAKE_CFG_INTDIR} -P ${CMAKE_SOURCE_DIR}/WriteFile.cmake PARENT_SCOPE)
+endfunction()
+
+function(create_targets prefix)
+ get_write_file_command(cmd ${prefix}Command.txt)
+ add_custom_command(OUTPUT ${prefix}Command.txt COMMAND ${cmd})
+ add_custom_target(${prefix}Command DEPENDS ${prefix}Command.txt)
+
+ get_write_file_command(cmd ${prefix}Target.txt)
+ add_custom_target(${prefix}Target COMMAND ${cmd} BYPRODUCTS ${prefix}Target.txt)
+
+ get_write_file_command(cmd ${prefix}PostBuild.txt)
+ add_executable(${prefix}PostBuild ${CMAKE_SOURCE_DIR}/main.c)
+ add_custom_command(TARGET ${prefix}PostBuild COMMAND ${cmd} BYPRODUCTS ${prefix}PostBuild.txt)
+
+ get_write_file_command(cmd ${prefix}TargetPostBuild.txt)
+ add_custom_target(${prefix}TargetPostBuild)
+ add_custom_command(TARGET ${prefix}TargetPostBuild COMMAND ${cmd} BYPRODUCTS ${prefix}TargetPostBuild.txt)
+
+ file(APPEND "${CMAKE_BINARY_DIR}/target_files_custom.cmake"
+"set(TARGET_DEPENDS_${prefix}Command [==[${CMAKE_CURRENT_BINARY_DIR}/${prefix}Command.txt]==])
+set(TARGET_BYPRODUCTS_${prefix}Target [==[${CMAKE_CURRENT_BINARY_DIR}/${prefix}Target.txt]==])
+set(TARGET_BYPRODUCTS_${prefix}PostBuild [==[${CMAKE_CURRENT_BINARY_DIR}/${prefix}PostBuild.txt]==])
+set(TARGET_BYPRODUCTS_${prefix}TargetPostBuild [==[${CMAKE_CURRENT_BINARY_DIR}/${prefix}TargetPostBuild.txt]==])
+")
+endfunction()
+
+add_subdirectory(CustomCommandsAndTargetsSubdir)
+
+create_targets(Top)
+
+include(${CMAKE_CURRENT_LIST_DIR}/Common.cmake)
+generate_output_files(TopPostBuild SubdirPostBuild)
+file(APPEND "${CMAKE_BINARY_DIR}/target_files.cmake" "include(\${CMAKE_CURRENT_LIST_DIR}/target_files_custom.cmake)\n")
diff --git a/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargetsSubdir/CMakeLists.txt b/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargetsSubdir/CMakeLists.txt
new file mode 100644
index 0000000..894e3ed
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CustomCommandsAndTargetsSubdir/CMakeLists.txt
@@ -0,0 +1 @@
+create_targets(Subdir)
diff --git a/Tests/RunCMake/NinjaMultiConfig/DefaultBuildFileConfig.cmake b/Tests/RunCMake/NinjaMultiConfig/DefaultBuildFileConfig.cmake
new file mode 100644
index 0000000..bb7b160
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/DefaultBuildFileConfig.cmake
@@ -0,0 +1 @@
+# Intentionally empty
diff --git a/Tests/RunCMake/NinjaMultiConfig/Framework.cmake b/Tests/RunCMake/NinjaMultiConfig/Framework.cmake
new file mode 100644
index 0000000..b4c35f6
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Framework.cmake
@@ -0,0 +1,22 @@
+enable_language(C)
+
+set(header "${CMAKE_CURRENT_BINARY_DIR}/header.h")
+file(GENERATE
+ OUTPUT "${header}"
+ CONTENT "/* foo */"
+ CONDITION "$<CONFIG:Release>"
+ )
+add_library(framework SHARED "${header}" empty.c)
+
+set_property(TARGET framework PROPERTY FRAMEWORK ON)
+set_property(TARGET framework APPEND PROPERTY PUBLIC_HEADER ${header})
+
+set_target_properties(framework PROPERTIES
+ LIBRARY_OUTPUT_DIRECTORY "lib"
+ LIBRARY_OUTPUT_DIRECTORY_DEBUG "lib"
+ LIBRARY_OUTPUT_DIRECTORY_RELEASE "lib"
+ DEBUG_POSTFIX "_debug"
+ )
+
+include(${CMAKE_CURRENT_LIST_DIR}/Common.cmake)
+generate_output_files(framework)
diff --git a/Tests/RunCMake/NinjaMultiConfig/FrameworkDependencyAutogen.cmake b/Tests/RunCMake/NinjaMultiConfig/FrameworkDependencyAutogen.cmake
new file mode 100644
index 0000000..75e21b9
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/FrameworkDependencyAutogen.cmake
@@ -0,0 +1,20 @@
+enable_language(C)
+
+set(CMAKE_LINK_DEPENDS_NO_SHARED ON)
+
+set(QT_VERSION_MAJOR 6)
+set(fake_moc_path "${CMAKE_CURRENT_BINARY_DIR}/fake_moc")
+file(WRITE "${fake_moc_path}" "")
+
+add_library(test1 SHARED simplelib.c)
+add_library(test2 SHARED empty.c)
+target_link_libraries(test2 test1)
+
+set_target_properties(test1 test2 PROPERTIES
+ FRAMEWORK ON
+ AUTOMOC ON
+ AUTOMOC_EXECUTABLE "${fake_moc_path}"
+ )
+
+include(${CMAKE_CURRENT_LIST_DIR}/Common.cmake)
+generate_output_files(test1 test2)
diff --git a/Tests/RunCMake/NinjaMultiConfig/Install-debug-in-release-graph-install-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/Install-debug-in-release-graph-install-ninja-check.cmake
new file mode 100644
index 0000000..bc15a25
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Install-debug-in-release-graph-install-ninja-check.cmake
@@ -0,0 +1,31 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${TARGET_FILE_exe_Debug}
+ ${TARGET_OBJECT_FILES_exe_Debug}
+
+ ${TARGET_FILE_mylib_Release}
+ ${TARGET_LINKER_FILE_mylib_Debug}
+ ${TARGET_OBJECT_FILES_mylib_Debug}
+
+ ${RunCMake_TEST_BINARY_DIR}/install/bin/Debug/${TARGET_FILE_NAME_exe_Debug}
+ ${RunCMake_TEST_BINARY_DIR}/install/lib/Debug/${TARGET_FILE_NAME_mylib_Debug}
+ ${RunCMake_TEST_BINARY_DIR}/install/lib/Debug/${TARGET_LINKER_FILE_NAME_mylib_Debug}
+
+ ${TARGET_FILE_exe_Release}
+ ${TARGET_OBJECT_FILES_exe_Release}
+
+ ${TARGET_FILE_mylib_Release}
+ ${TARGET_LINKER_FILE_mylib_Release}
+ ${TARGET_OBJECT_FILES_mylib_Release}
+
+ ${RunCMake_TEST_BINARY_DIR}/install/bin/Release/${TARGET_FILE_NAME_exe_Release}
+ ${RunCMake_TEST_BINARY_DIR}/install/lib/Release/${TARGET_FILE_NAME_mylib_Release}
+ ${RunCMake_TEST_BINARY_DIR}/install/lib/Release/${TARGET_LINKER_FILE_NAME_mylib_Release}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_exe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_mylib_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_exe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_mylib_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/Install-release-install-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/Install-release-install-build-check.cmake
new file mode 100644
index 0000000..3280c89
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Install-release-install-build-check.cmake
@@ -0,0 +1,23 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${TARGET_FILE_exe_Release}
+ ${TARGET_OBJECT_FILES_exe_Release}
+
+ ${TARGET_FILE_mylib_Release}
+ ${TARGET_LINKER_FILE_mylib_Release}
+ ${TARGET_OBJECT_FILES_mylib_Release}
+
+ ${RunCMake_TEST_BINARY_DIR}/install/bin/Release/${TARGET_FILE_NAME_exe_Release}
+ ${RunCMake_TEST_BINARY_DIR}/install/lib/Release/${TARGET_FILE_NAME_mylib_Release}
+ ${RunCMake_TEST_BINARY_DIR}/install/lib/Release/${TARGET_LINKER_FILE_NAME_mylib_Release}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_exe_Debug}
+ ${TARGET_OBJECT_FILES_mylib_Debug}
+
+ ${TARGET_OBJECT_FILES_exe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_mylib_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_exe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_mylib_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/Install.cmake b/Tests/RunCMake/NinjaMultiConfig/Install.cmake
new file mode 100644
index 0000000..e26e3e0
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Install.cmake
@@ -0,0 +1,10 @@
+enable_language(C)
+
+add_executable(exe main.c)
+add_library(mylib STATIC simplelib.c)
+
+install(TARGETS exe DESTINATION bin/$<CONFIG>)
+install(TARGETS mylib DESTINATION lib/$<CONFIG>)
+
+include(${CMAKE_CURRENT_LIST_DIR}/Common.cmake)
+generate_output_files(exe mylib)
diff --git a/Tests/RunCMake/NinjaMultiConfig/InvalidCrossConfigs-result.txt b/Tests/RunCMake/NinjaMultiConfig/InvalidCrossConfigs-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/InvalidCrossConfigs-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/NinjaMultiConfig/InvalidCrossConfigs-stderr.txt b/Tests/RunCMake/NinjaMultiConfig/InvalidCrossConfigs-stderr.txt
new file mode 100644
index 0000000..76c5ecf
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/InvalidCrossConfigs-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error:
+ CMAKE_CROSS_CONFIGS is not a subset of CMAKE_CONFIGURATION_TYPES
+
+
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/NinjaMultiConfig/InvalidCrossConfigs.cmake b/Tests/RunCMake/NinjaMultiConfig/InvalidCrossConfigs.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/InvalidCrossConfigs.cmake
diff --git a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultBuildFileConfig-result.txt b/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultBuildFileConfig-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultBuildFileConfig-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultBuildFileConfig-stderr.txt b/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultBuildFileConfig-stderr.txt
new file mode 100644
index 0000000..5aa9038
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultBuildFileConfig-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Error:
+ The configuration specified by CMAKE_DEFAULT_BUILD_TYPE \(RelWithDebInfo\) is
+ not present in CMAKE_CONFIGURATION_TYPES
+
+
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultBuildFileConfig.cmake b/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultBuildFileConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultBuildFileConfig.cmake
diff --git a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsCross-result.txt b/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsCross-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsCross-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsCross-stderr.txt b/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsCross-stderr.txt
new file mode 100644
index 0000000..6c2df86
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsCross-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error:
+ CMAKE_DEFAULT_CONFIGS is not a subset of CMAKE_CROSS_CONFIGS
+
+
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsCross.cmake b/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsCross.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsCross.cmake
diff --git a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoCross-result.txt b/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoCross-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoCross-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoCross-stderr.txt b/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoCross-stderr.txt
new file mode 100644
index 0000000..5d090a0
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoCross-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Error:
+ CMAKE_DEFAULT_CONFIGS cannot be used without CMAKE_DEFAULT_BUILD_TYPE or
+ CMAKE_CROSS_CONFIGS
+
+
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoCross.cmake b/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoCross.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoCross.cmake
diff --git a/Tests/RunCMake/NinjaMultiConfig/NoUnusedVariables.cmake b/Tests/RunCMake/NinjaMultiConfig/NoUnusedVariables.cmake
new file mode 100644
index 0000000..bb7b160
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/NoUnusedVariables.cmake
@@ -0,0 +1 @@
+# Intentionally empty
diff --git a/Tests/RunCMake/NinjaMultiConfig/PostfixAndLocation-debug-in-release-graph-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/PostfixAndLocation-debug-in-release-graph-build-check.cmake
new file mode 100644
index 0000000..3657b5b
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/PostfixAndLocation-debug-in-release-graph-build-check.cmake
@@ -0,0 +1,7 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${TARGET_FILE_mylib_Release}
+ ${TARGET_LINKER_FILE_mylib_Release}
+ ${TARGET_FILE_mylib_Debug}
+ ${TARGET_LINKER_FILE_mylib_Debug}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/PostfixAndLocation-release-in-release-graph-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/PostfixAndLocation-release-in-release-graph-build-check.cmake
new file mode 100644
index 0000000..3345ee8
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/PostfixAndLocation-release-in-release-graph-build-check.cmake
@@ -0,0 +1,5 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${TARGET_FILE_mylib_Release}
+ ${TARGET_LINKER_FILE_mylib_Release}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/PostfixAndLocation.cmake b/Tests/RunCMake/NinjaMultiConfig/PostfixAndLocation.cmake
new file mode 100644
index 0000000..abef3c8
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/PostfixAndLocation.cmake
@@ -0,0 +1,18 @@
+enable_language(C)
+
+set(CMAKE_DEBUG_POSTFIX "_debug")
+
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_BINARY_DIR}/lib)
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_BINARY_DIR}/lib)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_BINARY_DIR}/bin)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_BINARY_DIR}/bin)
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_BINARY_DIR}/lib)
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_BINARY_DIR}/lib)
+
+add_library(mylib SHARED simplelib.c)
+
+include(${CMAKE_CURRENT_LIST_DIR}/Common.cmake)
+generate_output_files(mylib)
diff --git a/Tests/RunCMake/NinjaMultiConfig/Qt5-debug-in-release-graph-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/Qt5-debug-in-release-graph-build-check.cmake
new file mode 100644
index 0000000..2d8df13
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Qt5-debug-in-release-graph-build-check.cmake
@@ -0,0 +1,7 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${AUTOGEN_FILES}
+
+ ${TARGET_FILE_exe_Debug}
+ ${TARGET_OBJECT_FILES_exe_Debug}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/Qt5.cmake b/Tests/RunCMake/NinjaMultiConfig/Qt5.cmake
new file mode 100644
index 0000000..3a1c7f5
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Qt5.cmake
@@ -0,0 +1,30 @@
+enable_language(CXX)
+
+find_package(Qt5Core REQUIRED)
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTOMOC_COMPILER_PREDEFINES OFF)
+
+add_executable(exe qt5.cxx)
+target_link_libraries(exe PRIVATE Qt5::Core)
+
+include(${CMAKE_CURRENT_LIST_DIR}/Common.cmake)
+generate_output_files(exe)
+
+set(moc_writes_depfiles 0)
+if(Qt5Core_VERSION VERSION_GREATER_EQUAL "5.15.0")
+ set(moc_writes_depfiles 1)
+endif()
+
+set(autogen_files "${CMAKE_BINARY_DIR}/exe_autogen/mocs_compilation.cpp")
+if(moc_writes_depfiles)
+ list(APPEND autogen_files "${CMAKE_BINARY_DIR}/exe_autogen/deps")
+ list(APPEND autogen_files "${CMAKE_BINARY_DIR}/exe_autogen/timestamp")
+endif()
+foreach(c IN LISTS CMAKE_CONFIGURATION_TYPES)
+ list(APPEND autogen_files "${CMAKE_BINARY_DIR}/exe_autogen/include_${c}/moc_qt5.cpp")
+ if(moc_writes_depfiles)
+ list(APPEND autogen_files "${CMAKE_BINARY_DIR}/exe_autogen/include_${c}/moc_qt5.cpp.d")
+ endif()
+endforeach()
+file(APPEND "${CMAKE_BINARY_DIR}/target_files.cmake" "set(AUTOGEN_FILES [==[${autogen_files}]==])\n")
diff --git a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake
new file mode 100644
index 0000000..6472f46
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake
@@ -0,0 +1,303 @@
+cmake_minimum_required(VERSION 3.16)
+
+include(RunCMake)
+
+set(RunCMake_GENERATOR "Ninja Multi-Config")
+set(RunCMake_GENERATOR_IS_MULTI_CONFIG 1)
+
+function(check_files dir)
+ cmake_parse_arguments(_check_files "" "" "INCLUDE;EXCLUDE" ${ARGN})
+
+ set(expected ${_check_files_INCLUDE})
+ list(FILTER expected EXCLUDE REGEX "^$")
+ list(REMOVE_DUPLICATES expected)
+ list(SORT expected)
+
+ file(GLOB_RECURSE actual "${dir}/*")
+ list(FILTER actual EXCLUDE REGEX "/CMakeFiles/|\\.ninja$|/CMakeCache\\.txt$|/target_files[^/]*\\.cmake$|/\\.ninja_[^/]*$|/cmake_install\\.cmake$|\\.ilk$|\\.manifest$|\\.pdb$|\\.exp$|/install_manifest\\.txt$")
+ foreach(f IN LISTS _check_files_INCLUDE _check_files_EXCLUDE)
+ if(EXISTS ${f})
+ list(APPEND actual ${f})
+ endif()
+ endforeach()
+ list(REMOVE_DUPLICATES actual)
+ list(SORT actual)
+
+ if(NOT "${expected}" STREQUAL "${actual}")
+ string(REPLACE ";" "\n " expected_formatted "${expected}")
+ string(REPLACE ";" "\n " actual_formatted "${actual}")
+ string(APPEND RunCMake_TEST_FAILED "Actual files did not match expected\nExpected:\n ${expected_formatted}\nActual:\n ${actual_formatted}\n")
+ endif()
+
+ set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
+endfunction()
+
+function(check_file_contents filename expected)
+ if(NOT EXISTS "${filename}")
+ string(APPEND RunCMake_TEST_FAILED "File ${filename} does not exist\n")
+ else()
+ file(READ "${filename}" actual)
+ if(NOT actual MATCHES "${expected}")
+ string(REPLACE "\n" "\n " expected_formatted "${expected}")
+ string(REPLACE "\n" "\n " actual_formatted "${actual}")
+ string(APPEND RunCMake_TEST_FAILED "Contents of ${filename} do not match expected\nExpected:\n ${expected_formatted}\nActual:\n ${actual_formatted}\n")
+ endif()
+ endif()
+
+ set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
+endfunction()
+
+function(run_cmake_configure case)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${case}-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+ run_cmake(${case})
+endfunction()
+
+function(run_cmake_build case suffix config)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${case}-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ set(tgts)
+ foreach(tgt IN LISTS ARGN)
+ list(APPEND tgts --target ${tgt})
+ endforeach()
+ if(config)
+ set(config_arg --config ${config})
+ else()
+ set(config_arg)
+ endif()
+ run_cmake_command(${case}-${suffix}-build "${CMAKE_COMMAND}" --build . ${config_arg} ${tgts})
+endfunction()
+
+function(run_ninja case suffix file)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${case}-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ run_cmake_command(${case}-${suffix}-ninja "${RunCMake_MAKE_PROGRAM}" -f "${file}" ${ARGN})
+endfunction()
+
+###############################################################################
+
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Simple-build)
+# IMPORTANT: Setting RelWithDebInfo as the first item in CMAKE_CONFIGURATION_TYPES
+# generates a build.ninja file with that configuration
+set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=RelWithDebInfo\\;Debug\\;Release\\;MinSizeRel;-DCMAKE_CROSS_CONFIGS=all")
+run_cmake_configure(Simple)
+unset(RunCMake_TEST_OPTIONS)
+include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
+run_cmake_build(Simple debug-target Debug simpleexe)
+run_ninja(Simple debug-target build-Debug.ninja simplestatic)
+get_filename_component(simpleshared_Release "${TARGET_FILE_simpleshared_Release}" NAME)
+run_cmake_build(Simple release-filename Release ${simpleshared_Release})
+file(RELATIVE_PATH simpleexe_Release "${RunCMake_TEST_BINARY_DIR}" "${TARGET_FILE_simpleexe_Release}")
+run_ninja(Simple release-file build-Release.ninja ${simpleexe_Release})
+run_cmake_build(Simple all-configs Release simplestatic:all)
+run_ninja(Simple default-build-file build.ninja simpleexe)
+run_cmake_build(Simple all-clean Release clean:all)
+run_cmake_build(Simple debug-subdir Debug SimpleSubdir/all)
+run_ninja(Simple release-in-minsizerel-graph-subdir build-MinSizeRel.ninja SimpleSubdir/all:Release)
+run_cmake_build(Simple all-subdir Release SimpleSubdir/all:all)
+run_ninja(Simple minsizerel-top build-MinSizeRel.ninja all)
+run_cmake_build(Simple debug-in-release-graph-top Release all:Debug)
+run_ninja(Simple all-clean-again build-Debug.ninja clean:all)
+run_ninja(Simple all-top build-RelWithDebInfo.ninja all:all)
+# Leave enough time for the timestamp to change on second-resolution systems
+execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 1)
+file(TOUCH "${RunCMake_TEST_BINARY_DIR}/empty.cmake")
+run_ninja(Simple reconfigure-config build-Release.ninja simpleexe)
+execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 1)
+file(TOUCH "${RunCMake_TEST_BINARY_DIR}/empty.cmake")
+run_ninja(Simple reconfigure-noconfig build.ninja simpleexe)
+run_ninja(Simple default-build-file-clean build.ninja clean)
+run_ninja(Simple default-build-file-clean-minsizerel build.ninja clean:MinSizeRel)
+run_ninja(Simple default-build-file-all build.ninja all)
+
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SimpleDefaultBuildAlias-build)
+set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release\\;MinSizeRel\\;RelWithDebInfo;-DCMAKE_DEFAULT_BUILD_TYPE=Release;-DCMAKE_DEFAULT_CONFIGS=all;-DCMAKE_CROSS_CONFIGS=all")
+run_cmake_configure(SimpleDefaultBuildAlias)
+unset(RunCMake_TEST_OPTIONS)
+include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
+run_ninja(SimpleDefaultBuildAlias target build.ninja simpleexe)
+run_ninja(SimpleDefaultBuildAlias all build.ninja all)
+run_ninja(SimpleDefaultBuildAlias clean build.ninja clean)
+
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SimpleDefaultBuildAliasList-build)
+set(RunCMake_TEST_OPTIONS "-DCMAKE_DEFAULT_BUILD_TYPE=Release;-DCMAKE_DEFAULT_CONFIGS=Debug\\;Release;-DCMAKE_CROSS_CONFIGS=all")
+run_cmake_configure(SimpleDefaultBuildAliasList)
+unset(RunCMake_TEST_OPTIONS)
+include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
+run_ninja(SimpleDefaultBuildAliasList target-configs build.ninja simpleexe)
+# IMPORTANT: This tests cmake --build . with no config using build.ninja
+run_cmake_build(SimpleDefaultBuildAliasList all-configs "" all)
+run_ninja(SimpleDefaultBuildAliasList all-relwithdebinfo build.ninja all:RelWithDebInfo)
+run_ninja(SimpleDefaultBuildAliasList clean-configs build.ninja clean)
+
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SimpleDefaultBuildAliasListCross-build)
+set(RunCMake_TEST_OPTIONS "-DCMAKE_DEFAULT_BUILD_TYPE=RelWithDebInfo;-DCMAKE_DEFAULT_CONFIGS=all;-DCMAKE_CROSS_CONFIGS=Debug\\;Release")
+run_cmake_configure(SimpleDefaultBuildAliasListCross)
+unset(RunCMake_TEST_OPTIONS)
+include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
+run_ninja(SimpleDefaultBuildAliasListCross target-configs build.ninja simpleexe)
+
+unset(RunCMake_TEST_BINARY_DIR)
+
+set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release;-DCMAKE_CROSS_CONFIGS=Debug\\;Release\\;RelWithDebInfo")
+run_cmake(InvalidCrossConfigs)
+unset(RunCMake_TEST_OPTIONS)
+
+set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release;-DCMAKE_DEFAULT_BUILD_TYPE=RelWithDebInfo")
+run_cmake(InvalidDefaultBuildFileConfig)
+unset(RunCMake_TEST_OPTIONS)
+
+set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=Debug\\;Release;-DCMAKE_DEFAULT_BUILD_TYPE=Release;-DCMAKE_DEFAULT_CONFIGS=Debug\\;Release\\;RelWithDebInfo")
+run_cmake(InvalidDefaultConfigsCross)
+unset(RunCMake_TEST_OPTIONS)
+
+set(RunCMake_TEST_OPTIONS "-DCMAKE_DEFAULT_BUILD_TYPE=Release;-DCMAKE_DEFAULT_CONFIGS=all")
+run_cmake(InvalidDefaultConfigsNoCross)
+unset(RunCMake_TEST_OPTIONS)
+
+set(RunCMake_TEST_OPTIONS "-DCMAKE_DEFAULT_BUILD_TYPE=Release")
+run_cmake(DefaultBuildFileConfig)
+unset(RunCMake_TEST_OPTIONS)
+
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SimpleNoCross-build)
+run_cmake_configure(SimpleNoCross)
+include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
+run_cmake_build(SimpleNoCross debug-target Debug simpleexe)
+run_ninja(SimpleNoCross debug-target build-Debug.ninja simplestatic:Debug)
+run_ninja(SimpleNoCross relwithdebinfo-in-release-graph-target build-Release.ninja simplestatic:RelWithDebInfo)
+run_cmake_build(SimpleNoCross relwithdebinfo-in-release-graph-all Release all:RelWithDebInfo)
+run_cmake_build(SimpleNoCross relwithdebinfo-in-release-graph-clean Release clean:RelWithDebInfo)
+run_ninja(SimpleNoCross all-target build-Debug.ninja simplestatic:all)
+run_ninja(SimpleNoCross all-all build-Debug.ninja all:all)
+run_cmake_build(SimpleNoCross all-clean Debug clean:all)
+
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SimpleCrossConfigs-build)
+set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=Debug\\;Release")
+run_cmake_configure(SimpleCrossConfigs)
+include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
+run_ninja(SimpleCrossConfigs release-in-release-graph build-Release.ninja simpleexe)
+run_cmake_build(SimpleCrossConfigs debug-in-release-graph Release simpleexe:Debug)
+run_cmake_build(SimpleCrossConfigs relwithdebinfo-in-release-graph Release simpleexe:RelWithDebInfo)
+run_ninja(SimpleCrossConfigs relwithdebinfo-in-relwithdebinfo-graph build-RelWithDebInfo.ninja simpleexe:RelWithDebInfo)
+run_ninja(SimpleCrossConfigs release-in-relwithdebinfo-graph build-RelWithDebInfo.ninja simplestatic:Release)
+run_cmake_build(SimpleCrossConfigs all-in-relwithdebinfo-graph RelWithDebInfo simplestatic:all)
+run_ninja(SimpleCrossConfigs clean-all-in-release-graph build-Release.ninja clean:all)
+run_cmake_build(SimpleCrossConfigs all-all-in-release-graph Release all:all)
+run_cmake_build(SimpleCrossConfigs all-relwithdebinfo-in-release-graph Release all:RelWithDebInfo)
+
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Framework-build)
+set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=all")
+run_cmake_configure(Framework)
+unset(RunCMake_TEST_OPTIONS)
+include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
+run_cmake_build(Framework framework Debug all)
+
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/FrameworkDependencyAutogen-build)
+set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=all")
+run_cmake_configure(FrameworkDependencyAutogen)
+unset(RunCMake_TEST_OPTIONS)
+include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
+run_cmake_build(FrameworkDependencyAutogen framework Release test2:Debug)
+
+set(RunCMake_TEST_NO_CLEAN 1)
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CustomCommandGenerator-build)
+set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release\\;MinSizeRel\\;RelWithDebInfo;-DCMAKE_CROSS_CONFIGS=all")
+run_cmake_configure(CustomCommandGenerator)
+unset(RunCMake_TEST_OPTIONS)
+include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
+run_cmake_build(CustomCommandGenerator debug Debug generated)
+run_cmake_command(CustomCommandGenerator-debug-generated "${TARGET_FILE_generated_Debug}")
+run_ninja(CustomCommandGenerator release build-Release.ninja generated)
+run_cmake_command(CustomCommandGenerator-release-generated "${TARGET_FILE_generated_Release}")
+run_ninja(CustomCommandGenerator debug-clean build-Debug.ninja clean)
+run_cmake_build(CustomCommandGenerator release-clean Release clean)
+run_cmake_build(CustomCommandGenerator debug-in-release-graph Release generated:Debug)
+run_cmake_command(CustomCommandGenerator-debug-in-release-graph-generated "${TARGET_FILE_generated_Debug}")
+run_ninja(CustomCommandGenerator debug-in-release-graph-clean build-Debug.ninja clean:Debug)
+run_ninja(CustomCommandGenerator release-in-debug-graph build-Debug.ninja generated:Release)
+run_cmake_command(CustomCommandGenerator-release-in-debug-graph-generated "${TARGET_FILE_generated_Release}")
+unset(RunCMake_TEST_NO_CLEAN)
+
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CustomCommandsAndTargets-build)
+set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=all")
+run_cmake_configure(CustomCommandsAndTargets)
+unset(RunCMake_TEST_OPTIONS)
+include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
+run_cmake_build(CustomCommandsAndTargets release-command Release SubdirCommand)
+#FIXME Get this working
+#run_ninja(CustomCommandsAndTargets minsizerel-command build-MinSizeRel.ninja CustomCommandsAndTargetsSubdir/SubdirCommand)
+run_ninja(CustomCommandsAndTargets debug-command build-Debug.ninja TopCommand)
+run_ninja(CustomCommandsAndTargets release-target build-Release.ninja SubdirTarget)
+run_cmake_build(CustomCommandsAndTargets debug-target Debug TopTarget)
+run_cmake_build(CustomCommandsAndTargets debug-in-release-graph-postbuild Release SubdirPostBuild:Debug)
+run_ninja(CustomCommandsAndTargets release-postbuild build-Release.ninja SubdirPostBuild)
+run_cmake_build(CustomCommandsAndTargets debug-targetpostbuild Debug TopTargetPostBuild)
+run_ninja(CustomCommandsAndTargets release-targetpostbuild build-Release.ninja SubdirTargetPostBuild)
+
+unset(RunCMake_TEST_BINARY_DIR)
+
+run_cmake(CustomCommandDepfile)
+
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/PostfixAndLocation-build)
+set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release;-DCMAKE_CROSS_CONFIGS=all")
+run_cmake_configure(PostfixAndLocation)
+unset(RunCMake_TEST_OPTIONS)
+include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
+run_cmake_build(PostfixAndLocation release-in-release-graph Release mylib:Release)
+run_cmake_build(PostfixAndLocation debug-in-release-graph Release mylib:Debug)
+
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Clean-build)
+run_cmake_configure(Clean)
+include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
+run_cmake_build(Clean release Release)
+run_ninja(Clean release-notall build-Release.ninja exenotall)
+run_cmake_build(Clean release-clean Release clean)
+
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/AdditionalCleanFiles-build)
+set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release\\;MinSizeRel\\;RelWithDebInfo;-DCMAKE_CROSS_CONFIGS=all")
+run_cmake_configure(AdditionalCleanFiles)
+unset(RunCMake_TEST_OPTIONS)
+run_cmake_build(AdditionalCleanFiles release-clean Release clean)
+run_ninja(AdditionalCleanFiles all-clean build-Debug.ninja clean:all)
+
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Install-build)
+set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_TEST_BINARY_DIR}/install;-DCMAKE_CROSS_CONFIGS=all")
+run_cmake_configure(Install)
+unset(RunCMake_TEST_OPTIONS)
+include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
+run_cmake_build(Install release-install Release install)
+run_ninja(Install debug-in-release-graph-install build-Release.ninja install:Debug)
+
+# FIXME Get this working
+#set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/AutoMocExecutable-build)
+#run_cmake_configure(AutoMocExecutable)
+#run_cmake_build(AutoMocExecutable debug-in-release-graph Release exe)
+
+# Need to test this manually because run_cmake() adds --no-warn-unused-cli
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/NoUnusedVariables-build)
+run_cmake_command(NoUnusedVariables ${CMAKE_COMMAND} ${CMAKE_CURRENT_LIST_DIR}
+ -G "Ninja Multi-Config"
+ "-DRunCMake_TEST=NoUnusedVariables"
+ "-DCMAKE_CROSS_CONFIGS=all"
+ "-DCMAKE_DEFAULT_BUILD_TYPE=Debug"
+ "-DCMAKE_DEFAULT_CONFIGS=all"
+ )
+
+if(CMake_TEST_CUDA)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CudaSimple-build)
+ run_cmake_configure(CudaSimple)
+ include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
+ run_cmake_build(CudaSimple debug-target Debug simplecudaexe)
+ run_ninja(CudaSimple all-clean build-Debug.ninja clean:Debug)
+endif()
+
+if(CMake_TEST_Qt5)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Qt5-build)
+ set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=all")
+ run_cmake_configure(Qt5)
+ unset(RunCMake_TEST_OPTIONS)
+ include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
+ run_cmake_build(Qt5 debug-in-release-graph Release exe:Debug)
+endif()
diff --git a/Tests/RunCMake/NinjaMultiConfig/Simple-all-clean-again-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/Simple-all-clean-again-ninja-check.cmake
new file mode 100644
index 0000000..0f919df
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Simple-all-clean-again-ninja-check.cmake
@@ -0,0 +1,25 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/Simple-all-clean-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/Simple-all-clean-build-check.cmake
new file mode 100644
index 0000000..0f919df
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Simple-all-clean-build-check.cmake
@@ -0,0 +1,25 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/Simple-all-configs-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/Simple-all-configs-build-check.cmake
new file mode 100644
index 0000000..170a0e8
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Simple-all-configs-build-check.cmake
@@ -0,0 +1,47 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+ ${TARGET_FILE_simpleshared_Debug}
+ ${TARGET_LINKER_FILE_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+ ${TARGET_FILE_simplestatic_Debug}
+ ${TARGET_LINKER_FILE_simplestatic_Debug}
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ ${TARGET_FILE_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+
+ ${TARGET_FILE_simpleshared_Release}
+ ${TARGET_LINKER_FILE_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+
+ ${TARGET_FILE_simplestatic_Release}
+ ${TARGET_LINKER_FILE_simplestatic_Release}
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ ${TARGET_FILE_simplestatic_MinSizeRel}
+ ${TARGET_LINKER_FILE_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+
+ ${TARGET_FILE_simplestatic_RelWithDebInfo}
+ ${TARGET_LINKER_FILE_simplestatic_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/Simple-all-subdir-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/Simple-all-subdir-build-check.cmake
new file mode 100644
index 0000000..de4505c
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Simple-all-subdir-build-check.cmake
@@ -0,0 +1,49 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+ ${TARGET_FILE_simpleshared_Debug}
+ ${TARGET_LINKER_FILE_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ ${TARGET_FILE_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+
+ ${TARGET_FILE_simpleshared_Release}
+ ${TARGET_LINKER_FILE_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ ${TARGET_FILE_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+
+ ${TARGET_FILE_simpleshared_MinSizeRel}
+ ${TARGET_LINKER_FILE_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+ ${TARGET_FILE_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+
+ ${TARGET_FILE_simpleshared_RelWithDebInfo}
+ ${TARGET_LINKER_FILE_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/Simple-all-top-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/Simple-all-top-ninja-check.cmake
new file mode 100644
index 0000000..c171e3d
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Simple-all-top-ninja-check.cmake
@@ -0,0 +1,56 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+ ${TARGET_FILE_simpleshared_Debug}
+ ${TARGET_LINKER_FILE_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+ ${TARGET_FILE_simplestatic_Debug}
+ ${TARGET_LINKER_FILE_simplestatic_Debug}
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ ${TARGET_FILE_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+
+ ${TARGET_FILE_simpleshared_Release}
+ ${TARGET_LINKER_FILE_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+
+ ${TARGET_FILE_simplestatic_Release}
+ ${TARGET_LINKER_FILE_simplestatic_Release}
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ ${TARGET_FILE_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+
+ ${TARGET_FILE_simpleshared_MinSizeRel}
+ ${TARGET_LINKER_FILE_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+
+ ${TARGET_FILE_simplestatic_MinSizeRel}
+ ${TARGET_LINKER_FILE_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+ ${TARGET_FILE_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+
+ ${TARGET_FILE_simpleshared_RelWithDebInfo}
+ ${TARGET_LINKER_FILE_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+
+ ${TARGET_FILE_simplestatic_RelWithDebInfo}
+ ${TARGET_LINKER_FILE_simplestatic_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/Simple-debug-in-release-graph-top-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/Simple-debug-in-release-graph-top-build-check.cmake
new file mode 100644
index 0000000..fe980fe
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Simple-debug-in-release-graph-top-build-check.cmake
@@ -0,0 +1,53 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+ ${TARGET_FILE_simpleshared_Debug}
+ ${TARGET_LINKER_FILE_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+ ${TARGET_FILE_simplestatic_Debug}
+ ${TARGET_LINKER_FILE_simplestatic_Debug}
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ ${TARGET_FILE_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+
+ ${TARGET_FILE_simpleshared_Release}
+ ${TARGET_LINKER_FILE_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ ${TARGET_FILE_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+
+ ${TARGET_FILE_simpleshared_MinSizeRel}
+ ${TARGET_LINKER_FILE_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+
+ ${TARGET_FILE_simplestatic_MinSizeRel}
+ ${TARGET_LINKER_FILE_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+ ${TARGET_FILE_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+
+ ${TARGET_FILE_simpleshared_RelWithDebInfo}
+ ${TARGET_LINKER_FILE_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/Simple-debug-subdir-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/Simple-debug-subdir-build-check.cmake
new file mode 100644
index 0000000..6bb7773
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Simple-debug-subdir-build-check.cmake
@@ -0,0 +1,31 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+ ${TARGET_FILE_simpleshared_Debug}
+ ${TARGET_LINKER_FILE_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/Simple-debug-target-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/Simple-debug-target-build-check.cmake
new file mode 100644
index 0000000..6bb7773
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Simple-debug-target-build-check.cmake
@@ -0,0 +1,31 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+ ${TARGET_FILE_simpleshared_Debug}
+ ${TARGET_LINKER_FILE_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/Simple-debug-target-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/Simple-debug-target-ninja-check.cmake
new file mode 100644
index 0000000..f9c1e92
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Simple-debug-target-ninja-check.cmake
@@ -0,0 +1,33 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+ ${TARGET_FILE_simpleshared_Debug}
+ ${TARGET_LINKER_FILE_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+ ${TARGET_FILE_simplestatic_Debug}
+ ${TARGET_LINKER_FILE_simplestatic_Debug}
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/Simple-default-build-file-all-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/Simple-default-build-file-all-ninja-check.cmake
new file mode 100644
index 0000000..4e6e654
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Simple-default-build-file-all-ninja-check.cmake
@@ -0,0 +1,49 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+ ${TARGET_FILE_simpleshared_Debug}
+ ${TARGET_LINKER_FILE_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+ ${TARGET_FILE_simplestatic_Debug}
+ ${TARGET_LINKER_FILE_simplestatic_Debug}
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ ${TARGET_FILE_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+
+ ${TARGET_FILE_simpleshared_Release}
+ ${TARGET_LINKER_FILE_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+
+ ${TARGET_FILE_simplestatic_Release}
+ ${TARGET_LINKER_FILE_simplestatic_Release}
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ ${TARGET_FILE_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+
+ ${TARGET_FILE_simpleshared_RelWithDebInfo}
+ ${TARGET_LINKER_FILE_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+
+ ${TARGET_FILE_simplestatic_RelWithDebInfo}
+ ${TARGET_LINKER_FILE_simplestatic_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/Simple-default-build-file-clean-minsizerel-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/Simple-default-build-file-clean-minsizerel-ninja-check.cmake
new file mode 100644
index 0000000..c09ae65
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Simple-default-build-file-clean-minsizerel-ninja-check.cmake
@@ -0,0 +1,41 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+ ${TARGET_FILE_simpleshared_Debug}
+ ${TARGET_LINKER_FILE_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+ ${TARGET_FILE_simplestatic_Debug}
+ ${TARGET_LINKER_FILE_simplestatic_Debug}
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ ${TARGET_FILE_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+
+ ${TARGET_FILE_simpleshared_Release}
+ ${TARGET_LINKER_FILE_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+
+ ${TARGET_FILE_simplestatic_Release}
+ ${TARGET_LINKER_FILE_simplestatic_Release}
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/Simple-default-build-file-clean-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/Simple-default-build-file-clean-ninja-check.cmake
new file mode 100644
index 0000000..43213dd
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Simple-default-build-file-clean-ninja-check.cmake
@@ -0,0 +1,49 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+ ${TARGET_FILE_simpleshared_Debug}
+ ${TARGET_LINKER_FILE_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+ ${TARGET_FILE_simplestatic_Debug}
+ ${TARGET_LINKER_FILE_simplestatic_Debug}
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ ${TARGET_FILE_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+
+ ${TARGET_FILE_simpleshared_Release}
+ ${TARGET_LINKER_FILE_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+
+ ${TARGET_FILE_simplestatic_Release}
+ ${TARGET_LINKER_FILE_simplestatic_Release}
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ ${TARGET_FILE_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+
+ ${TARGET_FILE_simpleshared_MinSizeRel}
+ ${TARGET_LINKER_FILE_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+
+ ${TARGET_FILE_simplestatic_MinSizeRel}
+ ${TARGET_LINKER_FILE_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/Simple-default-build-file-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/Simple-default-build-file-ninja-check.cmake
new file mode 100644
index 0000000..dae1f4d
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Simple-default-build-file-ninja-check.cmake
@@ -0,0 +1,51 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+ ${TARGET_FILE_simpleshared_Debug}
+ ${TARGET_LINKER_FILE_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+ ${TARGET_FILE_simplestatic_Debug}
+ ${TARGET_LINKER_FILE_simplestatic_Debug}
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ ${TARGET_FILE_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+
+ ${TARGET_FILE_simpleshared_Release}
+ ${TARGET_LINKER_FILE_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+
+ ${TARGET_FILE_simplestatic_Release}
+ ${TARGET_LINKER_FILE_simplestatic_Release}
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ ${TARGET_FILE_simplestatic_MinSizeRel}
+ ${TARGET_LINKER_FILE_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+
+ ${TARGET_FILE_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+
+ ${TARGET_FILE_simpleshared_RelWithDebInfo}
+ ${TARGET_LINKER_FILE_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+
+ ${TARGET_FILE_simplestatic_RelWithDebInfo}
+ ${TARGET_LINKER_FILE_simplestatic_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/Simple-minsizerel-top-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/Simple-minsizerel-top-ninja-check.cmake
new file mode 100644
index 0000000..bf4be49
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Simple-minsizerel-top-ninja-check.cmake
@@ -0,0 +1,51 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+ ${TARGET_FILE_simpleshared_Debug}
+ ${TARGET_LINKER_FILE_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ ${TARGET_FILE_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+
+ ${TARGET_FILE_simpleshared_Release}
+ ${TARGET_LINKER_FILE_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ ${TARGET_FILE_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+
+ ${TARGET_FILE_simpleshared_MinSizeRel}
+ ${TARGET_LINKER_FILE_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+
+ ${TARGET_FILE_simplestatic_MinSizeRel}
+ ${TARGET_LINKER_FILE_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+ ${TARGET_FILE_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+
+ ${TARGET_FILE_simpleshared_RelWithDebInfo}
+ ${TARGET_LINKER_FILE_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/Simple-reconfigure-config-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/Simple-reconfigure-config-ninja-stdout.txt
new file mode 100644
index 0000000..8877451
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Simple-reconfigure-config-ninja-stdout.txt
@@ -0,0 +1,4 @@
+-- Configuring done
+-- Generating done
+-- Build files have been written to: [^
+]*/Tests/RunCMake/NinjaMultiConfig/Simple-build
diff --git a/Tests/RunCMake/NinjaMultiConfig/Simple-reconfigure-noconfig-ninja-stdout.txt b/Tests/RunCMake/NinjaMultiConfig/Simple-reconfigure-noconfig-ninja-stdout.txt
new file mode 100644
index 0000000..8877451
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Simple-reconfigure-noconfig-ninja-stdout.txt
@@ -0,0 +1,4 @@
+-- Configuring done
+-- Generating done
+-- Build files have been written to: [^
+]*/Tests/RunCMake/NinjaMultiConfig/Simple-build
diff --git a/Tests/RunCMake/NinjaMultiConfig/Simple-release-file-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/Simple-release-file-ninja-check.cmake
new file mode 100644
index 0000000..6e63aae
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Simple-release-file-ninja-check.cmake
@@ -0,0 +1,39 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+ ${TARGET_FILE_simpleshared_Debug}
+ ${TARGET_LINKER_FILE_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+ ${TARGET_FILE_simplestatic_Debug}
+ ${TARGET_LINKER_FILE_simplestatic_Debug}
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ ${TARGET_FILE_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+
+ ${TARGET_FILE_simpleshared_Release}
+ ${TARGET_LINKER_FILE_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/Simple-release-filename-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/Simple-release-filename-build-check.cmake
new file mode 100644
index 0000000..a9bf42c
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Simple-release-filename-build-check.cmake
@@ -0,0 +1,36 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+ ${TARGET_FILE_simpleshared_Debug}
+ ${TARGET_LINKER_FILE_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+ ${TARGET_FILE_simplestatic_Debug}
+ ${TARGET_LINKER_FILE_simplestatic_Debug}
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ ${TARGET_FILE_simpleshared_Release}
+ ${TARGET_LINKER_FILE_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/Simple-release-in-minsizerel-graph-subdir-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/Simple-release-in-minsizerel-graph-subdir-ninja-check.cmake
new file mode 100644
index 0000000..b6c77ab
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Simple-release-in-minsizerel-graph-subdir-ninja-check.cmake
@@ -0,0 +1,37 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+ ${TARGET_FILE_simpleshared_Debug}
+ ${TARGET_LINKER_FILE_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ ${TARGET_FILE_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+
+ ${TARGET_FILE_simpleshared_Release}
+ ${TARGET_LINKER_FILE_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/Simple.cmake b/Tests/RunCMake/NinjaMultiConfig/Simple.cmake
new file mode 100644
index 0000000..a32f551
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/Simple.cmake
@@ -0,0 +1,13 @@
+enable_language(C)
+
+file(TOUCH ${CMAKE_BINARY_DIR}/empty.cmake)
+include(${CMAKE_BINARY_DIR}/empty.cmake)
+
+add_subdirectory(SimpleSubdir)
+
+add_library(simplestatic STATIC simplelib.c)
+
+include(${CMAKE_CURRENT_LIST_DIR}/Common.cmake)
+generate_output_files(simpleexe simpleshared simplestatic simpleobj)
+
+file(APPEND "${CMAKE_BINARY_DIR}/target_files.cmake" "set(GENERATED_FILES [==[${CMAKE_BINARY_DIR}/empty.cmake]==])\n")
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-all-all-in-release-graph-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-all-all-in-release-graph-build-check.cmake
new file mode 100644
index 0000000..fee5951
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-all-all-in-release-graph-build-check.cmake
@@ -0,0 +1,45 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+ ${TARGET_FILE_simpleshared_Debug}
+ ${TARGET_LINKER_FILE_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+ ${TARGET_FILE_simplestatic_Debug}
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ ${TARGET_FILE_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+
+ ${TARGET_FILE_simpleshared_Release}
+ ${TARGET_LINKER_FILE_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+
+ ${TARGET_FILE_simplestatic_Release}
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ ${TARGET_FILE_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+
+ ${TARGET_FILE_simpleshared_RelWithDebInfo}
+ ${TARGET_LINKER_FILE_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-all-in-relwithdebinfo-graph-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-all-in-relwithdebinfo-graph-build-check.cmake
new file mode 100644
index 0000000..fee5951
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-all-in-relwithdebinfo-graph-build-check.cmake
@@ -0,0 +1,45 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+ ${TARGET_FILE_simpleshared_Debug}
+ ${TARGET_LINKER_FILE_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+ ${TARGET_FILE_simplestatic_Debug}
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ ${TARGET_FILE_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+
+ ${TARGET_FILE_simpleshared_Release}
+ ${TARGET_LINKER_FILE_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+
+ ${TARGET_FILE_simplestatic_Release}
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ ${TARGET_FILE_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+
+ ${TARGET_FILE_simpleshared_RelWithDebInfo}
+ ${TARGET_LINKER_FILE_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-all-relwithdebinfo-in-release-graph-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-all-relwithdebinfo-in-release-graph-build-check.cmake
new file mode 100644
index 0000000..fee5951
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-all-relwithdebinfo-in-release-graph-build-check.cmake
@@ -0,0 +1,45 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+ ${TARGET_FILE_simpleshared_Debug}
+ ${TARGET_LINKER_FILE_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+ ${TARGET_FILE_simplestatic_Debug}
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ ${TARGET_FILE_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+
+ ${TARGET_FILE_simpleshared_Release}
+ ${TARGET_LINKER_FILE_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+
+ ${TARGET_FILE_simplestatic_Release}
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ ${TARGET_FILE_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+
+ ${TARGET_FILE_simpleshared_RelWithDebInfo}
+ ${TARGET_LINKER_FILE_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-all-relwithdebinfo-in-release-graph-build-result.txt b/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-all-relwithdebinfo-in-release-graph-build-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-all-relwithdebinfo-in-release-graph-build-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-all-relwithdebinfo-in-release-graph-build-stderr.txt b/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-all-relwithdebinfo-in-release-graph-build-stderr.txt
new file mode 100644
index 0000000..fa8b462
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-all-relwithdebinfo-in-release-graph-build-stderr.txt
@@ -0,0 +1 @@
+^ninja: error: unknown target 'all:RelWithDebInfo'$
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-clean-all-in-release-graph-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-clean-all-in-release-graph-ninja-check.cmake
new file mode 100644
index 0000000..6c94369
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-clean-all-in-release-graph-ninja-check.cmake
@@ -0,0 +1,31 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+
+ ${TARGET_FILE_simpleshared_RelWithDebInfo}
+ ${TARGET_LINKER_FILE_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-debug-in-release-graph-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-debug-in-release-graph-build-check.cmake
new file mode 100644
index 0000000..b6c77ab
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-debug-in-release-graph-build-check.cmake
@@ -0,0 +1,37 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+ ${TARGET_FILE_simpleshared_Debug}
+ ${TARGET_LINKER_FILE_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ ${TARGET_FILE_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+
+ ${TARGET_FILE_simpleshared_Release}
+ ${TARGET_LINKER_FILE_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-release-in-release-graph-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-release-in-release-graph-ninja-check.cmake
new file mode 100644
index 0000000..d8b5218
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-release-in-release-graph-ninja-check.cmake
@@ -0,0 +1,31 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+
+ ${TARGET_FILE_simpleshared_Release}
+ ${TARGET_LINKER_FILE_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-release-in-relwithdebinfo-graph-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-release-in-relwithdebinfo-graph-ninja-check.cmake
new file mode 100644
index 0000000..1a37aa3
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-release-in-relwithdebinfo-graph-ninja-check.cmake
@@ -0,0 +1,44 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+ ${TARGET_FILE_simpleshared_Debug}
+ ${TARGET_LINKER_FILE_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ ${TARGET_FILE_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+
+ ${TARGET_FILE_simpleshared_Release}
+ ${TARGET_LINKER_FILE_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+
+ ${TARGET_FILE_simplestatic_Release}
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ ${TARGET_FILE_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+
+ ${TARGET_FILE_simpleshared_RelWithDebInfo}
+ ${TARGET_LINKER_FILE_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-relwithdebinfo-in-release-graph-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-relwithdebinfo-in-release-graph-build-check.cmake
new file mode 100644
index 0000000..b6c77ab
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-relwithdebinfo-in-release-graph-build-check.cmake
@@ -0,0 +1,37 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+ ${TARGET_FILE_simpleshared_Debug}
+ ${TARGET_LINKER_FILE_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ ${TARGET_FILE_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+
+ ${TARGET_FILE_simpleshared_Release}
+ ${TARGET_LINKER_FILE_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-relwithdebinfo-in-release-graph-build-result.txt b/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-relwithdebinfo-in-release-graph-build-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-relwithdebinfo-in-release-graph-build-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-relwithdebinfo-in-release-graph-build-stderr.txt b/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-relwithdebinfo-in-release-graph-build-stderr.txt
new file mode 100644
index 0000000..f3a825c
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-relwithdebinfo-in-release-graph-build-stderr.txt
@@ -0,0 +1 @@
+^ninja: error: unknown target 'simpleexe:RelWithDebInfo'$
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-relwithdebinfo-in-relwithdebinfo-graph-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-relwithdebinfo-in-relwithdebinfo-graph-ninja-check.cmake
new file mode 100644
index 0000000..7eddb2f
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs-relwithdebinfo-in-relwithdebinfo-graph-ninja-check.cmake
@@ -0,0 +1,43 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+ ${TARGET_FILE_simpleshared_Debug}
+ ${TARGET_LINKER_FILE_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ ${TARGET_FILE_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+
+ ${TARGET_FILE_simpleshared_Release}
+ ${TARGET_LINKER_FILE_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ ${TARGET_FILE_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+
+ ${TARGET_FILE_simpleshared_RelWithDebInfo}
+ ${TARGET_LINKER_FILE_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs.cmake b/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs.cmake
new file mode 100644
index 0000000..2a5b708
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleCrossConfigs.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/Simple.cmake")
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAlias-all-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAlias-all-ninja-check.cmake
new file mode 100644
index 0000000..c171e3d
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAlias-all-ninja-check.cmake
@@ -0,0 +1,56 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+ ${TARGET_FILE_simpleshared_Debug}
+ ${TARGET_LINKER_FILE_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+ ${TARGET_FILE_simplestatic_Debug}
+ ${TARGET_LINKER_FILE_simplestatic_Debug}
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ ${TARGET_FILE_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+
+ ${TARGET_FILE_simpleshared_Release}
+ ${TARGET_LINKER_FILE_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+
+ ${TARGET_FILE_simplestatic_Release}
+ ${TARGET_LINKER_FILE_simplestatic_Release}
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ ${TARGET_FILE_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+
+ ${TARGET_FILE_simpleshared_MinSizeRel}
+ ${TARGET_LINKER_FILE_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+
+ ${TARGET_FILE_simplestatic_MinSizeRel}
+ ${TARGET_LINKER_FILE_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+ ${TARGET_FILE_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+
+ ${TARGET_FILE_simpleshared_RelWithDebInfo}
+ ${TARGET_LINKER_FILE_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+
+ ${TARGET_FILE_simplestatic_RelWithDebInfo}
+ ${TARGET_LINKER_FILE_simplestatic_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAlias-clean-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAlias-clean-ninja-check.cmake
new file mode 100644
index 0000000..0f919df
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAlias-clean-ninja-check.cmake
@@ -0,0 +1,25 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAlias-target-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAlias-target-ninja-check.cmake
new file mode 100644
index 0000000..de4505c
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAlias-target-ninja-check.cmake
@@ -0,0 +1,49 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+ ${TARGET_FILE_simpleshared_Debug}
+ ${TARGET_LINKER_FILE_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ ${TARGET_FILE_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+
+ ${TARGET_FILE_simpleshared_Release}
+ ${TARGET_LINKER_FILE_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ ${TARGET_FILE_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+
+ ${TARGET_FILE_simpleshared_MinSizeRel}
+ ${TARGET_LINKER_FILE_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+ ${TARGET_FILE_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+
+ ${TARGET_FILE_simpleshared_RelWithDebInfo}
+ ${TARGET_LINKER_FILE_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAlias.cmake b/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAlias.cmake
new file mode 100644
index 0000000..2a5b708
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAlias.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/Simple.cmake")
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAliasList-all-configs-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAliasList-all-configs-build-check.cmake
new file mode 100644
index 0000000..8ffdd20
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAliasList-all-configs-build-check.cmake
@@ -0,0 +1,39 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+ ${TARGET_FILE_simpleshared_Debug}
+ ${TARGET_LINKER_FILE_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+ ${TARGET_FILE_simplestatic_Debug}
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ ${TARGET_FILE_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+
+ ${TARGET_FILE_simpleshared_Release}
+ ${TARGET_LINKER_FILE_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+
+ ${TARGET_FILE_simplestatic_Release}
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAliasList-all-relwithdebinfo-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAliasList-all-relwithdebinfo-ninja-check.cmake
new file mode 100644
index 0000000..9e5baf9
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAliasList-all-relwithdebinfo-ninja-check.cmake
@@ -0,0 +1,46 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+ ${TARGET_FILE_simpleshared_Debug}
+ ${TARGET_LINKER_FILE_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+ ${TARGET_FILE_simplestatic_Debug}
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ ${TARGET_FILE_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+
+ ${TARGET_FILE_simpleshared_Release}
+ ${TARGET_LINKER_FILE_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+
+ ${TARGET_FILE_simplestatic_Release}
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ ${TARGET_FILE_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+
+ ${TARGET_FILE_simpleshared_RelWithDebInfo}
+ ${TARGET_LINKER_FILE_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+
+ ${TARGET_FILE_simplestatic_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAliasList-clean-configs-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAliasList-clean-configs-ninja-check.cmake
new file mode 100644
index 0000000..3829d3e
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAliasList-clean-configs-ninja-check.cmake
@@ -0,0 +1,32 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+
+ ${TARGET_FILE_simpleshared_RelWithDebInfo}
+ ${TARGET_LINKER_FILE_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+
+ ${TARGET_FILE_simplestatic_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAliasList-target-configs-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAliasList-target-configs-ninja-check.cmake
new file mode 100644
index 0000000..b6c77ab
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAliasList-target-configs-ninja-check.cmake
@@ -0,0 +1,37 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+ ${TARGET_FILE_simpleshared_Debug}
+ ${TARGET_LINKER_FILE_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ ${TARGET_FILE_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+
+ ${TARGET_FILE_simpleshared_Release}
+ ${TARGET_LINKER_FILE_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAliasList.cmake b/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAliasList.cmake
new file mode 100644
index 0000000..2a5b708
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAliasList.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/Simple.cmake")
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAliasListCross-target-configs-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAliasListCross-target-configs-ninja-check.cmake
new file mode 100644
index 0000000..b6c77ab
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAliasListCross-target-configs-ninja-check.cmake
@@ -0,0 +1,37 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+ ${TARGET_FILE_simpleshared_Debug}
+ ${TARGET_LINKER_FILE_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ ${TARGET_FILE_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+
+ ${TARGET_FILE_simpleshared_Release}
+ ${TARGET_LINKER_FILE_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAliasListCross.cmake b/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAliasListCross.cmake
new file mode 100644
index 0000000..2a5b708
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleDefaultBuildAliasListCross.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/Simple.cmake")
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-all-ninja-result.txt b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-all-ninja-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-all-ninja-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-all-ninja-stderr.txt b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-all-ninja-stderr.txt
new file mode 100644
index 0000000..905a355
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-all-ninja-stderr.txt
@@ -0,0 +1 @@
+^ninja: error: unknown target 'all:all'$
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-clean-build-result.txt b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-clean-build-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-clean-build-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-clean-build-stderr.txt b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-clean-build-stderr.txt
new file mode 100644
index 0000000..43528de
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-clean-build-stderr.txt
@@ -0,0 +1 @@
+^ninja: error: unknown target 'clean:all'$
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-target-ninja-result.txt b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-target-ninja-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-target-ninja-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-target-ninja-stderr.txt b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-target-ninja-stderr.txt
new file mode 100644
index 0000000..6db4bcc
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-all-target-ninja-stderr.txt
@@ -0,0 +1 @@
+^ninja: error: unknown target 'simplestatic:all'$
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-debug-target-build-check.cmake b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-debug-target-build-check.cmake
new file mode 100644
index 0000000..6bb7773
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-debug-target-build-check.cmake
@@ -0,0 +1,31 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+ ${TARGET_FILE_simpleshared_Debug}
+ ${TARGET_LINKER_FILE_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-debug-target-ninja-check.cmake b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-debug-target-ninja-check.cmake
new file mode 100644
index 0000000..c8a735a
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-debug-target-ninja-check.cmake
@@ -0,0 +1,32 @@
+check_files("${RunCMake_TEST_BINARY_DIR}"
+ INCLUDE
+ ${GENERATED_FILES}
+
+ ${TARGET_FILE_simpleexe_Debug}
+ ${TARGET_OBJECT_FILES_simpleexe_Debug}
+
+ ${TARGET_FILE_simpleshared_Debug}
+ ${TARGET_LINKER_FILE_simpleshared_Debug}
+ ${TARGET_OBJECT_FILES_simpleshared_Debug}
+
+ ${TARGET_FILE_simplestatic_Debug}
+ ${TARGET_OBJECT_FILES_simplestatic_Debug}
+
+ ${TARGET_OBJECT_FILES_simpleobj_Debug}
+
+ EXCLUDE
+ ${TARGET_OBJECT_FILES_simpleexe_Release}
+ ${TARGET_OBJECT_FILES_simpleshared_Release}
+ ${TARGET_OBJECT_FILES_simplestatic_Release}
+ ${TARGET_OBJECT_FILES_simpleobj_Release}
+
+ ${TARGET_OBJECT_FILES_simpleexe_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleshared_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simplestatic_MinSizeRel}
+ ${TARGET_OBJECT_FILES_simpleobj_MinSizeRel}
+
+ ${TARGET_OBJECT_FILES_simpleexe_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleshared_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simplestatic_RelWithDebInfo}
+ ${TARGET_OBJECT_FILES_simpleobj_RelWithDebInfo}
+ )
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-all-build-result.txt b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-all-build-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-all-build-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-all-build-stderr.txt b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-all-build-stderr.txt
new file mode 100644
index 0000000..fa8b462
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-all-build-stderr.txt
@@ -0,0 +1 @@
+^ninja: error: unknown target 'all:RelWithDebInfo'$
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-clean-build-result.txt b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-clean-build-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-clean-build-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-clean-build-stderr.txt b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-clean-build-stderr.txt
new file mode 100644
index 0000000..70eef2f
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-clean-build-stderr.txt
@@ -0,0 +1 @@
+^ninja: error: unknown target 'clean:RelWithDebInfo'$
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-target-ninja-result.txt b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-target-ninja-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-target-ninja-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-target-ninja-stderr.txt b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-target-ninja-stderr.txt
new file mode 100644
index 0000000..1a1fe9e
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross-relwithdebinfo-in-release-graph-target-ninja-stderr.txt
@@ -0,0 +1 @@
+^ninja: error: unknown target 'simplestatic:RelWithDebInfo'$
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross.cmake b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross.cmake
new file mode 100644
index 0000000..2a5b708
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleNoCross.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/Simple.cmake")
diff --git a/Tests/RunCMake/NinjaMultiConfig/SimpleSubdir/CMakeLists.txt b/Tests/RunCMake/NinjaMultiConfig/SimpleSubdir/CMakeLists.txt
new file mode 100644
index 0000000..7e754a3
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/SimpleSubdir/CMakeLists.txt
@@ -0,0 +1,4 @@
+add_library(simpleobj OBJECT ../empty.c)
+add_executable(simpleexe ../main.c $<TARGET_OBJECTS:simpleobj>)
+add_library(simpleshared SHARED ../simplelib.c)
+target_link_libraries(simpleexe PRIVATE simpleshared)
diff --git a/Tests/RunCMake/NinjaMultiConfig/WriteFile.cmake b/Tests/RunCMake/NinjaMultiConfig/WriteFile.cmake
new file mode 100644
index 0000000..82681a2
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/WriteFile.cmake
@@ -0,0 +1 @@
+file(WRITE "${OUTPUT_FILE}" "Genex config: ${GENEX_CONFIG}\nINTDIR config: ${INTDIR_CONFIG}\n")
diff --git a/Tests/RunCMake/NinjaMultiConfig/badmoc.c b/Tests/RunCMake/NinjaMultiConfig/badmoc.c
new file mode 100644
index 0000000..aec8dc3
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/badmoc.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main(void)
+{
+ printf("BadMoc Configuration: " CONFIG "\n");
+ return 1;
+}
diff --git a/Tests/RunCMake/NinjaMultiConfig/empty.c b/Tests/RunCMake/NinjaMultiConfig/empty.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/empty.c
diff --git a/Tests/RunCMake/NinjaMultiConfig/generator.c b/Tests/RunCMake/NinjaMultiConfig/generator.c
new file mode 100644
index 0000000..465ee2f
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/generator.c
@@ -0,0 +1,101 @@
+#include <genex_config.h>
+#include <stdio.h>
+/* FIXME Get this working */
+/*#include <intdir_config.h>*/
+
+const char* generatorlib_genex_config_definition(void);
+const char* generatorlib_genex_config_include_dir(void);
+const char* generatorobj_genex_config_definition(void);
+const char* generatorobj_genex_config_include_dir(void);
+
+static const char contents[] =
+ /* clang-format off */
+"#include <stdio.h>\n"
+"\n"
+"#include <genex_config.h>\n"
+/* FIXME Get this working */
+/*"#include <intdir_config.h>\n"*/
+"\n"
+"const char* generatorlib_genex_config_definition(void);\n"
+"const char* generatorlib_genex_config_include_dir(void);\n"
+"const char* generatorobj_genex_config_definition(void);\n"
+"const char* generatorobj_genex_config_include_dir(void);\n"
+"\n"
+"int main(void)\n"
+"{\n"
+" printf(\n"
+" \"Generator genex config definition: "
+ GENEX_CONFIG_DEFINITION "\\n\"\n"
+/* FIXME Get this working */
+/*" \"Generator INTDIR config definition: "
+ INTDIR_CONFIG_DEFINITION "\\n\"\n"*/
+" \"Generator genex config include dir: "
+ GENEX_CONFIG_INCLUDE_DIR "\\n\"\n"
+/* FIXME Get this working */
+/*" \"Generator INTDIR config include dir: "
+ INTDIR_CONFIG_INCLUDE_DIR "\\n\"\n"*/
+" \"Generator library genex config definition: %s\\n\"\n"
+/* FIXME Get this working */
+/*" \"Generator library INTDIR config definition: %s\\n\"\n"*/
+" \"Generator library genex config include dir: %s\\n\"\n"
+/* FIXME Get this working */
+/*" \"Generator library INTDIR config include dir: %s\\n\"\n"*/
+" \"Generator object genex config definition: %s\\n\"\n"
+/* FIXME Get this working */
+/*" \"Generator object INTDIR config definition: %s\\n\"\n"*/
+" \"Generator object genex config include dir: %s\\n\"\n"
+/* FIXME Get this working */
+/*" \"Generator object INTDIR config include dir: %s\\n\"\n"*/
+" \"Generated genex config definition: \""
+ " GENEX_CONFIG_DEFINITION \"\\n\"\n"
+/* FIXME Get this working */
+/*" \"Generated INTDIR config definition: \""
+ " INTDIR_CONFIG_DEFINITION \"\\n\"\n"*/
+" \"Generated genex config include dir: \""
+ " GENEX_CONFIG_INCLUDE_DIR \"\\n\"\n"
+/* FIXME Get this working */
+/*" \"Generated INTDIR config include dir: \""
+ " INTDIR_CONFIG_INCLUDE_DIR \"\\n\"\n"*/
+" \"Generated library genex config definition: %%s\\n\"\n"
+/* FIXME Get this working */
+/*" \"Generated library INTDIR config definition: %%s\\n\"\n"*/
+" \"Generated library genex config include dir: %%s\\n\"\n"
+/* FIXME Get this working */
+/*" \"Generated library INTDIR config include dir: %%s\\n\"\n"*/
+" \"Generated object genex config definition: %%s\\n\"\n"
+/* FIXME Get this working */
+/*" \"Generated object INTDIR config definition: %%s\\n\"\n"*/
+" \"Generated object genex config include dir: %%s\\n\"\n"
+/* FIXME Get this working */
+/*" \"Generated object INTDIR config include dir: %%s\\n\"\n"*/
+" , generatorlib_genex_config_definition()\n"
+" , generatorlib_genex_config_include_dir()\n"
+" , generatorobj_genex_config_definition()\n"
+" , generatorobj_genex_config_include_dir());\n"
+" return 0;\n"
+"}\n";
+/* clang-format on */
+
+int main(int argc, char** argv)
+{
+ const char* filename;
+ FILE* fout;
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
+ return 1;
+ }
+
+ filename = argv[1];
+ if (!(fout = fopen(filename, "w"))) {
+ fprintf(stderr, "Could not open %s for writing\n", filename);
+ return 1;
+ }
+ fprintf(fout, contents, generatorlib_genex_config_definition(),
+ generatorlib_genex_config_include_dir(),
+ generatorobj_genex_config_definition(),
+ generatorobj_genex_config_include_dir());
+ fclose(fout);
+
+ return 0;
+}
diff --git a/Tests/RunCMake/NinjaMultiConfig/generatorlib.c b/Tests/RunCMake/NinjaMultiConfig/generatorlib.c
new file mode 100644
index 0000000..de5c8f3
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/generatorlib.c
@@ -0,0 +1,24 @@
+#include <genex_config.h>
+/* FIXME Get this working */
+/*#include <intdir_config.h>*/
+
+const char* generatorlib_genex_config_definition(void)
+{
+ return GENEX_CONFIG_DEFINITION;
+}
+
+const char* generatorlib_genex_config_include_dir(void)
+{
+ return GENEX_CONFIG_INCLUDE_DIR;
+}
+
+/* FIXME Get this working */
+/*const char* generatorlib_intdir_config_definition(void)
+{
+ return INTDIR_CONFIG_DEFINITION;
+}
+
+const char* generatorlib_intdir_config_include_dir(void)
+{
+ return INTDIR_CONFIG_INCLUDE_DIR;
+}*/
diff --git a/Tests/RunCMake/NinjaMultiConfig/generatorobj.c b/Tests/RunCMake/NinjaMultiConfig/generatorobj.c
new file mode 100644
index 0000000..7bb5aa6
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/generatorobj.c
@@ -0,0 +1,24 @@
+#include <genex_config.h>
+/* FIXME Get this working */
+/*#include <intdir_config.h>*/
+
+const char* generatorobj_genex_config_definition(void)
+{
+ return GENEX_CONFIG_DEFINITION;
+}
+
+const char* generatorobj_genex_config_include_dir(void)
+{
+ return GENEX_CONFIG_INCLUDE_DIR;
+}
+
+/* FIXME Get this working */
+/*const char* generatorobj_intdir_config_definition(void)
+{
+ return INTDIR_CONFIG_DEFINITION;
+}
+
+const char* generatorobj_intdir_config_include_dir(void)
+{
+ return INTDIR_CONFIG_INCLUDE_DIR;
+}*/
diff --git a/Tests/RunCMake/NinjaMultiConfig/main.c b/Tests/RunCMake/NinjaMultiConfig/main.c
new file mode 100644
index 0000000..8488f4e
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/main.c
@@ -0,0 +1,4 @@
+int main(void)
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/NinjaMultiConfig/main.cu b/Tests/RunCMake/NinjaMultiConfig/main.cu
new file mode 100644
index 0000000..563b9b2
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/main.cu
@@ -0,0 +1,15 @@
+
+#include <cuda.h>
+
+#ifdef _WIN32
+# define IMPORT __declspec(dllimport)
+#else
+# define IMPORT
+#endif
+
+IMPORT int simplelib();
+
+int main(void)
+{
+ return simplelib();
+}
diff --git a/Tests/RunCMake/NinjaMultiConfig/qt5.cxx b/Tests/RunCMake/NinjaMultiConfig/qt5.cxx
new file mode 100644
index 0000000..972227f
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/qt5.cxx
@@ -0,0 +1,9 @@
+#include <QCoreApplication>
+
+int main(int argc, char** argv)
+{
+ QCoreApplication app(argc, argv);
+ return app.exec();
+}
+
+#include "moc_qt5.cpp"
diff --git a/Tests/RunCMake/NinjaMultiConfig/qt5.h b/Tests/RunCMake/NinjaMultiConfig/qt5.h
new file mode 100644
index 0000000..b365b92
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/qt5.h
@@ -0,0 +1,5 @@
+#include <QObject>
+class QBuffer : public QObject
+{
+ Q_OBJECT
+};
diff --git a/Tests/RunCMake/NinjaMultiConfig/simplelib.c b/Tests/RunCMake/NinjaMultiConfig/simplelib.c
new file mode 100644
index 0000000..76ff921
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/simplelib.c
@@ -0,0 +1,6 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+ void simplelib(void)
+{
+}
diff --git a/Tests/RunCMake/NinjaMultiConfig/simplelib.cu b/Tests/RunCMake/NinjaMultiConfig/simplelib.cu
new file mode 100644
index 0000000..7fc0812
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/simplelib.cu
@@ -0,0 +1,9 @@
+#include <cuda.h>
+
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+ int simplelib()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/ObjectLibrary/b.c b/Tests/RunCMake/ObjectLibrary/b.c
index 220ce03..2c65a2b 100644
--- a/Tests/RunCMake/ObjectLibrary/b.c
+++ b/Tests/RunCMake/ObjectLibrary/b.c
@@ -5,7 +5,7 @@
#endif
extern int a(void);
-EXPORT int b()
+EXPORT int b(void)
{
return a();
}
diff --git a/Tests/RunCMake/ObjectLibrary/requires.c b/Tests/RunCMake/ObjectLibrary/requires.c
index 685632b..a5b429a 100644
--- a/Tests/RunCMake/ObjectLibrary/requires.c
+++ b/Tests/RunCMake/ObjectLibrary/requires.c
@@ -1,5 +1,5 @@
#ifdef REQUIRED
-int required()
+int required(void)
{
return 0;
}
diff --git a/Tests/RunCMake/ParseImplicitData/mingw.org-C-GNU-4.9.3.input b/Tests/RunCMake/ParseImplicitData/mingw.org-C-GNU-4.9.3.input
index 81e9ee0..b1c4ce0 100644
--- a/Tests/RunCMake/ParseImplicitData/mingw.org-C-GNU-4.9.3.input
+++ b/Tests/RunCMake/ParseImplicitData/mingw.org-C-GNU-4.9.3.input
@@ -53,7 +53,7 @@ LIBRARY_PATH=c:/DoesNotExist/mingw/bin/../lib/gcc/mingw32/4.9.3/;c:/DoesNotExist
COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles\cmTC_ab097.dir\CMakeCCompilerABI.c.obj' '-c' '-mtune=generic' '-march=i586'
Linking C executable cmTC_ab097.exe
"C:\CMake\bin\cmake.exe" -E cmake_link_script CMakeFiles\cmTC_ab097.dir\link.txt --verbose=1
-"C:\CMake\bin\cmake.exe" -E remove -f CMakeFiles\cmTC_ab097.dir/objects.a
+"C:\CMake\bin\cmake.exe" -E rm -f CMakeFiles\cmTC_ab097.dir/objects.a
C:\DoesNotExist\MinGW\bin\ar.exe cr CMakeFiles\cmTC_ab097.dir/objects.a @CMakeFiles\cmTC_ab097.dir\objects1.rsp
C:\DoesNotExist\MinGW\bin\gcc.exe -v -Wl,--whole-archive CMakeFiles\cmTC_ab097.dir/objects.a -Wl,--no-whole-archive -o cmTC_ab097.exe -Wl,--out-implib,libcmTC_ab097.dll.a -Wl,--major-image-version,0,--minor-image-version,0
Using built-in specs.
diff --git a/Tests/RunCMake/ParseImplicitData/mingw.org-CXX-GNU-4.9.3.input b/Tests/RunCMake/ParseImplicitData/mingw.org-CXX-GNU-4.9.3.input
index cd77340..aae67bb 100644
--- a/Tests/RunCMake/ParseImplicitData/mingw.org-CXX-GNU-4.9.3.input
+++ b/Tests/RunCMake/ParseImplicitData/mingw.org-CXX-GNU-4.9.3.input
@@ -59,7 +59,7 @@ LIBRARY_PATH=c:/DoesNotExist/mingw/bin/../lib/gcc/mingw32/4.9.3/;c:/DoesNotExist
COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles\cmTC_2b790.dir\CMakeCXXCompilerABI.cpp.obj' '-c' '-shared-libgcc' '-mtune=generic' '-march=i586'
Linking CXX executable cmTC_2b790.exe
"C:\CMake\bin\cmake.exe" -E cmake_link_script CMakeFiles\cmTC_2b790.dir\link.txt --verbose=1
-"C:\CMake\bin\cmake.exe" -E remove -f CMakeFiles\cmTC_2b790.dir/objects.a
+"C:\CMake\bin\cmake.exe" -E rm -f CMakeFiles\cmTC_2b790.dir/objects.a
C:\DoesNotExist\MinGW\bin\ar.exe cr CMakeFiles\cmTC_2b790.dir/objects.a @CMakeFiles\cmTC_2b790.dir\objects1.rsp
C:\DoesNotExist\MinGW\bin\g++.exe -v -Wl,--whole-archive CMakeFiles\cmTC_2b790.dir/objects.a -Wl,--no-whole-archive -o cmTC_2b790.exe -Wl,--out-implib,libcmTC_2b790.dll.a -Wl,--major-image-version,0,--minor-image-version,0
Using built-in specs.
diff --git a/Tests/RunCMake/PrecompileHeaders/DisabledPch-check.cmake b/Tests/RunCMake/PrecompileHeaders/DisabledPch-check.cmake
index 494bcf7..cc719be 100644
--- a/Tests/RunCMake/PrecompileHeaders/DisabledPch-check.cmake
+++ b/Tests/RunCMake/PrecompileHeaders/DisabledPch-check.cmake
@@ -1,4 +1,7 @@
set(foo_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foo.dir/cmake_pch.h")
+if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+ set(foo_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foo.dir/Debug/cmake_pch.h")
+endif()
set(foobar_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foobar.dir/cmake_pch.h")
if (NOT EXISTS ${foo_pch_header})
diff --git a/Tests/RunCMake/PrecompileHeaders/PchDebugGenex-check.cmake b/Tests/RunCMake/PrecompileHeaders/PchDebugGenex-check.cmake
new file mode 100644
index 0000000..cb94ee5
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/PchDebugGenex-check.cmake
@@ -0,0 +1,17 @@
+if (NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
+ return()
+endif()
+
+set(foo_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foo.dir/Debug/cmake_pch.h")
+
+if (NOT EXISTS ${foo_pch_header})
+ set(RunCMake_TEST_FAILED "Generated foo pch header ${foo_pch_header} does not exist")
+ return()
+endif()
+
+file(STRINGS ${foo_pch_header} foo_pch_header_strings)
+
+if (NOT foo_pch_header_strings MATCHES ";#include \"[^\"]*PrecompileHeaders/include/foo.h\";#include <stdio.h>(;|$)")
+ set(RunCMake_TEST_FAILED "Generated foo pch header\n ${foo_pch_header}\nhas bad content:\n ${foo_pch_header_strings}")
+ return()
+endif()
diff --git a/Tests/RunCMake/PrecompileHeaders/PchDebugGenex.cmake b/Tests/RunCMake/PrecompileHeaders/PchDebugGenex.cmake
new file mode 100644
index 0000000..854689f
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/PchDebugGenex.cmake
@@ -0,0 +1,9 @@
+cmake_minimum_required(VERSION 3.15)
+project(PchDebugGenex C)
+
+add_library(foo foo.c)
+target_include_directories(foo PUBLIC include)
+target_precompile_headers(foo PUBLIC
+ "$<$<CONFIG:Debug>:${CMAKE_CURRENT_SOURCE_DIR}/include/foo.h>"
+ <stdio.h>
+)
diff --git a/Tests/RunCMake/PrecompileHeaders/PchInterface-check.cmake b/Tests/RunCMake/PrecompileHeaders/PchInterface-check.cmake
index 4e62b81..28c6ba4 100644
--- a/Tests/RunCMake/PrecompileHeaders/PchInterface-check.cmake
+++ b/Tests/RunCMake/PrecompileHeaders/PchInterface-check.cmake
@@ -1,5 +1,9 @@
set(foo_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foo.dir/cmake_pch.h")
set(foobar_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foobar.dir/cmake_pch.h")
+if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+ set(foo_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foo.dir/Debug/cmake_pch.h")
+ set(foobar_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foobar.dir/Debug/cmake_pch.h")
+endif()
if (NOT EXISTS ${foo_pch_header})
set(RunCMake_TEST_FAILED "Generated foo pch header ${foo_pch_header} does not exist")
diff --git a/Tests/RunCMake/PrecompileHeaders/PchMultilanguage-check.cmake b/Tests/RunCMake/PrecompileHeaders/PchMultilanguage-check.cmake
index 9714bea..3119341 100644
--- a/Tests/RunCMake/PrecompileHeaders/PchMultilanguage-check.cmake
+++ b/Tests/RunCMake/PrecompileHeaders/PchMultilanguage-check.cmake
@@ -1,5 +1,9 @@
set(foobar_pch_h_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foobar.dir/cmake_pch.h")
set(foobar_pch_hxx_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foobar.dir/cmake_pch.hxx")
+if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+ set(foobar_pch_h_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foobar.dir/Debug/cmake_pch.h")
+ set(foobar_pch_hxx_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/foobar.dir/Debug/cmake_pch.hxx")
+endif()
if (NOT EXISTS ${foobar_pch_h_header})
set(RunCMake_TEST_FAILED "Generated foobar C pch header ${foobar_pch_h_header} does not exist")
diff --git a/Tests/RunCMake/PrecompileHeaders/PchPrologueEpilogue-check.cmake b/Tests/RunCMake/PrecompileHeaders/PchPrologueEpilogue-check.cmake
index 9018664..f1504a7 100644
--- a/Tests/RunCMake/PrecompileHeaders/PchPrologueEpilogue-check.cmake
+++ b/Tests/RunCMake/PrecompileHeaders/PchPrologueEpilogue-check.cmake
@@ -1,4 +1,7 @@
set(main_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/main.dir/cmake_pch.hxx")
+if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+ set(main_pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/main.dir/Debug/cmake_pch.hxx")
+endif()
file(STRINGS ${main_pch_header} main_pch_header_strings)
string(REGEX MATCH "#pragma warning\\(push, 0\\).*#include.*pch.h.*#pragma warning\\(pop\\)" matched_code ${main_pch_header_strings})
diff --git a/Tests/RunCMake/PrecompileHeaders/PchWarnInvalid-check.cmake b/Tests/RunCMake/PrecompileHeaders/PchWarnInvalid-check.cmake
new file mode 100644
index 0000000..3e7fb30
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/PchWarnInvalid-check.cmake
@@ -0,0 +1,22 @@
+if (NOT CMAKE_C_COMPILER_ID MATCHES "GNU|Intel" OR
+ (CMAKE_C_COMPILER_ID STREQUAL "Intel" AND CMAKE_HOST_WIN32))
+ return()
+endif()
+
+file(STRINGS ${RunCMake_TEST_BINARY_DIR}/compile_commands.json empty_dir_commands
+ REGEX "command.*-Winvalid-pch.*empty.dir/cmake_pch.h")
+file(STRINGS ${RunCMake_TEST_BINARY_DIR}/compile_commands.json foo_dir_commands
+ REGEX "command.*-Winvalid-pch.*foo.dir/cmake_pch.h")
+
+list(LENGTH empty_dir_commands empty_dir_commands_size)
+list(LENGTH foo_dir_commands foo_dir_commands_size)
+
+if (empty_dir_commands_size EQUAL 0)
+ set(RunCMake_TEST_FAILED "empty target should have -Winvalid-pch compile option present")
+ return()
+endif()
+
+if (foo_dir_commands_size GREATER 0)
+ set(RunCMake_TEST_FAILED "foo target should not have -Winvalid-pch compile option present")
+ return()
+endif()
diff --git a/Tests/RunCMake/PrecompileHeaders/PchWarnInvalid.cmake b/Tests/RunCMake/PrecompileHeaders/PchWarnInvalid.cmake
new file mode 100644
index 0000000..4525664
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/PchWarnInvalid.cmake
@@ -0,0 +1,16 @@
+enable_language(C)
+
+set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+
+add_library(empty empty.c)
+target_precompile_headers(empty PUBLIC
+ <stdio.h>
+ <string.h>
+)
+
+add_library(foo foo.c)
+target_precompile_headers(foo PUBLIC
+ <stdio.h>
+ <string.h>
+)
+set_target_properties(foo PROPERTIES PCH_WARN_INVALID OFF)
diff --git a/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake b/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake
index 8d2f4f9..381b800 100644
--- a/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake
+++ b/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake
@@ -4,15 +4,13 @@ include(RunCMake)
function(run_test name)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${name}-build)
run_cmake(${name})
- # Precompiled headers are not supported with multiple architectures.
- if(NOT "$ENV{CMAKE_OSX_ARCHITECTURES}" MATCHES "[;$]")
- set(RunCMake_TEST_NO_CLEAN 1)
- run_cmake_command(${name}-build ${CMAKE_COMMAND} --build . --config Debug)
- run_cmake_command(${name}-test ${CMAKE_CTEST_COMMAND} -C Debug)
- endif()
+ set(RunCMake_TEST_NO_CLEAN 1)
+ run_cmake_command(${name}-build ${CMAKE_COMMAND} --build . --config Debug)
+ run_cmake_command(${name}-test ${CMAKE_CTEST_COMMAND} -C Debug)
endfunction()
run_cmake(DisabledPch)
+run_cmake(PchDebugGenex)
run_test(PchInterface)
run_cmake(PchPrologueEpilogue)
run_test(SkipPrecompileHeaders)
@@ -20,3 +18,6 @@ run_test(PchReuseFrom)
run_test(PchReuseFromPrefixed)
run_test(PchReuseFromSubdir)
run_cmake(PchMultilanguage)
+if(RunCMake_GENERATOR MATCHES "Make|Ninja")
+ run_cmake(PchWarnInvalid)
+endif()
diff --git a/Tests/RunCMake/PrecompileHeaders/empty.c b/Tests/RunCMake/PrecompileHeaders/empty.c
index 30ae1c4..2a51ebc 100644
--- a/Tests/RunCMake/PrecompileHeaders/empty.c
+++ b/Tests/RunCMake/PrecompileHeaders/empty.c
@@ -1,3 +1,3 @@
-void nothing()
+void nothing(void)
{
}
diff --git a/Tests/RunCMake/RunCMake.cmake b/Tests/RunCMake/RunCMake.cmake
index da4d1e5..cb20fb1 100644
--- a/Tests/RunCMake/RunCMake.cmake
+++ b/Tests/RunCMake/RunCMake.cmake
@@ -146,6 +146,12 @@ function(run_cmake test)
"|clang[^:]*: warning: the object size sanitizer has no effect at -O0, but is explicitly enabled:"
"|Error kstat returned"
"|Hit xcodebuild bug"
+
+ "|LICENSE WARNING:"
+ "|Your license to use PGI[^\n]*expired"
+ "|Please obtain a new version at"
+ "|contact PGI Sales at"
+
"|[^\n]*xcodebuild[^\n]*warning: file type[^\n]*is based on missing file type"
"|[^\n]*is a member of multiple groups"
"|[^\n]*from Time Machine by path"
@@ -204,5 +210,28 @@ function(run_cmake_with_options test)
run_cmake(${test})
endfunction()
+function(ensure_files_match expected_file actual_file)
+ if(NOT EXISTS "${expected_file}")
+ message(FATAL_ERROR "Expected file does not exist:\n ${expected_file}")
+ endif()
+ if(NOT EXISTS "${actual_file}")
+ message(FATAL_ERROR "Actual file does not exist:\n ${actual_file}")
+ endif()
+ file(READ "${expected_file}" expected_file_content)
+ file(READ "${actual_file}" actual_file_content)
+ if(NOT "${expected_file_content}" STREQUAL "${actual_file_content}")
+ message(FATAL_ERROR "Actual file content does not match expected:\n
+ \n
+ expected file: ${expected_file}\n
+ expected content:\n
+ ${expected_file_content}\n
+ \n
+ actual file: ${actual_file}\n
+ actual content:\n
+ ${actual_file_content}\n
+ ")
+ endif()
+endfunction()
+
# Protect RunCMake tests from calling environment.
unset(ENV{MAKEFLAGS})
diff --git a/Tests/RunCMake/RuntimePath/Relative.cmake b/Tests/RunCMake/RuntimePath/Relative.cmake
index 203241f..80ed189 100644
--- a/Tests/RunCMake/RuntimePath/Relative.cmake
+++ b/Tests/RunCMake/RuntimePath/Relative.cmake
@@ -1,5 +1,12 @@
enable_language(C)
+set(cfg_up)
+set(cfg_slash /)
+if(cfg_dir)
+ set(cfg_up /..)
+ set(cfg_slash)
+endif()
+
if(NOT CMAKE_SHARED_LIBRARY_RPATH_ORIGIN_TOKEN)
if(CMAKE_C_PLATFORM_ID STREQUAL "Linux")
# Sanity check for platform that is definitely known to support $ORIGIN.
@@ -45,25 +52,25 @@ CheckRpath(main "\$ORIGIN")
add_executable(main-norel main.c)
target_link_libraries(main-norel utils)
set_property(TARGET main-norel PROPERTY BUILD_RPATH_USE_ORIGIN OFF)
-CheckRpath(main-norel "${CMAKE_CURRENT_BINARY_DIR}")
+CheckRpath(main-norel "${CMAKE_CURRENT_BINARY_DIR}${cfg_dir}")
add_executable(mainsub main.c)
target_link_libraries(mainsub utils)
set_property(TARGET mainsub PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin)
-CheckRpath(mainsub "\$ORIGIN/../")
+CheckRpath(mainsub "\$ORIGIN${cfg_up}/..${cfg_dir}${cfg_slash}")
add_executable(main-sub main.c)
target_link_libraries(main-sub utils-sub)
-CheckRpath(main-sub "\$ORIGIN/libs")
+CheckRpath(main-sub "\$ORIGIN${cfg_up}/libs${cfg_dir}")
add_executable(mainsub-sub main.c)
target_link_libraries(mainsub-sub utils-sub)
set_property(TARGET mainsub-sub PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin)
-CheckRpath(mainsub-sub "\$ORIGIN/../libs")
+CheckRpath(mainsub-sub "\$ORIGIN${cfg_up}/../libs${cfg_dir}")
if(externDir)
# Binaries linking to libraries outside the build tree should have an absolute RPATH.
add_executable(main-extern main.c)
target_link_libraries(main-extern utils-extern)
- CheckRpath(main-extern "${externDir}")
+ CheckRpath(main-extern "${externDir}${cfg_dir}")
endif()
diff --git a/Tests/RunCMake/RuntimePath/RunCMakeTest.cmake b/Tests/RunCMake/RuntimePath/RunCMakeTest.cmake
index 4c9ddcd..ad446e9 100644
--- a/Tests/RunCMake/RuntimePath/RunCMakeTest.cmake
+++ b/Tests/RunCMake/RuntimePath/RunCMakeTest.cmake
@@ -6,7 +6,9 @@ function(run_RuntimePath name)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${name}-build)
set(RunCMake_TEST_NO_CLEAN 1)
if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
- set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
+ set(RunCMake_TEST_OPTIONS -Dcfg_dir= -DCMAKE_BUILD_TYPE=Debug)
+ else()
+ set(RunCMake_TEST_OPTIONS -Dcfg_dir=/$<CONFIG>)
endif()
file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
@@ -14,12 +16,16 @@ function(run_RuntimePath name)
run_cmake_command(${name}-build ${CMAKE_COMMAND} --build . --config Debug)
endfunction()
+set(cfg_dir)
+if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+ set(cfg_dir /Debug)
+endif()
+
run_RuntimePath(SymlinkImplicit)
run_cmake_command(SymlinkImplicitCheck
- ${CMAKE_COMMAND} -Ddir=${RunCMake_BINARY_DIR}/SymlinkImplicit-build -P ${RunCMake_SOURCE_DIR}/SymlinkImplicitCheck.cmake)
+ ${CMAKE_COMMAND} -Ddir=${RunCMake_BINARY_DIR}/SymlinkImplicit-build -Dcfg_dir=${cfg_dir} -P ${RunCMake_SOURCE_DIR}/SymlinkImplicitCheck.cmake)
run_RuntimePath(Relative)
-# FIXME: Run RelativeCheck (appears to be broken currently)
run_RuntimePath(Genex)
run_cmake_command(GenexCheck
diff --git a/Tests/RunCMake/RuntimePath/SymlinkImplicitCheck.cmake b/Tests/RunCMake/RuntimePath/SymlinkImplicitCheck.cmake
index d34742e..4f50d4b 100644
--- a/Tests/RunCMake/RuntimePath/SymlinkImplicitCheck.cmake
+++ b/Tests/RunCMake/RuntimePath/SymlinkImplicitCheck.cmake
@@ -1,2 +1,2 @@
-file(COPY ${dir}/bin/exe DESTINATION ${dir})
+file(COPY ${dir}/bin${cfg_dir}/exe DESTINATION ${dir})
file(RPATH_CHANGE FILE "${dir}/exe" OLD_RPATH "${dir}/libLink" NEW_RPATH "old-should-not-exist")
diff --git a/Tests/RunCMake/Swift/L.swift b/Tests/RunCMake/Swift/L.swift
new file mode 100644
index 0000000..79ff87e
--- /dev/null
+++ b/Tests/RunCMake/Swift/L.swift
@@ -0,0 +1 @@
+public let ThirtyTwo: Int = 32
diff --git a/Tests/RunCMake/Swift/RunCMakeTest.cmake b/Tests/RunCMake/Swift/RunCMakeTest.cmake
index 4817045..1db202e 100644
--- a/Tests/RunCMake/Swift/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Swift/RunCMakeTest.cmake
@@ -7,6 +7,16 @@ if(RunCMake_GENERATOR STREQUAL Xcode)
elseif(RunCMake_GENERATOR STREQUAL Ninja)
if(CMAKE_Swift_COMPILER)
run_cmake(Win32ExecutableDisallowed)
+
+ set(RunCMake_TEST_OPTIONS -DCMAKE_SYSTEM_NAME=Darwin)
+ run_cmake(SwiftMultiArch)
+ unset(RunCMake_TEST_OPTIONS)
+ endif()
+elseif(RunCMake_GENERATOR STREQUAL "Ninja Multi-Config")
+ if(CMAKE_Swift_COMPILER)
+ set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release")
+ run_cmake(SwiftSimple)
+ unset(RunCMake_TEST_OPTIONS)
endif()
else()
run_cmake(NotSupported)
diff --git a/Tests/RunCMake/Swift/SwiftMultiArch-result.txt b/Tests/RunCMake/Swift/SwiftMultiArch-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Swift/SwiftMultiArch-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Swift/SwiftMultiArch-stderr.txt b/Tests/RunCMake/Swift/SwiftMultiArch-stderr.txt
new file mode 100644
index 0000000..874bdc7
--- /dev/null
+++ b/Tests/RunCMake/Swift/SwiftMultiArch-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at SwiftMultiArch.cmake:3 \(project\):
+ multiple values for CMAKE_OSX_ARCHITECTURES not supported with Swift
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3
diff --git a/Tests/RunCMake/Swift/SwiftMultiArch.cmake b/Tests/RunCMake/Swift/SwiftMultiArch.cmake
new file mode 100644
index 0000000..5fdb688
--- /dev/null
+++ b/Tests/RunCMake/Swift/SwiftMultiArch.cmake
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.15.1)
+set(CMAKE_OSX_ARCHITECTURES "armv7;arm64;i386;x86_64")
+project(SwiftMultiArch
+ LANGUAGES Swift)
diff --git a/Tests/RunCMake/Swift/SwiftSimple.cmake b/Tests/RunCMake/Swift/SwiftSimple.cmake
new file mode 100644
index 0000000..1f2702d
--- /dev/null
+++ b/Tests/RunCMake/Swift/SwiftSimple.cmake
@@ -0,0 +1,2 @@
+enable_language(Swift)
+add_library(L L.swift)
diff --git a/Tests/RunCMake/Syntax/CommandEOF-stderr.txt b/Tests/RunCMake/Syntax/CommandEOF-stderr.txt
index 31cbc08..b9f8fd1 100644
--- a/Tests/RunCMake/Syntax/CommandEOF-stderr.txt
+++ b/Tests/RunCMake/Syntax/CommandEOF-stderr.txt
@@ -1,4 +1,4 @@
-^CMake Error in CommandEOF.cmake:
+^CMake Error at CommandEOF.cmake:1:
Unexpected end of file.
Parse error. Function missing opening "\(".
diff --git a/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt b/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt
index 6d72fac..2d270c5 100644
--- a/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt
+++ b/Tests/RunCMake/TargetPolicies/PolicyList-stderr.txt
@@ -28,6 +28,9 @@
\* CMP0081
\* CMP0083
\* CMP0095
+ \* CMP0099
+ \* CMP0104
+ \* CMP0105
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/TargetProperties/CMakeLists.txt b/Tests/RunCMake/TargetProperties/CMakeLists.txt
new file mode 100644
index 0000000..be9d403
--- /dev/null
+++ b/Tests/RunCMake/TargetProperties/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8.4)
+project(${RunCMake_TEST})
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/TargetProperties/Deprecation-stderr.txt b/Tests/RunCMake/TargetProperties/Deprecation-stderr.txt
new file mode 100644
index 0000000..11a4cd8
--- /dev/null
+++ b/Tests/RunCMake/TargetProperties/Deprecation-stderr.txt
@@ -0,0 +1,9 @@
+^CMake Warning \(dev\) at Deprecation\.cmake:[0-9]+ \(target_link_libraries\):
+ The library that is being linked to, testLibDeprecation, is marked as being
+ deprecated by the owner\. The message provided by the developer is:
+
+ Deprecated version\. Please use latest version
+
+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/TargetProperties/Deprecation.cmake b/Tests/RunCMake/TargetProperties/Deprecation.cmake
new file mode 100644
index 0000000..9361273
--- /dev/null
+++ b/Tests/RunCMake/TargetProperties/Deprecation.cmake
@@ -0,0 +1,5 @@
+add_library(testLibDeprecation STATIC empty.cpp)
+set_property(TARGET testLibDeprecation PROPERTY DEPRECATION "Deprecated version. Please use latest version")
+
+add_executable(testExe1 empty.cpp)
+target_link_libraries(testExe1 testLibDeprecation)
diff --git a/Tests/RunCMake/TargetProperties/RunCMakeTest.cmake b/Tests/RunCMake/TargetProperties/RunCMakeTest.cmake
new file mode 100644
index 0000000..5af31da
--- /dev/null
+++ b/Tests/RunCMake/TargetProperties/RunCMakeTest.cmake
@@ -0,0 +1,3 @@
+include(RunCMake)
+
+run_cmake(Deprecation)
diff --git a/Tests/RunCMake/TargetProperties/empty.cpp b/Tests/RunCMake/TargetProperties/empty.cpp
new file mode 100644
index 0000000..4086dcc
--- /dev/null
+++ b/Tests/RunCMake/TargetProperties/empty.cpp
@@ -0,0 +1,4 @@
+int empty()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/TargetSources/RunCMakeTest.cmake b/Tests/RunCMake/TargetSources/RunCMakeTest.cmake
index bee8c4e..0d462ba 100644
--- a/Tests/RunCMake/TargetSources/RunCMakeTest.cmake
+++ b/Tests/RunCMake/TargetSources/RunCMakeTest.cmake
@@ -1,6 +1,6 @@
include(RunCMake)
-if(RunCMake_GENERATOR MATCHES "Visual Studio|Xcode")
+if(RunCMake_GENERATOR STREQUAL "Xcode")
run_cmake(ConfigNotAllowed)
endif()
diff --git a/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake b/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake
index 24daa64..9ba3c85 100644
--- a/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake
+++ b/Tests/RunCMake/UnityBuild/RunCMakeTest.cmake
@@ -1,14 +1,20 @@
include(RunCMake)
run_cmake(unitybuild_c)
+run_cmake(unitybuild_c_batch)
+run_cmake(unitybuild_c_group)
run_cmake(unitybuild_cxx)
+run_cmake(unitybuild_cxx_group)
run_cmake(unitybuild_c_and_cxx)
+run_cmake(unitybuild_c_and_cxx_group)
run_cmake(unitybuild_batchsize)
run_cmake(unitybuild_default_batchsize)
run_cmake(unitybuild_skip)
run_cmake(unitybuild_code_before_and_after_include)
run_cmake(unitybuild_c_no_unity_build)
+run_cmake(unitybuild_c_no_unity_build_group)
run_cmake(unitybuild_order)
+run_cmake(unitybuild_invalid_mode)
function(run_test name)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${name}-build)
diff --git a/Tests/RunCMake/UnityBuild/f.c b/Tests/RunCMake/UnityBuild/f.c
new file mode 100644
index 0000000..d5813c6
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/f.c
@@ -0,0 +1,5 @@
+int f(int x)
+{
+ (void)x;
+ return 0;
+}
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_group-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_group-check.cmake
new file mode 100644
index 0000000..b027682
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_group-check.cmake
@@ -0,0 +1,42 @@
+set(unitybuild_a_c "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_a_c.c")
+if(NOT EXISTS "${unitybuild_a_c}")
+ set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_a_c} does not exist.")
+ return()
+else()
+ #verify that the 4 c file is part of this grouping and therefore UNITY_BUILD_BATCH_SIZE
+ #was ignored
+ file(STRINGS ${unitybuild_a_c} unitybuild_a_c_strings)
+ string(REGEX MATCH ".*#include.*s1.c.*#include.*s2.c.*#include.*s3.c.*#include.*s4.c.*" matched_code ${unitybuild_a_c_strings})
+ if(NOT matched_code)
+ set(RunCMake_TEST_FAILED "Generated unity file doesn't include expected source files")
+ return()
+ endif()
+endif()
+
+set(unitybuild_b_c "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_b_c.c")
+if(NOT EXISTS "${unitybuild_b_c}")
+ set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_b_c} does not exist.")
+ return()
+endif()
+
+
+set(unitybuild_a_cxx "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_a_cxx.cxx")
+if(NOT EXISTS "${unitybuild_a_cxx}")
+ set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_a_cxx} does not exist.")
+ return()
+else()
+ #verify that the 4 cxx file are part of this grouping and therefore UNITY_BUILD_BATCH_SIZE
+ #was ignored
+ file(STRINGS ${unitybuild_a_cxx} unitybuild_a_cxx_strings)
+ string(REGEX MATCH ".*#include.*s1.cxx.*#include.*s2.cxx.*#include.*s3.cxx.*#include.*s4.cxx.*" matched_code ${unitybuild_a_cxx_strings})
+ if(NOT matched_code)
+ set(RunCMake_TEST_FAILED "Generated unity file doesn't include expected source files")
+ return()
+ endif()
+endif()
+
+set(unitybuild_b_cxx "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_b_cxx.cxx")
+if(NOT EXISTS "${unitybuild_b_cxx}")
+ set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_b_cxx} does not exist.")
+ return()
+endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_group.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_group.cmake
new file mode 100644
index 0000000..7bf3f4b
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_c_and_cxx_group.cmake
@@ -0,0 +1,39 @@
+project(unitybuild_c_and_cxx C CXX)
+
+set(srcs f.c)
+foreach(s RANGE 1 8)
+ set(src_c "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c")
+ file(WRITE "${src_c}" "
+int f(int);\n
+int s${s}(void) { return f(${s}); }\n"
+ )
+
+ set(src_cxx "${CMAKE_CURRENT_BINARY_DIR}/s${s}.cxx")
+ file(WRITE "${src_cxx}" "
+extern \"C\" { \n
+ int f(int); \n
+}\n
+ int s${s}(void) { return f(${s}); }\n"
+ )
+
+ list(APPEND srcs "${src_c}")
+ list(APPEND srcs "${src_cxx}")
+endforeach()
+
+
+
+add_library(tgt SHARED ${srcs})
+
+set_target_properties(tgt PROPERTIES UNITY_BUILD ON
+ UNITY_BUILD_MODE GROUP
+ #UNITY_BUILD_BATCH_SIZE will be ignored
+ UNITY_BUILD_BATCH_SIZE 2)
+
+set_source_files_properties(s1.c s2.c s3.c s4.c
+ s1.cxx s2.cxx s3.cxx s4.cxx
+ PROPERTIES UNITY_GROUP "a"
+ )
+set_source_files_properties(s5.c s6.c s7.c s8.c
+ s5.cxx s6.cxx s7.cxx s8.cxx
+ PROPERTIES UNITY_GROUP "b"
+ )
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_batch-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_batch-check.cmake
new file mode 100644
index 0000000..024286d
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_c_batch-check.cmake
@@ -0,0 +1,5 @@
+set(unitybuild_c "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_0_c.c")
+if(NOT EXISTS "${unitybuild_c}")
+ set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_c} does not exist.")
+ return()
+endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_batch.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_batch.cmake
new file mode 100644
index 0000000..33873b6
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_c_batch.cmake
@@ -0,0 +1,15 @@
+project(unitybuild_c C)
+
+set(srcs "")
+foreach(s RANGE 1 8)
+ set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c")
+ file(WRITE "${src}" "int s${s}(void) { return 0; }\n")
+ list(APPEND srcs "${src}")
+endforeach()
+
+add_library(tgt SHARED ${srcs})
+
+set_target_properties(tgt PROPERTIES
+ UNITY_BUILD ON
+ UNITY_BUILD_MODE BATCH
+ )
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_group-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_group-check.cmake
new file mode 100644
index 0000000..0b9ea15
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_c_group-check.cmake
@@ -0,0 +1,11 @@
+set(unitybuild_a_c "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_a_c.c")
+if(NOT EXISTS "${unitybuild_a_c}")
+ set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_a_c} does not exist.")
+ return()
+endif()
+
+set(unitybuild_b_c "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_b_c.c")
+if(NOT EXISTS "${unitybuild_b_c}")
+ set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_b_c} does not exist.")
+ return()
+endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_group.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_group.cmake
new file mode 100644
index 0000000..1fa17f3
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_c_group.cmake
@@ -0,0 +1,17 @@
+project(unitybuild_c C)
+
+set(srcs "")
+foreach(s RANGE 1 8)
+ set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c")
+ file(WRITE "${src}" "int s${s}(void) { return 0; }\n")
+ list(APPEND srcs "${src}")
+endforeach()
+
+add_library(tgt SHARED ${srcs})
+
+set_target_properties(tgt PROPERTIES UNITY_BUILD ON
+ UNITY_BUILD_MODE GROUP)
+
+set_source_files_properties(s1.c PROPERTIES UNITY_GROUP "a")
+set_source_files_properties(s2.c PROPERTIES UNITY_GROUP "a")
+set_source_files_properties(s3.c s4.c PROPERTIES UNITY_GROUP "b")
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_no_unity_build_group-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_no_unity_build_group-check.cmake
new file mode 100644
index 0000000..e344627
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_c_no_unity_build_group-check.cmake
@@ -0,0 +1,5 @@
+set(unitybuild_c "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_a_c.c")
+if(EXISTS "${unitybuild_c}")
+ set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_c} should not exist.")
+ return()
+endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_c_no_unity_build_group.cmake b/Tests/RunCMake/UnityBuild/unitybuild_c_no_unity_build_group.cmake
new file mode 100644
index 0000000..7b26dc1
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_c_no_unity_build_group.cmake
@@ -0,0 +1,16 @@
+project(unitybuild_c_no_unity_build C)
+
+set(srcs "")
+foreach(s RANGE 1 8)
+ set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c")
+ file(WRITE "${src}" "int s${s}(void) { return 0; }\n")
+ list(APPEND srcs "${src}")
+endforeach()
+
+add_library(tgt SHARED ${srcs})
+
+#These should be ignored as UNITY_BUILD is off
+set_target_properties(tgt PROPERTIES UNITY_BUILD_MODE GROUP)
+set_source_files_properties(s1.c s2.c s3.c s4.c s5.c s6.c s7.c s8.c
+ PROPERTIES UNITY_GROUP "a"
+ )
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_cxx_group-check.cmake b/Tests/RunCMake/UnityBuild/unitybuild_cxx_group-check.cmake
new file mode 100644
index 0000000..ecef3a3
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_cxx_group-check.cmake
@@ -0,0 +1,27 @@
+set(unitybuild_a_cxx "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_a_cxx.cxx")
+if(NOT EXISTS "${unitybuild_a_cxx}")
+ set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_a_cxx} does not exist.")
+ return()
+else()
+ #verify that odr2 is not part of this source set
+ file(STRINGS ${unitybuild_a_cxx} unitybuild_a_cxx_strings)
+ string(REGEX MATCH ".*#include.*odr2.cxx" matched_code ${unitybuild_a_cxx_strings})
+ if(matched_code)
+ set(RunCMake_TEST_FAILED "Generated unity file includes un-expected ord2.cxx source file")
+ return()
+ endif()
+endif()
+
+set(unitybuild_b_cxx "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_b_cxx.cxx")
+if(NOT EXISTS "${unitybuild_b_cxx}")
+ set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_b_cxx} does not exist.")
+ return()
+else()
+ #verify that odr1 is not part of this source set
+ file(STRINGS ${unitybuild_b_cxx} unitybuild_b_cxx_strings)
+ string(REGEX MATCH ".*#include.*odr1.cxx" matched_code ${unitybuild_b_cxx_strings})
+ if(matched_code)
+ set(RunCMake_TEST_FAILED "Generated unity file includes un-expected ord1.cxx source file")
+ return()
+ endif()
+endif()
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_cxx_group.cmake b/Tests/RunCMake/UnityBuild/unitybuild_cxx_group.cmake
new file mode 100644
index 0000000..9804289
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_cxx_group.cmake
@@ -0,0 +1,27 @@
+project(unitybuild_cxx CXX)
+
+set(srcs "")
+foreach(s RANGE 1 4)
+ set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.cxx")
+ file(WRITE "${src}" "int s${s}(void) { return 0; }\n")
+ list(APPEND srcs "${src}")
+endforeach()
+
+foreach(s RANGE 1 2)
+ set(src "${CMAKE_CURRENT_BINARY_DIR}/odr${s}.cxx")
+ file(WRITE "${src}" "namespace odr { int s${s}(void) { return 0; } }\n")
+ list(APPEND srcs "${src}")
+endforeach()
+
+add_library(tgt SHARED ${srcs})
+
+set_target_properties(tgt PROPERTIES UNITY_BUILD ON
+ UNITY_BUILD_MODE GROUP
+ )
+
+set_source_files_properties(s1.cxx s2.cxx odr1.cxx
+ PROPERTIES UNITY_GROUP "a"
+ )
+set_source_files_properties(s3.cxx s4.cxx odr2.cxx
+ PROPERTIES UNITY_GROUP "b"
+ )
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_invalid_mode-result.txt b/Tests/RunCMake/UnityBuild/unitybuild_invalid_mode-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_invalid_mode-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_invalid_mode-stderr.txt b/Tests/RunCMake/UnityBuild/unitybuild_invalid_mode-stderr.txt
new file mode 100644
index 0000000..b1b17a0
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_invalid_mode-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error in CMakeLists.txt:
+ Invalid UNITY_BUILD_MODE value of INVALID assigned to target tgt\.
+ Acceptable values are BATCH and GROUP\.
+.*
+CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/UnityBuild/unitybuild_invalid_mode.cmake b/Tests/RunCMake/UnityBuild/unitybuild_invalid_mode.cmake
new file mode 100644
index 0000000..0212200
--- /dev/null
+++ b/Tests/RunCMake/UnityBuild/unitybuild_invalid_mode.cmake
@@ -0,0 +1,12 @@
+project(unitybuild_c C)
+
+set(srcs "")
+foreach(s RANGE 1 8)
+ set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c")
+ file(WRITE "${src}" "int s${s}(void) { return 0; }\n")
+ list(APPEND srcs "${src}")
+endforeach()
+
+add_library(tgt SHARED ${srcs})
+
+set_target_properties(tgt PROPERTIES UNITY_BUILD ON UNITY_BUILD_MODE INVALID)
diff --git a/Tests/RunCMake/VS10Project/CSharpSourceGroup/foo.cs b/Tests/RunCMake/VS10Project/CSharpSourceGroup/foo.cs
new file mode 100644
index 0000000..3695dc9
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/CSharpSourceGroup/foo.cs
@@ -0,0 +1,3 @@
+void foo()
+{
+}
diff --git a/Tests/RunCMake/VS10Project/CSharpSourceGroup/images/empty.bmp b/Tests/RunCMake/VS10Project/CSharpSourceGroup/images/empty.bmp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/CSharpSourceGroup/images/empty.bmp
diff --git a/Tests/RunCMake/VS10Project/CSharpSourceGroup/nested/baz.cs b/Tests/RunCMake/VS10Project/CSharpSourceGroup/nested/baz.cs
new file mode 100644
index 0000000..d5d334a
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/CSharpSourceGroup/nested/baz.cs
@@ -0,0 +1,3 @@
+void baz()
+{
+}
diff --git a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
index 44ccd6b..93ef603 100644
--- a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
+++ b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
@@ -1,12 +1,14 @@
+cmake_policy(SET CMP0057 NEW)
+
include(RunCMake)
cmake_policy(SET CMP0054 NEW)
+run_cmake(VsCsharpSourceGroup)
run_cmake(VsCSharpCompilerOpts)
run_cmake(ExplicitCMakeLists)
run_cmake(RuntimeLibrary)
run_cmake(SourceGroupCMakeLists)
run_cmake(SourceGroupTreeCMakeLists)
-
run_cmake(VsConfigurationType)
run_cmake(VsTargetsFileReferences)
run_cmake(VsCustomProps)
@@ -15,6 +17,7 @@ run_cmake(VsDebuggerCommand)
run_cmake(VsDebuggerCommandArguments)
run_cmake(VsDebuggerEnvironment)
run_cmake(VsCSharpCustomTags)
+run_cmake(VsCSharpDocumentationFile)
run_cmake(VsCSharpReferenceProps)
run_cmake(VsCSharpWithoutSources)
run_cmake(VsCSharpDeployFiles)
@@ -27,6 +30,16 @@ run_cmake(VsDpiAware)
run_cmake(VsDpiAwareBadParam)
run_cmake(VsPrecompileHeaders)
run_cmake(VsPrecompileHeadersReuseFromCompilePDBName)
+run_cmake(VsDeployEnabled)
+run_cmake(VsSettings)
+run_cmake(VsSourceSettingsTool)
+run_cmake(VsPlatformToolset)
+
+run_cmake(VsWinRTByDefault)
+
+set(RunCMake_GENERATOR_TOOLSET "VCTargetsPath=$(VCTargetsPath)")
+run_cmake(VsVCTargetsPath)
+unset(RunCMake_GENERATOR_TOOLSET)
if(CMAKE_C_COMPILER_ID STREQUAL "MSVC" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 19.05)
run_cmake(VsJustMyCode)
@@ -43,4 +56,8 @@ if (RunCMake_GENERATOR MATCHES "Visual Studio 1[0-4] 201[0-5]" OR
run_cmake(UnityBuildPre2017)
else()
run_cmake(UnityBuildNative)
+ run_cmake(UnityBuildNativeGrouped)
endif()
+
+run_cmake(VsDotnetTargetFramework)
+run_cmake(VsDotnetTargetFrameworkVersion)
diff --git a/Tests/RunCMake/VS10Project/UnityBuildNativeGrouped-check.cmake b/Tests/RunCMake/VS10Project/UnityBuildNativeGrouped-check.cmake
new file mode 100644
index 0000000..d6380da
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/UnityBuildNativeGrouped-check.cmake
@@ -0,0 +1,56 @@
+set(unitybuild_c0 "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_poolA_c.c")
+if(NOT EXISTS "${unitybuild_c0}")
+ set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_c0} does not exist.")
+ return()
+endif()
+
+set(unitybuild_c1 "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_poolB_c.c")
+if(NOT EXISTS "${unitybuild_c1}")
+ set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_c1} does not exist.")
+ return()
+endif()
+
+set(tgt_project "${RunCMake_TEST_BINARY_DIR}/tgt.vcxproj")
+if (NOT EXISTS "${tgt_project}")
+ set(RunCMake_TEST_FAILED "Generated project file ${tgt_project} doesn't exist.")
+ return()
+endif()
+
+file(STRINGS ${tgt_project} tgt_projects_strings)
+
+foreach(line IN LISTS tgt_projects_strings)
+ if (line MATCHES "<EnableUnitySupport>true</EnableUnitySupport>")
+ set(have_unity_support ON)
+ endif()
+
+ if (line MATCHES "<ClCompile Include=.*IncludeInUnityFile=\"false\" CustomUnityFile=\"true\"")
+ list(APPEND unity_source_lines ${line})
+ endif()
+
+ if (line MATCHES "<ClCompile Include=.*IncludeInUnityFile=\"true\" CustomUnityFile=\"true\"")
+ list(APPEND sources_list ${line})
+ endif()
+endforeach()
+
+if (NOT have_unity_support)
+ set(RunCMake_TEST_FAILED "Generated project should include the <EnableUnitySupport> block.")
+ return()
+endif()
+
+string(REPLACE "\\" "/" unity_source_lines "${unity_source_lines}")
+string(FIND "${unity_source_lines}" "CMakeFiles/tgt.dir/Unity/unity_poolA_c.c" unity_source_file_position)
+if (unity_source_file_position EQUAL "-1")
+ set(RunCMake_TEST_FAILED "Generated project should include the generated unity source file 'poolA'.")
+ return()
+endif()
+string(FIND "${unity_source_lines}" "CMakeFiles/tgt.dir/Unity/unity_poolB_c.c" unity_source_file_position)
+if (unity_source_file_position EQUAL "-1")
+ set(RunCMake_TEST_FAILED "Generated project should include the generated unity source file 'poolB'.")
+ return()
+endif()
+
+list(LENGTH sources_list number_of_sources)
+if(NOT number_of_sources EQUAL 7)
+ set(RunCMake_TEST_FAILED "Generated project doesn't include the expect number of files.")
+ return()
+endif()
diff --git a/Tests/RunCMake/VS10Project/UnityBuildNativeGrouped.cmake b/Tests/RunCMake/VS10Project/UnityBuildNativeGrouped.cmake
new file mode 100644
index 0000000..b740e3b
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/UnityBuildNativeGrouped.cmake
@@ -0,0 +1,20 @@
+project(unitybuild_c C)
+
+set(srcs "")
+foreach(s RANGE 1 8)
+ set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c")
+ file(WRITE "${src}" "int s${s}(void) { return 0; }\n")
+ list(APPEND srcs "${src}")
+endforeach()
+
+add_library(tgt SHARED ${srcs})
+
+set_target_properties(tgt PROPERTIES UNITY_BUILD ON UNITY_BUILD_MODE GROUP)
+
+set_source_files_properties(s1.c s2.c s3.c s4.c
+ PROPERTIES UNITY_GROUP "poolA"
+ )
+
+set_source_files_properties(s5.c s6.c s7.c
+ PROPERTIES UNITY_GROUP "poolB"
+ )
diff --git a/Tests/RunCMake/VS10Project/UnityBuildPre2017Grouped-check.cmake b/Tests/RunCMake/VS10Project/UnityBuildPre2017Grouped-check.cmake
new file mode 100644
index 0000000..d9b8c01
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/UnityBuildPre2017Grouped-check.cmake
@@ -0,0 +1,59 @@
+set(unitybuild_c0 "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_poolA.c")
+if(NOT EXISTS "${unitybuild_c0}")
+ set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_c0} does not exist.")
+ return()
+endif()
+
+set(unitybuild_c1 "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Unity/unity_poolB.c")
+if(NOT EXISTS "${unitybuild_c1}")
+ set(RunCMake_TEST_FAILED "Generated unity source files ${unitybuild_c1} does not exist.")
+ return()
+endif()
+
+set(tgt_project "${RunCMake_TEST_BINARY_DIR}/tgt.vcxproj")
+if (NOT EXISTS "${tgt_project}")
+ set(RunCMake_TEST_FAILED "Generated project file ${tgt_project} doesn't exist.")
+ return()
+endif()
+
+file(STRINGS ${tgt_project} tgt_projects_strings)
+
+foreach(line IN LISTS tgt_projects_strings)
+ if (line MATCHES "<ClCompile Include=.*/>")
+ set(unity_source_line ${line})
+ endif()
+
+ if (line MATCHES "<ClCompile Include=\"[^\"]*\">")
+ string(REGEX MATCH "<ClCompile Include=\"([^\"]*)\">" source_file ${line})
+ list(APPEND sources_list ${source_file})
+ endif()
+
+ if (line MATCHES "<ExcludedFromBuild.*</ExcludedFromBuild>")
+ list(APPEND excluded_sources_list ${source_file})
+ endif()
+endforeach()
+
+string(REPLACE "\\" "/" unity_source_line ${unity_source_line})
+string(FIND "${unity_source_line}" "CMakeFiles/tgt.dir/Unity/unity_poolA.c" unity_source_file_position)
+if (unity_source_file_position EQUAL "-1")
+ set(RunCMake_TEST_FAILED "Generated project should include the generated unity source file.")
+ return()
+endif()
+string(FIND "${unity_source_line}" "CMakeFiles/tgt.dir/Unity/unity_poolB.c" unity_source_file_position)
+if (unity_source_file_position EQUAL "-1")
+ set(RunCMake_TEST_FAILED "Generated project should include the generated unity source file.")
+ return()
+endif()
+
+list(LENGTH sources_list number_of_sources)
+if(NOT number_of_sources EQUAL 7)
+ set(RunCMake_TEST_FAILED "Generated project doesn't include the expect number of files.")
+ return()
+endif()
+
+# Exclusions for Debug|Release|MinSizeRel|RelWithDebInfo
+list(LENGTH excluded_sources_list number_of_excluded_sources)
+if(NOT number_of_excluded_sources EQUAL 28)
+ set(RunCMake_TEST_FAILED "Generated project doesn't exclude the source files for all configurations.")
+ return()
+endif()
diff --git a/Tests/RunCMake/VS10Project/UnityBuildPre2017Grouped.cmake b/Tests/RunCMake/VS10Project/UnityBuildPre2017Grouped.cmake
new file mode 100644
index 0000000..b740e3b
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/UnityBuildPre2017Grouped.cmake
@@ -0,0 +1,20 @@
+project(unitybuild_c C)
+
+set(srcs "")
+foreach(s RANGE 1 8)
+ set(src "${CMAKE_CURRENT_BINARY_DIR}/s${s}.c")
+ file(WRITE "${src}" "int s${s}(void) { return 0; }\n")
+ list(APPEND srcs "${src}")
+endforeach()
+
+add_library(tgt SHARED ${srcs})
+
+set_target_properties(tgt PROPERTIES UNITY_BUILD ON UNITY_BUILD_MODE GROUP)
+
+set_source_files_properties(s1.c s2.c s3.c s4.c
+ PROPERTIES UNITY_GROUP "poolA"
+ )
+
+set_source_files_properties(s5.c s6.c s7.c
+ PROPERTIES UNITY_GROUP "poolB"
+ )
diff --git a/Tests/RunCMake/VS10Project/VSDotnetTargetFrameworkVersion.cmake b/Tests/RunCMake/VS10Project/VSDotnetTargetFrameworkVersion.cmake
new file mode 100644
index 0000000..8e0e0b4
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VSDotnetTargetFrameworkVersion.cmake
@@ -0,0 +1,10 @@
+enable_language(CSharp)
+if(NOT CMAKE_CSharp_COMPILER)
+ return()
+endif()
+
+set(CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION "v4.6.1")
+add_library(foo SHARED foo.cs)
+
+set(CMAKE_DOTNET_TARGET_FRAMEWORK "netcoreapp3.1")
+add_library(bar SHARED foo.cs)
diff --git a/Tests/RunCMake/VS10Project/VsCSharpDefines-check.cmake b/Tests/RunCMake/VS10Project/VsCSharpDefines-check.cmake
index 152bf9c..631abac 100644
--- a/Tests/RunCMake/VS10Project/VsCSharpDefines-check.cmake
+++ b/Tests/RunCMake/VS10Project/VsCSharpDefines-check.cmake
@@ -27,15 +27,15 @@ foreach(line IN LISTS lines)
elseif(inDebug AND
(line MATCHES "^ *<DefineConstants>.*MY_FOO_DEFINE.*</DefineConstants> *$") AND
(line MATCHES "^ *<DefineConstants>.*DEFINE_ONLY_FOR_DEBUG.*</DefineConstants> *$") AND
- (line MATCHES "^ *<DefineConstants>.*MY_BAR_ASSIGNMENT=bar.*</DefineConstants> *$") AND
- (NOT (line MATCHES "^ *<DefineConstants>.*DEFINE_ONLY_FOR_RELEASE.*</DefineConstants> *$"))
+ (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
- (line MATCHES "^ *<DefineConstants>.*MY_BAR_ASSIGNMENT=bar.*</DefineConstants> *$") AND
- (NOT (line MATCHES "^ *<DefineConstants>.*DEFINE_ONLY_FOR_DEBUG.*</DefineConstants> *$"))
+ (NOT (line MATCHES "^ *<DefineConstants>.*DEFINE_ONLY_FOR_DEBUG.*</DefineConstants> *$")) AND
+ (NOT (line MATCHES "^ *<DefineConstants>.*MY_BAR_ASSIGNMENT=bar.*</DefineConstants> *$"))
)
set(releaseOK TRUE)
endif()
diff --git a/Tests/RunCMake/VS10Project/VsCSharpDocumentationFile-check.cmake b/Tests/RunCMake/VS10Project/VsCSharpDocumentationFile-check.cmake
new file mode 100644
index 0000000..0393362
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsCSharpDocumentationFile-check.cmake
@@ -0,0 +1,26 @@
+#
+# 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()
+
+file(STRINGS "${csProjectFile}" lines)
+
+set(HAVE_DocumentationFile 0)
+foreach(line IN LISTS lines)
+ if(line MATCHES "^ *<DocumentationFile>([^<>]+)</DocumentationFile>")
+ if(HAVE_DocumentationFile)
+ set(RunCMake_TEST_FAILED "Documentation node has been generated more than once for\n ${csProjectFile}")
+ return()
+ endif()
+ set(HAVE_DocumentationFile 1)
+ endif()
+endforeach()
+
+if(NOT HAVE_DocumentationFile)
+ set(RunCMake_TEST_FAILED "Documentation node has not been generated for\n ${csProjectFile}")
+ return()
+endif()
diff --git a/Tests/RunCMake/VS10Project/VsCSharpDocumentationFile.cmake b/Tests/RunCMake/VS10Project/VsCSharpDocumentationFile.cmake
new file mode 100644
index 0000000..83b6b97
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsCSharpDocumentationFile.cmake
@@ -0,0 +1,8 @@
+set(CMAKE_CONFIGURATION_TYPES Debug)
+enable_language(CSharp)
+
+add_library(foo SHARED
+ foo.cs)
+
+set_target_properties(foo PROPERTIES
+ VS_DOTNET_DOCUMENTATION_FILE foo.xml)
diff --git a/Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake b/Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake
new file mode 100644
index 0000000..3b5c70f
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake
@@ -0,0 +1,22 @@
+set(csProjFile "${RunCMake_TEST_BINARY_DIR}/VsCsharpSourceGroup.csproj")
+if(NOT EXISTS "${csProjFile}")
+ set(RunCMake_TEST_FAILED "Project file ${csProjFile} does not exist.")
+ return()
+endif()
+
+file(STRINGS "${csProjFile}" lines)
+
+include(${RunCMake_TEST_SOURCE_DIR}/VsCsharpSourceGroupHelpers.cmake)
+
+set(SOURCE_GROUPS_TO_FIND
+ "CSharpSourceGroup"
+ "CSharpSourceGroup/nested"
+ "Images"
+)
+
+foreach(GROUP_NAME IN LISTS ${SOURCE_GROUPS_TO_FIND})
+ find_source_group("${lines}" ${GROUP_NAME})
+ if(NOT ${SOURCE_GROUP_FOUND})
+ return()
+ endif()
+endforeach()
diff --git a/Tests/RunCMake/VS10Project/VsCsharpSourceGroup.cmake b/Tests/RunCMake/VS10Project/VsCsharpSourceGroup.cmake
new file mode 100644
index 0000000..024993c
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsCsharpSourceGroup.cmake
@@ -0,0 +1,16 @@
+enable_language(CSharp)
+set(CMAKE_CONFIGURATION_TYPES Debug)
+
+set(SRC_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/CSharpSourceGroup/foo.cs
+ ${CMAKE_CURRENT_SOURCE_DIR}/CSharpSourceGroup/nested/baz.cs
+)
+
+set(IMAGE_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/CSharpSourceGroup/Images/empty.bmp
+)
+
+add_library(VsCsharpSourceGroup SHARED ${SRC_FILES} ${IMAGE_FILES})
+source_group("CSharpSourceGroup" FILES ${CMAKE_CURRENT_SOURCE_DIR}/CSharpSourceGroup/foo.cs)
+source_group("CSharpSourceGroup/nested" FILES ${CMAKE_CURRENT_SOURCE_DIR}/CSharpSourceGroup/nested/baz.cs)
+source_group("Images" FILES ${IMAGE_FILES})
diff --git a/Tests/RunCMake/VS10Project/VsCsharpSourceGroupHelpers.cmake b/Tests/RunCMake/VS10Project/VsCsharpSourceGroupHelpers.cmake
new file mode 100644
index 0000000..bfa9a67
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsCsharpSourceGroupHelpers.cmake
@@ -0,0 +1,15 @@
+function(find_source_group LINES NAME)
+ set(foundSourceGroupLink 0)
+ foreach(line IN LISTS LINES)
+ if(line MATCHES "<Link>${NAME}</Link>")
+ set(foundSourceGroupLink 1)
+ endif()
+ endforeach()
+
+ if(NOT foundSourceGroupLink)
+ set(RunCMake_TEST_FAILED "Source group link for ${NAME} not found." PARENT_SCOPE)
+ set(SOURCE_GROUP_FOUND 0 PARENT_SCOPE)
+ return()
+ endif()
+ set(SOURCE_GROUP_FOUND 1 PARENT_SCOPE)
+endfunction()
diff --git a/Tests/RunCMake/VS10Project/VsDeployEnabled-check.cmake b/Tests/RunCMake/VS10Project/VsDeployEnabled-check.cmake
new file mode 100644
index 0000000..0ff8678
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsDeployEnabled-check.cmake
@@ -0,0 +1,58 @@
+set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/foo.vcxproj")
+if(NOT EXISTS "${vcProjectFile}")
+ set(RunCMake_TEST_FAILED "Project file ${vcProjectFile} does not exist.")
+ return()
+endif()
+#
+# Test solution file for deployment.
+#
+
+set(vcSlnFile "${RunCMake_TEST_BINARY_DIR}/VsDeployEnabled.sln")
+if(NOT EXISTS "${vcSlnFile}")
+ set(RunCMake_TEST_FAILED "Solution file ${vcSlnFile} does not exist.")
+ return()
+endif()
+
+
+
+set(FooProjGUID "")
+set(FoundFooProj FALSE)
+set(InFooProj FALSE)
+set(FoundReleaseDeploy FALSE)
+set(DeployConfigs Debug MinSizeRel RelWithDebInfo )
+
+file(STRINGS "${vcSlnFile}" lines)
+foreach(line IN LISTS lines)
+#message(STATUS "${line}")
+ if( (NOT InFooProj ) AND (line MATCHES "^[ \\t]*Project\\(\"{[A-F0-9-]+}\"\\) = \"foo\", \"foo.vcxproj\", \"({[A-F0-9-]+})\"[ \\t]*$"))
+ # First, identify the GUID for the foo project, and record it.
+ set(FoundFooProj TRUE)
+ set(InFooProj TRUE)
+ set(FooProjGUID ${CMAKE_MATCH_1})
+ elseif(InFooProj AND line MATCHES "EndProject")
+ set(InFooProj FALSE)
+ elseif((NOT InFooProj) AND line MATCHES "${FooProjGUID}\\.Release.*\\.Deploy\\.0")
+ # If foo's Release configuration is set to deploy, this is the error.
+ set(FoundReleaseDeploy TRUE)
+ endif()
+ if( line MATCHES "{[A-F0-9-]+}\\.([^\\|]+).*\\.Deploy\\.0" )
+ # Check that the other configurations ARE set to deploy.
+ list( REMOVE_ITEM DeployConfigs ${CMAKE_MATCH_1})
+ endif()
+endforeach()
+
+if(FoundReleaseDeploy)
+ set(RunCMake_TEST_FAILED "Release deployment enabled.")
+ return()
+endif()
+
+if(NOT FoundFooProj)
+ set(RunCMake_TEST_FAILED "Failed to find foo project in the solution.")
+ return()
+endif()
+
+list(LENGTH DeployConfigs length)
+if( length GREATER 0 )
+ set(RunCMake_TEST_FAILED "Failed to find Deploy lines for non-Release configurations. (${length})")
+ return()
+endif()
diff --git a/Tests/RunCMake/VS10Project/VsDeployEnabled.cmake b/Tests/RunCMake/VS10Project/VsDeployEnabled.cmake
new file mode 100644
index 0000000..02b42b2
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsDeployEnabled.cmake
@@ -0,0 +1,12 @@
+enable_language(CXX)
+
+set(DEPLOY_DIR
+ "temp\\foodir"
+)
+
+add_library(foo SHARED foo.cpp)
+
+set_target_properties(foo
+ PROPERTIES
+ VS_SOLUTION_DEPLOY $<NOT:$<CONFIG:Release>>
+)
diff --git a/Tests/RunCMake/VS10Project/VsDotnetTargetFramework-check.cmake b/Tests/RunCMake/VS10Project/VsDotnetTargetFramework-check.cmake
new file mode 100644
index 0000000..e656639
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsDotnetTargetFramework-check.cmake
@@ -0,0 +1,40 @@
+set(files foo.csproj bar.csproj)
+
+set(inLib1 FALSE)
+set(targetFrameworkInLib1 FALSE)
+
+set(inLib2 FALSE)
+set(targetFrameworksInLib2 FALSE)
+
+foreach(file ${files})
+ set(csProjectFile ${RunCMake_TEST_BINARY_DIR}/${file})
+
+ if(NOT EXISTS "${csProjectFile}")
+ set(RunCMake_TEST_FAILED "Project file ${csProjectFile} does not exist.")
+ return()
+ endif()
+
+ file(STRINGS "${csProjectFile}" lines)
+
+ foreach(line IN LISTS lines)
+ if(NOT inLib1)
+ if(line MATCHES " *<TargetFramework>netcoreapp3.1</TargetFramework> *$")
+ set(targetFrameworkInLib1 TRUE)
+ set(inLib1 TRUE)
+ endif()
+ elseif(NOT inLib2)
+ if(line MATCHES " *<TargetFrameworks>netcoreapp3.1;net461</TargetFrameworks> *$")
+ set(targetFrameworksInLib2 TRUE)
+ set(inLib2 TRUE)
+ endif()
+ endif()
+ endforeach()
+endforeach()
+
+if(NOT targetFrameworkInLib1)
+ set(RunCMake_TEST_FAILED "TargetFramework not set correctly.")
+endif()
+
+if(NOT targetFrameworksInLib2)
+ set(RunCMake_TEST_FAILED "TargetFrameworks not set correctly.")
+endif()
diff --git a/Tests/RunCMake/VS10Project/VsDotnetTargetFramework.cmake b/Tests/RunCMake/VS10Project/VsDotnetTargetFramework.cmake
new file mode 100644
index 0000000..f553679
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsDotnetTargetFramework.cmake
@@ -0,0 +1,11 @@
+enable_language(CSharp)
+if(NOT CMAKE_CSharp_COMPILER)
+ return()
+endif()
+
+set(CMAKE_DOTNET_TARGET_FRAMEWORK "netcoreapp3.1")
+set(CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION "net461")
+add_library(foo SHARED foo.cs)
+
+set(CMAKE_DOTNET_TARGET_FRAMEWORK "netcoreapp3.1;net461")
+add_library(bar SHARED foo.cs)
diff --git a/Tests/RunCMake/VS10Project/VsDotnetTargetFrameworkVersion-check.cmake b/Tests/RunCMake/VS10Project/VsDotnetTargetFrameworkVersion-check.cmake
new file mode 100644
index 0000000..d2c3c3b
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsDotnetTargetFrameworkVersion-check.cmake
@@ -0,0 +1,40 @@
+set(files foo.csproj bar.csproj)
+
+set(inLib1 FALSE)
+set(targetFrameworkInLib1 FALSE)
+
+set(inLib2 FALSE)
+set(targetFrameworksInLib2 FALSE)
+
+foreach(file ${files})
+ set(csProjectFile ${RunCMake_TEST_BINARY_DIR}/${file})
+
+ if(NOT EXISTS "${csProjectFile}")
+ set(RunCMake_TEST_FAILED "Project file ${csProjectFile} does not exist.")
+ return()
+ endif()
+
+ file(STRINGS "${csProjectFile}" lines)
+
+ foreach(line IN LISTS lines)
+ if(NOT inLib1)
+ if(line MATCHES " *<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion> *$")
+ set(targetFrameworkInLib1 TRUE)
+ set(inLib1 TRUE)
+ endif()
+ elseif(NOT inLib2)
+ if(line MATCHES " *<TargetFramework>netcoreapp3.1</TargetFramework> *$")
+ set(targetFrameworksInLib2 TRUE)
+ set(inLib2 TRUE)
+ endif()
+ endif()
+ endforeach()
+endforeach()
+
+if(NOT targetFrameworkInLib1)
+ set(RunCMake_TEST_FAILED "TargetFrameworkVersion not set correctly.")
+endif()
+
+if(NOT targetFrameworksInLib2)
+ set(RunCMake_TEST_FAILED "TargetFramework not set correctly.")
+endif()
diff --git a/Tests/RunCMake/VS10Project/VsGlobals-check.cmake b/Tests/RunCMake/VS10Project/VsGlobals-check.cmake
index 0e7fd45..6a30099 100644
--- a/Tests/RunCMake/VS10Project/VsGlobals-check.cmake
+++ b/Tests/RunCMake/VS10Project/VsGlobals-check.cmake
@@ -1,44 +1,65 @@
-set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/foo.vcxproj")
-if(NOT EXISTS "${vcProjectFile}")
- set(RunCMake_TEST_FAILED "Project file ${vcProjectFile} does not exist.")
- return()
-endif()
+macro(check_project_file projectFile)
+ if(NOT EXISTS "${projectFile}")
+ set(RunCMake_TEST_FAILED "Project file ${projectFile} does not exist.")
+ return()
+ endif()
+
+ string(REPLACE "${RunCMake_TEST_BINARY_DIR}/" "" projectName ${projectFile})
-set(InsideGlobals FALSE)
-set(DefaultLanguageSet FALSE)
-set(MinimumVisualStudioVersionSet FALSE)
+ set(InsideGlobals FALSE)
+ set(DefaultLanguageSet FALSE)
+ set(MinimumVisualStudioVersionSet FALSE)
+ set(TestPropertySet FALSE)
-file(STRINGS "${vcProjectFile}" lines)
-foreach(line IN LISTS lines)
- if(line MATCHES "^ *<PropertyGroup Label=\"Globals\"> *$")
- set(InsideGlobals TRUE)
- elseif(line MATCHES "^ *<DefaultLanguage>([a-zA-Z\\-]+)</DefaultLanguage> *$")
- if("${CMAKE_MATCH_1}" STREQUAL "en-US")
- if(InsideGlobals)
- message(STATUS "foo.vcxproj has correct DefaultLanguage global property")
- set(DefaultLanguageSet TRUE)
- else()
- message(STATUS "DefaultLanguage is set but not within \"Globals\" property group")
+ file(STRINGS "${projectFile}" lines)
+ foreach(line IN LISTS lines)
+ if(line MATCHES "^ *<PropertyGroup Label=\"Globals\"> *$")
+ set(InsideGlobals TRUE)
+ elseif(line MATCHES "^ *<DefaultLanguage>([a-zA-Z\\-]+)</DefaultLanguage> *$")
+ if("${CMAKE_MATCH_1}" STREQUAL "en-US")
+ if(InsideGlobals)
+ message(STATUS "${projectName} has correct DefaultLanguage global property")
+ set(DefaultLanguageSet TRUE)
+ else()
+ message(STATUS "DefaultLanguage is set but not within \"Globals\" property group")
+ endif()
endif()
- endif()
- elseif(line MATCHES "^ *<MinimumVisualStudioVersion>([0-9\\.]+)</MinimumVisualStudioVersion> *$")
- if("${CMAKE_MATCH_1}" STREQUAL "14.0")
- if(InsideGlobals)
- message(STATUS "foo.vcxproj has correct MinimumVisualStudioVersion global property")
- set(MinimumVisualStudioVersionSet TRUE)
- else()
- message(STATUS "MinimumVisualStudioVersion is set but not within \"Globals\" property group")
+ elseif(line MATCHES "^ *<MinimumVisualStudioVersion>([0-9\\.]+)</MinimumVisualStudioVersion> *$")
+ if("${CMAKE_MATCH_1}" STREQUAL "10.0")
+ if(InsideGlobals)
+ message(STATUS "${projectName} has correct MinimumVisualStudioVersion global property")
+ set(MinimumVisualStudioVersionSet TRUE)
+ else()
+ message(STATUS "MinimumVisualStudioVersion is set but not within \"Globals\" property group")
+ endif()
+ endif()
+ elseif(line MATCHES "^ *<TestProperty>(.+)</TestProperty> *$")
+ if("${CMAKE_MATCH_1}" STREQUAL "TestValue")
+ if(InsideGlobals)
+ message(STATUS "${projectName} has correct TestProperty global property")
+ set(TestPropertySet TRUE)
+ else()
+ message(STATUS "TestProperty is set but not within \"Globals\" property group")
+ endif()
endif()
endif()
+ endforeach()
+
+ if(NOT DefaultLanguageSet)
+ set(RunCMake_TEST_FAILED "DefaultLanguage not found or not set correctly in ${projectName}.")
+ return()
+ endif()
+
+ if(NOT MinimumVisualStudioVersionSet)
+ set(RunCMake_TEST_FAILED "MinimumVisualStudioVersion not found or not set correctly in ${projectName}.")
+ return()
endif()
-endforeach()
-if(NOT DefaultLanguageSet)
- set(RunCMake_TEST_FAILED "DefaultLanguageSet not found or not set correctly.")
- return()
-endif()
+ if(NOT TestPropertySet)
+ set(RunCMake_TEST_FAILED "TestProperty not found or not set correctly in ${projectName}.")
+ return()
+ endif()
+endmacro()
-if(NOT MinimumVisualStudioVersionSet)
- set(RunCMake_TEST_FAILED "MinimumVisualStudioVersionSet not found or not set correctly.")
- return()
-endif()
+check_project_file("${RunCMake_TEST_BINARY_DIR}/CMakeFiles/${CMAKE_VERSION}/CompilerIdCXX/CompilerIdCXX.vcxproj")
+check_project_file("${RunCMake_TEST_BINARY_DIR}/foo.vcxproj")
diff --git a/Tests/RunCMake/VS10Project/VsGlobals.cmake b/Tests/RunCMake/VS10Project/VsGlobals.cmake
index a3ed5af..09d806d 100644
--- a/Tests/RunCMake/VS10Project/VsGlobals.cmake
+++ b/Tests/RunCMake/VS10Project/VsGlobals.cmake
@@ -1,8 +1,9 @@
-enable_language(CXX)
-
set(CMAKE_VS_GLOBALS
"DefaultLanguage=en-US"
- "MinimumVisualStudioVersion=14.0"
+ "MinimumVisualStudioVersion=10.0"
+ "TestProperty=TestValue"
)
+enable_language(CXX)
+
add_library(foo foo.cpp)
diff --git a/Tests/RunCMake/VS10Project/VsPlatformToolset-check.cmake b/Tests/RunCMake/VS10Project/VsPlatformToolset-check.cmake
new file mode 100644
index 0000000..416220b
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsPlatformToolset-check.cmake
@@ -0,0 +1,36 @@
+macro(ReadPlatformToolset tgt outvar)
+ set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/${tgt}.vcxproj")
+ if(NOT EXISTS "${vcProjectFile}")
+ set(RunCMake_TEST_FAILED "Project file ${tgt}.vcxproj does not exist.")
+ return()
+ endif()
+
+ set(HAVE_PlatformToolset 0)
+
+ file(STRINGS "${vcProjectFile}" lines)
+ foreach(line IN LISTS lines)
+ if(line MATCHES "^ *<PlatformToolset>([^<>]+)</PlatformToolset>")
+ set(${outvar} "${CMAKE_MATCH_1}")
+ set(HAVE_PlatformToolset 1)
+ break()
+ endif()
+ endforeach()
+
+ if(NOT HAVE_PlatformToolset)
+ set(RunCMake_TEST_FAILED "Project file ${tgt}.vcxproj does not have a <PlatformToolset> field.")
+ return()
+ endif()
+endmacro()
+
+ReadPlatformToolset(NormalPlatformToolset NORMAL_TOOLSET)
+ReadPlatformToolset(OverridenPlatformToolset OVERRIDEN_TOOLSET)
+
+if (NOT "${OVERRIDEN_TOOLSET}" STREQUAL "MyCustomToolset")
+ set(RunCMake_TEST_FAILED "Failed to override the platform toolset")
+ return()
+endif()
+
+if ("${NORMAL_TOOLSET}" STREQUAL "MyCustomToolset")
+ set(RunCMake_TEST_FAILED "Main toolset was overriden (it shouldn't)")
+ return()
+endif()
diff --git a/Tests/RunCMake/VS10Project/VsPlatformToolset.cmake b/Tests/RunCMake/VS10Project/VsPlatformToolset.cmake
new file mode 100644
index 0000000..dce9717
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsPlatformToolset.cmake
@@ -0,0 +1,6 @@
+enable_language(CXX)
+
+add_library(NormalPlatformToolset foo.cpp)
+add_library(OverridenPlatformToolset foo.cpp)
+set_target_properties(OverridenPlatformToolset
+ PROPERTIES VS_PLATFORM_TOOLSET MyCustomToolset)
diff --git a/Tests/RunCMake/VS10Project/VsPrecompileHeaders-check.cmake b/Tests/RunCMake/VS10Project/VsPrecompileHeaders-check.cmake
index 91cea0e..9c214f1 100644
--- a/Tests/RunCMake/VS10Project/VsPrecompileHeaders-check.cmake
+++ b/Tests/RunCMake/VS10Project/VsPrecompileHeaders-check.cmake
@@ -1,4 +1,4 @@
-set(pch_header "CMakeFiles/tgt.dir/cmake_pch.hxx")
+set(pch_header "CMakeFiles/tgt.dir/Debug/cmake_pch.hxx")
set(pch_source [=[CMakeFiles\\tgt.dir\\cmake_pch.cxx]=])
if(NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/${pch_header}")
diff --git a/Tests/RunCMake/VS10Project/VsSettings-check.cmake b/Tests/RunCMake/VS10Project/VsSettings-check.cmake
new file mode 100644
index 0000000..0f8b26c
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsSettings-check.cmake
@@ -0,0 +1,23 @@
+macro(ensure_props_set projectFile)
+ if(NOT EXISTS "${projectFile}")
+ set(RunCMake_TEST_FAILED "Project file ${projectFile} does not exist.")
+ return()
+ endif()
+
+ set(SettingFound FALSE)
+
+ file(STRINGS "${projectFile}" lines)
+ foreach(line IN LISTS lines)
+ if(line MATCHES "<SourceProperty1.*Debug.*>SourceProperty1Value</SourceProperty1>")
+ message("SourceProperty1 setting found")
+ set(SettingFound TRUE)
+ endif()
+ endforeach()
+
+ if (NOT SettingFound)
+ set(RunCMake_TEST_FAILED "SourceProperty1 setting was not found")
+ return()
+ endif()
+endmacro()
+
+ensure_props_set("${RunCMake_TEST_BINARY_DIR}/foo.vcxproj")
diff --git a/Tests/RunCMake/VS10Project/VsSettings.cmake b/Tests/RunCMake/VS10Project/VsSettings.cmake
new file mode 100644
index 0000000..a4b321b
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsSettings.cmake
@@ -0,0 +1,5 @@
+enable_language(CXX)
+
+add_library(foo foo.cpp shader.hlsl)
+set_property(SOURCE shader.hlsl PROPERTY VS_SETTINGS
+ "$<$<CONFIG:DEBUG>:SourceProperty1=SourceProperty1Value>")
diff --git a/Tests/RunCMake/VS10Project/VsSourceSettingsTool-check.cmake b/Tests/RunCMake/VS10Project/VsSourceSettingsTool-check.cmake
new file mode 100644
index 0000000..29a89c3
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsSourceSettingsTool-check.cmake
@@ -0,0 +1,34 @@
+macro(ensure_props_set projectFile)
+ if(NOT EXISTS "${projectFile}")
+ set(RunCMake_TEST_FAILED "Project file ${projectFile} does not exist.")
+ return()
+ endif()
+
+ set(FirstSettingFound FALSE)
+ set(SecondSettingFound FALSE)
+
+ file(STRINGS "${projectFile}" lines)
+ foreach(line IN LISTS lines)
+ if(line MATCHES "<TargetProperty1.*Debug.*>TargetProperty1ValueDebug</TargetProperty1>")
+ if (FirstSettingFound)
+ message("TargetProperty1 setting found twice")
+ set(SecondSettingFound TRUE)
+ else()
+ message("TargetProperty1 setting found once")
+ set(FirstSettingFound TRUE)
+ endif()
+ endif()
+ endforeach()
+
+ if (NOT FirstSettingFound)
+ set(RunCMake_TEST_FAILED "TargetProperty1 setting not found at all")
+ return()
+ endif()
+
+ if (NOT SecondSettingFound)
+ set(RunCMake_TEST_FAILED "TargetProperty1 setting found once when it should be found twice")
+ return()
+ endif()
+endmacro()
+
+ensure_props_set("${RunCMake_TEST_BINARY_DIR}/foo.vcxproj")
diff --git a/Tests/RunCMake/VS10Project/VsSourceSettingsTool.cmake b/Tests/RunCMake/VS10Project/VsSourceSettingsTool.cmake
new file mode 100644
index 0000000..498962f
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsSourceSettingsTool.cmake
@@ -0,0 +1,5 @@
+enable_language(CXX)
+
+add_library(foo foo.cpp shader.hlsl shader2.hlsl)
+set_property(TARGET foo PROPERTY VS_SOURCE_SETTINGS_FXCompile
+ "$<$<CONFIG:DEBUG>:TargetProperty1=TargetProperty1ValueDebug>")
diff --git a/Tests/RunCMake/VS10Project/VsVCTargetsPath-check.cmake b/Tests/RunCMake/VS10Project/VsVCTargetsPath-check.cmake
new file mode 100644
index 0000000..5b1701c
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsVCTargetsPath-check.cmake
@@ -0,0 +1,32 @@
+macro(check_project_file projectFile)
+ set(insideGlobals FALSE)
+ set(pathFound FALSE)
+
+ if(NOT EXISTS "${projectFile}")
+ set(RunCMake_TEST_FAILED "Project file ${projectFile} does not exist.")
+ return()
+ endif()
+
+ string(REPLACE "${RunCMake_TEST_BINARY_DIR}/" "" projectName ${projectFile})
+
+ file(STRINGS "${projectFile}" lines)
+ foreach(line IN LISTS lines)
+ if(line MATCHES "^ *<PropertyGroup Label=\"Globals\">.*$")
+ set(insideGlobals TRUE)
+ elseif(insideGlobals)
+ if(line MATCHES "^ *</PropertyGroup>.*$")
+ set(insideGlobals FALSE)
+ elseif(line MATCHES "^ *<VCTargetsPath>(.+)</VCTargetsPath>*$")
+ message(STATUS "Found VCTargetsPath = ${CMAKE_MATCH_1} in PropertyGroup 'Globals' in ${projectName}")
+ set(pathFound TRUE)
+ endif()
+ endif()
+ endforeach()
+ if(NOT pathFound)
+ set(RunCMake_TEST_FAILED "VCTargetsPath not found in \"Globals\" propertygroup in ${projectName}")
+ return() # This should intentionally return from the caller, not the macro
+ endif()
+endmacro()
+
+check_project_file("${RunCMake_TEST_BINARY_DIR}/CMakeFiles/${CMAKE_VERSION}/CompilerIdCXX/CompilerIdCXX.vcxproj")
+check_project_file("${RunCMake_TEST_BINARY_DIR}/foo.vcxproj")
diff --git a/Tests/RunCMake/VS10Project/VsVCTargetsPath.cmake b/Tests/RunCMake/VS10Project/VsVCTargetsPath.cmake
new file mode 100644
index 0000000..6a6088f
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsVCTargetsPath.cmake
@@ -0,0 +1,3 @@
+enable_language(CXX)
+
+add_library(foo foo.cpp)
diff --git a/Tests/RunCMake/VS10Project/VsWinRTByDefault-check.cmake b/Tests/RunCMake/VS10Project/VsWinRTByDefault-check.cmake
new file mode 100644
index 0000000..15bbaf2
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsWinRTByDefault-check.cmake
@@ -0,0 +1,66 @@
+macro(checkCompileAsWinRT projectPath)
+ if(RunCMake_TEST_FAILED)
+ return()
+ endif()
+
+ if (NOT EXISTS "${projectPath}")
+ set(RunCMake_TEST_FAILED "Project file ${projectPath} does not exist.")
+ return()
+ endif()
+
+ get_filename_component(projectName "${projectPath}" NAME_WE)
+
+ cmake_parse_arguments("" "" "GLOBAL" "OVERRIDES_ENABLE;OVERRIDES_DISABLE" ${ARGN})
+
+ unset(sourceOverride)
+
+ file(STRINGS "${projectPath}" lines)
+ set(foundGlobalWinRT false)
+
+ foreach(line IN LISTS lines)
+ if(line MATCHES "^ *<CompileAsWinRT( Condition=\"[^\\\"]+\")?>(true|false)</CompileAsWinRT>$")
+ set(value ${CMAKE_MATCH_2})
+
+ if(sourceOverride)
+ set(expectedList)
+
+ if(value)
+ set(expectedList _OVERRIDES_ENABLE)
+ else()
+ set(expectedList _OVERRIDES_DISABLE)
+ endif()
+
+ if(NOT sourceOverride IN_LIST ${expectedList})
+ set(RunCMake_TEST_FAILED
+ "${projectName}: Unexpected CompileAsWinRT override ${value} for ${sourceOverride}")
+ return()
+ endif()
+ else()
+ if (NOT _GLOBAL STREQUAL value)
+ set(RunCMake_TEST_FAILED
+ "${projectName}: Global CompileAsWinRT value is ${value}, but expected ${_GLOBAL}")
+ return()
+ endif()
+
+ set(foundGlobalWinRT true)
+ endif()
+ elseif(line MATCHES "^ *<ClCompile Include=\"([^\"]+)\">$")
+ get_filename_component(sourceOverride "${CMAKE_MATCH_1}" NAME)
+ elseif(line MATCHES "^ *</ClCompile>$")
+ unset(sourceOverride)
+ endif()
+ endforeach()
+
+ if(NOT foundGlobalWinRT AND DEFINED _GLOBAL)
+ set(RunCMake_TEST_FAILED "${projectName}: Global CompileAsWinRT not found or have invalid value, but expected")
+ return()
+ endif()
+endmacro()
+
+checkCompileAsWinRT("${RunCMake_TEST_BINARY_DIR}/noFlagOnlyC.vcxproj" GLOBAL false)
+checkCompileAsWinRT("${RunCMake_TEST_BINARY_DIR}/noFlagMixedCAndCxx.vcxproj" GLOBAL false)
+checkCompileAsWinRT("${RunCMake_TEST_BINARY_DIR}/noFlagOnlyCxx.vcxproj" GLOBAL false)
+
+checkCompileAsWinRT("${RunCMake_TEST_BINARY_DIR}/flagOnlyC.vcxproj" GLOBAL true OVERRIDES_DISABLE empty.c)
+checkCompileAsWinRT("${RunCMake_TEST_BINARY_DIR}/flagMixedCAndCxx.vcxproj" GLOBAL true OVERRIDES_DISABLE empty.c)
+checkCompileAsWinRT("${RunCMake_TEST_BINARY_DIR}/flagOnlyCxx.vcxproj" GLOBAL true)
diff --git a/Tests/RunCMake/VS10Project/VsWinRTByDefault.cmake b/Tests/RunCMake/VS10Project/VsWinRTByDefault.cmake
new file mode 100644
index 0000000..139048b
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsWinRTByDefault.cmake
@@ -0,0 +1,16 @@
+set(CMAKE_VS_WINRT_BY_DEFAULT true)
+
+enable_language(C)
+enable_language(CXX)
+
+add_library(noFlagOnlyC empty.c)
+add_library(noFlagMixedCAndCXX empty.c foo.cpp)
+add_library(noFlagOnlyCXX foo.cpp)
+
+add_library(flagOnlyC empty.c)
+add_library(flagMixedCAndCXX empty.c foo.cpp)
+add_library(flagOnlyCXX foo.cpp)
+
+target_compile_options(flagOnlyC PRIVATE /ZW)
+target_compile_options(flagMixedCAndCXX PRIVATE /ZW)
+target_compile_options(flagOnlyCXX PRIVATE /ZW)
diff --git a/Tests/RunCMake/VS10Project/shader.hlsl b/Tests/RunCMake/VS10Project/shader.hlsl
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/shader.hlsl
@@ -0,0 +1 @@
+
diff --git a/Tests/RunCMake/VS10Project/shader2.hlsl b/Tests/RunCMake/VS10Project/shader2.hlsl
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/shader2.hlsl
@@ -0,0 +1 @@
+
diff --git a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
index 6ecf3f2..342dbbc 100644
--- a/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
+++ b/Tests/RunCMake/XcodeProject/RunCMakeTest.cmake
@@ -8,6 +8,16 @@ run_cmake(XcodeAttributeLocation)
run_cmake(XcodeAttributeGenex)
run_cmake(XcodeAttributeGenexError)
run_cmake(XcodeGenerateTopLevelProjectOnly)
+
+function(XcodeGenerateTopLevelProjectOnlyWithObjectLibrary)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/XcodeGenerateTopLevelProjectOnlyWithObjectLibrary-build)
+ run_cmake(XcodeGenerateTopLevelProjectOnlyWithObjectLibrary)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ run_cmake_command(XcodeGenerateTopLevelProjectOnlyWithObjectLibrary-build ${CMAKE_COMMAND} --build . --target shared_lib)
+endfunction()
+
+XcodeGenerateTopLevelProjectOnlyWithObjectLibrary()
+
run_cmake(XcodeObjectNeedsEscape)
run_cmake(XcodeObjectNeedsQuote)
run_cmake(XcodeOptimizationFlags)
@@ -68,6 +78,15 @@ endfunction()
XcodeObjcxxFlags(XcodeObjcFlags)
XcodeObjcxxFlags(XcodeObjcxxFlags)
+function(XcodeRemoveExcessiveISystem)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/XcodeRemoveExcessiveISystem-build)
+ run_cmake(XcodeRemoveExcessiveISystem)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ run_cmake_command(XcodeRemoveExcessiveISystem-build ${CMAKE_COMMAND} --build .)
+endfunction()
+
+XcodeRemoveExcessiveISystem()
+
# Isolate device tests from host architecture selection.
unset(ENV{CMAKE_OSX_ARCHITECTURES})
@@ -287,4 +306,16 @@ if(XCODE_VERSION VERSION_GREATER_EQUAL 8)
xctest_lookup_test(tvOS appletvsimulator)
endif()
+if(XCODE_VERSION VERSION_GREATER_EQUAL 8)
+ function(XcodeRemoveExcessiveISystemSDK SDK)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/XcodeRemoveExcessiveISystemSDK-${SDK}-build)
+ set(RunCMake_TEST_OPTIONS "-DCMAKE_SYSTEM_NAME=iOS")
+ run_cmake(XcodeRemoveExcessiveISystem)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ run_cmake_command(XcodeRemoveExcessiveISystemSDK-${SDK}-build ${CMAKE_COMMAND} --build . -- -sdk ${SDK})
+ endfunction()
+
+ XcodeRemoveExcessiveISystemSDK(iphoneos)
+ XcodeRemoveExcessiveISystemSDK(iphonesimulator)
+endif()
# Please add macOS-only tests above before the device-specific tests.
diff --git a/Tests/RunCMake/XcodeProject/XcodeGenerateTopLevelProjectOnlyWithObjectLibrary.cmake b/Tests/RunCMake/XcodeProject/XcodeGenerateTopLevelProjectOnlyWithObjectLibrary.cmake
new file mode 100644
index 0000000..67e4a00
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeGenerateTopLevelProjectOnlyWithObjectLibrary.cmake
@@ -0,0 +1,3 @@
+set(CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY TRUE)
+project(XcodeGenerateTopLevelProjectOnly NONE)
+add_subdirectory(subproject_with_object_lib)
diff --git a/Tests/RunCMake/XcodeProject/XcodePrecompileHeaders-check.cmake b/Tests/RunCMake/XcodeProject/XcodePrecompileHeaders-check.cmake
index aa3eafc..4e85db6 100644
--- a/Tests/RunCMake/XcodeProject/XcodePrecompileHeaders-check.cmake
+++ b/Tests/RunCMake/XcodeProject/XcodePrecompileHeaders-check.cmake
@@ -1,4 +1,4 @@
-set(pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/cmake_pch.hxx")
+set(pch_header "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/tgt.dir/Debug/cmake_pch.hxx")
if(NOT EXISTS "${pch_header}")
set(RunCMake_TEST_FAILED "Generated PCH header ${pch_header} does not exist.")
diff --git a/Tests/RunCMake/XcodeProject/XcodeRemoveExcessiveISystem.cmake b/Tests/RunCMake/XcodeProject/XcodeRemoveExcessiveISystem.cmake
new file mode 100644
index 0000000..44052f0
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/XcodeRemoveExcessiveISystem.cmake
@@ -0,0 +1,52 @@
+cmake_minimum_required (VERSION 3.14)
+
+if(NOT "$ENV{CMAKE_OSX_ARCHITECTURES}" MATCHES "[;$]")
+ set(USE_SWIFT 1)
+else()
+ set(USE_SWIFT 0)
+endif()
+
+if(IOS)
+ set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED NO)
+ set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
+ if(XCODE_VERSION VERSION_LESS 9)
+ set(USE_SWIFT 0)
+ endif()
+endif ()
+
+enable_language (CXX)
+
+if(USE_SWIFT)
+ enable_language (Swift)
+ if(NOT XCODE_VERSION VERSION_LESS 10.2)
+ set(CMAKE_Swift_LANGUAGE_VERSION 5.0)
+ elseif(NOT XCODE_VERSION VERSION_LESS 8.0)
+ set(CMAKE_Swift_LANGUAGE_VERSION 3.0)
+ endif()
+endif()
+
+# Try to find ZLIB in the SDK rather than in system locations.
+set(CMAKE_FIND_USE_PACKAGE_ROOT_PATH FALSE)
+set(CMAKE_FIND_USE_CMAKE_PATH FALSE)
+set(CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH FALSE)
+set(CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH FALSE)
+list(REMOVE_ITEM CMAKE_SYSTEM_PREFIX_PATH /usr/local /usr / /usr/X11R6 /usr/pkg /opt /sw /opt/local)
+
+find_package(ZLIB REQUIRED)
+add_library (framework_dependency STATIC)
+target_sources (framework_dependency PRIVATE use_cmath.cpp)
+target_link_libraries(framework_dependency INTERFACE ZLIB::ZLIB)
+
+add_library (framework_test SHARED use_cmath.cpp)
+if(USE_SWIFT)
+ target_sources(framework_test PRIVATE foo.swift)
+endif()
+target_link_libraries (framework_test PRIVATE framework_dependency)
+
+set_target_properties (framework_test PROPERTIES
+ FRAMEWORK TRUE
+ FRAMEWORK_VERSION A
+ MACOSX_FRAMEWORK_IDENTIFIER "framework.test"
+ VERSION "1.0"
+ SOVERSION 1.0
+ )
diff --git a/Tests/RunCMake/XcodeProject/XcodeSchemaProperty-check.cmake b/Tests/RunCMake/XcodeProject/XcodeSchemaProperty-check.cmake
index 7d83a70..c742f50 100644
--- a/Tests/RunCMake/XcodeProject/XcodeSchemaProperty-check.cmake
+++ b/Tests/RunCMake/XcodeProject/XcodeSchemaProperty-check.cmake
@@ -45,6 +45,7 @@ check_property("ENVIRONMENT" [=[key="FOO"]=])
check_property("ENVIRONMENT" [=[value="foo"]=])
check_property("ENVIRONMENT" [=[key="BAR"]=])
check_property("ENVIRONMENT" [=[value="bar"]=])
+check_property("WORKING_DIRECTORY" [=["/working/dir"]=])
expect_no_schema("NoSchema")
diff --git a/Tests/RunCMake/XcodeProject/XcodeSchemaProperty.cmake b/Tests/RunCMake/XcodeProject/XcodeSchemaProperty.cmake
index be219f4..ce5c0c9 100644
--- a/Tests/RunCMake/XcodeProject/XcodeSchemaProperty.cmake
+++ b/Tests/RunCMake/XcodeProject/XcodeSchemaProperty.cmake
@@ -35,6 +35,7 @@ endfunction()
create_scheme_for_property(EXECUTABLE myExecutable)
create_scheme_for_property(ARGUMENTS "--foo;--bar=baz")
create_scheme_for_property(ENVIRONMENT "FOO=foo;BAR=bar")
+create_scheme_for_property(WORKING_DIRECTORY "/working/dir")
add_executable(NoSchema main.cpp)
set_target_properties(NoSchema PROPERTIES XCODE_GENERATE_SCHEME OFF)
diff --git a/Tests/RunCMake/XcodeProject/foo.swift b/Tests/RunCMake/XcodeProject/foo.swift
new file mode 100644
index 0000000..fb2d3dc
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/foo.swift
@@ -0,0 +1,2 @@
+func foo() {
+}
diff --git a/Tests/RunCMake/XcodeProject/subproject_with_object_lib/CMakeLists.txt b/Tests/RunCMake/XcodeProject/subproject_with_object_lib/CMakeLists.txt
new file mode 100644
index 0000000..ab400f4
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/subproject_with_object_lib/CMakeLists.txt
@@ -0,0 +1,7 @@
+project(subproject_with_object_lib)
+
+add_library(object_lib_dependency OBJECT dummy.cpp)
+
+add_library(shared_lib SHARED dummy.cpp)
+target_sources(shared_lib PRIVATE $<TARGET_OBJECTS:object_lib_dependency>)
+set_target_properties(shared_lib PROPERTIES MACOSX_RPATH ON)
diff --git a/Tests/RunCMake/XcodeProject/subproject_with_object_lib/dummy.cpp b/Tests/RunCMake/XcodeProject/subproject_with_object_lib/dummy.cpp
new file mode 100644
index 0000000..bb4218a
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/subproject_with_object_lib/dummy.cpp
@@ -0,0 +1,5 @@
+namespace {
+void dummy()
+{
+}
+}
diff --git a/Tests/RunCMake/XcodeProject/use_cmath.cpp b/Tests/RunCMake/XcodeProject/use_cmath.cpp
new file mode 100644
index 0000000..8a58af5
--- /dev/null
+++ b/Tests/RunCMake/XcodeProject/use_cmath.cpp
@@ -0,0 +1,6 @@
+#include <cmath>
+
+bool foo(double arg)
+{
+ return std::isfinite(arg);
+}
diff --git a/Tests/RunCMake/add_link_options/GENEX_LINK_LANG.cmake b/Tests/RunCMake/add_link_options/GENEX_LINK_LANG.cmake
new file mode 100644
index 0000000..cc4ce4c
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/GENEX_LINK_LANG.cmake
@@ -0,0 +1,16 @@
+
+enable_language(C)
+
+set(obj "${CMAKE_C_OUTPUT_EXTENSION}")
+if(BORLAND)
+ set(pre -)
+endif()
+
+add_link_options ($<$<LINK_LANGUAGE:C>:${pre}BADFLAG_LANG_C${obj}>
+ $<$<LINK_LANGUAGE:CXX>:${pre}BADFLAG_LANG_CXX${obj}>)
+
+add_library(LinkOptions_shared SHARED LinkOptionsLib.c)
+
+add_library(LinkOptions_mod MODULE LinkOptionsLib.c)
+
+add_executable(LinkOptions_exe LinkOptionsExe.c)
diff --git a/Tests/RunCMake/add_link_options/LINKER_expansion-list.cmake b/Tests/RunCMake/add_link_options/LINKER_expansion-list.cmake
index 34dcc67..c77b43c 100644
--- a/Tests/RunCMake/add_link_options/LINKER_expansion-list.cmake
+++ b/Tests/RunCMake/add_link_options/LINKER_expansion-list.cmake
@@ -11,7 +11,7 @@ string(REPLACE "${CMAKE_END_TEMP_FILE}" "" CMAKE_C_CREATE_SHARED_LIBRARY "${CMAK
add_library(example SHARED LinkOptionsLib.c)
# use LAUNCH facility to dump linker command
-set_property(TARGET example PROPERTY RULE_LAUNCH_LINK "\"${CMAKE_CURRENT_BINARY_DIR}/dump${CMAKE_EXECUTABLE_SUFFIX}\"")
+set_property(TARGET example PROPERTY RULE_LAUNCH_LINK "\"${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/dump${CMAKE_EXECUTABLE_SUFFIX}\"")
add_dependencies (example dump)
diff --git a/Tests/RunCMake/add_link_options/LINKER_expansion-validation.cmake b/Tests/RunCMake/add_link_options/LINKER_expansion-validation.cmake
index bebd6c7..ece3ba0 100644
--- a/Tests/RunCMake/add_link_options/LINKER_expansion-validation.cmake
+++ b/Tests/RunCMake/add_link_options/LINKER_expansion-validation.cmake
@@ -11,5 +11,8 @@ endif()
file(READ "${RunCMake_TEST_BINARY_DIR}/LINKER.txt" linker_flag)
if (NOT actual_stdout MATCHES "${linker_flag}")
- set (RunCMake_TEST_FAILED "LINKER: was not expanded correctly.")
+ if (RunCMake_TEST_FAILED)
+ string (APPEND RunCMake_TEST_FAILED "\n")
+ endif()
+ string (APPEND RunCMake_TEST_FAILED "LINKER: was not expanded correctly.")
endif()
diff --git a/Tests/RunCMake/add_link_options/LINK_OPTIONS-exe-check.cmake b/Tests/RunCMake/add_link_options/LINK_OPTIONS-exe-check.cmake
index 4a22d7e..127a2f5 100644
--- a/Tests/RunCMake/add_link_options/LINK_OPTIONS-exe-check.cmake
+++ b/Tests/RunCMake/add_link_options/LINK_OPTIONS-exe-check.cmake
@@ -3,5 +3,8 @@ if (NOT actual_stdout MATCHES "BADFLAG_EXECUTABLE_RELEASE")
set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG_EXECUTABLE_RELEASE'.")
endif()
if (actual_stdout MATCHES "BADFLAG_(SHARED|MODULE)_RELEASE")
- set (RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_(SHARED|MODULE)_RELEASE'.")
+ if (RunCMake_TEST_FAILED)
+ string (APPEND RunCMake_TEST_FAILED "\n")
+ endif()
+ string (APPEND RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_(SHARED|MODULE)_RELEASE'.")
endif()
diff --git a/Tests/RunCMake/add_link_options/LINK_OPTIONS-mod-check.cmake b/Tests/RunCMake/add_link_options/LINK_OPTIONS-mod-check.cmake
index d695761..874e0ad 100644
--- a/Tests/RunCMake/add_link_options/LINK_OPTIONS-mod-check.cmake
+++ b/Tests/RunCMake/add_link_options/LINK_OPTIONS-mod-check.cmake
@@ -3,5 +3,8 @@ if (NOT actual_stdout MATCHES "BADFLAG_MODULE_RELEASE")
set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG_MODULE_RELEASE'.")
endif()
if (actual_stdout MATCHES "BADFLAG_(SHARED|EXECUTABLE)_RELEASE")
- set (RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_(SHARED|EXECUTABLE)_RELEASE'.")
+ if (RunCMake_TEST_FAILED)
+ string (APPEND RunCMake_TEST_FAILED "\n")
+ endif()
+ string (APPEND RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_(SHARED|EXECUTABLE)_RELEASE'.")
endif()
diff --git a/Tests/RunCMake/add_link_options/LINK_OPTIONS-shared-check.cmake b/Tests/RunCMake/add_link_options/LINK_OPTIONS-shared-check.cmake
index eaac8e3..ecba17e 100644
--- a/Tests/RunCMake/add_link_options/LINK_OPTIONS-shared-check.cmake
+++ b/Tests/RunCMake/add_link_options/LINK_OPTIONS-shared-check.cmake
@@ -3,5 +3,8 @@ if (NOT actual_stdout MATCHES "BADFLAG_SHARED_RELEASE")
set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG_SHARED_RELEASE'.")
endif()
if (actual_stdout MATCHES "BADFLAG_(MODULE|EXECUTABLE)_RELEASE")
- set (RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_(MODULE|EXECUTABLE)_RELEASE'.")
+ if (RunCMake_TEST_FAILED)
+ string (APPEND RunCMake_TEST_FAILED "\n")
+ endif()
+ string (APPEND RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_(MODULE|EXECUTABLE)_RELEASE'.")
endif()
diff --git a/Tests/RunCMake/add_link_options/LinkOptionsLib.cxx b/Tests/RunCMake/add_link_options/LinkOptionsLib.cxx
new file mode 100644
index 0000000..9bbd24c
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/LinkOptionsLib.cxx
@@ -0,0 +1,7 @@
+#if defined(_WIN32)
+__declspec(dllexport)
+#endif
+ int flags_lib(void)
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/add_link_options/RunCMakeTest.cmake b/Tests/RunCMake/add_link_options/RunCMakeTest.cmake
index 4f5df72..465ff85 100644
--- a/Tests/RunCMake/add_link_options/RunCMakeTest.cmake
+++ b/Tests/RunCMake/add_link_options/RunCMakeTest.cmake
@@ -23,6 +23,21 @@ if (NOT CMAKE_C_COMPILER_ID STREQUAL "Intel")
run_cmake_target(LINK_OPTIONS mod LinkOptions_mod --config Release)
run_cmake_target(LINK_OPTIONS exe LinkOptions_exe --config Release)
+
+ run_cmake(genex_LINK_LANGUAGE)
+
+ run_cmake_target(genex_LINK_LANGUAGE shared_c LinkOptions_shared_c --config Release)
+ run_cmake_target(genex_LINK_LANGUAGE shared_cxx LinkOptions_shared_cxx --config Release)
+ run_cmake_target(genex_LINK_LANGUAGE mod LinkOptions_mod --config Release)
+ run_cmake_target(genex_LINK_LANGUAGE exe LinkOptions_exe --config Release)
+
+ run_cmake(genex_LINK_LANG_AND_ID)
+
+ run_cmake_target(genex_LINK_LANG_AND_ID shared_c LinkOptions_shared_c --config Release)
+ run_cmake_target(genex_LINK_LANG_AND_ID shared_cxx LinkOptions_shared_cxx --config Release)
+ run_cmake_target(genex_LINK_LANG_AND_ID mod LinkOptions_mod --config Release)
+ run_cmake_target(genex_LINK_LANG_AND_ID exe LinkOptions_exe --config Release)
+
unset(RunCMake_TEST_OPTIONS)
unset(RunCMake_TEST_OUTPUT_MERGE)
endif()
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-exe-check.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-exe-check.cmake
new file mode 100644
index 0000000..71f641d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-exe-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANGUAGE-validation.cmake")
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-exe-result.txt b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-exe-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-exe-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-mod-check.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-mod-check.cmake
new file mode 100644
index 0000000..71f641d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-mod-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANGUAGE-validation.cmake")
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-mod-result.txt b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-mod-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-mod-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_c-check.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_c-check.cmake
new file mode 100644
index 0000000..ba0120c
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_c-check.cmake
@@ -0,0 +1,5 @@
+
+set (VALID_LANG C)
+set (INVALID_LANG CXX)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANGUAGE-validation.cmake")
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_c-result.txt b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_c-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_c-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_cxx-check.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_cxx-check.cmake
new file mode 100644
index 0000000..aa39810
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_cxx-check.cmake
@@ -0,0 +1,5 @@
+
+set (VALID_LANG CXX)
+set (INVALID_LANG C)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANGUAGE-validation.cmake")
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_cxx-result.txt b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_cxx-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_cxx-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-validation.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-validation.cmake
new file mode 100644
index 0000000..f0237ab
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-validation.cmake
@@ -0,0 +1,17 @@
+
+if (NOT DEFINED VALID_LANG)
+ set (VALID_LANG C)
+endif()
+if (NOT DEFINED INVALID_LANG)
+ set (INVALID_LANG CXX)
+endif()
+
+if (NOT actual_stdout MATCHES "BADFLAG_${VALID_LANG}_LANG")
+ set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG_${VALID_LANG}_LANG'.")
+endif()
+if (actual_stdout MATCHES "BADFLAG_${INVALID_LANG}_LANG")
+ if (RunCMake_TEST_FAILED)
+ string (APPEND RunCMake_TEST_FAILED "\n")
+ endif()
+ string (APPEND RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_${INVALID_LANG}_LANG'.")
+endif()
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE.cmake
new file mode 100644
index 0000000..d74d448
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE.cmake
@@ -0,0 +1,17 @@
+
+enable_language(C)
+enable_language(CXX)
+
+if(BORLAND)
+ set(pre -)
+endif()
+
+add_link_options ($<$<LINK_LANGUAGE:C>:${pre}BADFLAG_$<LINK_LANGUAGE>_LANG${CMAKE_C_OUTPUT_EXTENSION}>
+ $<$<LINK_LANGUAGE:CXX>:${pre}BADFLAG_$<LINK_LANGUAGE>_LANG${CMAKE_CXX_OUTPUT_EXTENSION}>)
+
+add_library(LinkOptions_shared_c SHARED LinkOptionsLib.c)
+add_library(LinkOptions_shared_cxx SHARED LinkOptionsLib.cxx)
+
+add_library(LinkOptions_mod MODULE LinkOptionsLib.c)
+
+add_executable(LinkOptions_exe LinkOptionsExe.c)
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-exe-check.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-exe-check.cmake
new file mode 100644
index 0000000..6bddee1
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-exe-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANG_AND_ID-validation.cmake")
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-exe-result.txt b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-exe-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-exe-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-mod-check.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-mod-check.cmake
new file mode 100644
index 0000000..6bddee1
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-mod-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANG_AND_ID-validation.cmake")
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-mod-result.txt b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-mod-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-mod-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_c-check.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_c-check.cmake
new file mode 100644
index 0000000..cf498d9
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_c-check.cmake
@@ -0,0 +1,5 @@
+
+set (VALID_LANG C)
+set (INVALID_LANG CXX)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANG_AND_ID-validation.cmake")
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_c-result.txt b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_c-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_c-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_cxx-check.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_cxx-check.cmake
new file mode 100644
index 0000000..ed4f851
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_cxx-check.cmake
@@ -0,0 +1,5 @@
+
+set (VALID_LANG CXX)
+set (INVALID_LANG C)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANG_AND_ID-validation.cmake")
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_cxx-result.txt b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_cxx-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_cxx-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-validation.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-validation.cmake
new file mode 100644
index 0000000..a5dc27f
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-validation.cmake
@@ -0,0 +1,23 @@
+
+if (NOT VALID_LANG)
+ set (VALID_LANG C)
+endif()
+if (NOT INVALID_LANG)
+ set (INVALID_LANG CXX)
+endif()
+
+if (NOT actual_stdout MATCHES "BADFLAG_${VALID_LANG}_LANG_ID")
+ set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG_${VALID_LANG}_LANG_ID'.\n")
+endif()
+if (actual_stdout MATCHES "BADFLAG_${INVALID_LANG}_LANG_ID")
+ if (RunCMake_TEST_FAILED)
+ string (APPEND RunCMake_TEST_FAILED "\n")
+ endif()
+ string (APPEND RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_${INVALID_LANG}_LANG_ID '.")
+endif()
+if (actual_stdout MATCHES "BADFLAG_(${VALID_LANG}|${INVALID_LANG})_BADID")
+ if (RunCMake_TEST_FAILED)
+ string (APPEND RunCMake_TEST_FAILED "\n")
+ endif()
+ string (APPEND RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_(${VALID_LANG}|${INVALID_LANG})_BADID'.")
+endif()
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID.cmake
new file mode 100644
index 0000000..c807050
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID.cmake
@@ -0,0 +1,19 @@
+
+enable_language(C)
+enable_language(CXX)
+
+if(BORLAND)
+ set(pre -)
+endif()
+
+add_link_options ($<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:${pre}BADFLAG_C_LANG_ID${CMAKE_C_OUTPUT_EXTENSION}>
+ $<$<LINK_LANG_AND_ID:CXX,${CMAKE_CXX_COMPILER_ID}>:${pre}BADFLAG_CXX_LANG_ID${CMAKE_CXX_OUTPUT_EXTENSION}>
+ $<$<LINK_LANG_AND_ID:C,BADID>:${pre}BADFLAG_C_BADID${CMAKE_C_OUTPUT_EXTENSION}>
+ $<$<LINK_LANG_AND_ID:CXX,BADID>:${pre}BADFLAG_CXX_BADID${CMAKE_CXX_OUTPUT_EXTENSION}>)
+
+add_library(LinkOptions_shared_c SHARED LinkOptionsLib.c)
+add_library(LinkOptions_shared_cxx SHARED LinkOptionsLib.cxx)
+
+add_library(LinkOptions_mod MODULE LinkOptionsLib.c)
+
+add_executable(LinkOptions_exe LinkOptionsExe.c)
diff --git a/Tests/RunCMake/cmake_command/CMakeLists.txt b/Tests/RunCMake/cmake_command/CMakeLists.txt
new file mode 100644
index 0000000..2632ffa
--- /dev/null
+++ b/Tests/RunCMake/cmake_command/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.16)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/cmake_command/RunCMakeTest.cmake b/Tests/RunCMake/cmake_command/RunCMakeTest.cmake
new file mode 100644
index 0000000..0f12b80
--- /dev/null
+++ b/Tests/RunCMake/cmake_command/RunCMakeTest.cmake
@@ -0,0 +1,14 @@
+include(RunCMake)
+
+run_cmake(cmake_command_no_parameters)
+run_cmake(cmake_command_unknown_meta_operation)
+run_cmake(cmake_command_invoke_message)
+run_cmake(cmake_command_invoke_message_fatal_error)
+run_cmake(cmake_command_invoke_no_parameters)
+run_cmake(cmake_command_invoke_preserve_arguments)
+run_cmake(cmake_command_invoke_unknown_function)
+run_cmake(cmake_command_eval_message)
+run_cmake(cmake_command_eval_message_fatal_error)
+run_cmake(cmake_command_eval_no_code)
+run_cmake(cmake_command_eval_no_parameters)
+run_cmake(cmake_command_eval_variable_outside_message)
diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_message-stderr.txt b/Tests/RunCMake/cmake_command/cmake_command_eval_message-stderr.txt
new file mode 100644
index 0000000..cfc8694
--- /dev/null
+++ b/Tests/RunCMake/cmake_command/cmake_command_eval_message-stderr.txt
@@ -0,0 +1 @@
+WORKS!
diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_message.cmake b/Tests/RunCMake/cmake_command/cmake_command_eval_message.cmake
new file mode 100644
index 0000000..9ef5e25
--- /dev/null
+++ b/Tests/RunCMake/cmake_command/cmake_command_eval_message.cmake
@@ -0,0 +1 @@
+cmake_command(EVAL CODE message(WORKS!))
diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_message_fatal_error-result.txt b/Tests/RunCMake/cmake_command/cmake_command_eval_message_fatal_error-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/cmake_command/cmake_command_eval_message_fatal_error-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_message_fatal_error-stderr.txt b/Tests/RunCMake/cmake_command/cmake_command_eval_message_fatal_error-stderr.txt
new file mode 100644
index 0000000..6a8a124
--- /dev/null
+++ b/Tests/RunCMake/cmake_command/cmake_command_eval_message_fatal_error-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error at cmake_command_eval_message_fatal_error.cmake:1:EVAL:2 \(message\):
+ error!
+Call Stack \(most recent call first\):
+ cmake_command_eval_message_fatal_error.cmake:1 \(cmake_command\)
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_message_fatal_error.cmake b/Tests/RunCMake/cmake_command/cmake_command_eval_message_fatal_error.cmake
new file mode 100644
index 0000000..22913de
--- /dev/null
+++ b/Tests/RunCMake/cmake_command/cmake_command_eval_message_fatal_error.cmake
@@ -0,0 +1,5 @@
+cmake_command(EVAL CODE
+"
+ message(FATAL_ERROR error!)
+"
+)
diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_no_code-result.txt b/Tests/RunCMake/cmake_command/cmake_command_eval_no_code-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/cmake_command/cmake_command_eval_no_code-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_no_code-stderr.txt b/Tests/RunCMake/cmake_command/cmake_command_eval_no_code-stderr.txt
new file mode 100644
index 0000000..ee53312
--- /dev/null
+++ b/Tests/RunCMake/cmake_command/cmake_command_eval_no_code-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error at cmake_command_eval_no_code.cmake:1 \(cmake_command\):
+ cmake_command called without CODE argument
diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_no_code.cmake b/Tests/RunCMake/cmake_command/cmake_command_eval_no_code.cmake
new file mode 100644
index 0000000..22e1667
--- /dev/null
+++ b/Tests/RunCMake/cmake_command/cmake_command_eval_no_code.cmake
@@ -0,0 +1 @@
+cmake_command(EVAL message "too many parameters")
diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_no_parameters-result.txt b/Tests/RunCMake/cmake_command/cmake_command_eval_no_parameters-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/cmake_command/cmake_command_eval_no_parameters-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_no_parameters-stderr.txt b/Tests/RunCMake/cmake_command/cmake_command_eval_no_parameters-stderr.txt
new file mode 100644
index 0000000..e9fc317
--- /dev/null
+++ b/Tests/RunCMake/cmake_command/cmake_command_eval_no_parameters-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error at cmake_command_eval_no_parameters.cmake:1 \(cmake_command\):
+ cmake_command called with incorrect number of arguments
diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_no_parameters.cmake b/Tests/RunCMake/cmake_command/cmake_command_eval_no_parameters.cmake
new file mode 100644
index 0000000..a5ba2c7
--- /dev/null
+++ b/Tests/RunCMake/cmake_command/cmake_command_eval_no_parameters.cmake
@@ -0,0 +1 @@
+cmake_command(EVAL)
diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_variable_outside_message-stderr.txt b/Tests/RunCMake/cmake_command/cmake_command_eval_variable_outside_message-stderr.txt
new file mode 100644
index 0000000..cfc8694
--- /dev/null
+++ b/Tests/RunCMake/cmake_command/cmake_command_eval_variable_outside_message-stderr.txt
@@ -0,0 +1 @@
+WORKS!
diff --git a/Tests/RunCMake/cmake_command/cmake_command_eval_variable_outside_message.cmake b/Tests/RunCMake/cmake_command/cmake_command_eval_variable_outside_message.cmake
new file mode 100644
index 0000000..b7a06a5
--- /dev/null
+++ b/Tests/RunCMake/cmake_command/cmake_command_eval_variable_outside_message.cmake
@@ -0,0 +1,2 @@
+cmake_command(EVAL CODE "set(phrase \"WORKS!\")")
+message(${phrase})
diff --git a/Tests/RunCMake/cmake_command/cmake_command_invoke_message-stderr.txt b/Tests/RunCMake/cmake_command/cmake_command_invoke_message-stderr.txt
new file mode 100644
index 0000000..cfc8694
--- /dev/null
+++ b/Tests/RunCMake/cmake_command/cmake_command_invoke_message-stderr.txt
@@ -0,0 +1 @@
+WORKS!
diff --git a/Tests/RunCMake/cmake_command/cmake_command_invoke_message.cmake b/Tests/RunCMake/cmake_command/cmake_command_invoke_message.cmake
new file mode 100644
index 0000000..336d78a
--- /dev/null
+++ b/Tests/RunCMake/cmake_command/cmake_command_invoke_message.cmake
@@ -0,0 +1 @@
+cmake_command(INVOKE message WORKS!)
diff --git a/Tests/RunCMake/cmake_command/cmake_command_invoke_message_fatal_error-result.txt b/Tests/RunCMake/cmake_command/cmake_command_invoke_message_fatal_error-result.txt
new file mode 100644