summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitlab-ci.yml34
-rw-r--r--.gitlab/ci/configure_cuda9.2_nvidia.cmake3
-rw-r--r--.gitlab/ci/configure_debian10_aarch64_ninja.cmake1
-rw-r--r--.gitlab/ci/configure_debian10_ninja.cmake1
-rw-r--r--.gitlab/ci/configure_fedora34_makefiles.cmake1
-rw-r--r--.gitlab/ci/configure_hip4.2_radeon.cmake3
-rw-r--r--.gitlab/ci/docker/cuda9.2/Dockerfile5
-rwxr-xr-x.gitlab/ci/docker/cuda9.2/install_deps.sh14
-rw-r--r--.gitlab/ci/docker/hip4.2/Dockerfile7
-rwxr-xr-x.gitlab/ci/docker/hip4.2/install_deps.sh13
-rw-r--r--.gitlab/ci/env_cuda9.2_nvidia.sh4
-rw-r--r--.gitlab/os-linux.yml39
-rw-r--r--Auxiliary/vim/syntax/cmake.vim2
-rw-r--r--CMakeLists.txt10
-rw-r--r--Help/command/cmake_host_system_information.rst268
-rw-r--r--Help/command/ctest_test.rst47
-rw-r--r--Help/command/file.rst5
-rw-r--r--Help/command/find_package.rst38
-rw-r--r--Help/command/get_property.rst2
-rw-r--r--Help/command/if.rst2
-rw-r--r--Help/command/install.rst4
-rw-r--r--Help/command/set_property.rst4
-rw-r--r--Help/command/source_group.rst3
-rw-r--r--Help/command/string.rst91
-rw-r--r--Help/cpack_gen/deb.rst30
-rw-r--r--Help/cpack_gen/nsis.rst10
-rw-r--r--Help/cpack_gen/rpm.rst15
-rw-r--r--Help/envvar/CMAKE_BUILD_TYPE.rst10
-rw-r--r--Help/envvar/CMAKE_CONFIGURATION_TYPES.rst11
-rw-r--r--Help/envvar/CMAKE_INSTALL_MODE.rst37
-rw-r--r--Help/generator/Visual Studio 10 2010.rst9
-rw-r--r--Help/manual/cmake-env-variables.7.rst3
-rw-r--r--Help/manual/cmake-packages.7.rst6
-rw-r--r--Help/manual/cmake-properties.7.rst2
-rw-r--r--Help/manual/cmake-variables.7.rst3
-rw-r--r--Help/prop_test/ENVIRONMENT.rst4
-rw-r--r--Help/prop_test/ENVIRONMENT_MODIFICATION.rst33
-rw-r--r--Help/prop_tgt/Fortran_BUILDING_INSTRINSIC_MODULES.rst14
-rw-r--r--Help/prop_tgt/LINK_WHAT_YOU_USE.rst24
-rw-r--r--Help/release/dev/0-sample-topic.rst7
-rw-r--r--Help/release/dev/FindPkgConfig-PKG_CONFIG-args.rst5
-rw-r--r--Help/release/dev/GoogleTest-gtest-filter.rst6
-rw-r--r--Help/release/dev/LINK_WHAT_USE_USE-configuration.rst5
-rw-r--r--Help/release/dev/UseSWIG-dependencies.rst6
-rw-r--r--Help/release/dev/cmake-install-mode-symlink.rst16
-rw-r--r--Help/release/dev/cpack-deb-add-zstd-compression.rst6
-rw-r--r--Help/release/dev/cpack-rpm-requires-exclude-from.rst6
-rw-r--r--Help/release/dev/ctest-environment-modifications.rst7
-rw-r--r--Help/release/dev/ctest-runtime-labels.rst7
-rw-r--r--Help/release/dev/env-init-configs.rst9
-rw-r--r--Help/release/dev/find_package-required-var.rst5
-rw-r--r--Help/release/dev/msvc-isystem.rst7
-rw-r--r--Help/release/dev/ninja-edit_cache.rst5
-rw-r--r--Help/release/dev/nsis-minimal-version.rst4
-rw-r--r--Help/release/dev/nsis_ignore_install_page.rst6
-rw-r--r--Help/release/dev/os-release.rst6
-rw-r--r--Help/release/dev/string-TIMESTAMP-specifier-V.rst5
-rw-r--r--Help/release/dev/target_compile_features-ignore-disabled-langs.rst5
-rw-r--r--Help/release/dev/vs10-deprecate.rst5
-rw-r--r--Help/release/index.rst2
-rw-r--r--Help/variable/CMAKE_BUILD_TYPE.rst9
-rw-r--r--Help/variable/CMAKE_CONFIGURATION_TYPES.rst6
-rw-r--r--Help/variable/CMAKE_DISABLE_FIND_PACKAGE_PackageName.rst2
-rw-r--r--Help/variable/CMAKE_LANG_LINK_WHAT_YOU_USE_FLAG.rst9
-rw-r--r--Help/variable/CMAKE_LINK_WHAT_YOU_USE.rst2
-rw-r--r--Help/variable/CMAKE_LINK_WHAT_YOU_USE_CHECK.rst10
-rw-r--r--Help/variable/CMAKE_REQUIRE_FIND_PACKAGE_PackageName.rst14
-rw-r--r--Modules/CMakeASM_MASMInformation.cmake2
-rw-r--r--Modules/CMakeCInformation.cmake10
-rw-r--r--Modules/CMakeCUDAInformation.cmake9
-rw-r--r--Modules/CMakeCXXInformation.cmake9
-rw-r--r--Modules/CMakeDetermineCUDACompiler.cmake19
-rw-r--r--Modules/CMakeDetermineCompilerId.cmake7
-rw-r--r--Modules/CMakeFortranCompilerABI.F9048
-rw-r--r--Modules/CMakeFortranInformation.cmake9
-rw-r--r--Modules/CMakeHIPInformation.cmake9
-rw-r--r--Modules/CMakeOBJCInformation.cmake9
-rw-r--r--Modules/CMakeOBJCXXInformation.cmake9
-rw-r--r--Modules/CMakeSwiftInformation.cmake9
-rw-r--r--Modules/CMakeTestFortranCompiler.cmake9
-rw-r--r--Modules/CheckCXXSymbolExists.cmake2
-rw-r--r--Modules/CheckFortranFunctionExists.cmake6
-rw-r--r--Modules/CheckSymbolExists.cmake2
-rw-r--r--Modules/Compiler/ARMClang-C.cmake8
-rw-r--r--Modules/Compiler/ARMClang-CXX.cmake8
-rw-r--r--Modules/Compiler/MSVC-C.cmake6
-rw-r--r--Modules/Compiler/MSVC-CXX.cmake6
-rw-r--r--Modules/Compiler/PGI.cmake2
-rw-r--r--Modules/FetchContent.cmake452
-rw-r--r--Modules/FindBLAS.cmake67
-rw-r--r--Modules/FindCUDAToolkit.cmake7
-rw-r--r--Modules/FindGLUT.cmake163
-rw-r--r--Modules/FindLAPACK.cmake76
-rw-r--r--Modules/FindMPI.cmake54
-rw-r--r--Modules/FindMPI/test_mpi.c18
-rw-r--r--Modules/FindPatch.cmake2
-rw-r--r--Modules/FindPkgConfig.cmake52
-rw-r--r--Modules/FindX11.cmake6
-rw-r--r--Modules/GoogleTest.cmake11
-rw-r--r--Modules/GoogleTestAddTests.cmake11
-rw-r--r--Modules/InstallRequiredSystemLibraries.cmake33
-rw-r--r--Modules/Internal/CPack/CPackDeb.cmake6
-rw-r--r--Modules/Internal/CPack/CPackRPM.cmake12
-rw-r--r--Modules/Internal/CPack/NSIS.template.in15
-rw-r--r--Modules/Internal/OSRelease/010-TryOldCentOS.cmake41
-rw-r--r--Modules/Internal/OSRelease/020-TryDebianVersion.cmake38
-rw-r--r--Modules/UseSWIG.cmake25
-rw-r--r--Modules/VTKCompatibility.cmake4
-rw-r--r--Source/CMakeLists.txt42
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CPack/cmCPackDebGenerator.cxx353
-rw-r--r--Source/CPack/cmCPackDebGenerator.h5
-rw-r--r--Source/CPack/cmCPackNSISGenerator.cxx11
-rw-r--r--Source/CTest/cmCTestMemCheckHandler.cxx2
-rw-r--r--Source/CTest/cmCTestMemCheckHandler.h4
-rw-r--r--Source/CTest/cmCTestMultiProcessHandler.cxx5
-rw-r--r--Source/CTest/cmCTestRunTest.cxx182
-rw-r--r--Source/CTest/cmCTestRunTest.h3
-rw-r--r--Source/CTest/cmCTestStartCommand.cxx8
-rw-r--r--Source/CTest/cmCTestSubmitCommand.cxx4
-rw-r--r--Source/CTest/cmCTestTestHandler.cxx196
-rw-r--r--Source/CTest/cmCTestTestHandler.h14
-rw-r--r--Source/CTest/cmCTestTestMeasurementXMLParser.cxx26
-rw-r--r--Source/CTest/cmCTestTestMeasurementXMLParser.h21
-rw-r--r--Source/LexerParser/cmFortranParser.cxx78
-rw-r--r--Source/LexerParser/cmFortranParser.y4
-rw-r--r--Source/QtDialog/QCMake.cxx21
-rw-r--r--Source/cmAddTestCommand.cxx2
-rw-r--r--Source/cmArchiveWrite.cxx3
-rw-r--r--Source/cmBinUtilsLinuxELFLinker.cxx11
-rw-r--r--Source/cmCMakeHostSystemInformationCommand.cxx606
-rw-r--r--Source/cmCMakePolicyCommand.cxx1
-rw-r--r--Source/cmCacheManager.cxx6
-rw-r--r--Source/cmCacheManager.h2
-rw-r--r--Source/cmCommandArgumentParserHelper.cxx2
-rw-r--r--Source/cmCommonTargetGenerator.cxx6
-rw-r--r--Source/cmCommonTargetGenerator.h6
-rw-r--r--Source/cmComputeLinkInformation.cxx7
-rw-r--r--Source/cmComputeLinkInformation.h3
-rw-r--r--Source/cmConditionEvaluator.cxx972
-rw-r--r--Source/cmConditionEvaluator.h30
-rw-r--r--Source/cmConfigure.cmake.h.in1
-rw-r--r--Source/cmCoreTryCompile.cxx10
-rw-r--r--Source/cmDefinitions.cxx6
-rw-r--r--Source/cmDefinitions.h4
-rw-r--r--Source/cmDependsFortran.cxx17
-rw-r--r--Source/cmDependsFortran.h3
-rw-r--r--Source/cmELF.cxx74
-rw-r--r--Source/cmELF.h7
-rw-r--r--Source/cmExportBuildFileGenerator.cxx7
-rw-r--r--Source/cmExportBuildFileGenerator.h8
-rw-r--r--Source/cmExportFileGenerator.cxx52
-rw-r--r--Source/cmExportFileGenerator.h37
-rw-r--r--Source/cmExportInstallFileGenerator.cxx15
-rw-r--r--Source/cmExportInstallFileGenerator.h8
-rw-r--r--Source/cmExportTryCompileFileGenerator.cxx2
-rw-r--r--Source/cmExportTryCompileFileGenerator.h5
-rw-r--r--Source/cmFileAPICodemodel.cxx3
-rw-r--r--Source/cmFileCommand.cxx24
-rw-r--r--Source/cmFileCopier.h5
-rw-r--r--Source/cmFileInstaller.cxx118
-rw-r--r--Source/cmFileInstaller.h5
-rw-r--r--Source/cmFindBase.cxx4
-rw-r--r--Source/cmFindLibraryCommand.cxx35
-rw-r--r--Source/cmFindPackageCommand.cxx24
-rw-r--r--Source/cmForEachCommand.cxx1
-rw-r--r--Source/cmFortranParser.h5
-rw-r--r--Source/cmFortranParserImpl.cxx13
-rw-r--r--Source/cmGeneratorExpressionNode.cxx2
-rw-r--r--Source/cmGeneratorTarget.cxx145
-rw-r--r--Source/cmGeneratorTarget.h16
-rw-r--r--Source/cmGetDirectoryPropertyCommand.cxx11
-rw-r--r--Source/cmGetPropertyCommand.cxx24
-rw-r--r--Source/cmGetTestPropertyCommand.cxx5
-rw-r--r--Source/cmGhsMultiTargetGenerator.cxx2
-rw-r--r--Source/cmGlobalCommonGenerator.cxx34
-rw-r--r--Source/cmGlobalCommonGenerator.h5
-rw-r--r--Source/cmGlobalGenerator.cxx48
-rw-r--r--Source/cmGlobalGenerator.h5
-rw-r--r--Source/cmGlobalGhsMultiGenerator.cxx3
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx22
-rw-r--r--Source/cmGlobalNinjaGenerator.h4
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx30
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.h2
-rw-r--r--Source/cmGlobalVisualStudio10Generator.cxx2
-rw-r--r--Source/cmGlobalVisualStudio71Generator.cxx6
-rw-r--r--Source/cmGlobalVisualStudio71Generator.h2
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx35
-rw-r--r--Source/cmGlobalVisualStudio7Generator.h3
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx11
-rw-r--r--Source/cmIncludeGuardCommand.cxx1
-rw-r--r--Source/cmIncludeRegularExpressionCommand.cxx2
-rw-r--r--Source/cmInstallCommand.cxx5
-rw-r--r--Source/cmInstallMode.h17
-rw-r--r--Source/cmListFileCache.cxx4
-rw-r--r--Source/cmLocalGenerator.cxx109
-rw-r--r--Source/cmLocalGenerator.h6
-rw-r--r--Source/cmLocalNinjaGenerator.cxx2
-rw-r--r--Source/cmLocalVisualStudioGenerator.cxx2
-rw-r--r--Source/cmMakefile.cxx78
-rw-r--r--Source/cmMakefile.h20
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx23
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx25
-rw-r--r--Source/cmMakefileTargetGenerator.cxx14
-rw-r--r--Source/cmMarkAsAdvancedCommand.cxx1
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx39
-rw-r--r--Source/cmNinjaTargetGenerator.cxx6
-rw-r--r--Source/cmOptionCommand.cxx4
-rw-r--r--Source/cmPolicies.cxx1
-rw-r--r--Source/cmProperty.cxx113
-rw-r--r--Source/cmProperty.h210
-rw-r--r--Source/cmPropertyMap.cxx11
-rw-r--r--Source/cmPropertyMap.h5
-rw-r--r--Source/cmQTWrapCPPCommand.cxx3
-rw-r--r--Source/cmQtAutoGenGlobalInitializer.cxx2
-rw-r--r--Source/cmSetDirectoryPropertiesCommand.cxx2
-rw-r--r--Source/cmSetPropertyCommand.cxx10
-rw-r--r--Source/cmSetSourceFilesPropertiesCommand.cxx2
-rw-r--r--Source/cmSetTestsPropertiesCommand.cxx2
-rw-r--r--Source/cmSourceFile.cxx26
-rw-r--r--Source/cmSourceFile.h8
-rw-r--r--Source/cmStandardLevelResolver.cxx36
-rw-r--r--Source/cmStandardLevelResolver.h4
-rw-r--r--Source/cmState.cxx55
-rw-r--r--Source/cmState.h29
-rw-r--r--Source/cmStateDirectory.cxx46
-rw-r--r--Source/cmStateDirectory.h6
-rw-r--r--Source/cmStateSnapshot.cxx5
-rw-r--r--Source/cmStateSnapshot.h3
-rw-r--r--Source/cmStringAlgorithms.cxx70
-rw-r--r--Source/cmStringAlgorithms.h85
-rw-r--r--Source/cmSystemTools.cxx211
-rw-r--r--Source/cmTarget.cxx179
-rw-r--r--Source/cmTarget.h9
-rw-r--r--Source/cmTargetExport.h1
-rw-r--r--Source/cmTargetPropertyComputer.h6
-rw-r--r--Source/cmTest.cxx10
-rw-r--r--Source/cmTest.h8
-rw-r--r--Source/cmTimestamp.cxx23
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx13
-rw-r--r--Source/cmWhileCommand.cxx89
-rw-r--r--Source/cmake.cxx28
-rw-r--r--Source/cmake.h9
-rw-r--r--Source/cmcmd.cxx11
-rw-r--r--Source/kwsys/Status.hxx.in5
-rw-r--r--Source/kwsys/SystemInformation.cxx6
-rw-r--r--Source/kwsys/SystemTools.cxx24
-rw-r--r--Source/kwsys/testDirectory.cxx2
-rw-r--r--Source/kwsys/testStatus.cxx12
-rw-r--r--Source/kwsys/testSystemTools.cxx2
-rw-r--r--Tests/CMakeLists.txt55
-rw-r--r--Tests/CMakeTests/CMakeLists.txt1
-rw-r--r--Tests/CPackNSISGenerator/CMakeLists.txt1
-rw-r--r--Tests/CPackNSISGenerator/RunCPackVerifyResult.cmake9
-rw-r--r--Tests/CTestTestSerialInDepends/test.ctest3
-rw-r--r--Tests/Cuda/CMakeLists.txt1
-rw-r--r--Tests/Cuda/ConsumeCompileFeatures/CMakeLists.txt16
-rw-r--r--Tests/Cuda/ConsumeCompileFeatures/main.cu20
-rw-r--r--Tests/Cuda/ConsumeCompileFeatures/static.cpp10
-rw-r--r--Tests/Cuda/ConsumeCompileFeatures/static.cu9
-rw-r--r--Tests/EnforceConfig.cmake.in1
-rw-r--r--Tests/Environment/CMakeLists.txt35
-rw-r--r--Tests/Environment/check_mod.cmake55
-rw-r--r--Tests/FindGLUT/CMakeLists.txt9
-rw-r--r--Tests/FindGLUT/Test/CMakeLists.txt17
-rw-r--r--Tests/FindGLUT/Test/main.c11
-rw-r--r--Tests/IncludeDirectories/CMakeLists.txt24
-rw-r--r--Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt26
-rw-r--r--Tests/IncludeDirectories/SystemIncludeDirectories/consumer.cpp3
-rw-r--r--Tests/IncludeDirectories/SystemIncludeDirectories/imported_consumer.cpp2
-rw-r--r--Tests/IncludeDirectories/SystemIncludeDirectories/upstream.h2
-rw-r--r--Tests/IncludeDirectories/SystemIncludeDirectoriesPerLang/CMakeLists.txt4
-rw-r--r--Tests/InstallMode/CMakeLists.txt124
-rw-r--r--Tests/InstallMode/README.txt43
-rw-r--r--Tests/InstallMode/Subproject.cmake73
-rw-r--r--Tests/InstallMode/Test.cmake38
-rw-r--r--Tests/InstallMode/subpro_a_static_lib/CMakeLists.txt60
-rw-r--r--Tests/InstallMode/subpro_a_static_lib/cmake/PackageConfig.cmake.in8
-rw-r--r--Tests/InstallMode/subpro_a_static_lib/include/static_lib.h3
-rw-r--r--Tests/InstallMode/subpro_a_static_lib/src/static_lib.cpp10
-rw-r--r--Tests/InstallMode/subpro_b_shared_lib/CMakeLists.txt75
-rw-r--r--Tests/InstallMode/subpro_b_shared_lib/cmake/PackageConfig.cmake.in8
-rw-r--r--Tests/InstallMode/subpro_b_shared_lib/include/shared_lib.h5
-rw-r--r--Tests/InstallMode/subpro_b_shared_lib/src/shared_lib.cpp10
-rw-r--r--Tests/InstallMode/subpro_c_nested_lib/CMakeLists.txt10
-rw-r--r--Tests/InstallMode/subpro_c_nested_lib/subsubpro_c1_lib/CMakeLists.txt61
-rw-r--r--Tests/InstallMode/subpro_c_nested_lib/subsubpro_c1_lib/cmake/PackageConfig.cmake.in8
-rw-r--r--Tests/InstallMode/subpro_c_nested_lib/subsubpro_c1_lib/include/c1_lib.h3
-rw-r--r--Tests/InstallMode/subpro_c_nested_lib/subsubpro_c1_lib/src/c1_lib.cpp10
-rw-r--r--Tests/InstallMode/subpro_c_nested_lib/subsubpro_c2_lib/CMakeLists.txt71
-rw-r--r--Tests/InstallMode/subpro_c_nested_lib/subsubpro_c2_lib/cmake/PackageConfig.cmake.in11
-rw-r--r--Tests/InstallMode/subpro_c_nested_lib/subsubpro_c2_lib/include/c2_lib.h3
-rw-r--r--Tests/InstallMode/subpro_c_nested_lib/subsubpro_c2_lib/src/c2_lib.cpp12
-rw-r--r--Tests/InstallMode/subpro_d_executable/CMakeLists.txt27
-rw-r--r--Tests/InstallMode/subpro_d_executable/src/main.cpp13
-rw-r--r--Tests/InstallMode/superpro/CMakeLists.txt29
-rw-r--r--Tests/InstallMode/superpro/file_copy.txt1
-rw-r--r--Tests/InstallMode/superpro/file_copy_file.txt1
-rw-r--r--Tests/InstallMode/superpro/file_create_link_symbolic.txt2
-rw-r--r--Tests/InstallMode/superpro/file_install.txt6
-rw-r--r--Tests/RunCMake/CMAKE_MSVCIDE_RUN_PATH/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMAKE_MSVCIDE_RUN_PATH/CheckEnvironmentVar-build-stdout.txt1
-rw-r--r--Tests/RunCMake/CMAKE_MSVCIDE_RUN_PATH/CheckEnvironmentVar.cmake2
-rw-r--r--Tests/RunCMake/CMAKE_MSVCIDE_RUN_PATH/RunCMakeTest.cmake8
-rwxr-xr-xTests/RunCMake/CMAKE_MSVCIDE_RUN_PATH/echo_message.bat1
-rw-r--r--Tests/RunCMake/CMakeLists.txt7
-rw-r--r--Tests/RunCMake/CPack/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/CPack/tests/DEBUGINFO/ExpectedFiles.cmake66
-rw-r--r--Tests/RunCMake/CPack/tests/DEBUGINFO/test.cmake2
-rw-r--r--Tests/RunCMake/CPack/tests/MD5SUMS/ExpectedFiles.cmake2
-rw-r--r--Tests/RunCMake/CPack/tests/MD5SUMS/VerifyResult.cmake3
-rw-r--r--Tests/RunCMake/CPack/tests/MD5SUMS/test.cmake2
-rw-r--r--Tests/RunCMake/CommandLine/DeprecateVS10-WARN-OFF.cmake0
-rw-r--r--Tests/RunCMake/CommandLine/DeprecateVS10-WARN-ON-stderr.txt5
-rw-r--r--Tests/RunCMake/CommandLine/DeprecateVS10-WARN-ON.cmake0
-rw-r--r--Tests/RunCMake/CommandLine/EnvBuildType-stdout.txt2
-rw-r--r--Tests/RunCMake/CommandLine/EnvBuildType.cmake2
-rw-r--r--Tests/RunCMake/CommandLine/EnvBuildTypeIgnore-stdout.txt2
-rw-r--r--Tests/RunCMake/CommandLine/EnvBuildTypeIgnore.cmake1
-rw-r--r--Tests/RunCMake/CommandLine/EnvConfigTypes-stdout.txt2
-rw-r--r--Tests/RunCMake/CommandLine/EnvConfigTypes.cmake2
-rw-r--r--Tests/RunCMake/CommandLine/EnvConfigTypesIgnore-stdout.txt2
-rw-r--r--Tests/RunCMake/CommandLine/EnvConfigTypesIgnore.cmake1
-rw-r--r--Tests/RunCMake/CommandLine/RunCMakeTest.cmake27
-rw-r--r--Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_MATCHING_ARGN.cmake17
-rw-r--r--Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH-stdout.txt3
-rw-r--r--Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH.cmake29
-rw-r--r--Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake5
-rwxr-xr-xTests/RunCMake/FindPkgConfig/dummy-pkg-config.bat17
-rwxr-xr-xTests/RunCMake/FindPkgConfig/dummy-pkg-config.sh19
-rw-r--r--Tests/RunCMake/GeneratorExpression/CMP0085-OLD-stderr.txt8
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTest-test3-stdout.txt16
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTest-test4-stdout.txt9
-rw-r--r--Tests/RunCMake/GoogleTest/GoogleTest.cmake18
-rw-r--r--Tests/RunCMake/GoogleTest/RunCMakeTest.cmake14
-rw-r--r--Tests/RunCMake/GoogleTest/fake_gtest.cpp55
-rw-r--r--Tests/RunCMake/UseSWIG/CMP0086-OLD-stderr.txt10
-rw-r--r--Tests/RunCMake/VS10Project/VsDpiAwareBadParam-stderr.txt2
-rw-r--r--Tests/RunCMake/add_subdirectory/CMP0082-OLD-stderr.txt8
-rw-r--r--Tests/RunCMake/cmake_host_system_information/000-FirstFallbackScript.cmake1
-rw-r--r--Tests/RunCMake/cmake_host_system_information/999-LastFallbackScript.cmake21
-rw-r--r--Tests/RunCMake/cmake_host_system_information/BadArg1-result.txt1
-rw-r--r--Tests/RunCMake/cmake_host_system_information/BadArg1-stderr.txt4
-rw-r--r--Tests/RunCMake/cmake_host_system_information/BadArg1.cmake (renamed from Tests/CMakeTests/CMakeHostSystemInformation-BadArg1.cmake)0
-rw-r--r--Tests/RunCMake/cmake_host_system_information/BadArg2-result.txt1
-rw-r--r--Tests/RunCMake/cmake_host_system_information/BadArg2-stderr.txt4
-rw-r--r--Tests/RunCMake/cmake_host_system_information/BadArg2.cmake (renamed from Tests/CMakeTests/CMakeHostSystemInformation-BadArg2.cmake)0
-rw-r--r--Tests/RunCMake/cmake_host_system_information/BadArg3-result.txt1
-rw-r--r--Tests/RunCMake/cmake_host_system_information/BadArg3-stderr.txt4
-rw-r--r--Tests/RunCMake/cmake_host_system_information/BadArg3.cmake (renamed from Tests/CMakeTests/CMakeHostSystemInformation-BadArg3.cmake)0
-rw-r--r--Tests/RunCMake/cmake_host_system_information/CMakeLists.txt7
-rw-r--r--Tests/RunCMake/cmake_host_system_information/CentOS6-stdout.txt7
-rw-r--r--Tests/RunCMake/cmake_host_system_information/CentOS6.cmake5
-rw-r--r--Tests/RunCMake/cmake_host_system_information/CentOS6/etc/centos-release1
-rw-r--r--Tests/RunCMake/cmake_host_system_information/Debian6-stdout.txt5
-rw-r--r--Tests/RunCMake/cmake_host_system_information/Debian6.cmake5
-rw-r--r--Tests/RunCMake/cmake_host_system_information/Debian6/etc/debian_version1
-rw-r--r--Tests/RunCMake/cmake_host_system_information/Exherbo-stdout.txt9
-rw-r--r--Tests/RunCMake/cmake_host_system_information/Exherbo.cmake11
-rw-r--r--Tests/RunCMake/cmake_host_system_information/Exherbo/etc/os-release7
-rw-r--r--Tests/RunCMake/cmake_host_system_information/QueryKeys-stdout.txt27
-rw-r--r--Tests/RunCMake/cmake_host_system_information/QueryKeys.cmake (renamed from Tests/CMakeTests/CMakeHostSystemInformationTest.cmake.in)24
-rw-r--r--Tests/RunCMake/cmake_host_system_information/QueryList-stdout.txt1
-rw-r--r--Tests/RunCMake/cmake_host_system_information/QueryList.cmake (renamed from Tests/CMakeTests/CMakeHostSystemInformation-QueryList.cmake)2
-rw-r--r--Tests/RunCMake/cmake_host_system_information/RunCMakeTest.cmake17
-rw-r--r--Tests/RunCMake/cmake_host_system_information/Ubuntu-stdout.txt14
-rw-r--r--Tests/RunCMake/cmake_host_system_information/Ubuntu.cmake11
-rw-r--r--Tests/RunCMake/cmake_host_system_information/Ubuntu/etc/os-release12
-rw-r--r--Tests/RunCMake/cmake_host_system_information/UnitTest-stdout.txt7
-rw-r--r--Tests/RunCMake/cmake_host_system_information/UnitTest.cmake5
-rw-r--r--Tests/RunCMake/cmake_host_system_information/UnitTest/etc/os-release9
-rw-r--r--Tests/RunCMake/cmake_host_system_information/UserFallbackScript-stderr.txt5
-rw-r--r--Tests/RunCMake/cmake_host_system_information/UserFallbackScript-stdout.txt7
-rw-r--r--Tests/RunCMake/cmake_host_system_information/UserFallbackScript.cmake12
-rw-r--r--Tests/RunCMake/ctest_environment/CMakeLists.txt.in3
-rw-r--r--Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-invalid-op-result.txt1
-rw-r--r--Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-invalid-op-stderr.txt1
-rw-r--r--Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-invalid-op.cmake6
-rw-r--r--Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-no-colon-result.txt1
-rw-r--r--Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-no-colon-stderr.txt1
-rw-r--r--Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-no-colon.cmake6
-rw-r--r--Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-no-equals-result.txt1
-rw-r--r--Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-no-equals-stderr.txt1
-rw-r--r--Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-no-equals.cmake6
-rw-r--r--Tests/RunCMake/ctest_environment/RunCMakeTest.cmake12
-rw-r--r--Tests/RunCMake/ctest_environment/test.cmake.in16
-rw-r--r--Tests/RunCMake/ctest_test/RunCMakeTest.cmake25
-rw-r--r--Tests/RunCMake/ctest_test/TestExtraLabels-check.cmake25
-rw-r--r--Tests/RunCMake/ctest_test/TestMeasurements-check.cmake18
-rw-r--r--Tests/RunCMake/file-RPATH/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/find_library/FromScriptMode-stderr-darwin.txt4
-rw-r--r--Tests/RunCMake/find_library/FromScriptMode-stderr-windows.txt4
-rw-r--r--Tests/RunCMake/find_library/FromScriptMode-stderr.txt4
-rw-r--r--Tests/RunCMake/find_library/FromScriptMode.cmake15
-rw-r--r--Tests/RunCMake/find_library/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/find_package/CMP0084-OLD-stderr.txt10
-rw-r--r--Tests/RunCMake/find_package/MissingNormalForceRequired-result.txt1
-rw-r--r--Tests/RunCMake/find_package/MissingNormalForceRequired-stderr.txt20
-rw-r--r--Tests/RunCMake/find_package/MissingNormalForceRequired.cmake3
-rw-r--r--Tests/RunCMake/find_package/RequiredOptionValuesClash-result.txt1
-rw-r--r--Tests/RunCMake/find_package/RequiredOptionValuesClash-stderr.txt11
-rw-r--r--Tests/RunCMake/find_package/RequiredOptionValuesClash.cmake5
-rw-r--r--Tests/RunCMake/find_package/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/if/IncompleteMatches-stdout.txt6
-rw-r--r--Tests/RunCMake/if/IncompleteMatches.cmake36
-rw-r--r--Tests/RunCMake/if/IncompleteMatchesFail-result.txt1
-rw-r--r--Tests/RunCMake/if/IncompleteMatchesFail-stderr.txt6
-rw-r--r--Tests/RunCMake/if/IncompleteMatchesFail.cmake2
-rw-r--r--Tests/RunCMake/if/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/if/unbalanced-parenthesis-result.txt1
-rw-r--r--Tests/RunCMake/if/unbalanced-parenthesis-stderr.txt8
-rw-r--r--Tests/RunCMake/if/unbalanced-parenthesis.cmake8
-rw-r--r--Tests/RunCMake/install/CMP0087-OLD-stderr.txt8
-rw-r--r--Tests/RunCMake/string/Timestamp-stderr.txt2
-rw-r--r--Tests/RunCMake/string/Timestamp.cmake2
-rw-r--r--Tests/RunCMake/target_compile_features/cxx_not_enabled-stderr.txt6
-rw-r--r--Tests/RunCMake/while/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/while/unbalanced-parenthesis-result.txt1
-rw-r--r--Tests/RunCMake/while/unbalanced-parenthesis-stderr.txt8
-rw-r--r--Tests/RunCMake/while/unbalanced-parenthesis.cmake8
-rw-r--r--Tests/UseSWIG/CMakeLists.txt2
-rw-r--r--Utilities/Doxygen/CMakeLists.txt2
-rw-r--r--Utilities/KWIML/include/kwiml/int.h17
-rwxr-xr-xUtilities/Scripts/update-elf.bash28
-rwxr-xr-xUtilities/Scripts/update-libarchive.bash2
-rw-r--r--Utilities/Sphinx/CMakeLists.txt2
-rw-r--r--Utilities/cmThirdPartyChecks.cmake1
-rw-r--r--Utilities/cmelf/.gitattributes1
-rw-r--r--Utilities/cmelf/elf32.h265
-rw-r--r--Utilities/cmelf/elf64.h269
-rw-r--r--Utilities/cmelf/elf_common.h1492
-rw-r--r--Utilities/cmlibarchive/CMakeLists.txt30
-rw-r--r--Utilities/cmlibarchive/COPYING1
-rw-r--r--Utilities/cmlibarchive/build/cmake/CreatePkgConfigFile.cmake4
-rw-r--r--Utilities/cmlibarchive/build/cmake/config.h.in4
-rw-r--r--Utilities/cmlibarchive/build/version2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive.h11
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_acl.c10
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_check_magic.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_cryptor.c23
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_cryptor_private.h9
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_digest.c534
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_digest_private.h4
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry.c85
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry.h15
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_private.h16
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry_stat.34
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_ppmd7.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read.c17
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_add_passphrase.c4
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c48
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c46
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_filter.312
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_open_filename.c4
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_set_format.c9
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_by_code.c83
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_program.c23
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_zstd.c4
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_by_code.c15
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_empty.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c137
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c14
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c13
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c18
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c20
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c19
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c135
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_string.c52
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_string.h2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_util.c6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write.c42
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_program.c26
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_xz.c4
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_add_filter_zstd.c79
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c52
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c19
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_open.337
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_open_fd.c10
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_open_file.c10
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_open_filename.c21
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_open_memory.c10
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_private.h1
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c4
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio.c4
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_newc.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_iso9660.c3
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_mtree.c49
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c7
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c5
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_options.33
-rw-r--r--Utilities/cmlibarchive/libarchive/config_freebsd.h2
-rw-r--r--Utilities/cmlibarchive/libarchive/cpio.52
-rw-r--r--Utilities/cmlibarchive/libarchive/filter_fork.h9
-rw-r--r--Utilities/cmlibarchive/libarchive/filter_fork_posix.c10
-rw-r--r--Utilities/cmlibarchive/libarchive/filter_fork_windows.c17
-rw-r--r--Utilities/cmlibuv/src/win/process.c5
-rwxr-xr-xbootstrap2
499 files changed, 10186 insertions, 3325 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 2ead13b..a964b46 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -52,7 +52,7 @@ prep:doc-package:
- .cmake_doc_artifacts
- .run_only_for_package
-.upload:source-package:
+upload:source-package:
extends:
- .rsync_upload_binary
- .run_only_for_package
@@ -70,7 +70,7 @@ build:help:master:
- .cmake_org_help
- .run_only_for_continuous_master
-.upload:help:master:
+upload:help:master:
extends:
- .rsync_upload_help
- .run_only_for_continuous_master
@@ -86,7 +86,7 @@ build:help:stage:
- .cmake_org_help
- .run_only_for_continuous_stage
-.upload:help:stage:
+upload:help:stage:
extends:
- .rsync_upload_help
- .run_only_for_continuous_stage
@@ -219,6 +219,16 @@ test:fedora34-makefiles-nospace:
CMAKE_CI_BUILD_NAME: fedora34_makefiles_nospace
CMAKE_CI_JOB_NIGHTLY: "true"
+test:cuda9.2-nvidia:
+ extends:
+ - .cuda9.2_nvidia
+ - .cmake_test_linux_release
+ - .linux_builder_tags_cuda
+ - .run_dependent
+ - .needs_centos6_x86_64
+ variables:
+ CMAKE_CI_JOB_NIGHTLY: "true"
+
test:cuda10.2-nvidia:
extends:
- .cuda10.2_nvidia
@@ -238,6 +248,16 @@ test:cuda10.2-clang:
variables:
CMAKE_CI_JOB_NIGHTLY: "true"
+test:hip4.2-radeon:
+ extends:
+ - .hip4.2_radeon
+ - .cmake_test_linux_release
+ - .linux_builder_tags_radeon
+ - .run_dependent
+ - .needs_centos6_x86_64
+ variables:
+ CMAKE_CI_JOB_NIGHTLY: "true"
+
build:fedora34-ninja:
extends:
- .fedora34_ninja
@@ -500,7 +520,7 @@ build:linux-x86_64-package:
needs:
- prep:doc-package
-.upload:linux-x86_64-package:
+upload:linux-x86_64-package:
extends:
- .rsync_upload_binary
- .run_only_for_package
@@ -524,7 +544,7 @@ build:linux-aarch64-package:
needs:
- prep:doc-package
-.upload:linux-aarch64-package:
+upload:linux-aarch64-package:
extends:
- .rsync_upload_binary
- .run_only_for_package
@@ -663,7 +683,7 @@ build:macos-package:
needs:
- prep:doc-package
-.upload:macos-package:
+upload:macos-package:
extends:
- .rsync_upload_binary
- .run_only_for_package
@@ -686,7 +706,7 @@ build:macos10.10-package:
needs:
- prep:doc-package
-.upload:macos10.10-package:
+upload:macos10.10-package:
extends:
- .rsync_upload_binary
- .run_only_for_package
diff --git a/.gitlab/ci/configure_cuda9.2_nvidia.cmake b/.gitlab/ci/configure_cuda9.2_nvidia.cmake
new file mode 100644
index 0000000..519699b
--- /dev/null
+++ b/.gitlab/ci/configure_cuda9.2_nvidia.cmake
@@ -0,0 +1,3 @@
+set(CMake_TEST_CUDA "NVIDIA" CACHE STRING "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_debian10_aarch64_ninja.cmake b/.gitlab/ci/configure_debian10_aarch64_ninja.cmake
index 4d8dde6..a6b7cb5 100644
--- a/.gitlab/ci/configure_debian10_aarch64_ninja.cmake
+++ b/.gitlab/ci/configure_debian10_aarch64_ninja.cmake
@@ -16,6 +16,7 @@ set(CMake_TEST_FindGDAL "ON" CACHE BOOL "")
set(CMake_TEST_FindGIF "ON" CACHE BOOL "")
set(CMake_TEST_FindGit "ON" CACHE BOOL "")
set(CMake_TEST_FindGLEW "ON" CACHE BOOL "")
+set(CMake_TEST_FindGLUT "ON" CACHE BOOL "")
set(CMake_TEST_FindGnuTLS "ON" CACHE BOOL "")
set(CMake_TEST_FindGSL "ON" CACHE BOOL "")
set(CMake_TEST_FindGTest "ON" CACHE BOOL "")
diff --git a/.gitlab/ci/configure_debian10_ninja.cmake b/.gitlab/ci/configure_debian10_ninja.cmake
index 732624a..10d0997 100644
--- a/.gitlab/ci/configure_debian10_ninja.cmake
+++ b/.gitlab/ci/configure_debian10_ninja.cmake
@@ -16,6 +16,7 @@ set(CMake_TEST_FindGDAL "ON" CACHE BOOL "")
set(CMake_TEST_FindGIF "ON" CACHE BOOL "")
set(CMake_TEST_FindGit "ON" CACHE BOOL "")
set(CMake_TEST_FindGLEW "ON" CACHE BOOL "")
+set(CMake_TEST_FindGLUT "ON" CACHE BOOL "")
set(CMake_TEST_FindGnuTLS "ON" CACHE BOOL "")
set(CMake_TEST_FindGSL "ON" CACHE BOOL "")
set(CMake_TEST_FindGTest "ON" CACHE BOOL "")
diff --git a/.gitlab/ci/configure_fedora34_makefiles.cmake b/.gitlab/ci/configure_fedora34_makefiles.cmake
index 48786e4..d4bdb6a 100644
--- a/.gitlab/ci/configure_fedora34_makefiles.cmake
+++ b/.gitlab/ci/configure_fedora34_makefiles.cmake
@@ -16,6 +16,7 @@ set(CMake_TEST_FindGDAL "ON" CACHE BOOL "")
set(CMake_TEST_FindGIF "ON" CACHE BOOL "")
set(CMake_TEST_FindGit "ON" CACHE BOOL "")
set(CMake_TEST_FindGLEW "ON" CACHE BOOL "")
+set(CMake_TEST_FindGLUT "ON" CACHE BOOL "")
set(CMake_TEST_FindGnuTLS "ON" CACHE BOOL "")
set(CMake_TEST_FindGSL "ON" CACHE BOOL "")
set(CMake_TEST_FindGTest "ON" CACHE BOOL "")
diff --git a/.gitlab/ci/configure_hip4.2_radeon.cmake b/.gitlab/ci/configure_hip4.2_radeon.cmake
new file mode 100644
index 0000000..58036b0
--- /dev/null
+++ b/.gitlab/ci/configure_hip4.2_radeon.cmake
@@ -0,0 +1,3 @@
+set(CMake_TEST_HIP "ON" CACHE BOOL "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/docker/cuda9.2/Dockerfile b/.gitlab/ci/docker/cuda9.2/Dockerfile
new file mode 100644
index 0000000..7eae886
--- /dev/null
+++ b/.gitlab/ci/docker/cuda9.2/Dockerfile
@@ -0,0 +1,5 @@
+FROM nvidia/cuda:9.2-devel-ubuntu16.04
+MAINTAINER Brad King <brad.king@kitware.com>
+
+COPY install_deps.sh /root/install_deps.sh
+RUN sh /root/install_deps.sh
diff --git a/.gitlab/ci/docker/cuda9.2/install_deps.sh b/.gitlab/ci/docker/cuda9.2/install_deps.sh
new file mode 100755
index 0000000..146f982
--- /dev/null
+++ b/.gitlab/ci/docker/cuda9.2/install_deps.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+set -e
+
+apt-get update
+
+# Install development tools.
+apt-get install -y \
+ g++ \
+ clang-3.8 \
+ curl \
+ git
+
+apt-get clean
diff --git a/.gitlab/ci/docker/hip4.2/Dockerfile b/.gitlab/ci/docker/hip4.2/Dockerfile
new file mode 100644
index 0000000..563e94f
--- /dev/null
+++ b/.gitlab/ci/docker/hip4.2/Dockerfile
@@ -0,0 +1,7 @@
+FROM rocm/dev-ubuntu-20.04:4.2
+MAINTAINER Brad King <brad.king@kitware.com>
+
+ENV PATH="/opt/rocm/bin:$PATH"
+
+COPY install_deps.sh /root/install_deps.sh
+RUN sh /root/install_deps.sh
diff --git a/.gitlab/ci/docker/hip4.2/install_deps.sh b/.gitlab/ci/docker/hip4.2/install_deps.sh
new file mode 100755
index 0000000..2b45bc9
--- /dev/null
+++ b/.gitlab/ci/docker/hip4.2/install_deps.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+set -e
+
+apt-get update
+
+# Install development tools.
+apt-get install -y --no-install-recommends \
+ g++ \
+ curl \
+ git
+
+apt-get clean
diff --git a/.gitlab/ci/env_cuda9.2_nvidia.sh b/.gitlab/ci/env_cuda9.2_nvidia.sh
new file mode 100644
index 0000000..16bfba4
--- /dev/null
+++ b/.gitlab/ci/env_cuda9.2_nvidia.sh
@@ -0,0 +1,4 @@
+export CC=/usr/bin/clang-3.8
+export CXX=/usr/bin/clang++-3.8
+export CUDAHOSTCXX=/usr/bin/g++-5
+export CUDACXX=/usr/local/cuda/bin/nvcc
diff --git a/.gitlab/os-linux.yml b/.gitlab/os-linux.yml
index 95cab05..1513c90 100644
--- a/.gitlab/os-linux.yml
+++ b/.gitlab/os-linux.yml
@@ -208,6 +208,21 @@
### CUDA builds
+.cuda9.2:
+ image: "kitware/cmake:ci-cuda9.2-x86_64-2021-07-01"
+
+ variables:
+ GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci"
+ CMAKE_ARCH: x86_64
+ CTEST_LABELS: "CUDA"
+
+.cuda9.2_nvidia:
+ extends: .cuda9.2
+
+ variables:
+ CMAKE_CONFIGURATION: cuda9.2_nvidia
+ CMAKE_GENERATOR: "Ninja Multi-Config"
+
.cuda10.2:
image: "kitware/cmake:ci-cuda10.2-x86_64-2021-06-16"
@@ -230,6 +245,23 @@
CMAKE_CONFIGURATION: cuda10.2_clang
CTEST_NO_WARNINGS_ALLOWED: 1
+### HIP builds
+
+.hip4.2:
+ image: "kitware/cmake:ci-hip4.2-x86_64-2021-07-09"
+
+ variables:
+ GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci"
+ CMAKE_ARCH: x86_64
+ CTEST_LABELS: "HIP"
+
+.hip4.2_radeon:
+ extends: .hip4.2
+
+ variables:
+ CMAKE_CONFIGURATION: hip4.2_radeon
+ CMAKE_GENERATOR: "Ninja Multi-Config"
+
## Tags
.linux_builder_tags:
@@ -262,6 +294,13 @@
- docker
- linux
+.linux_builder_tags_radeon:
+ tags:
+ - cmake
+ - radeon
+ - docker
+ - linux
+
.linux_builder_tags_aarch64:
tags:
- cmake
diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim
index d2a04fe..7a3e4ed 100644
--- a/Auxiliary/vim/syntax/cmake.vim
+++ b/Auxiliary/vim/syntax/cmake.vim
@@ -160,6 +160,7 @@ syn keyword cmakeProperty contained
\ ENABLED_LANGUAGES
\ ENABLE_EXPORTS
\ ENVIRONMENT
+ \ ENVIRONMENT_MODIFICATION
\ EXCLUDE_FROM_ALL
\ EXCLUDE_FROM_DEFAULT_BUILD
\ EXPORT_NAME
@@ -2807,6 +2808,7 @@ syn keyword cmakeKWfind_package contained
\ ABI
\ BUNDLE
\ CMAKE_DISABLE_FIND_PACKAGE_
+ \ CMAKE_REQUIRE_FIND_PACKAGE_
\ CMAKE_FIND_ROOT_PATH_BOTH
\ COMPONENTS
\ CONFIG
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9944ea4..fdfe456 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,7 +1,7 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
-cmake_minimum_required(VERSION 3.1...3.19 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.1...3.20 FATAL_ERROR)
set(CMAKE_USER_MAKE_RULES_OVERRIDE_C ${CMAKE_CURRENT_SOURCE_DIR}/Source/Modules/OverrideC.cmake)
set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX ${CMAKE_CURRENT_SOURCE_DIR}/Source/Modules/OverrideCXX.cmake)
project(CMake)
@@ -815,8 +815,12 @@ CMAKE_SETUP_TESTING()
if(NOT CMake_TEST_EXTERNAL_CMAKE)
if(NOT CMake_VERSION_IS_RELEASE)
- if(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND
- NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS 4.2)
+ if((CMAKE_C_COMPILER_ID STREQUAL "GNU" AND
+ NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS 4.2) OR
+ (CMAKE_C_COMPILER_ID STREQUAL "Clang" AND
+ NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS 3.0 AND
+ NOT "x${CMAKE_C_SIMULATE_ID}" STREQUAL "xMSVC") OR
+ CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
set(C_FLAGS_LIST -Wcast-align -Werror-implicit-function-declaration -Wchar-subscripts
-Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security
-Wmissing-format-attribute -fno-common -Wundef
diff --git a/Help/command/cmake_host_system_information.rst b/Help/command/cmake_host_system_information.rst
index 2b902a9..998e146 100644
--- a/Help/command/cmake_host_system_information.rst
+++ b/Help/command/cmake_host_system_information.rst
@@ -13,46 +13,236 @@ queried. The list of queried values is stored in ``<variable>``.
``<key>`` can be one of the following values:
-============================= ================================================
-Key Description
-============================= ================================================
-``NUMBER_OF_LOGICAL_CORES`` Number of logical cores
-``NUMBER_OF_PHYSICAL_CORES`` Number of physical cores
-``HOSTNAME`` Hostname
-``FQDN`` Fully qualified domain name
-``TOTAL_VIRTUAL_MEMORY`` Total virtual memory in MiB [#mebibytes]_
-``AVAILABLE_VIRTUAL_MEMORY`` Available virtual memory in MiB [#mebibytes]_
-``TOTAL_PHYSICAL_MEMORY`` Total physical memory in MiB [#mebibytes]_
-``AVAILABLE_PHYSICAL_MEMORY`` Available physical memory in MiB [#mebibytes]_
-============================= ================================================
-
-.. versionadded:: 3.10
- Additional ``<key>`` values are available:
-
-============================= ================================================
-Key Description
-============================= ================================================
-``IS_64BIT`` One if processor is 64Bit
-``HAS_FPU`` One if processor has floating point unit
-``HAS_MMX`` One if processor supports MMX instructions
-``HAS_MMX_PLUS`` One if processor supports Ext. MMX instructions
-``HAS_SSE`` One if processor supports SSE instructions
-``HAS_SSE2`` One if processor supports SSE2 instructions
-``HAS_SSE_FP`` One if processor supports SSE FP instructions
-``HAS_SSE_MMX`` One if processor supports SSE MMX instructions
-``HAS_AMD_3DNOW`` One if processor supports 3DNow instructions
-``HAS_AMD_3DNOW_PLUS`` One if processor supports 3DNow+ instructions
-``HAS_IA64`` One if IA64 processor emulating x86
-``HAS_SERIAL_NUMBER`` One if processor has serial number
-``PROCESSOR_SERIAL_NUMBER`` Processor serial number
-``PROCESSOR_NAME`` Human readable processor name
-``PROCESSOR_DESCRIPTION`` Human readable full processor description
-``OS_NAME`` See :variable:`CMAKE_HOST_SYSTEM_NAME`
-``OS_RELEASE`` The OS sub-type e.g. on Windows ``Professional``
-``OS_VERSION`` The OS build ID
-``OS_PLATFORM`` See :variable:`CMAKE_HOST_SYSTEM_PROCESSOR`
-============================= ================================================
+``NUMBER_OF_LOGICAL_CORES``
+ Number of logical cores
+
+``NUMBER_OF_PHYSICAL_CORES``
+ Number of physical cores
+
+``HOSTNAME``
+ Hostname
+
+``FQDN``
+ Fully qualified domain name
+
+``TOTAL_VIRTUAL_MEMORY``
+ Total virtual memory in MiB [#mebibytes]_
+
+``AVAILABLE_VIRTUAL_MEMORY``
+ Available virtual memory in MiB [#mebibytes]_
+
+``TOTAL_PHYSICAL_MEMORY``
+ Total physical memory in MiB [#mebibytes]_
+
+``AVAILABLE_PHYSICAL_MEMORY``
+ Available physical memory in MiB [#mebibytes]_
+
+``IS_64BIT``
+ .. versionadded:: 3.10
+
+ One if processor is 64Bit
+
+``HAS_FPU``
+ .. versionadded:: 3.10
+
+ One if processor has floating point unit
+
+``HAS_MMX``
+ .. versionadded:: 3.10
+
+ One if processor supports MMX instructions
+
+``HAS_MMX_PLUS``
+ .. versionadded:: 3.10
+
+ One if processor supports Ext. MMX instructions
+
+``HAS_SSE``
+ .. versionadded:: 3.10
+
+ One if processor supports SSE instructions
+
+``HAS_SSE2``
+ .. versionadded:: 3.10
+
+ One if processor supports SSE2 instructions
+
+``HAS_SSE_FP``
+ .. versionadded:: 3.10
+
+ One if processor supports SSE FP instructions
+
+``HAS_SSE_MMX``
+ .. versionadded:: 3.10
+
+ One if processor supports SSE MMX instructions
+
+``HAS_AMD_3DNOW``
+ .. versionadded:: 3.10
+
+ One if processor supports 3DNow instructions
+
+``HAS_AMD_3DNOW_PLUS``
+ .. versionadded:: 3.10
+
+ One if processor supports 3DNow+ instructions
+
+``HAS_IA64``
+ .. versionadded:: 3.10
+
+ One if IA64 processor emulating x86
+
+``HAS_SERIAL_NUMBER``
+ .. versionadded:: 3.10
+
+ One if processor has serial number
+
+``PROCESSOR_SERIAL_NUMBER``
+ .. versionadded:: 3.10
+
+ Processor serial number
+
+``PROCESSOR_NAME``
+ .. versionadded:: 3.10
+
+ Human readable processor name
+
+``PROCESSOR_DESCRIPTION``
+ .. versionadded:: 3.10
+
+ Human readable full processor description
+
+``OS_NAME``
+ .. versionadded:: 3.10
+
+ See :variable:`CMAKE_HOST_SYSTEM_NAME`
+
+``OS_RELEASE``
+ .. versionadded:: 3.10
+
+ The OS sub-type e.g. on Windows ``Professional``
+
+``OS_VERSION``
+ .. versionadded:: 3.10
+
+ The OS build ID
+
+``OS_PLATFORM``
+ .. versionadded:: 3.10
+
+ See :variable:`CMAKE_HOST_SYSTEM_PROCESSOR`
+
+``DISTRIB_INFO``
+ .. versionadded:: 3.22
+
+ Read :file:`/etc/os-release` file and define the given ``<variable>``
+ into a list of read variables
+
+``DISTRIB_<name>``
+ .. versionadded:: 3.22
+
+ Get the ``<name>`` variable (see `man 5 os-release`_) if it exists in the
+ :file:`/etc/os-release` file
+
+ Example:
+
+ .. code-block:: cmake
+
+ cmake_host_system_information(RESULT PRETTY_NAME QUERY DISTRIB_PRETTY_NAME)
+ message(STATUS "${PRETTY_NAME}")
+
+ cmake_host_system_information(RESULT DISTRO QUERY DISTRIB_INFO)
+
+ foreach(VAR IN LISTS DISTRO)
+ message(STATUS "${VAR}=`${${VAR}}`")
+ endforeach()
+
+
+ Output::
+
+ -- Ubuntu 20.04.2 LTS
+ -- DISTRO_BUG_REPORT_URL=`https://bugs.launchpad.net/ubuntu/`
+ -- DISTRO_HOME_URL=`https://www.ubuntu.com/`
+ -- DISTRO_ID=`ubuntu`
+ -- DISTRO_ID_LIKE=`debian`
+ -- DISTRO_NAME=`Ubuntu`
+ -- DISTRO_PRETTY_NAME=`Ubuntu 20.04.2 LTS`
+ -- DISTRO_PRIVACY_POLICY_URL=`https://www.ubuntu.com/legal/terms-and-policies/privacy-policy`
+ -- DISTRO_SUPPORT_URL=`https://help.ubuntu.com/`
+ -- DISTRO_UBUNTU_CODENAME=`focal`
+ -- DISTRO_VERSION=`20.04.2 LTS (Focal Fossa)`
+ -- DISTRO_VERSION_CODENAME=`focal`
+ -- DISTRO_VERSION_ID=`20.04`
+
+If :file:`/etc/os-release` file is not found, the command tries to gather OS
+identification via fallback scripts. The fallback script can use `various
+distribution-specific files`_ to collect OS identification data and map it
+into `man 5 os-release`_ variables.
+
+Fallback Interface Variables
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. variable:: CMAKE_GET_OS_RELEASE_FALLBACK_SCRIPTS
+
+ In addition to the scripts shipped with CMake, a user may append full
+ paths to his script(s) to the this list. The script filename has the
+ following format: ``NNN-<name>.cmake``, where ``NNN`` is three digits
+ used to apply collected scripts in a specific order.
+
+.. variable:: CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_<varname>
+
+ Variables collected by the user provided fallback script
+ ought to be assigned to CMake variables using this naming
+ convention. Example, the ``ID`` variable from the manual becomes
+ ``CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_ID``.
+
+.. variable:: CMAKE_GET_OS_RELEASE_FALLBACK_RESULT
+
+ The fallback script ought to store names of all assigned
+ ``CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_<varname>`` variables in this list.
+
+Example:
+
+.. code-block:: cmake
+
+ # Try to detect some old distribution
+ # See also
+ # - http://linuxmafia.com/faq/Admin/release-files.html
+ #
+ if(NOT EXISTS "${CMAKE_SYSROOT}/etc/foobar-release")
+ return()
+ endif()
+ # Get the first string only
+ file(
+ STRINGS "${CMAKE_SYSROOT}/etc/foobar-release" CMAKE_GET_OS_RELEASE_FALLBACK_CONTENT
+ LIMIT_COUNT 1
+ )
+ #
+ # Example:
+ #
+ # Foobar distribution release 1.2.3 (server)
+ #
+ if(CMAKE_GET_OS_RELEASE_FALLBACK_CONTENT MATCHES "Foobar distribution release ([0-9\.]+) .*")
+ set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_NAME Foobar)
+ set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_PRETTY_NAME "${CMAKE_GET_OS_RELEASE_FALLBACK_CONTENT}")
+ set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_ID foobar)
+ set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION ${CMAKE_MATCH_1})
+ set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION_ID ${CMAKE_MATCH_1})
+ list(
+ APPEND CMAKE_GET_OS_RELEASE_FALLBACK_RESULT
+ CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_NAME
+ CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_PRETTY_NAME
+ CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_ID
+ CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION
+ CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION_ID
+ )
+ endif()
+ unset(CMAKE_GET_OS_RELEASE_FALLBACK_CONTENT)
+
.. rubric:: Footnotes
.. [#mebibytes] One MiB (mebibyte) is equal to 1024x1024 bytes.
+
+.. _man 5 os-release: https://www.freedesktop.org/software/systemd/man/os-release.html
+.. _various distribution-specific files: http://linuxmafia.com/faq/Admin/release-files.html
diff --git a/Help/command/ctest_test.rst b/Help/command/ctest_test.rst
index 89787d1..4e5484f 100644
--- a/Help/command/ctest_test.rst
+++ b/Help/command/ctest_test.rst
@@ -190,29 +190,33 @@ Check the `CDash test measurement documentation
<https://github.com/Kitware/CDash/blob/master/docs/test_measurements.md>`_
for more information on the types of test measurements that CDash recognizes.
+Starting in version 3.22, CTest can parse custom measurements from tags named
+``<CTestMeasurement>`` or ``<CTestMeasurementFile>``. The older names
+``<DartMeasurement>`` and ``<DartMeasurementFile>`` are still supported.
+
The following example demonstrates how to output a variety of custom test
measurements.
.. code-block:: c++
std::cout <<
- "<DartMeasurement type=\"numeric/double\" name=\"score\">28.3</DartMeasurement>"
+ "<CTestMeasurement type=\"numeric/double\" name=\"score\">28.3</CTestMeasurement>"
<< std::endl;
std::cout <<
- "<DartMeasurement type=\"text/string\" name=\"color\">red</DartMeasurement>"
+ "<CTestMeasurement type=\"text/string\" name=\"color\">red</CTestMeasurement>"
<< std::endl;
std::cout <<
- "<DartMeasurement type=\"text/link\" name=\"CMake URL\">https://cmake.org</DartMeasurement>"
+ "<CTestMeasurement type=\"text/link\" name=\"CMake URL\">https://cmake.org</CTestMeasurement>"
<< std::endl;
std::cout <<
- "<DartMeasurement type=\"text/preformatted\" name=\"Console Output\">" <<
+ "<CTestMeasurement type=\"text/preformatted\" name=\"Console Output\">" <<
"line 1.\n" <<
" \033[31;1m line 2. Bold red, and indented!\033[0;0ml\n" <<
"line 3. Not bold or indented...\n" <<
- "</DartMeasurement>" << std::endl;
+ "</CTestMeasurement>" << std::endl;
Image Measurements
""""""""""""""""""
@@ -222,16 +226,16 @@ The following example demonstrates how to upload test images to CDash.
.. code-block:: c++
std::cout <<
- "<DartMeasurementFile type=\"image/jpg\" name=\"TestImage\">" <<
- "/dir/to/test_img.jpg</DartMeasurementFile>" << std::endl;
+ "<CTestMeasurementFile type=\"image/jpg\" name=\"TestImage\">" <<
+ "/dir/to/test_img.jpg</CTestMeasurementFile>" << std::endl;
std::cout <<
- "<DartMeasurementFile type=\"image/gif\" name=\"ValidImage\">" <<
- "/dir/to/valid_img.gif</DartMeasurementFile>" << std::endl;
+ "<CTestMeasurementFile type=\"image/gif\" name=\"ValidImage\">" <<
+ "/dir/to/valid_img.gif</CTestMeasurementFile>" << std::endl;
std::cout <<
- "<DartMeasurementFile type=\"image/png\" name=\"AlgoResult\"> <<
- "/dir/to/img.png</DartMeasurementFile>"
+ "<CTestMeasurementFile type=\"image/png\" name=\"AlgoResult\"> <<
+ "/dir/to/img.png</CTestMeasurementFile>"
<< std::endl;
Images will be displayed together in an interactive comparison mode on CDash
@@ -257,8 +261,10 @@ The following example demonstrates how to upload non-image files to CDash.
.. code-block:: c++
std::cout <<
- "<DartMeasurementFile type=\"file\" name=\"MyTestInputData\">" <<
- "/dir/to/data.csv</DartMeasurementFile>" << std::endl;
+ "<CTestMeasurementFile type=\"file\" name=\"TestInputData1\">" <<
+ "/dir/to/data1.csv</CTestMeasurementFile>\n" <<
+ "<CTestMeasurementFile type=\"file\" name=\"TestInputData2\">" <<
+ "/dir/to/data2.csv</CTestMeasurementFile>" << std::endl;
If the name of the file to upload is known at configure time, you can use the
:prop_test:`ATTACHED_FILES` or :prop_test:`ATTACHED_FILES_ON_FAIL` test
@@ -274,3 +280,18 @@ The following example demonstrates how to specify a custom value for the
std::cout <<
"<CTestDetails>My Custom Details Value</CTestDetails>" << std::endl;
+
+Additional Labels
+"""""""""""""""""
+
+The following example demonstrates how to add additional labels to a test
+at runtime.
+
+.. code-block:: c++
+
+ std::cout <<
+ "<CTestLabel>Custom Label 1</CTestLabel>\n" <<
+ "<CTestLabel>Custom Label 2</CTestLabel>" << std::endl;
+
+Use the :prop_test:`LABELS` test property instead for labels that can be
+determined at configure time.
diff --git a/Help/command/file.rst b/Help/command/file.rst
index f038871..96a55ee 100644
--- a/Help/command/file.rst
+++ b/Help/command/file.rst
@@ -843,6 +843,11 @@ and ``NO_SOURCE_PERMISSIONS`` is default.
Installation scripts generated by the :command:`install` command
use this signature (with some undocumented options for internal use).
+.. versionchanged:: 3.22
+
+ The environment variable :envvar:`CMAKE_INSTALL_MODE` can override the
+ default copying behavior of :command:`file(INSTALL)`.
+
.. _SIZE:
.. code-block:: cmake
diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst
index 3dfd62f..490a5c7 100644
--- a/Help/command/find_package.rst
+++ b/Help/command/find_package.rst
@@ -28,11 +28,26 @@ that the package cannot be found if it is not ``REQUIRED``. The ``REQUIRED``
option stops processing with an error message if the package cannot be found.
A package-specific list of required components may be listed after the
-``COMPONENTS`` option (or after the ``REQUIRED`` option if present).
+``COMPONENTS`` keyword. If any of these components are not able to be
+satisfied, the package overall is considered to be not found. If the
+``REQUIRED`` option is also present, this is treated as a fatal error,
+otherwise execution still continues. As a form of shorthand, if the
+``REQUIRED`` option is present, the ``COMPONENTS`` keyword can be omitted
+and the required components can be listed directly after ``REQUIRED``.
+
Additional optional components may be listed after
-``OPTIONAL_COMPONENTS``. Available components and their influence on
-whether a package is considered to be found are defined by the target
-package.
+``OPTIONAL_COMPONENTS``. If these cannot be satisfied, the package overall
+can still be considered found, as long as all required components are
+satisfied.
+
+The set of available components and their meaning are defined by the
+target package. Formally, it is up to the target package how to
+interpret the component information given to it, but it should follow
+the expectations stated above. For calls where no components are specified,
+there is no single expected behavior and target packages should clearly
+define what occurs in such cases. Common arrangements include assuming it
+should find all components, no components or some well-defined subset of the
+available components.
.. _FIND_PACKAGE_VERSION_FORMAT:
@@ -432,7 +447,7 @@ enabled.
hard-coded guesses.
.. versionadded:: 3.16
- Added the ``CMAKE_FIND_USE_<CATEGORY>_PATH`` variables to globally disable
+ Added the ``CMAKE_FIND_USE_<CATEGORY>`` variables to globally disable
various search locations.
.. |FIND_XXX| replace:: find_package
@@ -448,8 +463,15 @@ which the file is found. The :variable:`CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS`
variable may be set to ``TRUE`` before calling ``find_package`` in order
to resolve symbolic links and store the real path to the file.
-Every non-REQUIRED ``find_package`` call can be disabled by setting the
-:variable:`CMAKE_DISABLE_FIND_PACKAGE_<PackageName>` variable to ``TRUE``.
+Every non-REQUIRED ``find_package`` call can be disabled or made REQUIRED:
+
+* Setting the :variable:`CMAKE_DISABLE_FIND_PACKAGE_<PackageName>` variable
+ to ``TRUE`` disables the package.
+
+* Setting the :variable:`CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>` variable
+ to ``TRUE`` makes the package REQUIRED.
+
+Setting both variables to ``TRUE`` simultaneously is an error.
Package File Interface Variables
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -479,7 +501,7 @@ restores their original state before returning):
``<PackageName>_FIND_VERSION_EXACT``
True if ``EXACT`` option was given
``<PackageName>_FIND_COMPONENTS``
- List of requested components
+ List of specified components (required and optional)
``<PackageName>_FIND_REQUIRED_<c>``
True if component ``<c>`` is required,
false if component ``<c>`` is optional
diff --git a/Help/command/get_property.rst b/Help/command/get_property.rst
index f77d8af..46da285 100644
--- a/Help/command/get_property.rst
+++ b/Help/command/get_property.rst
@@ -9,7 +9,7 @@ Get a property.
<GLOBAL |
DIRECTORY [<dir>] |
TARGET <target> |
- SOURCE <source> |
+ SOURCE <source>
[DIRECTORY <dir> | TARGET_DIRECTORY <target>] |
INSTALL <file> |
TEST <test> |
diff --git a/Help/command/if.rst b/Help/command/if.rst
index fbf3e36..6ff8852 100644
--- a/Help/command/if.rst
+++ b/Help/command/if.rst
@@ -171,7 +171,7 @@ Comparisons
``if(<variable|string> MATCHES regex)``
True if the given string or variable's value matches the given regular
- condition. See :ref:`Regex Specification` for regex format.
+ expression. See :ref:`Regex Specification` for regex format.
.. versionadded:: 3.9
``()`` groups are captured in :variable:`CMAKE_MATCH_<n>` variables.
diff --git a/Help/command/install.rst b/Help/command/install.rst
index c6af489..1236f1d 100644
--- a/Help/command/install.rst
+++ b/Help/command/install.rst
@@ -30,6 +30,10 @@ are executed in order during installation.
with those in the parent directory to run in the order declared (see
policy :policy:`CMP0082`).
+.. versionchanged:: 3.22
+ The environment variable :envvar:`CMAKE_INSTALL_MODE` can override the
+ default copying behavior of :command:`install()`.
+
There are multiple signatures for this command. Some of them define
installation options for files and targets. Options common to
multiple signatures are covered here but they are valid only for
diff --git a/Help/command/set_property.rst b/Help/command/set_property.rst
index bf437b4..555520d 100644
--- a/Help/command/set_property.rst
+++ b/Help/command/set_property.rst
@@ -9,8 +9,8 @@ Set a named property in a given scope.
DIRECTORY [<dir>] |
TARGET [<target1> ...] |
SOURCE [<src1> ...]
- [DIRECTORY <dirs> ...] |
- [TARGET_DIRECTORY <targets> ...]
+ [DIRECTORY <dirs> ...]
+ [TARGET_DIRECTORY <targets> ...] |
INSTALL [<file1> ...] |
TEST [<test1> ...] |
CACHE [<entry1> ...] >
diff --git a/Help/command/source_group.rst b/Help/command/source_group.rst
index a4b5bf1..83ae286 100644
--- a/Help/command/source_group.rst
+++ b/Help/command/source_group.rst
@@ -22,7 +22,8 @@ The options are:
CMake will automatically detect, from ``<src>`` files paths, source groups
it needs to create, to keep structure of source groups analogically to the
actual files and directories structure in the project. Paths of ``<src>``
- files will be cut to be relative to ``<root>``.
+ files will be cut to be relative to ``<root>``. The command fails if the
+ paths within ``src`` do not start with ``root``.
``PREFIX``
.. versionadded:: 3.8
diff --git a/Help/command/string.rst b/Help/command/string.rst
index 8ad0089..29ad082 100644
--- a/Help/command/string.rst
+++ b/Help/command/string.rst
@@ -449,38 +449,73 @@ be in Coordinated Universal Time (UTC) rather than local time.
The optional ``<format_string>`` may contain the following format
specifiers:
-::
+``%%``
+ .. versionadded:: 3.8
- %% A literal percent sign (%).
- %d The day of the current month (01-31).
- %H The hour on a 24-hour clock (00-23).
- %I The hour on a 12-hour clock (01-12).
- %j The day of the current year (001-366).
- %m The month of the current year (01-12).
- %b Abbreviated month name (e.g. Oct).
- %B Full month name (e.g. October).
- %M The minute of the current hour (00-59).
- %s Seconds since midnight (UTC) 1-Jan-1970 (UNIX time).
- %S The second of the current minute.
- 60 represents a leap second. (00-60)
- %U The week number of the current year (00-53).
- %w The day of the current week. 0 is Sunday. (0-6)
- %a Abbreviated weekday name (e.g. Fri).
- %A Full weekday name (e.g. Friday).
- %y The last two digits of the current year (00-99)
- %Y The current year.
-
-.. versionadded:: 3.6
- ``%s`` format specifier (UNIX time).
+ A literal percent sign (%).
-.. versionadded:: 3.7
- ``%a`` and ``%b`` format specifiers (abbreviated month and weekday names).
+``%d``
+ The day of the current month (01-31).
-.. versionadded:: 3.8
- ``%%`` specifier (literal ``%``).
+``%H``
+ The hour on a 24-hour clock (00-23).
-.. versionadded:: 3.7
- ``%A`` and ``%B`` format specifiers (full month and weekday names).
+``%I``
+ The hour on a 12-hour clock (01-12).
+
+``%j``
+ The day of the current year (001-366).
+
+``%m``
+ The month of the current year (01-12).
+
+``%b``
+ .. versionadded:: 3.7
+
+ Abbreviated month name (e.g. Oct).
+
+``%B``
+ .. versionadded:: 3.10
+
+ Full month name (e.g. October).
+
+``%M``
+ The minute of the current hour (00-59).
+
+``%s``
+ .. versionadded:: 3.6
+
+ Seconds since midnight (UTC) 1-Jan-1970 (UNIX time).
+
+``%S``
+ The second of the current minute. 60 represents a leap second. (00-60)
+
+``%U``
+ The week number of the current year (00-53).
+
+``%V``
+ .. versionadded:: 3.22
+
+ The ISO 8601 week number of the current year (01-53).
+
+``%w``
+ The day of the current week. 0 is Sunday. (0-6)
+
+``%a``
+ .. versionadded:: 3.7
+
+ Abbreviated weekday name (e.g. Fri).
+
+``%A``
+ .. versionadded:: 3.10
+
+ Full weekday name (e.g. Friday).
+
+``%y``
+ The last two digits of the current year (00-99).
+
+``%Y``
+ The current year.
Unknown format specifiers will be ignored and copied to the output
as-is.
diff --git a/Help/cpack_gen/deb.rst b/Help/cpack_gen/deb.rst
index d8d53ec..f96ca32 100644
--- a/Help/cpack_gen/deb.rst
+++ b/Help/cpack_gen/deb.rst
@@ -274,10 +274,23 @@ List of CPack DEB generator specific variables:
Possible values are:
- - lzma
- - xz
- - bzip2
- - gzip
+ ``lzma``
+ Lempel–Ziv–Markov chain algorithm
+
+ ``xz``
+ XZ Utils compression
+
+ ``bzip2``
+ bzip2 Burrows–Wheeler algorithm
+
+ ``gzip``
+ GNU Gzip compression
+
+ ``zstd``
+ .. versionadded:: 3.22
+
+ Zstandard compression
+
.. variable:: CPACK_DEBIAN_PACKAGE_PRIORITY
CPACK_DEBIAN_<COMPONENT>_PACKAGE_PRIORITY
@@ -652,9 +665,18 @@ Dbgsym packaging has its own set of variables:
.. note::
+ Setting this also strips the ELF files in the generated non-dbgsym package,
+ which results in debuginfo only being available in the dbgsym package.
+
+.. note::
+
Binaries must contain debug symbols before packaging so use either ``Debug``
or ``RelWithDebInfo`` for :variable:`CMAKE_BUILD_TYPE` variable value.
+ Additionally, if :variable:`CPACK_STRIP_FILES` is set, the files will be stripped before
+ they get to the DEB generator, so will not contain debug symbols and
+ a dbgsym package will not get built. Do not use with :variable:`CPACK_STRIP_FILES`.
+
Building Debian packages on Windows
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/Help/cpack_gen/nsis.rst b/Help/cpack_gen/nsis.rst
index 02e33ba..299cfec 100644
--- a/Help/cpack_gen/nsis.rst
+++ b/Help/cpack_gen/nsis.rst
@@ -3,8 +3,8 @@ CPack NSIS Generator
CPack Nullsoft Scriptable Install System (NSIS) generator specific options.
-.. versionchanged:: 3.17
- The NSIS generator requires NSIS 3.0 or newer.
+.. versionchanged:: 3.22
+ The NSIS generator requires NSIS 3.03 or newer.
Variables specific to CPack NSIS generator
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -201,3 +201,9 @@ on Windows Nullsoft Scriptable Install System.
.. versionadded:: 3.21
If set, specify the name of the NSIS executable. Default is ``makensis``.
+
+.. variable:: CPACK_NSIS_IGNORE_LICENSE_PAGE
+
+ .. versionadded:: 3.22
+
+ If set, do not display the page containing the license during installation.
diff --git a/Help/cpack_gen/rpm.rst b/Help/cpack_gen/rpm.rst
index 322ab68..823594a 100644
--- a/Help/cpack_gen/rpm.rst
+++ b/Help/cpack_gen/rpm.rst
@@ -840,6 +840,10 @@ Debuginfo RPM packaging has its own set of variables:
Binaries must contain debug symbols before packaging so use either ``Debug``
or ``RelWithDebInfo`` for :variable:`CMAKE_BUILD_TYPE` variable value.
+ Additionally, if :variable:`CPACK_STRIP_FILES` is set, the files will be stripped before
+ they get to the RPM generator, so will not contain debug symbols and
+ a debuginfo package will not get built. Do not use with :variable:`CPACK_STRIP_FILES`.
+
.. note::
Packages generated from packages without binary files, with binary files but
@@ -1035,3 +1039,14 @@ Source RPM packaging has its own set of variables:
example::
set(CPACK_RPM_BUILDREQUIRES "python >= 2.5.0, cmake >= 2.8")
+
+.. VARIABLE:: CPACK_RPM_REQUIRES_EXCLUDE_FROM
+
+ * Mandatory : NO
+ * Default : -
+
+ May be used to keep the dependency generator from scanning specific files
+ or directories for dependencies. Note that you can use a regular
+ expression that matches all of the directories or files, for example::
+
+ set(CPACK_RPM_REQUIRES_EXCLUDE_FROM "bin/libqsqloci.*\\.so.*")
diff --git a/Help/envvar/CMAKE_BUILD_TYPE.rst b/Help/envvar/CMAKE_BUILD_TYPE.rst
new file mode 100644
index 0000000..f798aff
--- /dev/null
+++ b/Help/envvar/CMAKE_BUILD_TYPE.rst
@@ -0,0 +1,10 @@
+CMAKE_BUILD_TYPE
+----------------
+
+.. versionadded:: 3.22
+
+.. include:: ENV_VAR.txt
+
+The ``CMAKE_BUILD_TYPE`` environment variable specifies a default value
+for the :variable:`CMAKE_BUILD_TYPE` variable when there is no explicit
+configuration given on the first run while creating a new build tree.
diff --git a/Help/envvar/CMAKE_CONFIGURATION_TYPES.rst b/Help/envvar/CMAKE_CONFIGURATION_TYPES.rst
new file mode 100644
index 0000000..833aa4a
--- /dev/null
+++ b/Help/envvar/CMAKE_CONFIGURATION_TYPES.rst
@@ -0,0 +1,11 @@
+CMAKE_CONFIGURATION_TYPES
+-------------------------
+
+.. versionadded:: 3.22
+
+.. include:: ENV_VAR.txt
+
+The ``CMAKE_CONFIGURATION_TYPES`` environment variable specifies a
+default value for the :variable:`CMAKE_CONFIGURATION_TYPES` variable
+when there is no explicit configuration given on the first run while
+creating a new build tree.
diff --git a/Help/envvar/CMAKE_INSTALL_MODE.rst b/Help/envvar/CMAKE_INSTALL_MODE.rst
new file mode 100644
index 0000000..37db0d7
--- /dev/null
+++ b/Help/envvar/CMAKE_INSTALL_MODE.rst
@@ -0,0 +1,37 @@
+CMAKE_INSTALL_MODE
+------------------
+
+.. versionadded:: 3.22
+
+.. include:: ENV_VAR.txt
+
+The ``CMAKE_INSTALL_MODE`` environment variable allows users to operate
+CMake in an alternate mode of :command:`file(INSTALL)` and :command:`install()`.
+
+The default behavior for an installation is to copy a source file from a
+source directory into a destination directory. This environment variable
+however allows the user to override this behavior, causing CMake to create
+symbolic links instead.
+
+.. note::
+ A symbolic link consists of a reference file path rather than contents of its own,
+ hence there are two ways to express the relation, either by a relative or an absolute path.
+
+The following values are allowed for ``CMAKE_INSTALL_MODE``:
+
+* empty, unset or ``COPY``: default behavior, duplicate the file at its destination
+* ``ABS_SYMLINK``: create an *absolute* symbolic link to the source file at the destination *or fail*
+* ``ABS_SYMLINK_OR_COPY``: like ``ABS_SYMLINK`` but silently copy on error
+* ``REL_SYMLINK``: create an *relative* symbolic link to the source file at the destination *or fail*
+* ``REL_SYMLINK_OR_COPY``: like ``REL_SYMLINK`` but silently copy on error
+* ``SYMLINK``: try as if through ``REL_SYMLINK`` and fall back to ``ABS_SYMLINK`` if the referenced
+ file cannot be expressed using a relative path. Fail on error.
+* ``SYMLINK_OR_COPY``: like ``SYMLINK`` but silently copy on error
+
+Installing symbolic links rather than copying files can help conserve storage space because files do
+not have to be duplicated on disk. However, modifications applied to the source immediately affects
+the symbolic link and vice versa. *Use with caution*.
+
+.. note:: ``CMAKE_INSTALL_MODE`` only affects files, *not* directories.
+
+.. note:: Symbolic links are not available on all platforms.
diff --git a/Help/generator/Visual Studio 10 2010.rst b/Help/generator/Visual Studio 10 2010.rst
index c065550..9ec33c3 100644
--- a/Help/generator/Visual Studio 10 2010.rst
+++ b/Help/generator/Visual Studio 10 2010.rst
@@ -1,7 +1,14 @@
Visual Studio 10 2010
---------------------
-Generates Visual Studio 10 (VS 2010) project files.
+Deprecated. Generates Visual Studio 10 (VS 2010) project files.
+
+.. note::
+ This generator is deprecated and will be removed in a future version
+ of CMake. It will still be possible to build with VS 10 2010 tools
+ using the :generator:`Visual Studio 11 2012` (or above) generator
+ with :variable:`CMAKE_GENERATOR_TOOLSET` set to ``v100``, or by
+ using the :generator:`NMake Makefiles` generator.
For compatibility with CMake versions prior to 3.0, one may specify this
generator using the name ``Visual Studio 10`` without the year component.
diff --git a/Help/manual/cmake-env-variables.7.rst b/Help/manual/cmake-env-variables.7.rst
index fa38588..0799fdd 100644
--- a/Help/manual/cmake-env-variables.7.rst
+++ b/Help/manual/cmake-env-variables.7.rst
@@ -30,12 +30,15 @@ Environment Variables that Control the Build
/envvar/CMAKE_APPLE_SILICON_PROCESSOR
/envvar/CMAKE_BUILD_PARALLEL_LEVEL
+ /envvar/CMAKE_BUILD_TYPE
+ /envvar/CMAKE_CONFIGURATION_TYPES
/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_INSTALL_MODE
/envvar/CMAKE_LANG_COMPILER_LAUNCHER
/envvar/CMAKE_LANG_LINKER_LAUNCHER
/envvar/CMAKE_MSVCIDE_RUN_PATH
diff --git a/Help/manual/cmake-packages.7.rst b/Help/manual/cmake-packages.7.rst
index 4b2934a..5c109ff 100644
--- a/Help/manual/cmake-packages.7.rst
+++ b/Help/manual/cmake-packages.7.rst
@@ -74,7 +74,9 @@ package.
By setting the :variable:`CMAKE_DISABLE_FIND_PACKAGE_<PackageName>` variable to
``TRUE``, the ``<PackageName>`` package will not be searched, and will always
-be ``NOTFOUND``.
+be ``NOTFOUND``. Likewise, setting the
+:variable:`CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>` to ``TRUE`` will make the
+package REQUIRED.
.. _`Config File Packages`:
@@ -447,7 +449,7 @@ be true. This can be tested with logic in the package configuration file:
set(_supported_components Plot Table)
foreach(_comp ${ClimbingStats_FIND_COMPONENTS})
- if (NOT ";${_supported_components};" MATCHES _comp)
+ if (NOT ";${_supported_components};" MATCHES ";${_comp};")
set(ClimbingStats_FOUND False)
set(ClimbingStats_NOT_FOUND_MESSAGE "Unsupported component: ${_comp}")
endif()
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 5f18a82..c71e8ff 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -202,6 +202,7 @@ Properties on Targets
/prop_tgt/EXPORT_NAME
/prop_tgt/EXPORT_PROPERTIES
/prop_tgt/FOLDER
+ /prop_tgt/Fortran_BUILDING_INSTRINSIC_MODULES
/prop_tgt/Fortran_FORMAT
/prop_tgt/Fortran_MODULE_DIRECTORY
/prop_tgt/Fortran_PREPROCESS
@@ -450,6 +451,7 @@ Properties on Tests
/prop_test/DEPENDS
/prop_test/DISABLED
/prop_test/ENVIRONMENT
+ /prop_test/ENVIRONMENT_MODIFICATION
/prop_test/FAIL_REGULAR_EXPRESSION
/prop_test/FIXTURES_CLEANUP
/prop_test/FIXTURES_REQUIRED
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 9cea0fb..7cfa0c8 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -231,6 +231,7 @@ Variables that Change Behavior
/variable/CMAKE_PROJECT_INCLUDE_BEFORE
/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE
/variable/CMAKE_PROJECT_PROJECT-NAME_INCLUDE_BEFORE
+ /variable/CMAKE_REQUIRE_FIND_PACKAGE_PackageName
/variable/CMAKE_SKIP_INSTALL_ALL_DEPENDENCY
/variable/CMAKE_STAGING_PREFIX
/variable/CMAKE_SUBLIME_TEXT_2_ENV_SETTINGS
@@ -428,6 +429,7 @@ Variables that Control the Build
/variable/CMAKE_LANG_LINKER_LAUNCHER
/variable/CMAKE_LANG_LINK_LIBRARY_FILE_FLAG
/variable/CMAKE_LANG_LINK_LIBRARY_FLAG
+ /variable/CMAKE_LANG_LINK_WHAT_YOU_USE_FLAG
/variable/CMAKE_LANG_VISIBILITY_PRESET
/variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY
/variable/CMAKE_LIBRARY_OUTPUT_DIRECTORY_CONFIG
@@ -438,6 +440,7 @@ Variables that Control the Build
/variable/CMAKE_LINK_LIBRARY_FILE_FLAG
/variable/CMAKE_LINK_LIBRARY_FLAG
/variable/CMAKE_LINK_WHAT_YOU_USE
+ /variable/CMAKE_LINK_WHAT_YOU_USE_CHECK
/variable/CMAKE_MACOSX_BUNDLE
/variable/CMAKE_MACOSX_RPATH
/variable/CMAKE_MAP_IMPORTED_CONFIG_CONFIG
diff --git a/Help/prop_test/ENVIRONMENT.rst b/Help/prop_test/ENVIRONMENT.rst
index 102c792..43bcdbe 100644
--- a/Help/prop_test/ENVIRONMENT.rst
+++ b/Help/prop_test/ENVIRONMENT.rst
@@ -5,5 +5,5 @@ Specify environment variables that should be defined for running a test.
If set to a list of environment variables and values of the form
``MYVAR=value`` those environment variables will be defined while running
-the test. The environment is restored to its previous state after the
-test is done.
+the test. The environment changes from this property do not affect other
+tests.
diff --git a/Help/prop_test/ENVIRONMENT_MODIFICATION.rst b/Help/prop_test/ENVIRONMENT_MODIFICATION.rst
new file mode 100644
index 0000000..ffd5de4
--- /dev/null
+++ b/Help/prop_test/ENVIRONMENT_MODIFICATION.rst
@@ -0,0 +1,33 @@
+ENVIRONMENT_MODIFICATION
+------------------------
+
+Specify environment variables that should be modified for running a test. Note
+that the operations performed by this property are performed after the
+:prop_test:`ENVIRONMENT` property is already applied.
+
+If set to a list of environment variables and values of the form
+``MYVAR=OP:VALUE``. Entries are considered in the order specified in the
+property's value. The ``OP`` may be one of:
+
+ - ``reset``: Reset to the unmodified value, ignoring all modifications to
+ ``MYVAR`` prior to this entry. Note that this will reset the variable to
+ the value set by :prop_test:`ENVIRONMENT`, if it was set, and otherwise
+ to its state from the rest of the CTest execution.
+ - ``set``: Replaces the current value of ``MYVAR`` with ``VALUE``.
+ - ``unset``: Unsets the current value of ``MYVAR``.
+ - ``string_append``: Appends ``VALUE`` to the current value of ``MYVAR``.
+ - ``string_prepend``: Prepends ``VALUE`` to the current value of ``MYVAR``.
+ - ``path_list_append``: Appends ``VALUE`` to the current value of ``MYVAR``
+ using the platform-specific list separator.
+ - ``path_list_prepend``: Prepends ``VALUE`` to the current value of
+ ``MYVAR`` using the platform-specific list separator.
+ - ``cmake_list_append``: Appends ``VALUE`` to the current value of ``MYVAR``
+ using ``;`` as the separator.
+ - ``cmake_list_prepend``: Prepends ``VALUE`` to the current value of
+ ``MYVAR`` using ``;`` as the separator.
+
+Unrecognized ``OP`` values will result in the test failing before it is
+executed. This is so that future operations may be added without changing
+valid behavior of existing tests.
+
+The environment changes from this property do not affect other tests.
diff --git a/Help/prop_tgt/Fortran_BUILDING_INSTRINSIC_MODULES.rst b/Help/prop_tgt/Fortran_BUILDING_INSTRINSIC_MODULES.rst
new file mode 100644
index 0000000..518bca7
--- /dev/null
+++ b/Help/prop_tgt/Fortran_BUILDING_INSTRINSIC_MODULES.rst
@@ -0,0 +1,14 @@
+Fortran_BUILDING_INSTRINSIC_MODULES
+-----------------------------------
+
+Instructs the CMake Fortran preprocessor that the target is building
+Fortran intrinsics for building a Fortran compiler.
+
+This property is off by default and should be turned only on projects
+that build a Fortran compiler. It should not be turned on for projects
+that use a Fortran compiler.
+
+Turning this property on will correctly add dependencies for building
+Fortran intrinsic modules whereas turning the property off will ignore
+Fortran intrinsic modules in the dependency graph as they are supplied
+by the compiler itself.
diff --git a/Help/prop_tgt/LINK_WHAT_YOU_USE.rst b/Help/prop_tgt/LINK_WHAT_YOU_USE.rst
index 2ed93ad..d6de0d4 100644
--- a/Help/prop_tgt/LINK_WHAT_YOU_USE.rst
+++ b/Help/prop_tgt/LINK_WHAT_YOU_USE.rst
@@ -1,16 +1,22 @@
LINK_WHAT_YOU_USE
----------------------------
+-----------------
.. versionadded:: 3.7
-This is a boolean option that when set to ``TRUE`` will automatically run
-``ldd -r -u`` on the target after it is linked. In addition, the linker flag
-``-Wl,--no-as-needed`` will be passed to the target with the link command so
-that all libraries specified on the command line will be linked into the
-target. This will result in the link producing a list of libraries that
-provide no symbols used by this target but are being linked to it.
-This is only applicable to executable and shared library targets and
-will only work when ld and ldd accept the flags used.
+This is a boolean option that, when set to ``TRUE``, will automatically run
+contents of variable :variable:`CMAKE_LINK_WHAT_YOU_USE_CHECK` on the target
+after it is linked. In addition, the linker flag specified by variable
+:variable:`CMAKE_<LANG>_LINK_WHAT_YOU_USE_FLAG` will be passed to the target
+with the link command so that all libraries specified on the command line will
+be linked into the target. This will result in the link producing a list of
+libraries that provide no symbols used by this target but are being linked to
+it.
+
+.. note::
+
+ For now, it is only supported for ``ELF`` platforms and is only applicable to
+ executable and shared or module library targets. This property will be
+ ignored for any other targets and configurations.
This property is initialized by the value of
the :variable:`CMAKE_LINK_WHAT_YOU_USE` variable if it is set
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/FindPkgConfig-PKG_CONFIG-args.rst b/Help/release/dev/FindPkgConfig-PKG_CONFIG-args.rst
new file mode 100644
index 0000000..44c26b5
--- /dev/null
+++ b/Help/release/dev/FindPkgConfig-PKG_CONFIG-args.rst
@@ -0,0 +1,5 @@
+FindPkgConfig-PKG_CONFIG-args
+-----------------------------
+
+* The :module:`FindPkgConfig` module gained a :variable:`PKG_CONFIG_ARGN`
+ variable to specify arguments to ``pkg-config`` calls.
diff --git a/Help/release/dev/GoogleTest-gtest-filter.rst b/Help/release/dev/GoogleTest-gtest-filter.rst
new file mode 100644
index 0000000..48b97a7
--- /dev/null
+++ b/Help/release/dev/GoogleTest-gtest-filter.rst
@@ -0,0 +1,6 @@
+GoogleTest-gtest-filter
+-----------------------
+
+* The :module:`GoogleTest` module :command:`gtest_discover_tests`
+ function gained a ``TEST_FILTER`` option to filter tests using
+ ``--gtest_filter`` during test discovery.
diff --git a/Help/release/dev/LINK_WHAT_USE_USE-configuration.rst b/Help/release/dev/LINK_WHAT_USE_USE-configuration.rst
new file mode 100644
index 0000000..990ed36
--- /dev/null
+++ b/Help/release/dev/LINK_WHAT_USE_USE-configuration.rst
@@ -0,0 +1,5 @@
+LINK_WHAT_YOU_USE-configuration
+-------------------------------
+
+* Configuration for :prop_tgt:`LINK_WHAT_YOU_USE` feature is now controlled by
+ ``CMake`` variables and only active for ``ELF`` platforms.
diff --git a/Help/release/dev/UseSWIG-dependencies.rst b/Help/release/dev/UseSWIG-dependencies.rst
new file mode 100644
index 0000000..a3ec29e
--- /dev/null
+++ b/Help/release/dev/UseSWIG-dependencies.rst
@@ -0,0 +1,6 @@
+UseSWIG-dependencies
+--------------------
+
+* :module:`UseSWIG` module gained the capability, for
+ :ref:`Visual Studio Generators` to use `swig` tool to generate implicit
+ dependencies.
diff --git a/Help/release/dev/cmake-install-mode-symlink.rst b/Help/release/dev/cmake-install-mode-symlink.rst
new file mode 100644
index 0000000..a5f75ca
--- /dev/null
+++ b/Help/release/dev/cmake-install-mode-symlink.rst
@@ -0,0 +1,16 @@
+cmake-install-mode-symlink
+--------------------------
+
+* The :envvar:`CMAKE_INSTALL_MODE` environment variable was added to
+ allow users to override the default file-copying behavior of
+ :command:`install` and :command:`file(INSTALL)` into creating
+ symbolic links. This can aid in lowering storage space requirements
+ and avoiding redundancy.
+
+* The :command:`file(INSTALL)` can now be affected / modified by the
+ :envvar:`CMAKE_INSTALL_MODE` environment variable causing installation
+ of symbolic links instead of copying of files.
+
+* The :command:`install` can now be affected / modified by the
+ :envvar:`CMAKE_INSTALL_MODE` environment variable causing installation
+ of symbolic links instead of copying of files.
diff --git a/Help/release/dev/cpack-deb-add-zstd-compression.rst b/Help/release/dev/cpack-deb-add-zstd-compression.rst
new file mode 100644
index 0000000..a138455
--- /dev/null
+++ b/Help/release/dev/cpack-deb-add-zstd-compression.rst
@@ -0,0 +1,6 @@
+cpack-deb-add-zstd-compression
+------------------------------
+
+* The :cpack_gen:`CPack DEB Generator` gained the
+ option to set :variable:`CPACK_DEBIAN_COMPRESSION_TYPE` to zstd,
+ which enables Zstandard compression for deb packages.
diff --git a/Help/release/dev/cpack-rpm-requires-exclude-from.rst b/Help/release/dev/cpack-rpm-requires-exclude-from.rst
new file mode 100644
index 0000000..7125901
--- /dev/null
+++ b/Help/release/dev/cpack-rpm-requires-exclude-from.rst
@@ -0,0 +1,6 @@
+cpack-rpm-requires-exclude-from
+-------------------------------
+
+* The :cpack_gen:`CPack RPM Generator` gained the
+ :variable:`CPACK_RPM_REQUIRES_EXCLUDE_FROM` option avoid scanning
+ specific paths for dependencies.
diff --git a/Help/release/dev/ctest-environment-modifications.rst b/Help/release/dev/ctest-environment-modifications.rst
new file mode 100644
index 0000000..64265f0
--- /dev/null
+++ b/Help/release/dev/ctest-environment-modifications.rst
@@ -0,0 +1,7 @@
+ctest-environment-modifications
+-------------------------------
+
+* :manual:`ctest(1)` learned to be able to modify the environment for a test
+ through the :prop_test:`ENVIRONMENT_MODIFICATION` property. This is allows
+ for updates to environment variables based on the environment present at
+ test time.
diff --git a/Help/release/dev/ctest-runtime-labels.rst b/Help/release/dev/ctest-runtime-labels.rst
new file mode 100644
index 0000000..7ce0b64
--- /dev/null
+++ b/Help/release/dev/ctest-runtime-labels.rst
@@ -0,0 +1,7 @@
+ctest-runtime-labels
+--------------------
+
+* :manual:`ctest(1)` learned to recognize labels attached to a test at run time.
+ Previously it was only possible to attach labels to tests at configure time
+ by using the :prop_test:`LABELS` test property.
+ See :ref:`Additional Test Measurements` for more information.
diff --git a/Help/release/dev/env-init-configs.rst b/Help/release/dev/env-init-configs.rst
new file mode 100644
index 0000000..5c9892d
--- /dev/null
+++ b/Help/release/dev/env-init-configs.rst
@@ -0,0 +1,9 @@
+env-init-configs
+----------------
+
+* The :envvar:`CMAKE_BUILD_TYPE` environment variable was added to
+ provide a default value for the :variable:`CMAKE_BUILD_TYPE` variable.
+
+* The :envvar:`CMAKE_CONFIGURATION_TYPES` environment variable was added to
+ provide a default value for the :variable:`CMAKE_CONFIGURATION_TYPES`
+ variable.
diff --git a/Help/release/dev/find_package-required-var.rst b/Help/release/dev/find_package-required-var.rst
new file mode 100644
index 0000000..36935ef
--- /dev/null
+++ b/Help/release/dev/find_package-required-var.rst
@@ -0,0 +1,5 @@
+find_package-required-var
+-------------------------
+
+* The :variable:`CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>` variable was added
+ to turn a non-REQUIRED :command:`find_package` call into a REQUIRED one.
diff --git a/Help/release/dev/msvc-isystem.rst b/Help/release/dev/msvc-isystem.rst
new file mode 100644
index 0000000..4a5d79f
--- /dev/null
+++ b/Help/release/dev/msvc-isystem.rst
@@ -0,0 +1,7 @@
+msvc-isystem
+------------
+
+* The MSVC compilers learned to pass the ``-external:I`` flag for system
+ includes when using the :generator:`Ninja` and :generator:`NMake Makefiles`
+ generators. This became available as of Visual Studio 16.10 (toolchain
+ version 14.29.30037).
diff --git a/Help/release/dev/ninja-edit_cache.rst b/Help/release/dev/ninja-edit_cache.rst
new file mode 100644
index 0000000..9083f56
--- /dev/null
+++ b/Help/release/dev/ninja-edit_cache.rst
@@ -0,0 +1,5 @@
+ninja-edit_cache
+----------------
+
+* The :ref:`Ninja Generators` now implement the ``edit_cache`` target
+ using :manual:`ccmake(1)` if available.
diff --git a/Help/release/dev/nsis-minimal-version.rst b/Help/release/dev/nsis-minimal-version.rst
new file mode 100644
index 0000000..b19597a
--- /dev/null
+++ b/Help/release/dev/nsis-minimal-version.rst
@@ -0,0 +1,4 @@
+nsis-minimal-version.rst
+------------------------
+
+* The :cpack_gen:`CPack NSIS Generator` now requires NSIS 3.03 or later.
diff --git a/Help/release/dev/nsis_ignore_install_page.rst b/Help/release/dev/nsis_ignore_install_page.rst
new file mode 100644
index 0000000..2d8a8d0
--- /dev/null
+++ b/Help/release/dev/nsis_ignore_install_page.rst
@@ -0,0 +1,6 @@
+nsis_ignore_install_page
+------------------------
+
+* The :cpack_gen:`CPack NSIS Generator` gained a new variable
+ :variable:`CPACK_NSIS_IGNORE_LICENSE_PAGE` to ignore the
+ license page in the installer.
diff --git a/Help/release/dev/os-release.rst b/Help/release/dev/os-release.rst
new file mode 100644
index 0000000..cce6aee
--- /dev/null
+++ b/Help/release/dev/os-release.rst
@@ -0,0 +1,6 @@
+os-release
+----------
+
+* The :command:`cmake_host_system_information` command query operating system
+ identification `variables <https://www.freedesktop.org/software/systemd/man/os-release.html>`_
+ from the :file:`/etc/os-release` file.
diff --git a/Help/release/dev/string-TIMESTAMP-specifier-V.rst b/Help/release/dev/string-TIMESTAMP-specifier-V.rst
new file mode 100644
index 0000000..afd3f03
--- /dev/null
+++ b/Help/release/dev/string-TIMESTAMP-specifier-V.rst
@@ -0,0 +1,5 @@
+string-TIMESTAMP-specifier-V
+----------------------------
+
+* The :command:`string(TIMESTAMP)` command now supports the ``%V``
+ specifier for ISO 8601 week numbers.
diff --git a/Help/release/dev/target_compile_features-ignore-disabled-langs.rst b/Help/release/dev/target_compile_features-ignore-disabled-langs.rst
new file mode 100644
index 0000000..0eba125
--- /dev/null
+++ b/Help/release/dev/target_compile_features-ignore-disabled-langs.rst
@@ -0,0 +1,5 @@
+target_compile_features-ignore-disabled-langs
+---------------------------------------------
+
+* :command:`target_compile_features` learned to ignored features for languages that
+ aren't enabled.
diff --git a/Help/release/dev/vs10-deprecate.rst b/Help/release/dev/vs10-deprecate.rst
new file mode 100644
index 0000000..7bec391
--- /dev/null
+++ b/Help/release/dev/vs10-deprecate.rst
@@ -0,0 +1,5 @@
+vs10-deprecate
+--------------
+
+* The :generator:`Visual Studio 10 2010` generator is now deprecated
+ and will be removed in a future version of CMake.
diff --git a/Help/release/index.rst b/Help/release/index.rst
index 75667e5..5938878 100644
--- a/Help/release/index.rst
+++ b/Help/release/index.rst
@@ -7,6 +7,8 @@ CMake Release Notes
This file should include the adjacent "dev.txt" file
in development versions but not in release versions.
+.. include:: dev.txt
+
Releases
========
diff --git a/Help/variable/CMAKE_BUILD_TYPE.rst b/Help/variable/CMAKE_BUILD_TYPE.rst
index 405f7d5..9ad1481 100644
--- a/Help/variable/CMAKE_BUILD_TYPE.rst
+++ b/Help/variable/CMAKE_BUILD_TYPE.rst
@@ -23,3 +23,12 @@ Note that configuration names are case-insensitive. The value of this
variable will be the same as it is specified when invoking CMake.
For instance, if ``-DCMAKE_BUILD_TYPE=ReLeAsE`` is specified, then the
value of ``CMAKE_BUILD_TYPE`` will be ``ReLeAsE``.
+
+This variable is initialized by the first :command:`project` or
+:command:`enable_language` command called in a project when a new build
+tree is first created. If the :envvar:`CMAKE_BUILD_TYPE` environment
+variable is set, its value is used. Otherwise, a toolchain-specific
+default is chosen when a language is enabled.
+
+See :variable:`CMAKE_CONFIGURATION_TYPES` for specifying the configuration
+with multi-config generators.
diff --git a/Help/variable/CMAKE_CONFIGURATION_TYPES.rst b/Help/variable/CMAKE_CONFIGURATION_TYPES.rst
index 8fcc798..5298a72 100644
--- a/Help/variable/CMAKE_CONFIGURATION_TYPES.rst
+++ b/Help/variable/CMAKE_CONFIGURATION_TYPES.rst
@@ -8,5 +8,11 @@ such as ``Debug``, ``Release``, ``RelWithDebInfo`` etc. This has reasonable
defaults on most platforms, but can be extended to provide other build
types.
+This variable is initialized by the first :command:`project` or
+:command:`enable_language` command called in a project when a new build
+tree is first created. If the :envvar:`CMAKE_CONFIGURATION_TYPES`
+environment variable is set, its value is used. Otherwise, the default
+value is generator-specific.
+
See :variable:`CMAKE_BUILD_TYPE` for specifying the configuration with
single-config generators.
diff --git a/Help/variable/CMAKE_DISABLE_FIND_PACKAGE_PackageName.rst b/Help/variable/CMAKE_DISABLE_FIND_PACKAGE_PackageName.rst
index ed60020..f77e939 100644
--- a/Help/variable/CMAKE_DISABLE_FIND_PACKAGE_PackageName.rst
+++ b/Help/variable/CMAKE_DISABLE_FIND_PACKAGE_PackageName.rst
@@ -14,3 +14,5 @@ the package has already been found in a previous CMake run, the
variables which have been stored in the cache will still be there. In
that case it is recommended to remove the cache variables for this
package from the cache using the cache editor or :manual:`cmake(1)` ``-U``
+
+See also the :variable:`CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>` variable.
diff --git a/Help/variable/CMAKE_LANG_LINK_WHAT_YOU_USE_FLAG.rst b/Help/variable/CMAKE_LANG_LINK_WHAT_YOU_USE_FLAG.rst
new file mode 100644
index 0000000..5004530
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_LINK_WHAT_YOU_USE_FLAG.rst
@@ -0,0 +1,9 @@
+CMAKE_<LANG>_LINK_WHAT_YOU_USE_FLAG
+-----------------------------------
+
+.. versionadded:: 3.22
+
+Linker flag to be used to configure linker so that all specified libraries on
+the command line will be linked into the target.
+
+See also variable :variable:`CMAKE_LINK_WHAT_YOU_USE_CHECK`.
diff --git a/Help/variable/CMAKE_LINK_WHAT_YOU_USE.rst b/Help/variable/CMAKE_LINK_WHAT_YOU_USE.rst
index 06b3aa8..bca4519 100644
--- a/Help/variable/CMAKE_LINK_WHAT_YOU_USE.rst
+++ b/Help/variable/CMAKE_LINK_WHAT_YOU_USE.rst
@@ -1,5 +1,5 @@
CMAKE_LINK_WHAT_YOU_USE
----------------------------------
+-----------------------
.. versionadded:: 3.7
diff --git a/Help/variable/CMAKE_LINK_WHAT_YOU_USE_CHECK.rst b/Help/variable/CMAKE_LINK_WHAT_YOU_USE_CHECK.rst
new file mode 100644
index 0000000..e626641
--- /dev/null
+++ b/Help/variable/CMAKE_LINK_WHAT_YOU_USE_CHECK.rst
@@ -0,0 +1,10 @@
+CMAKE_LINK_WHAT_YOU_USE_CHECK
+-----------------------------
+
+.. versionadded:: 3.22
+
+Defines the command executed after the link step to check libraries usage.
+This check is currently only defined on ``ELF`` platforms with value
+``ldd -u -r``.
+
+See also :variable:`CMAKE_<LANG>_LINK_WHAT_YOU_USE_FLAG` variables.
diff --git a/Help/variable/CMAKE_REQUIRE_FIND_PACKAGE_PackageName.rst b/Help/variable/CMAKE_REQUIRE_FIND_PACKAGE_PackageName.rst
new file mode 100644
index 0000000..893f1ae
--- /dev/null
+++ b/Help/variable/CMAKE_REQUIRE_FIND_PACKAGE_PackageName.rst
@@ -0,0 +1,14 @@
+CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>
+----------------------------------------
+
+.. versionadded:: 3.22
+
+Variable for making :command:`find_package` call ``REQUIRED``.
+
+Every non-``REQUIRED`` :command:`find_package` call in a project can be
+turned into ``REQUIRED`` by setting the variable
+``CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>`` to ``TRUE``.
+This can be used to assert assumptions about build environment and to
+ensure the build will fail early if they do not hold.
+
+See also the :variable:`CMAKE_DISABLE_FIND_PACKAGE_<PackageName>` variable.
diff --git a/Modules/CMakeASM_MASMInformation.cmake b/Modules/CMakeASM_MASMInformation.cmake
index 6d1e174..656b75e 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/CMakeCInformation.cmake b/Modules/CMakeCInformation.cmake
index 6be1865..665f309 100644
--- a/Modules/CMakeCInformation.cmake
+++ b/Modules/CMakeCInformation.cmake
@@ -91,6 +91,14 @@ if(CMAKE_USER_MAKE_RULES_OVERRIDE_C)
set(CMAKE_USER_MAKE_RULES_OVERRIDE_C "${_override}")
endif()
+if(CMAKE_EXECUTABLE_FORMAT STREQUAL "ELF")
+ if(NOT DEFINED CMAKE_C_LINK_WHAT_YOU_USE_FLAG)
+ set(CMAKE_C_LINK_WHAT_YOU_USE_FLAG "LINKER:--no-as-needed")
+ endif()
+ if(NOT DEFINED CMAKE_LINK_WHAT_YOU_USE_CHECK)
+ set(CMAKE_LINK_WHAT_YOU_USE_CHECK ldd -u -r)
+ endif()
+endif()
# for most systems a module is the same as a shared library
# so unless the variable CMAKE_MODULE_EXISTS is set just
@@ -196,5 +204,3 @@ if(NOT CMAKE_EXECUTABLE_RPATH_LINK_C_FLAG)
endif()
set(CMAKE_C_INFORMATION_LOADED 1)
-
-
diff --git a/Modules/CMakeCUDAInformation.cmake b/Modules/CMakeCUDAInformation.cmake
index a2946f4..e9cfed6 100644
--- a/Modules/CMakeCUDAInformation.cmake
+++ b/Modules/CMakeCUDAInformation.cmake
@@ -100,6 +100,15 @@ if(NOT CMAKE_MODULE_EXISTS)
set(CMAKE_SHARED_MODULE_CREATE_CUDA_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_CUDA_FLAGS})
endif()
+if(CMAKE_EXECUTABLE_FORMAT STREQUAL "ELF")
+ if(NOT DEFINED CMAKE_CUDA_LINK_WHAT_YOU_USE_FLAG)
+ set(CMAKE_CUDA_LINK_WHAT_YOU_USE_FLAG "LINKER:--no-as-needed")
+ endif()
+ if(NOT DEFINED CMAKE_LINK_WHAT_YOU_USE_CHECK)
+ set(CMAKE_LINK_WHAT_YOU_USE_CHECK ldd -u -r)
+ endif()
+endif()
+
# add the flags to the cache based
# on the initial values computed in the platform/*.cmake files
# use _INIT variables so that this only happens the first time
diff --git a/Modules/CMakeCXXInformation.cmake b/Modules/CMakeCXXInformation.cmake
index 944d236..53abf37 100644
--- a/Modules/CMakeCXXInformation.cmake
+++ b/Modules/CMakeCXXInformation.cmake
@@ -193,6 +193,15 @@ foreach(type SHARED_LIBRARY SHARED_MODULE EXE)
endif()
endforeach()
+if(CMAKE_EXECUTABLE_FORMAT STREQUAL "ELF")
+ if(NOT DEFINED CMAKE_CXX_LINK_WHAT_YOU_USE_FLAG)
+ set(CMAKE_CXX_LINK_WHAT_YOU_USE_FLAG "LINKER:--no-as-needed")
+ endif()
+ if(NOT DEFINED CMAKE_LINK_WHAT_YOU_USE_CHECK)
+ set(CMAKE_LINK_WHAT_YOU_USE_CHECK ldd -u -r)
+ endif()
+endif()
+
# add the flags to the cache based
# on the initial values computed in the platform/*.cmake files
# use _INIT variables so that this only happens the first time
diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake
index e360d31..342425c 100644
--- a/Modules/CMakeDetermineCUDACompiler.cmake
+++ b/Modules/CMakeDetermineCUDACompiler.cmake
@@ -192,17 +192,31 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN)
get_filename_component(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT "${_CUDA_NVCC_EXECUTABLE}" DIRECTORY)
get_filename_component(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}" DIRECTORY)
endif()
+
+ if(_CUDA_NVCC_OUT MATCHES "\\#\\$ NVVMIR_LIBRARY_DIR=([^\r\n]*)")
+ get_filename_component(_CUDA_NVVMIR_LIBRARY_DIR "${CMAKE_MATCH_1}" ABSOLUTE)
+
+ #We require the path to end in `/nvvm/libdevice'
+ if(_CUDA_NVVMIR_LIBRARY_DIR MATCHES "nvvm/libdevice$")
+ get_filename_component(_CUDA_NVVMIR_LIBRARY_DIR "${_CUDA_NVVMIR_LIBRARY_DIR}/../.." ABSOLUTE)
+ set(CMAKE_CUDA_COMPILER_LIBRARY_ROOT_FROM_NVVMIR_LIBRARY_DIR "${_CUDA_NVVMIR_LIBRARY_DIR}")
+ endif()
+
+ unset(_CUDA_NVVMIR_LIBRARY_DIR)
+ unset(_cuda_nvvmir_dir_name)
+ endif()
unset(_CUDA_NVCC_OUT)
set(CMAKE_CUDA_DEVICE_LINKER "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}/bin/nvlink${CMAKE_EXECUTABLE_SUFFIX}")
set(CMAKE_CUDA_FATBINARY "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}/bin/fatbinary${CMAKE_EXECUTABLE_SUFFIX}")
-
# In a non-scattered installation the following are equivalent to CMAKE_CUDA_COMPILER_TOOLKIT_ROOT.
# We first check for a non-scattered installation to prefer it over a scattered installation.
# CMAKE_CUDA_COMPILER_LIBRARY_ROOT contains the device library.
- if(EXISTS "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}/nvvm/libdevice")
+ if(DEFINED CMAKE_CUDA_COMPILER_LIBRARY_ROOT_FROM_NVVMIR_LIBRARY_DIR)
+ set(CMAKE_CUDA_COMPILER_LIBRARY_ROOT "${CMAKE_CUDA_COMPILER_LIBRARY_ROOT_FROM_NVVMIR_LIBRARY_DIR}")
+ elseif(EXISTS "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}/nvvm/libdevice")
set(CMAKE_CUDA_COMPILER_LIBRARY_ROOT "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}")
elseif(CMAKE_SYSROOT_LINK AND EXISTS "${CMAKE_SYSROOT_LINK}/usr/lib/cuda/nvvm/libdevice")
set(CMAKE_CUDA_COMPILER_LIBRARY_ROOT "${CMAKE_SYSROOT_LINK}/usr/lib/cuda")
@@ -211,6 +225,7 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN)
else()
message(FATAL_ERROR "Couldn't find CUDA library root.")
endif()
+ unset(CMAKE_CUDA_COMPILER_LIBRARY_ROOT_FROM_NVVMIR_LIBRARY_DIR)
# CMAKE_CUDA_COMPILER_TOOLKIT_LIBRARY_ROOT contains the linking stubs necessary for device linking and other low-level library files.
if(CMAKE_SYSROOT_LINK AND EXISTS "${CMAKE_SYSROOT_LINK}/usr/lib/nvidia-cuda-toolkit/bin/crt/link.stub")
diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake
index e933cf4..16243c7 100644
--- a/Modules/CMakeDetermineCompilerId.cmake
+++ b/Modules/CMakeDetermineCompilerId.cmake
@@ -722,7 +722,7 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS}
# Check the result of compilation.
if(CMAKE_${lang}_COMPILER_ID_RESULT
# Intel Fortran warns and ignores preprocessor lines without /fpp
- OR CMAKE_${lang}_COMPILER_ID_OUTPUT MATCHES "Bad # preprocessor line"
+ OR CMAKE_${lang}_COMPILER_ID_OUTPUT MATCHES "warning #5117: Bad # preprocessor line"
)
# Compilation failed.
set(MSG
@@ -733,7 +733,10 @@ ${CMAKE_${lang}_COMPILER_ID_RESULT}
${CMAKE_${lang}_COMPILER_ID_OUTPUT}
")
- file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "${MSG}")
+ # Log the output unless we recognize it as a known-bad case.
+ if(NOT CMAKE_${lang}_COMPILER_ID_OUTPUT MATCHES "warning #5117: Bad # preprocessor line")
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "${MSG}")
+ endif()
# Some languages may know the correct/desired set of flags and want to fail right away if they don't work.
# This is currently only used by CUDA.
diff --git a/Modules/CMakeFortranCompilerABI.F90 b/Modules/CMakeFortranCompilerABI.F90
new file mode 100644
index 0000000..4a17153
--- /dev/null
+++ b/Modules/CMakeFortranCompilerABI.F90
@@ -0,0 +1,48 @@
+program CMakeFortranCompilerABI
+
+implicit none
+
+integer :: i(1) = 0
+where (i==0) i=1
+if (any(i/=1)) stop 1
+! showing Fortran 90 syntax is OK
+
+#if 0
+! Address Size
+#endif
+#if defined(_LP64)
+PRINT *, 'INFO:sizeof_dptr[8]'
+#elif defined(_M_IA64)
+PRINT *, 'INFO:sizeof_dptr[8]'
+#elif defined(_M_X64)
+PRINT *, 'INFO:sizeof_dptr[8]'
+#elif defined(_M_AMD64)
+PRINT *, 'INFO:sizeof_dptr[8]'
+#elif defined(__x86_64__)
+PRINT *, 'INFO:sizeof_dptr[8]'
+
+#elif defined(_ILP32)
+PRINT *, 'INFO:sizeof_dptr[4]'
+#elif defined(_M_IX86)
+PRINT *, 'INFO:sizeof_dptr[4]'
+#elif defined(__i386__)
+PRINT *, 'INFO:sizeof_dptr[4]'
+
+#elif defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ == 8
+PRINT *, 'INFO:sizeof_dptr[8]'
+#elif defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ == 4
+PRINT *, 'INFO:sizeof_dptr[4]'
+#elif defined(__SIZEOF_SIZE_T__) && __SIZEOF_SIZE_T__ == 8
+PRINT *, 'INFO:sizeof_dptr[8]'
+#elif defined(__SIZEOF_SIZE_T__) && __SIZEOF_SIZE_T__ == 4
+PRINT *, 'INFO:sizeof_dptr[4]'
+#endif
+
+#if 0
+! Application Binary Interface
+#endif
+#if defined(__ELF__)
+PRINT *, 'INFO:abi[ELF]'
+#endif
+PRINT *, 'ABI Detection'
+end program
diff --git a/Modules/CMakeFortranInformation.cmake b/Modules/CMakeFortranInformation.cmake
index 9a4ce63..0f71c6f 100644
--- a/Modules/CMakeFortranInformation.cmake
+++ b/Modules/CMakeFortranInformation.cmake
@@ -157,6 +157,15 @@ if(NOT CMAKE_INCLUDE_FLAG_Fortran)
set(CMAKE_INCLUDE_FLAG_Fortran ${CMAKE_INCLUDE_FLAG_C})
endif()
+if(CMAKE_EXECUTABLE_FORMAT STREQUAL "ELF")
+ if(NOT DEFINED CMAKE_Fortran_LINK_WHAT_YOU_USE_FLAG)
+ set(CMAKE_Fortran_LINK_WHAT_YOU_USE_FLAG "LINKER:--no-as-needed")
+ endif()
+ if(NOT DEFINED CMAKE_LINK_WHAT_YOU_USE_CHECK)
+ set(CMAKE_LINK_WHAT_YOU_USE_CHECK ldd -u -r)
+ endif()
+endif()
+
set(CMAKE_VERBOSE_MAKEFILE FALSE CACHE BOOL "If this value is on, makefiles will be generated without the .SILENT directive, and all commands will be echoed to the console during the make. This is useful for debugging only. With Visual Studio IDE projects all commands are done without /nologo.")
set(CMAKE_Fortran_FLAGS_INIT "$ENV{FFLAGS} ${CMAKE_Fortran_FLAGS_INIT}")
diff --git a/Modules/CMakeHIPInformation.cmake b/Modules/CMakeHIPInformation.cmake
index ec37e1c..9862f24 100644
--- a/Modules/CMakeHIPInformation.cmake
+++ b/Modules/CMakeHIPInformation.cmake
@@ -68,6 +68,15 @@ if(NOT CMAKE_MODULE_EXISTS)
set(CMAKE_SHARED_MODULE_CREATE_HIP_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_HIP_FLAGS})
endif()
+if(CMAKE_EXECUTABLE_FORMAT STREQUAL "ELF")
+ if(NOT DEFINED CMAKE_HIP_LINK_WHAT_YOU_USE_FLAG)
+ set(CMAKE_HIP_LINK_WHAT_YOU_USE_FLAG "LINKER:--no-as-needed")
+ endif()
+ if(NOT DEFINED CMAKE_LINK_WHAT_YOU_USE_CHECK)
+ set(CMAKE_LINK_WHAT_YOU_USE_CHECK ldd -u -r)
+ endif()
+endif()
+
# add the flags to the cache based
# on the initial values computed in the platform/*.cmake files
# use _INIT variables so that this only happens the first time
diff --git a/Modules/CMakeOBJCInformation.cmake b/Modules/CMakeOBJCInformation.cmake
index ac67d01..4c697da 100644
--- a/Modules/CMakeOBJCInformation.cmake
+++ b/Modules/CMakeOBJCInformation.cmake
@@ -91,6 +91,15 @@ if(CMAKE_USER_MAKE_RULES_OVERRIDE_OBJC)
set(CMAKE_USER_MAKE_RULES_OVERRIDE_OBJC "${_override}")
endif()
+if(CMAKE_EXECUTABLE_FORMAT STREQUAL "ELF")
+ if(NOT DEFINED CMAKE_OBJC_LINK_WHAT_YOU_USE_FLAG)
+ set(CMAKE_OBJC_LINK_WHAT_YOU_USE_FLAG "LINKER:--no-as-needed")
+ endif()
+ if(NOT DEFINED CMAKE_LINK_WHAT_YOU_USE_CHECK)
+ set(CMAKE_LINK_WHAT_YOU_USE_CHECK ldd -u -r)
+ endif()
+endif()
+
# for most systems a module is the same as a shared library
# so unless the variable CMAKE_MODULE_EXISTS is set just
diff --git a/Modules/CMakeOBJCXXInformation.cmake b/Modules/CMakeOBJCXXInformation.cmake
index 70e8579..a6d824f 100644
--- a/Modules/CMakeOBJCXXInformation.cmake
+++ b/Modules/CMakeOBJCXXInformation.cmake
@@ -189,6 +189,15 @@ foreach(type SHARED_LIBRARY SHARED_MODULE EXE)
endif()
endforeach()
+if(CMAKE_EXECUTABLE_FORMAT STREQUAL "ELF")
+ if(NOT DEFINED CMAKE_OBJCXX_LINK_WHAT_YOU_USE_FLAG)
+ set(CMAKE_OBJCXX_LINK_WHAT_YOU_USE_FLAG "LINKER:--no-as-needed")
+ endif()
+ if(NOT DEFINED CMAKE_LINK_WHAT_YOU_USE_CHECK)
+ set(CMAKE_LINK_WHAT_YOU_USE_CHECK ldd -u -r)
+ endif()
+endif()
+
# add the flags to the cache based
# on the initial values computed in the platform/*.cmake files
# use _INIT variables so that this only happens the first time
diff --git a/Modules/CMakeSwiftInformation.cmake b/Modules/CMakeSwiftInformation.cmake
index 8f0909c..ecad1d5 100644
--- a/Modules/CMakeSwiftInformation.cmake
+++ b/Modules/CMakeSwiftInformation.cmake
@@ -70,6 +70,15 @@ set(CMAKE_Swift_FLAGS_RELEASE_INIT "-O")
set(CMAKE_Swift_FLAGS_RELWITHDEBINFO_INIT "-O -g")
set(CMAKE_Swift_FLAGS_MINSIZEREL_INIT "-Osize")
+if(CMAKE_EXECUTABLE_FORMAT STREQUAL "ELF")
+ if(NOT DEFINED CMAKE_Swift_LINK_WHAT_YOU_USE_FLAG)
+ set(CMAKE_Swift_LINK_WHAT_YOU_USE_FLAG "LINKER:--no-as-needed")
+ endif()
+ if(NOT DEFINED CMAKE_LINK_WHAT_YOU_USE_CHECK)
+ set(CMAKE_LINK_WHAT_YOU_USE_CHECK ldd -u -r)
+ endif()
+endif()
+
cmake_initialize_per_config_variable(CMAKE_Swift_FLAGS "Swift Compiler Flags")
# NOTE(compnerd) we do not have an object compile rule since we build the objects as part of the link step
diff --git a/Modules/CMakeTestFortranCompiler.cmake b/Modules/CMakeTestFortranCompiler.cmake
index f25788d..579f83f 100644
--- a/Modules/CMakeTestFortranCompiler.cmake
+++ b/Modules/CMakeTestFortranCompiler.cmake
@@ -17,11 +17,18 @@ unset(CMAKE_Fortran_COMPILER_WORKS CACHE)
# Try to identify the ABI and configure it into CMakeFortranCompiler.cmake
include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerABI.cmake)
-CMAKE_DETERMINE_COMPILER_ABI(Fortran ${CMAKE_ROOT}/Modules/CMakeFortranCompilerABI.F)
+CMAKE_DETERMINE_COMPILER_ABI(Fortran ${CMAKE_ROOT}/Modules/CMakeFortranCompilerABI.F90)
if(CMAKE_Fortran_ABI_COMPILED)
# The compiler worked so skip dedicated test below.
set(CMAKE_Fortran_COMPILER_WORKS TRUE)
+ set(CMAKE_Fortran_COMPILER_SUPPORTS_F90 1)
message(STATUS "Check for working Fortran compiler: ${CMAKE_Fortran_COMPILER} - skipped")
+else()
+ cmake_determine_compiler_abi(Fortran ${CMAKE_ROOT}/Modules/CMakeFortranCompilerABI.F)
+ if(CMAKE_Fortran_ABI_COMPILED)
+ set(CMAKE_Fortran_COMPILER_WORKS TRUE)
+ message(STATUS "Check for working Fortran 77 compiler: ${CMAKE_Fortran_COMPILER} - skipped")
+ endif()
endif()
# This file is used by EnableLanguage in cmGlobalGenerator to
diff --git a/Modules/CheckCXXSymbolExists.cmake b/Modules/CheckCXXSymbolExists.cmake
index b4da4fa..7b13c3a 100644
--- a/Modules/CheckCXXSymbolExists.cmake
+++ b/Modules/CheckCXXSymbolExists.cmake
@@ -25,7 +25,7 @@ Check if a symbol exists as a function, variable, or macro in ``C++``.
as a function or variable then the symbol must also be available for
linking. If the symbol is a type, enum value, or C++ template it will
not be recognized: consider using the :module:`CheckTypeSize`
- or :module:`CheckCXXSourceCompiles` module instead.
+ or :module:`CheckSourceCompiles` module instead.
.. note::
diff --git a/Modules/CheckFortranFunctionExists.cmake b/Modules/CheckFortranFunctionExists.cmake
index ad72e2f..8f1ca9d 100644
--- a/Modules/CheckFortranFunctionExists.cmake
+++ b/Modules/CheckFortranFunctionExists.cmake
@@ -20,6 +20,12 @@ Check if a Fortran function exists.
``<result>``
variable to store the result; will be created as an internal cache variable.
+.. note::
+
+ This command does not detect functions in Fortran modules. In general it is
+ recommended to use :module:`CheckSourceCompiles` instead to determine if a
+ Fortran function or subroutine is available.
+
The following variables may be set before calling this macro to modify
the way the check is run:
diff --git a/Modules/CheckSymbolExists.cmake b/Modules/CheckSymbolExists.cmake
index f8ca584..48ee3c4 100644
--- a/Modules/CheckSymbolExists.cmake
+++ b/Modules/CheckSymbolExists.cmake
@@ -24,7 +24,7 @@ available and assumed to work. If the header files declare the symbol
as a function or variable then the symbol must also be available for
linking (so intrinsics may not be detected).
If the symbol is a type, enum value, or intrinsic it will not be recognized
-(consider using :module:`CheckTypeSize` or :module:`CheckCSourceCompiles`).
+(consider using :module:`CheckTypeSize` or :module:`CheckSourceCompiles`).
If the check needs to be done in C++, consider using
:module:`CheckCXXSymbolExists` instead.
diff --git a/Modules/Compiler/ARMClang-C.cmake b/Modules/Compiler/ARMClang-C.cmake
index 0a64a8a..01c4cea 100644
--- a/Modules/Compiler/ARMClang-C.cmake
+++ b/Modules/Compiler/ARMClang-C.cmake
@@ -2,6 +2,14 @@ include(Compiler/Clang-C)
include(Compiler/ARMClang)
__compiler_armclang(C)
+if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
+ AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
+ AND CMAKE_DEPFILE_FLAGS_C)
+ # dependencies are computed by the compiler itself
+ set(CMAKE_C_DEPFILE_FORMAT gcc)
+ set(CMAKE_C_DEPENDS_USE_COMPILER TRUE)
+endif()
+
set(CMAKE_C90_STANDARD_COMPILE_OPTION "-std=c90")
set(CMAKE_C90_EXTENSION_COMPILE_OPTION "-std=gnu90")
set(CMAKE_C90_STANDARD__HAS_FULL_SUPPORT ON)
diff --git a/Modules/Compiler/ARMClang-CXX.cmake b/Modules/Compiler/ARMClang-CXX.cmake
index 5dfb401..045b783 100644
--- a/Modules/Compiler/ARMClang-CXX.cmake
+++ b/Modules/Compiler/ARMClang-CXX.cmake
@@ -1,3 +1,11 @@
include(Compiler/Clang-CXX)
include(Compiler/ARMClang)
__compiler_armclang(CXX)
+
+if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
+ AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
+ AND CMAKE_DEPFILE_FLAGS_CXX)
+ # dependencies are computed by the compiler itself
+ set(CMAKE_CXX_DEPFILE_FORMAT gcc)
+ set(CMAKE_CXX_DEPENDS_USE_COMPILER TRUE)
+endif()
diff --git a/Modules/Compiler/MSVC-C.cmake b/Modules/Compiler/MSVC-C.cmake
index 9a5104b..73cca36 100644
--- a/Modules/Compiler/MSVC-C.cmake
+++ b/Modules/Compiler/MSVC-C.cmake
@@ -63,3 +63,9 @@ endmacro()
if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 19.05)
set(CMAKE_C_COMPILE_OPTIONS_JMC "-JMC")
endif()
+
+# The `/external:I` flag was made non-experimental in 19.29.30036.3.
+if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 19.29.30036.3)
+ set(CMAKE_INCLUDE_SYSTEM_FLAG_C "-external:I ")
+ set(_CMAKE_INCLUDE_SYSTEM_FLAG_C_WARNING "-external:W0 ")
+endif ()
diff --git a/Modules/Compiler/MSVC-CXX.cmake b/Modules/Compiler/MSVC-CXX.cmake
index f1c7450..09fe851 100644
--- a/Modules/Compiler/MSVC-CXX.cmake
+++ b/Modules/Compiler/MSVC-CXX.cmake
@@ -79,3 +79,9 @@ endif()
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.05)
set(CMAKE_CXX_COMPILE_OPTIONS_JMC "-JMC")
endif()
+
+# The `/external:I` flag was made non-experimental in 19.29.30036.3.
+if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.29.30036.3)
+ set(CMAKE_INCLUDE_SYSTEM_FLAG_CXX "-external:I ")
+ set(_CMAKE_INCLUDE_SYSTEM_FLAG_CXX_WARNING "-external:W0 ")
+endif ()
diff --git a/Modules/Compiler/PGI.cmake b/Modules/Compiler/PGI.cmake
index 4f8b90b..d111be9 100644
--- a/Modules/Compiler/PGI.cmake
+++ b/Modules/Compiler/PGI.cmake
@@ -26,7 +26,7 @@ macro(__compiler_pgi lang)
endif()
set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Wl,")
- set(CMAKE_${lang}_LINKER_WRAPPER_FLAG ",")
+ set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP ",")
set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES)
if(NOT CMAKE_SYSTEM_PROCESSOR STREQUAL ppc64le AND (NOT CMAKE_HOST_WIN32 OR CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 16.3))
diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake
index bd82a90..5ea8b2a 100644
--- a/Modules/FetchContent.cmake
+++ b/Modules/FetchContent.cmake
@@ -21,13 +21,14 @@ supported by the :module:`ExternalProject` module. Whereas
configure step to use the content in commands like :command:`add_subdirectory`,
:command:`include` or :command:`file` operations.
-Content population details would normally be defined separately from the
-command that performs the actual population. This separation ensures that
-all of the dependency details are defined before anything may try to use those
-details to populate content. This is particularly important in more complex
-project hierarchies where dependencies may be shared between multiple projects.
+Content population details should be defined separately from the command that
+performs the actual population. This separation ensures that all the
+dependency details are defined before anything might try to use them to
+populate content. This is particularly important in more complex project
+hierarchies where dependencies may be shared between multiple projects.
-The following shows a typical example of declaring content details:
+The following shows a typical example of declaring content details for some
+dependencies and then ensuring they are populated with a separate call:
.. code-block:: cmake
@@ -36,57 +37,67 @@ The following shows a typical example of declaring content details:
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG 703bd9caab50b139428cea1aaff9974ebee5742e # release-1.10.0
)
+ FetchContent_Declare(
+ myCompanyIcons
+ URL https://intranet.mycompany.com/assets/iconset_1.12.tar.gz
+ URL_HASH MD5=5588a7b18261c20068beabfb4f530b87
+ )
+
+ FetchContent_MakeAvailable(googletest secret_sauce)
+
+The :command:`FetchContent_MakeAvailable` command ensures the named
+dependencies have been populated, either by an earlier call or by populating
+them itself. When performing the population, it will also add them to the
+main build, if possible, so that the main build can use the populated
+projects' targets, etc. See the command's documentation for how these steps
+are performed.
+
+When using a hierarchical project arrangement, projects at higher levels in
+the hierarchy are able to override the declared details of content specified
+anywhere lower in the project hierarchy. The first details to be declared
+for a given dependency take precedence, regardless of where in the project
+hierarchy that occurs. Similarly, the first call that tries to populate a
+dependency "wins", with subsequent populations reusing the result of the
+first instead of repeating the population again.
+See the :ref:`Examples <fetch-content-examples>` which demonstrate
+this scenario.
-For most typical cases, populating the content can then be done with a single
-command like so:
+In some cases, the main project may need to have more precise control over
+the population, or it may be required to explicitly define the population
+steps in a way that cannot be captured by the declared details alone.
+For such situations, the lower level :command:`FetchContent_GetProperties` and
+:command:`FetchContent_Populate` commands can be used. These lack the richer
+features provided by :command:`FetchContent_MakeAvailable` though, so their
+direct use should be considered a last resort. The typical pattern of such
+custom steps looks like this:
.. code-block:: cmake
- FetchContent_MakeAvailable(googletest)
+ # NOTE: Where possible, prefer to use FetchContent_MakeAvailable()
+ # instead of custom logic like this
-The above command not only populates the content, it also adds it to the main
-build (if possible) so that the main build can use the populated project's
-targets, etc. In some cases, the main project may need to have more precise
-control over the population or may be required to explicitly define the
-population steps (e.g. if CMake versions earlier than 3.14 need to be
-supported). The typical pattern of such custom steps looks like this:
+ # Check if population has already been performed
+ FetchContent_GetProperties(depname)
+ if(NOT depname_POPULATED)
+ # Fetch the content using previously declared details
+ FetchContent_Populate(depname)
-.. code-block:: cmake
+ # Set custom variables, policies, etc.
+ # ...
- FetchContent_GetProperties(googletest)
- if(NOT googletest_POPULATED)
- FetchContent_Populate(googletest)
- add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR})
+ # Bring the populated content into the build
+ add_subdirectory(${depname_SOURCE_DIR} ${depname_BINARY_DIR})
endif()
-Regardless of which population method is used, when using the
-declare-populate pattern with a hierarchical project arrangement, projects at
-higher levels in the hierarchy are able to override the population details of
-content specified anywhere lower in the project hierarchy. The ability to
-detect whether content has already been populated ensures that even if
-multiple child projects want certain content to be available, the first one
-to populate it wins. The other child project can simply make use of the
-already available content instead of repeating the population for itself.
-See the :ref:`Examples <fetch-content-examples>` section which demonstrates
-this scenario.
-
The ``FetchContent`` module also supports defining and populating
content in a single call, with no check for whether the content has been
-populated elsewhere in the project already. This is a more low level
-operation and would not normally be the way the module is used, but it is
-sometimes useful as part of implementing some higher level feature or to
-populate some content in CMake's script mode.
-
-.. versionchanged:: 3.14
- ``FetchContent`` commands can access the terminal. This is necessary
- for password prompts and real-time progress displays to work.
+populated elsewhere already. This should not be done in projects, but may
+be appropriate for populating content in CMake's script mode.
+See :command:`FetchContent_Populate` for details.
Commands
^^^^^^^^
-Declaring Content Details
-"""""""""""""""""""""""""
-
.. command:: FetchContent_Declare
.. code-block:: cmake
@@ -94,7 +105,7 @@ Declaring Content Details
FetchContent_Declare(<name> <contentOptions>...)
The ``FetchContent_Declare()`` function records the options that describe
- how to populate the specified content, but if such details have already
+ how to populate the specified content. If such details have already
been recorded earlier in this project (regardless of where in the project
hierarchy), this and all later calls for the same content ``<name>`` are
ignored. This "first to record, wins" approach is what allows hierarchical
@@ -110,7 +121,7 @@ Declaring Content Details
projects needing that same content will use the same name, leading to
the content being populated multiple times.
- The ``<contentOptions>`` can be any of the download or update/patch options
+ The ``<contentOptions>`` can be any of the download, update or patch options
that the :command:`ExternalProject_Add` command understands. The configure,
build, install and test steps are explicitly disabled and therefore options
related to them will be ignored. The ``SOURCE_SUBDIR`` option is an
@@ -146,47 +157,88 @@ Declaring Content Details
than a branch or tag name. A commit hash is more secure and helps to
confirm that the downloaded contents are what you expected.
-Populating The Content
-""""""""""""""""""""""
+ .. versionchanged:: 3.14
+ Commands for the download, update or patch steps can access the terminal.
+ This may be needed for things like password prompts or real-time display
+ of command progress.
-For most common scenarios, population means making content available to the
-main build according to previously declared details for that dependency.
-There are two main patterns for populating content, one based on calling
-:command:`FetchContent_GetProperties` and
-:command:`FetchContent_Populate` for more precise control and the other on
-calling :command:`FetchContent_MakeAvailable` for a simpler, more automated
-approach. The former generally follows this canonical pattern:
+.. command:: FetchContent_MakeAvailable
-.. _`fetch-content-canonical-pattern`:
+ .. versionadded:: 3.14
-.. code-block:: cmake
+ .. code-block:: cmake
- # Check if population has already been performed
- FetchContent_GetProperties(<name>)
- string(TOLOWER "<name>" lcName)
- if(NOT ${lcName}_POPULATED)
- # Fetch the content using previously declared details
- FetchContent_Populate(<name>)
+ FetchContent_MakeAvailable(<name1> [<name2>...])
+
+ This command ensures that each of the named dependencies are populated and
+ potentially added to the build by the time it returns. It iterates over
+ the list, and for each dependency, the following logic is applied:
+
+ * If the dependency has already been populated earlier in this run, set
+ the ``<lowercaseName>_POPULATED``, ``<lowercaseName>_SOURCE_DIR`` and
+ ``<lowercaseName>_BINARY_DIR`` variables in the same way as a call to
+ :command:`FetchContent_GetProperties`, then skip the remaining steps
+ below and move on to the next dependency in the list.
+
+ * Call :command:`FetchContent_Populate` to populate the dependency using
+ the details recorded by an earlier call to :command:`FetchContent_Declare`.
+ Halt with a fatal error if no such details have been recorded.
+ :variable:`FETCHCONTENT_SOURCE_DIR_<uppercaseName>` can be used to override
+ the declared details and use content provided at the specified location
+ instead.
+
+ * If the top directory of the populated content contains a ``CMakeLists.txt``
+ file, call :command:`add_subdirectory` to add it to the main build.
+ It is not an error for there to be no ``CMakeLists.txt`` file, which
+ allows the command to be used for dependencies that make downloaded
+ content available at a known location, but which do not need or support
+ being added directly to the build.
+
+ .. versionadded:: 3.18
+ The ``SOURCE_SUBDIR`` option can be given in the declared details to
+ look somewhere below the top directory instead (i.e. the same way that
+ ``SOURCE_SUBDIR`` is used by the :command:`ExternalProject_Add`
+ command). The path provided with ``SOURCE_SUBDIR`` must be relative
+ and will be treated as relative to the top directory. It can also
+ point to a directory that does not contain a ``CMakeLists.txt`` file
+ or even to a directory that doesn't exist. This can be used to avoid
+ adding a project that contains a ``CMakeLists.txt`` file in its top
+ directory.
+
+ Projects should aim to declare the details of all dependencies they might
+ use before they call ``FetchContent_MakeAvailable()`` for any of them.
+ This ensures that if any of the dependencies are also sub-dependencies of
+ one or more of the others, the main project still controls the details
+ that will be used (because it will declare them first before the
+ dependencies get a chance to). In the following code samples, assume that
+ the ``uses_other`` dependency also uses ``FetchContent`` to add the ``other``
+ dependency internally:
- # Set custom variables, policies, etc.
- # ...
+ .. code-block:: cmake
- # Bring the populated content into the build
- add_subdirectory(${${lcName}_SOURCE_DIR} ${${lcName}_BINARY_DIR})
- endif()
+ # WRONG: Should declare all details first
+ FetchContent_Declare(uses_other ...)
+ FetchContent_MakeAvailable(uses_other)
+
+ FetchContent_Declare(other ...) # Will be ignored, uses_other beat us to it
+ FetchContent_MakeAvailable(other) # Would use details declared by uses_other
-The above is such a common pattern that, where no custom steps are needed
-between the calls to :command:`FetchContent_Populate` and
-:command:`add_subdirectory`, equivalent logic can be obtained by calling
-:command:`FetchContent_MakeAvailable` instead. Where it meets the needs of
-the project, :command:`FetchContent_MakeAvailable` should be preferred, as it
-is simpler and provides additional features over the pattern above.
+ .. code-block:: cmake
+
+ # CORRECT: All details declared first, so they will take priority
+ FetchContent_Declare(uses_other ...)
+ FetchContent_Declare(other ...)
+ FetchContent_MakeAvailable(uses_other other)
.. command:: FetchContent_Populate
+ .. note::
+ Where possible, prefer to use :command:`FetchContent_MakeAvailable`
+ instead of implementing population manually with this command.
+
.. code-block:: cmake
- FetchContent_Populate( <name> )
+ FetchContent_Populate(<name>)
In most cases, the only argument given to ``FetchContent_Populate()`` is the
``<name>``. When used this way, the command assumes the content details have
@@ -211,88 +263,29 @@ is simpler and provides additional features over the pattern above.
``FetchContent_Populate()``.
``FetchContent_Populate()`` will set three variables in the scope of the
- caller; ``<lcName>_POPULATED``, ``<lcName>_SOURCE_DIR`` and
- ``<lcName>_BINARY_DIR``, where ``<lcName>`` is the lowercased ``<name>``.
- ``<lcName>_POPULATED`` will always be set to ``True`` by the call.
- ``<lcName>_SOURCE_DIR`` is the location where the
- content can be found upon return (it will have already been populated), while
- ``<lcName>_BINARY_DIR`` is a directory intended for use as a corresponding
- build directory. The main use case for the two directory variables is to
- call :command:`add_subdirectory` immediately after population, i.e.:
+ caller:
+
+ ``<lowercaseName>_POPULATED``
+ This will always be set to ``TRUE`` by the call.
+
+ ``<lowercaseName>_SOURCE_DIR``
+ The location where the populated content can be found upon return.
+
+ ``<lowercaseName>_BINARY_DIR``
+ A directory intended for use as a corresponding build directory.
+
+ The main use case for the ``<lowercaseName>_SOURCE_DIR`` and
+ ``<lowercaseName>_BINARY_DIR`` variables is to call
+ :command:`add_subdirectory` immediately after population:
.. code-block:: cmake
- FetchContent_Populate(FooBar ...)
+ FetchContent_Populate(FooBar)
add_subdirectory(${foobar_SOURCE_DIR} ${foobar_BINARY_DIR})
The values of the three variables can also be retrieved from anywhere in the
project hierarchy using the :command:`FetchContent_GetProperties` command.
- A number of cache variables influence the behavior of all content population
- performed using details saved from a :command:`FetchContent_Declare` call:
-
- ``FETCHCONTENT_BASE_DIR``
- In most cases, the saved details do not specify any options relating to the
- directories to use for the internal sub-build, final source and build areas.
- It is generally best to leave these decisions up to the ``FetchContent``
- module to handle on the project's behalf. The ``FETCHCONTENT_BASE_DIR``
- cache variable controls the point under which all content population
- directories are collected, but in most cases developers would not need to
- change this. The default location is ``${CMAKE_BINARY_DIR}/_deps``, but if
- developers change this value, they should aim to keep the path short and
- just below the top level of the build tree to avoid running into path
- length problems on Windows.
-
- ``FETCHCONTENT_QUIET``
- The logging output during population can be quite verbose, making the
- configure stage quite noisy. This cache option (``ON`` by default) hides
- all population output unless an error is encountered. If experiencing
- problems with hung downloads, temporarily switching this option off may
- help diagnose which content population is causing the issue.
-
- ``FETCHCONTENT_FULLY_DISCONNECTED``
- When this option is enabled, no attempt is made to download or update
- any content. It is assumed that all content has already been populated in
- a previous run or the source directories have been pointed at existing
- contents the developer has provided manually (using options described
- further below). When the developer knows that no changes have been made to
- any content details, turning this option ``ON`` can significantly speed up
- the configure stage. It is ``OFF`` by default.
-
- ``FETCHCONTENT_UPDATES_DISCONNECTED``
- This is a less severe download/update control compared to
- ``FETCHCONTENT_FULLY_DISCONNECTED``. Instead of bypassing all download and
- update logic, the ``FETCHCONTENT_UPDATES_DISCONNECTED`` only disables the
- update stage. Therefore, if content has not been downloaded previously,
- it will still be downloaded when this option is enabled. This can speed up
- the configure stage, but not as much as
- ``FETCHCONTENT_FULLY_DISCONNECTED``. It is ``OFF`` by default.
-
- In addition to the above cache variables, the following cache variables are
- also defined for each content name (``<ucName>`` is the uppercased value of
- ``<name>``):
-
- ``FETCHCONTENT_SOURCE_DIR_<ucName>``
- If this is set, no download or update steps are performed for the specified
- content and the ``<lcName>_SOURCE_DIR`` variable returned to the caller is
- pointed at this location. This gives developers a way to have a separate
- checkout of the content that they can modify freely without interference
- from the build. The build simply uses that existing source, but it still
- defines ``<lcName>_BINARY_DIR`` to point inside its own build area.
- Developers are strongly encouraged to use this mechanism rather than
- editing the sources populated in the default location, as changes to
- sources in the default location can be lost when content population details
- are changed by the project.
-
- ``FETCHCONTENT_UPDATES_DISCONNECTED_<ucName>``
- This is the per-content equivalent of
- ``FETCHCONTENT_UPDATES_DISCONNECTED``. If the global option or this option
- is ``ON``, then updates will be disabled for the named content.
- Disabling updates for individual content can be useful for content whose
- details rarely change, while still leaving other frequently changing
- content with updates enabled.
-
-
The ``FetchContent_Populate()`` command also supports a syntax allowing the
content details to be specified directly rather than using any saved
details. This is more low-level and use of this form is generally to be
@@ -303,7 +296,8 @@ is simpler and provides additional features over the pattern above.
.. code-block:: cmake
- FetchContent_Populate( <name>
+ FetchContent_Populate(
+ <name>
[QUIET]
[SUBBUILD_DIR <subBuildDir>]
[SOURCE_DIR <srcDir>]
@@ -325,16 +319,17 @@ is simpler and provides additional features over the pattern above.
- The ``FETCHCONTENT_FULLY_DISCONNECTED`` and
``FETCHCONTENT_UPDATES_DISCONNECTED`` cache variables are ignored.
- The ``<lcName>_SOURCE_DIR`` and ``<lcName>_BINARY_DIR`` variables are still
- returned to the caller, but since these locations are not stored as global
- properties when this form is used, they are only available to the calling
- scope and below rather than the entire project hierarchy. No
- ``<lcName>_POPULATED`` variable is set in the caller's scope with this form.
+ The ``<lowercaseName>_SOURCE_DIR`` and ``<lowercaseName>_BINARY_DIR``
+ variables are still returned to the caller, but since these locations are
+ not stored as global properties when this form is used, they are only
+ available to the calling scope and below rather than the entire project
+ hierarchy. No ``<lowercaseName>_POPULATED`` variable is set in the caller's
+ scope with this form.
The supported options for ``FetchContent_Populate()`` are the same as those
for :command:`FetchContent_Declare()`. Those few options shown just
above are either specific to ``FetchContent_Populate()`` or their behavior is
- slightly modified from how :command:`ExternalProject_Add` treats them.
+ slightly modified from how :command:`ExternalProject_Add` treats them:
``QUIET``
The ``QUIET`` option can be given to hide the output associated with
@@ -347,9 +342,9 @@ is simpler and provides additional features over the pattern above.
``SUBBUILD_DIR``
The ``SUBBUILD_DIR`` argument can be provided to change the location of the
sub-build created to perform the population. The default value is
- ``${CMAKE_CURRENT_BINARY_DIR}/<lcName>-subbuild`` and it would be unusual
- to need to override this default. If a relative path is specified, it will
- be interpreted as relative to :variable:`CMAKE_CURRENT_BINARY_DIR`.
+ ``${CMAKE_CURRENT_BINARY_DIR}/<lowercaseName>-subbuild`` and it would be
+ unusual to need to override this default. If a relative path is specified,
+ it will be interpreted as relative to :variable:`CMAKE_CURRENT_BINARY_DIR`.
This option should not be confused with the ``SOURCE_SUBDIR`` option which
only affects the :command:`FetchContent_MakeAvailable` command.
@@ -357,9 +352,9 @@ is simpler and provides additional features over the pattern above.
The ``SOURCE_DIR`` and ``BINARY_DIR`` arguments are supported by
:command:`ExternalProject_Add`, but different default values are used by
``FetchContent_Populate()``. ``SOURCE_DIR`` defaults to
- ``${CMAKE_CURRENT_BINARY_DIR}/<lcName>-src`` and ``BINARY_DIR`` defaults to
- ``${CMAKE_CURRENT_BINARY_DIR}/<lcName>-build``. If a relative path is
- specified, it will be interpreted as relative to
+ ``${CMAKE_CURRENT_BINARY_DIR}/<lowercaseName>-src`` and ``BINARY_DIR``
+ defaults to ``${CMAKE_CURRENT_BINARY_DIR}/<lowercaseName>-build``.
+ If a relative path is specified, it will be interpreted as relative to
:variable:`CMAKE_CURRENT_BINARY_DIR`.
In addition to the above explicit options, any other unrecognized options are
@@ -380,11 +375,12 @@ is simpler and provides additional features over the pattern above.
on the command line invoking the script.
.. versionadded:: 3.18
- Added support for ``DOWNLOAD_NO_EXTRACT`` and ``SOURCE_SUBDIR`` options.
+ Added support for the ``DOWNLOAD_NO_EXTRACT`` option.
.. command:: FetchContent_GetProperties
- When using saved content details, a call to :command:`FetchContent_Populate`
+ When using saved content details, a call to
+ :command:`FetchContent_MakeAvailable` or :command:`FetchContent_Populate`
records information in global properties which can be queried at any time.
This information includes the source and binary directories associated with
the content and also whether or not the content population has been processed
@@ -392,7 +388,8 @@ is simpler and provides additional features over the pattern above.
.. code-block:: cmake
- FetchContent_GetProperties( <name>
+ FetchContent_GetProperties(
+ <name>
[SOURCE_DIR <srcDirVar>]
[BINARY_DIR <binDirVar>]
[POPULATED <doneVar>]
@@ -403,49 +400,104 @@ is simpler and provides additional features over the pattern above.
which is the name of the variable in which to store that property. Most of
the time though, only ``<name>`` is given, in which case the call will then
set the same variables as a call to
- :command:`FetchContent_Populate(name) <FetchContent_Populate>`. This allows
- the following canonical pattern to be used, which ensures that the relevant
- variables will always be defined regardless of whether or not the population
- has been performed elsewhere in the project already:
-
- .. code-block:: cmake
-
- FetchContent_GetProperties(foobar)
- if(NOT foobar_POPULATED)
- FetchContent_Populate(foobar)
- ...
- endif()
+ :command:`FetchContent_MakeAvailable(name) <FetchContent_MakeAvailable>` or
+ :command:`FetchContent_Populate(name) <FetchContent_Populate>`.
- The above pattern allows other parts of the overall project hierarchy to
- re-use the same content and ensure that it is only populated once.
-
-
-.. command:: FetchContent_MakeAvailable
+ This command is rarely needed when using
+ :command:`FetchContent_MakeAvailable`. It is more commonly used as part of
+ implementing the following pattern with :command:`FetchContent_Populate`,
+ which ensures that the relevant variables will always be defined regardless
+ of whether or not the population has been performed elsewhere in the project
+ already:
.. code-block:: cmake
- FetchContent_MakeAvailable( <name1> [<name2>...] )
+ # Check if population has already been performed
+ FetchContent_GetProperties(depname)
+ if(NOT depname_POPULATED)
+ # Fetch the content using previously declared details
+ FetchContent_Populate(depname)
- .. versionadded:: 3.14
+ # Set custom variables, policies, etc.
+ # ...
- This command implements the common pattern typically needed for most
- dependencies. It iterates over each of the named dependencies in turn
- and for each one it loosely follows the
- :ref:`canonical pattern <fetch-content-canonical-pattern>` as
- presented at the beginning of this section. An important difference is
- that :command:`add_subdirectory` will only be called on the
- populated content if there is a ``CMakeLists.txt`` file in its top level
- source directory. This allows the command to be used for dependencies
- that make downloaded content available at a known location but which do
- not need or support being added directly to the build.
-
- The ``SOURCE_SUBDIR`` option can be given in the declared details to
- instruct ``FetchContent_MakeAvailable()`` to look for a ``CMakeLists.txt``
- file in a subdirectory below the top level (i.e. the same way that
- ``SOURCE_SUBDIR`` is used by the :command:`ExternalProject_Add` command).
- ``SOURCE_SUBDIR`` must always be a relative path. See the next section
- for an example of this option.
+ # Bring the populated content into the build
+ add_subdirectory(${depname_SOURCE_DIR} ${depname_BINARY_DIR})
+ endif()
+Variables
+^^^^^^^^^
+
+A number of cache variables can influence the behavior where details from a
+:command:`FetchContent_Declare` call are used to populate content.
+The variables are all intended for the developer to customize behavior and
+should not normally be set by the project.
+
+.. variable:: FETCHCONTENT_BASE_DIR
+
+ In most cases, the saved details do not specify any options relating to the
+ directories to use for the internal sub-build, final source and build areas.
+ It is generally best to leave these decisions up to the ``FetchContent``
+ module to handle on the project's behalf. The ``FETCHCONTENT_BASE_DIR``
+ cache variable controls the point under which all content population
+ directories are collected, but in most cases, developers would not need to
+ change this. The default location is ``${CMAKE_BINARY_DIR}/_deps``, but if
+ developers change this value, they should aim to keep the path short and
+ just below the top level of the build tree to avoid running into path
+ length problems on Windows.
+
+.. variable:: FETCHCONTENT_QUIET
+
+ The logging output during population can be quite verbose, making the
+ configure stage quite noisy. This cache option (``ON`` by default) hides
+ all population output unless an error is encountered. If experiencing
+ problems with hung downloads, temporarily switching this option off may
+ help diagnose which content population is causing the issue.
+
+.. variable:: FETCHCONTENT_FULLY_DISCONNECTED
+
+ When this option is enabled, no attempt is made to download or update
+ any content. It is assumed that all content has already been populated in
+ a previous run or the source directories have been pointed at existing
+ contents the developer has provided manually (using options described
+ further below). When the developer knows that no changes have been made to
+ any content details, turning this option ``ON`` can significantly speed up
+ the configure stage. It is ``OFF`` by default.
+
+.. variable:: FETCHCONTENT_UPDATES_DISCONNECTED
+
+ This is a less severe download/update control compared to
+ :variable:`FETCHCONTENT_FULLY_DISCONNECTED`. Instead of bypassing all
+ download and update logic, ``FETCHCONTENT_UPDATES_DISCONNECTED`` only
+ disables the update stage. Therefore, if content has not been downloaded
+ previously, it will still be downloaded when this option is enabled.
+ This can speed up the configure stage, but not as much as
+ :variable:`FETCHCONTENT_FULLY_DISCONNECTED`. It is ``OFF`` by default.
+
+In addition to the above cache variables, the following cache variables are
+also defined for each content name:
+
+.. variable:: FETCHCONTENT_SOURCE_DIR_<uppercaseName>
+
+ If this is set, no download or update steps are performed for the specified
+ content and the ``<lowercaseName>_SOURCE_DIR`` variable returned to the
+ caller is pointed at this location. This gives developers a way to have a
+ separate checkout of the content that they can modify freely without
+ interference from the build. The build simply uses that existing source,
+ but it still defines ``<lowercaseName>_BINARY_DIR`` to point inside its own
+ build area. Developers are strongly encouraged to use this mechanism rather
+ than editing the sources populated in the default location, as changes to
+ sources in the default location can be lost when content population details
+ are changed by the project.
+
+.. variable:: FETCHCONTENT_UPDATES_DISCONNECTED_<uppercaseName>
+
+ This is the per-content equivalent of
+ :variable:`FETCHCONTENT_UPDATES_DISCONNECTED`. If the global option or
+ this option is ``ON``, then updates will be disabled for the named content.
+ Disabling updates for individual content can be useful for content whose
+ details rarely change, while still leaving other frequently changing content
+ with updates enabled.
.. _`fetch-content-examples`:
@@ -470,7 +522,7 @@ frameworks are available to the main build:
)
# After the following call, the CMake targets defined by googletest and
- # Catch2 will be defined and available to the rest of the build
+ # Catch2 will be available to the rest of the build
FetchContent_MakeAvailable(googletest Catch2)
If the sub-project's ``CMakeLists.txt`` file is not at the top level of its
diff --git a/Modules/FindBLAS.cmake b/Modules/FindBLAS.cmake
index 726ff75..a44af4d 100644
--- a/Modules/FindBLAS.cmake
+++ b/Modules/FindBLAS.cmake
@@ -109,7 +109,8 @@ BLAS/LAPACK Vendors
``Goto``
GotoBLAS
-``IBMESSL``
+``IBMESSL``, ``IBMESSL_SMP``
+
IBM Engineering and Scientific Subroutine Library
``Intel``
@@ -150,7 +151,7 @@ BLAS/LAPACK Vendors
``PhiPACK``
Portable High Performance ANSI C (PHiPAC)
-``SCSL``
+``SCSL``, ``SCSL_mp``
Scientific Computing Software Library
``SGIMATH``
@@ -386,6 +387,8 @@ if(BLA_VENDOR STREQUAL "All")
)
endif()
if(BLAS_WORKS)
+ # Give a more helpful "found" message
+ set(BLAS_WORKS "implicitly linked")
set(_blas_fphsa_req_var BLAS_WORKS)
endif()
endif()
@@ -439,7 +442,7 @@ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All")
if(BLA_F95)
set(BLAS_mkl_SEARCH_SYMBOL "sgemm_f95")
- set(_LIBRARIES BLAS95_LIBRARIES)
+ set(_BLAS_LIBRARIES BLAS95_LIBRARIES)
if(WIN32)
# Find the main file (32-bit or 64-bit)
set(BLAS_SEARCH_LIBS_WIN_MAIN "")
@@ -501,7 +504,7 @@ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All")
endif()
else()
set(BLAS_mkl_SEARCH_SYMBOL sgemm)
- set(_LIBRARIES BLAS_LIBRARIES)
+ set(_BLAS_LIBRARIES BLAS_LIBRARIES)
if(WIN32)
# Find the main file (32-bit or 64-bit)
set(BLAS_SEARCH_LIBS_WIN_MAIN "")
@@ -613,15 +616,15 @@ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All")
"lib/${BLAS_mkl_ARCH_NAME}"
)
- foreach(IT ${BLAS_SEARCH_LIBS})
- string(REPLACE " " ";" SEARCH_LIBS ${IT})
- if(NOT ${_LIBRARIES})
+ foreach(_search ${BLAS_SEARCH_LIBS})
+ string(REPLACE " " ";" _search ${_search})
+ if(NOT ${_BLAS_LIBRARIES})
check_blas_libraries(
- ${_LIBRARIES}
+ ${_BLAS_LIBRARIES}
BLAS
${BLAS_mkl_SEARCH_SYMBOL}
""
- "${SEARCH_LIBS}"
+ "${_search}"
"${CMAKE_THREAD_LIBS_INIT};${BLAS_mkl_LM};${BLAS_mkl_LDL}"
"${BLAS_mkl_MKLROOT}"
"${BLAS_mkl_LIB_PATH_SUFFIXES}"
@@ -629,6 +632,7 @@ if(BLA_VENDOR MATCHES "Intel" OR BLA_VENDOR STREQUAL "All")
endif()
endforeach()
+ unset(_search)
unset(BLAS_mkl_ILP_MODE)
unset(BLAS_mkl_INTFACE)
unset(BLAS_mkl_THREADING)
@@ -734,14 +738,14 @@ 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")
+ set(_blas_armpl_lib "armpl_ilp64")
else()
- set(BLAS_armpl_LIB "armpl_lp64")
+ 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")
+ set(_blas_armpl_lib "${_blas_armpl_lib}_mp")
endif()
if(NOT BLAS_LIBRARIES)
@@ -750,13 +754,13 @@ if(BLA_VENDOR MATCHES "Arm" OR BLA_VENDOR STREQUAL "All")
BLAS
sgemm
""
- "${BLAS_armpl_LIB}"
+ "${_blas_armpl_lib}"
""
""
""
)
endif()
-
+ unset(_blas_armpl_lib)
endif()
# FLAME's blis library? (https://github.com/flame/blis)
@@ -859,19 +863,27 @@ if(BLA_VENDOR STREQUAL "SunPerf" OR BLA_VENDOR STREQUAL "All")
endif()
# BLAS in SCSL library? (SGI/Cray Scientific Library)
-if(BLA_VENDOR STREQUAL "SCSL" OR BLA_VENDOR STREQUAL "All")
+if(BLA_VENDOR MATCHES "SCSL" OR BLA_VENDOR STREQUAL "All")
+ set(_blas_scsl_lib "scs")
+
+ if(BLA_VENDOR MATCHES "_mp")
+ set(_blas_scsl_lib "${_blas_scsl_lib}_mp")
+ endif()
+
if(NOT BLAS_LIBRARIES)
check_blas_libraries(
BLAS_LIBRARIES
BLAS
sgemm
""
- "scsl"
+ "${_blas_scsl_lib}"
""
""
""
)
endif()
+
+ unset(_blas_scsl_lib)
endif()
# BLAS in SGIMATH library?
@@ -890,20 +902,27 @@ if(BLA_VENDOR STREQUAL "SGIMATH" OR BLA_VENDOR STREQUAL "All")
endif()
endif()
-# BLAS in IBM ESSL library? (requires generic BLAS lib, too)
-if(BLA_VENDOR STREQUAL "IBMESSL" OR BLA_VENDOR STREQUAL "All")
+# BLAS in IBM ESSL library?
+if(BLA_VENDOR MATCHES "IBMESSL" OR BLA_VENDOR STREQUAL "All")
+ set(_blas_essl_lib "essl")
+
+ if(BLA_VENDOR MATCHES "_SMP")
+ set(_blas_essl_lib "${_blas_essl_lib}smp")
+ endif()
if(NOT BLAS_LIBRARIES)
check_blas_libraries(
BLAS_LIBRARIES
BLAS
sgemm
""
- "essl;blas"
+ "${_blas_essl_lib}"
""
""
""
)
endif()
+
+ unset(_blas_essl_lib)
endif()
# BLAS in acml library?
@@ -1087,11 +1106,11 @@ endif()
# Elbrus Math Library?
if(BLA_VENDOR MATCHES "EML" OR BLA_VENDOR STREQUAL "All")
- set(BLAS_EML_LIB "eml")
+ set(_blas_eml_lib "eml")
# Check for OpenMP support, VIA BLA_VENDOR of eml_mt
if(BLA_VENDOR MATCHES "_mt")
- set(BLAS_EML_LIB "${BLAS_EML_LIB}_mt")
+ set(_blas_eml_lib "${_blas_eml_lib}_mt")
endif()
if(NOT BLAS_LIBRARIES)
@@ -1100,13 +1119,13 @@ if(BLA_VENDOR MATCHES "EML" OR BLA_VENDOR STREQUAL "All")
BLAS
sgemm
""
- "${BLAS_EML_LIB}"
+ "${_blas_eml_lib}"
""
""
""
)
endif()
-
+ unset(_blas_eml_lib)
endif()
# Fujitsu SSL2 Library?
@@ -1163,3 +1182,5 @@ if(NOT BLA_F95)
endif()
_add_blas_target()
+unset(_blas_fphsa_req_var)
+unset(_BLAS_LIBRARIES)
diff --git a/Modules/FindCUDAToolkit.cmake b/Modules/FindCUDAToolkit.cmake
index 89b8c99..92042d2 100644
--- a/Modules/FindCUDAToolkit.cmake
+++ b/Modules/FindCUDAToolkit.cmake
@@ -844,14 +844,17 @@ if(CUDAToolkit_FOUND)
HINTS ${CUDAToolkit_LIBRARY_DIR}
ENV CUDA_PATH
PATH_SUFFIXES lib64/stubs lib/x64/stubs lib/stubs stubs
+ # Support NVHPC splayed math library layout
+ ../../math_libs/${CUDAToolkit_VERSION_MAJOR}.${CUDAToolkit_VERSION_MINOR}/lib64
+ ../../math_libs/lib64
)
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)
+ add_library(CUDA::${lib_name} UNKNOWN IMPORTED)
target_include_directories(CUDA::${lib_name} SYSTEM INTERFACE "${CUDAToolkit_INCLUDE_DIRS}")
- target_link_libraries(CUDA::${lib_name} INTERFACE "${CUDA_${lib_name}_LIBRARY}")
+ set_property(TARGET CUDA::${lib_name} PROPERTY IMPORTED_LOCATION "${CUDA_${lib_name}_LIBRARY}")
foreach(dep ${arg_DEPS})
if(TARGET CUDA::${dep})
target_link_libraries(CUDA::${lib_name} INTERFACE CUDA::${dep})
diff --git a/Modules/FindGLUT.cmake b/Modules/FindGLUT.cmake
index 2770c60..dd0975d 100644
--- a/Modules/FindGLUT.cmake
+++ b/Modules/FindGLUT.cmake
@@ -41,8 +41,43 @@ Also defined, but not for general use are:
#]=======================================================================]
include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
-if (WIN32)
+function(_add_glut_target_simple)
+ if(TARGET GLUT::GLUT)
+ return()
+ endif()
+ add_library(GLUT::GLUT INTERFACE IMPORTED)
+ if(GLUT_INCLUDE_DIRS)
+ target_include_directories(GLUT::GLUT SYSTEM
+ INTERFACE "${GLUT_INCLUDE_DIRS}")
+ endif()
+ if(GLUT_LIBRARIES)
+ target_link_libraries(GLUT::GLUT INTERFACE ${GLUT_LIBRARIES})
+ endif()
+ if(GLUT_LDFLAGS)
+ target_link_options(GLUT::GLUT INTERFACE ${GLUT_LDFLAGS})
+ endif()
+ if(GLUT_CFLAGS)
+ separate_arguments(GLUT_CFLAGS_SPLIT UNIX_COMMAND "${GLUT_CFLAGS}")
+ target_compile_options(GLUT::GLUT INTERFACE ${GLUT_CFLAGS_SPLIT})
+ endif()
+
+ set_property(TARGET GLUT::GLUT APPEND PROPERTY
+ IMPORTED_LOCATION "${GLUT_glut_LIBRARY}")
+endfunction()
+
+find_package(PkgConfig)
+if(PKG_CONFIG_FOUND)
+ pkg_check_modules(GLUT glut)
+ if(GLUT_FOUND)
+ _add_glut_target_simple()
+ FIND_PACKAGE_HANDLE_STANDARD_ARGS(GLUT REQUIRED_VARS GLUT_FOUND)
+ return()
+ endif()
+endif()
+
+if(WIN32)
find_path( GLUT_INCLUDE_DIR NAMES GL/glut.h
PATHS ${GLUT_ROOT_PATH}/include )
find_library( GLUT_glut_LIBRARY_RELEASE NAMES glut glut32 freeglut
@@ -57,85 +92,75 @@ if (WIN32)
)
mark_as_advanced(GLUT_glut_LIBRARY_RELEASE GLUT_glut_LIBRARY_DEBUG)
select_library_configurations(GLUT_glut)
-else ()
-
- if (APPLE)
- find_path(GLUT_INCLUDE_DIR glut.h ${OPENGL_LIBRARY_DIR})
- find_library(GLUT_glut_LIBRARY GLUT DOC "GLUT library for OSX")
- find_library(GLUT_cocoa_LIBRARY Cocoa DOC "Cocoa framework for OSX")
- mark_as_advanced(GLUT_glut_LIBRARY GLUT_cocoa_LIBRARY)
-
- if(GLUT_cocoa_LIBRARY AND NOT TARGET GLUT::Cocoa)
- add_library(GLUT::Cocoa UNKNOWN IMPORTED)
- # Cocoa should always be a Framework, but we check to make sure.
- if(GLUT_cocoa_LIBRARY MATCHES "/([^/]+)\\.framework$")
- set(_glut_cocoa "${GLUT_cocoa_LIBRARY}/${CMAKE_MATCH_1}")
- if(EXISTS "${_glut_cocoa}.tbd")
- string(APPEND _glut_cocoa ".tbd")
- endif()
- set_target_properties(GLUT::Cocoa PROPERTIES
- IMPORTED_LOCATION "${_glut_cocoa}")
- else()
- set_target_properties(GLUT::Cocoa PROPERTIES
- IMPORTED_LOCATION "${GLUT_cocoa_LIBRARY}")
+elseif(APPLE)
+ find_path(GLUT_INCLUDE_DIR glut.h ${OPENGL_LIBRARY_DIR})
+ find_library(GLUT_glut_LIBRARY GLUT DOC "GLUT library for OSX")
+ find_library(GLUT_cocoa_LIBRARY Cocoa DOC "Cocoa framework for OSX")
+ mark_as_advanced(GLUT_glut_LIBRARY GLUT_cocoa_LIBRARY)
+
+ if(GLUT_cocoa_LIBRARY AND NOT TARGET GLUT::Cocoa)
+ add_library(GLUT::Cocoa UNKNOWN IMPORTED)
+ # Cocoa should always be a Framework, but we check to make sure.
+ if(GLUT_cocoa_LIBRARY MATCHES "/([^/]+)\\.framework$")
+ set(_glut_cocoa "${GLUT_cocoa_LIBRARY}/${CMAKE_MATCH_1}")
+ if(EXISTS "${_glut_cocoa}.tbd")
+ string(APPEND _glut_cocoa ".tbd")
endif()
- endif()
- else ()
-
- if (BEOS)
-
- set(_GLUT_INC_DIR /boot/develop/headers/os/opengl)
- set(_GLUT_glut_LIB_DIR /boot/develop/lib/x86)
-
+ set_target_properties(GLUT::Cocoa PROPERTIES
+ IMPORTED_LOCATION "${_glut_cocoa}")
else()
-
- find_library( GLUT_Xi_LIBRARY Xi
- /usr/openwin/lib
- )
- mark_as_advanced(GLUT_Xi_LIBRARY)
-
- find_library( GLUT_Xmu_LIBRARY Xmu
- /usr/openwin/lib
- )
- mark_as_advanced(GLUT_Xmu_LIBRARY)
-
- if(GLUT_Xi_LIBRARY AND NOT TARGET GLUT::Xi)
- add_library(GLUT::Xi UNKNOWN IMPORTED)
- set_target_properties(GLUT::Xi PROPERTIES
- IMPORTED_LOCATION "${GLUT_Xi_LIBRARY}")
- endif()
-
- if(GLUT_Xmu_LIBRARY AND NOT TARGET GLUT::Xmu)
- add_library(GLUT::Xmu UNKNOWN IMPORTED)
- set_target_properties(GLUT::Xmu PROPERTIES
- IMPORTED_LOCATION "${GLUT_Xmu_LIBRARY}")
- endif()
-
- endif ()
-
- find_path( GLUT_INCLUDE_DIR GL/glut.h
- /usr/include/GL
- /usr/openwin/share/include
- /usr/openwin/include
- /opt/graphics/OpenGL/include
- /opt/graphics/OpenGL/contrib/libglut
- ${_GLUT_INC_DIR}
+ set_target_properties(GLUT::Cocoa PROPERTIES
+ IMPORTED_LOCATION "${GLUT_cocoa_LIBRARY}")
+ endif()
+ endif()
+else()
+ if(BEOS)
+ set(_GLUT_INC_DIR /boot/develop/headers/os/opengl)
+ set(_GLUT_glut_LIB_DIR /boot/develop/lib/x86)
+ else()
+ find_library( GLUT_Xi_LIBRARY Xi
+ /usr/openwin/lib
)
+ mark_as_advanced(GLUT_Xi_LIBRARY)
- find_library( GLUT_glut_LIBRARY glut
+ find_library( GLUT_Xmu_LIBRARY Xmu
/usr/openwin/lib
- ${_GLUT_glut_LIB_DIR}
)
- mark_as_advanced(GLUT_glut_LIBRARY)
+ mark_as_advanced(GLUT_Xmu_LIBRARY)
- unset(_GLUT_INC_DIR)
- unset(_GLUT_glut_LIB_DIR)
+ if(GLUT_Xi_LIBRARY AND NOT TARGET GLUT::Xi)
+ add_library(GLUT::Xi UNKNOWN IMPORTED)
+ set_target_properties(GLUT::Xi PROPERTIES
+ IMPORTED_LOCATION "${GLUT_Xi_LIBRARY}")
+ endif()
+
+ if(GLUT_Xmu_LIBRARY AND NOT TARGET GLUT::Xmu)
+ add_library(GLUT::Xmu UNKNOWN IMPORTED)
+ set_target_properties(GLUT::Xmu PROPERTIES
+ IMPORTED_LOCATION "${GLUT_Xmu_LIBRARY}")
+ endif()
endif ()
-endif ()
+ find_path( GLUT_INCLUDE_DIR GL/glut.h
+ /usr/include/GL
+ /usr/openwin/share/include
+ /usr/openwin/include
+ /opt/graphics/OpenGL/include
+ /opt/graphics/OpenGL/contrib/libglut
+ ${_GLUT_INC_DIR}
+ )
+
+ find_library( GLUT_glut_LIBRARY glut
+ /usr/openwin/lib
+ ${_GLUT_glut_LIB_DIR}
+ )
+
+ unset(_GLUT_INC_DIR)
+ unset(_GLUT_glut_LIB_DIR)
+endif()
+mark_as_advanced(GLUT_glut_LIBRARY)
-include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GLUT REQUIRED_VARS GLUT_glut_LIBRARY GLUT_INCLUDE_DIR)
if (GLUT_FOUND)
diff --git a/Modules/FindLAPACK.cmake b/Modules/FindLAPACK.cmake
index 3146e06..f36acfd 100644
--- a/Modules/FindLAPACK.cmake
+++ b/Modules/FindLAPACK.cmake
@@ -298,7 +298,7 @@ if(NOT LAPACK_NOT_FOUND_MESSAGE)
if(BLA_F95)
set(LAPACK_mkl_SEARCH_SYMBOL "cheev_f95")
- set(_LIBRARIES LAPACK95_LIBRARIES)
+ set(_LAPACK_LIBRARIES LAPACK95_LIBRARIES)
set(_BLAS_LIBRARIES ${BLAS95_LIBRARIES})
# old
@@ -311,7 +311,7 @@ if(NOT LAPACK_NOT_FOUND_MESSAGE)
"mkl_lapack95_${LAPACK_mkl_ILP_MODE}")
else()
set(LAPACK_mkl_SEARCH_SYMBOL "cheev")
- set(_LIBRARIES LAPACK_LIBRARIES)
+ set(_LAPACK_LIBRARIES LAPACK_LIBRARIES)
set(_BLAS_LIBRARIES ${BLAS_LIBRARIES})
# old and new >= 10.3
@@ -350,10 +350,10 @@ if(NOT LAPACK_NOT_FOUND_MESSAGE)
"lib/${LAPACK_mkl_ARCH_NAME}"
)
- # First try empty lapack libs
- if(NOT ${_LIBRARIES})
+ # First try empty lapack libs (implicitly linked or automatic from BLAS)
+ if(NOT ${_LAPACK_LIBRARIES})
check_lapack_libraries(
- ${_LIBRARIES}
+ ${_LAPACK_LIBRARIES}
LAPACK
${LAPACK_mkl_SEARCH_SYMBOL}
""
@@ -363,18 +363,23 @@ if(NOT LAPACK_NOT_FOUND_MESSAGE)
"${LAPACK_mkl_LIB_PATH_SUFFIXES}"
"${_BLAS_LIBRARIES}"
)
+ if(LAPACK_WORKS AND NOT _BLAS_LIBRARIES)
+ # Give a more helpful "found" message
+ set(LAPACK_WORKS "implicitly linked")
+ set(_lapack_fphsa_req_var LAPACK_WORKS)
+ endif()
endif()
# Then try the search libs
- foreach(IT ${LAPACK_SEARCH_LIBS})
- string(REPLACE " " ";" SEARCH_LIBS ${IT})
- if(NOT ${_LIBRARIES})
+ foreach(_search ${LAPACK_SEARCH_LIBS})
+ string(REPLACE " " ";" _search ${_search})
+ if(NOT ${_LAPACK_LIBRARIES})
check_lapack_libraries(
- ${_LIBRARIES}
+ ${_LAPACK_LIBRARIES}
LAPACK
${LAPACK_mkl_SEARCH_SYMBOL}
""
- "${SEARCH_LIBS}"
+ "${_search}"
"${CMAKE_THREAD_LIBS_INIT};${LAPACK_mkl_LM};${LAPACK_mkl_LDL}"
"${LAPACK_mkl_MKLROOT}"
"${LAPACK_mkl_LIB_PATH_SUFFIXES}"
@@ -383,6 +388,7 @@ if(NOT LAPACK_NOT_FOUND_MESSAGE)
endif()
endforeach()
+ unset(_search)
unset(LAPACK_mkl_ILP_MODE)
unset(LAPACK_mkl_SEARCH_SYMBOL)
unset(LAPACK_mkl_LM)
@@ -485,6 +491,30 @@ if(NOT LAPACK_NOT_FOUND_MESSAGE)
)
endif()
+ # LAPACK in SCSL library? (SGI/Cray Scientific Library)
+ if(NOT LAPACK_LIBRARIES
+ AND (BLA_VENDOR MATCHES "SCSL" OR BLA_VENDOR STREQUAL "All"))
+ set(_lapack_scsl_lib "scs")
+
+ # Check for OpenMP support, VIA BLA_VENDOR of scs_mp
+ if(BLA_VENDOR MATCHES "_mp")
+ set(_lapack_scsl_lib "${_lapack_scsl_lib}_mp")
+ endif()
+
+ check_lapack_libraries(
+ LAPACK_LIBRARIES
+ LAPACK
+ cheev
+ ""
+ "${_lapack_scsl_lib}"
+ ""
+ ""
+ ""
+ "${BLAS_LIBRARIES}"
+ )
+ unset(_lapack_scsl_lib)
+ endif()
+
# BLAS in acml library?
if(BLA_VENDOR MATCHES "ACML" OR BLA_VENDOR STREQUAL "All")
if(BLAS_LIBRARIES MATCHES ".+acml.+")
@@ -580,6 +610,30 @@ if(NOT LAPACK_NOT_FOUND_MESSAGE)
unset(_ssl2_suffix)
endif()
+ # LAPACK in IBM ESSL library?
+ if(NOT LAPACK_LIBRARIES
+ AND (BLA_VENDOR MATCHES "IBMESSL" OR BLA_VENDOR STREQUAL "All"))
+ set(_lapack_essl_lib "essl")
+
+ # Check for OpenMP support, VIA BLA_VENDOR of esslsmp
+ if(BLA_VENDOR MATCHES "_SMP")
+ set(_lapack_essl_lib "${_lapack_essl_lib}smp")
+ endif()
+
+ check_lapack_libraries(
+ LAPACK_LIBRARIES
+ LAPACK
+ cheev
+ ""
+ "${_lapack_essl_lib}"
+ ""
+ ""
+ ""
+ "${BLAS_LIBRARIES}"
+ )
+ unset(_lapack_essl_lib)
+ endif()
+
# NVHPC Library?
if(NOT LAPACK_LIBRARIES
AND (BLA_VENDOR MATCHES "NVHPC" OR BLA_VENDOR STREQUAL "All"))
@@ -646,3 +700,5 @@ if(LAPACK_LIBRARIES STREQUAL "LAPACK_LIBRARIES-PLACEHOLDER-FOR-EMPTY-LIBRARIES")
endif()
_add_lapack_target()
+unset(_lapack_fphsa_req_var)
+unset(_LAPACK_LIBRARIES)
diff --git a/Modules/FindMPI.cmake b/Modules/FindMPI.cmake
index d8f0334..d4b4a34 100644
--- a/Modules/FindMPI.cmake
+++ b/Modules/FindMPI.cmake
@@ -105,7 +105,7 @@ This module performs a four step search for an MPI implementation:
1. Search for ``MPIEXEC_EXECUTABLE`` and, if found, use its base directory.
2. Check if the compiler has MPI support built-in. This is the case if the user passed a
- compiler wrapper as ``CMAKE_<LANG>_COMPILER`` or if they're on a Cray system.
+ compiler wrapper as ``CMAKE_<LANG>_COMPILER`` or if they use Cray system compiler wrappers.
3. Attempt to find an MPI compiler wrapper and determine the compiler information from it.
4. Try to find an MPI implementation that does not ship such a wrapper by guessing settings.
Currently, only Microsoft MPI and MPICH2 on Windows are supported.
@@ -333,6 +333,11 @@ set(_MPI_XL_Fortran_COMPILER_NAMES mpixlf95 mpixlf95_r mpxlf95 mpxlf95
mpixlf77 mpixlf77_r mpxlf77 mpxlf77_r
mpixlf mpixlf_r mpxlf mpxlf_r)
+# Cray Compiler names
+set(_MPI_Cray_C_COMPILER_NAMES cc)
+set(_MPI_Cray_CXX_COMPILER_NAMES CC)
+set(_MPI_Cray_Fortran_COMPILER_NAMES ftn)
+
# Prepend vendor-specific compiler wrappers to the list. If we don't know the compiler,
# attempt all of them.
# By attempting vendor-specific compiler names first, we should avoid situations where the compiler wrapper
@@ -488,6 +493,26 @@ function (_MPI_interrogate_compiler LANG)
endif()
endif()
+ # Cray compiler wrappers come usually without a separate mpicc/c++/ftn, but offer
+ # --cray-print-opts=...
+ if (NOT MPI_COMPILER_RETURN EQUAL 0)
+ _MPI_check_compiler(${LANG} "--cray-print-opts=cflags"
+ MPI_COMPILE_CMDLINE MPI_COMPILER_RETURN)
+
+ if (MPI_COMPILER_RETURN EQUAL 0)
+ # Pass --no-as-needed so the mpi library is always linked. Otherwise, the
+ # Cray compiler wrapper puts an --as-needed flag around the mpi library,
+ # and it is not linked unless code directly refers to it.
+ _MPI_check_compiler(${LANG} "--no-as-needed;--cray-print-opts=libs"
+ MPI_LINK_CMDLINE MPI_COMPILER_RETURN)
+
+ if (NOT MPI_COMPILER_RETURN EQUAL 0)
+ unset(MPI_COMPILE_CMDLINE)
+ unset(MPI_LINK_CMDLINE)
+ endif()
+ endif()
+ endif()
+
# MPICH, MVAPICH2 and Intel MPI just use "-show". Open MPI also offers this, but the
# -showme commands are more specialized.
if (NOT MPI_COMPILER_RETURN EQUAL 0)
@@ -1441,9 +1466,10 @@ foreach(LANG IN ITEMS C CXX Fortran)
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.")
+ option(MPI_CXX_SKIP_MPICXX "If true, the MPI-2 C++ bindings are disabled using definitions." FALSE)
mark_as_advanced(MPI_CXX_SKIP_MPICXX)
endif()
+ _MPI_adjust_compile_definitions(${LANG})
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)
@@ -1520,6 +1546,29 @@ foreach(LANG IN ITEMS C CXX Fortran)
endif()
endif()
+ # We are on a Cray, environment identfier: PE_ENV is set (CRAY), and
+ # have NOT found an mpic++-like compiler wrapper (previous block),
+ # and we do NOT use the Cray cc/CC compiler wrappers as CC/CXX CMake
+ # compiler.
+ # So as a last resort, we now interrogate cc/CC/ftn for MPI flags.
+ if(DEFINED ENV{PE_ENV} AND NOT "${MPI_${LANG}_COMPILER}")
+ set(MPI_PINNED_COMPILER TRUE)
+ find_program(MPI_${LANG}_COMPILER
+ NAMES ${_MPI_Cray_${LANG}_COMPILER_NAMES}
+ PATH_SUFFIXES bin sbin
+ DOC "MPI compiler for ${LANG}"
+ )
+
+ # If we haven't made the implicit compiler test yet, perform it now.
+ if(NOT MPI_${LANG}_TRIED_IMPLICIT)
+ _MPI_create_imported_target(${LANG})
+ _MPI_check_lang_works(${LANG} TRUE)
+ endif()
+
+ set(MPI_${LANG}_WORKS_IMPLICIT TRUE)
+ _MPI_interrogate_compiler(${LANG})
+ endif()
+
if(NOT MPI_PINNED_COMPILER AND NOT MPI_${LANG}_WRAPPER_FOUND)
# If MPI_PINNED_COMPILER wasn't given, and the MPI compiler we potentially found didn't work, we withdraw it.
set(MPI_${LANG}_COMPILER "MPI_${LANG}_COMPILER-NOTFOUND" CACHE FILEPATH "MPI compiler for ${LANG}" FORCE)
@@ -1548,7 +1597,6 @@ foreach(LANG IN ITEMS C CXX Fortran)
endif()
_MPI_assemble_libraries(${LANG})
- _MPI_adjust_compile_definitions(${LANG})
# We always create imported targets even if they're empty
_MPI_create_imported_target(${LANG})
diff --git a/Modules/FindMPI/test_mpi.c b/Modules/FindMPI/test_mpi.c
index 7c96d54..70d7e1d 100644
--- a/Modules/FindMPI/test_mpi.c
+++ b/Modules/FindMPI/test_mpi.c
@@ -7,15 +7,15 @@
#endif
#if defined(MPI_VERSION) && defined(MPI_SUBVERSION)
-const char mpiver_str[] = { 'I', 'N',
- 'F', 'O',
- ':', 'M',
- 'P', 'I',
- '-', 'V',
- 'E', 'R',
- '[', ('0' + MPI_VERSION),
- '.', ('0' + MPI_SUBVERSION),
- ']', '\0' };
+const static char mpiver_str[] = { 'I', 'N',
+ 'F', 'O',
+ ':', 'M',
+ 'P', 'I',
+ '-', 'V',
+ 'E', 'R',
+ '[', ('0' + MPI_VERSION),
+ '.', ('0' + MPI_SUBVERSION),
+ ']', '\0' };
#endif
int main(int argc, char* argv[])
diff --git a/Modules/FindPatch.cmake b/Modules/FindPatch.cmake
index 4108651..f4fe4a6 100644
--- a/Modules/FindPatch.cmake
+++ b/Modules/FindPatch.cmake
@@ -43,7 +43,7 @@ endif()
# First search the PATH
find_program(Patch_EXECUTABLE
- NAME patch
+ NAMES patch
PATHS ${_patch_path}
DOC ${_doc}
)
diff --git a/Modules/FindPkgConfig.cmake b/Modules/FindPkgConfig.cmake
index 01ad5ac..4de5331 100644
--- a/Modules/FindPkgConfig.cmake
+++ b/Modules/FindPkgConfig.cmake
@@ -15,6 +15,8 @@ following variables will also be set:
if pkg-config executable was found
``PKG_CONFIG_EXECUTABLE``
pathname of the pkg-config program
+``PKG_CONFIG_ARGN``
+ list of arguments to pass to pkg-config
``PKG_CONFIG_VERSION_STRING``
version of pkg-config (since CMake 2.8.8)
@@ -29,13 +31,22 @@ set(PKG_CONFIG_VERSION 1)
# find pkg-config, use PKG_CONFIG if set
if((NOT PKG_CONFIG_EXECUTABLE) AND (NOT "$ENV{PKG_CONFIG}" STREQUAL ""))
- set(PKG_CONFIG_EXECUTABLE "$ENV{PKG_CONFIG}" CACHE FILEPATH "pkg-config executable")
+ separate_arguments(PKG_CONFIG_FROM_ENV_SPLIT NATIVE_COMMAND PROGRAM SEPARATE_ARGS "$ENV{PKG_CONFIG}")
+ list(LENGTH PKG_CONFIG_FROM_ENV_SPLIT PKG_CONFIG_FROM_ENV_SPLIT_ARGC)
+ if(PKG_CONFIG_FROM_ENV_SPLIT_ARGC GREATER 0)
+ list(GET PKG_CONFIG_FROM_ENV_SPLIT 0 PKG_CONFIG_FROM_ENV_ARGV0)
+ if(PKG_CONFIG_FROM_ENV_SPLIT_ARGC GREATER 1)
+ list(SUBLIST PKG_CONFIG_FROM_ENV_SPLIT 1 -1 PKG_CONFIG_ARGN)
+ endif()
+ set(PKG_CONFIG_EXECUTABLE "${PKG_CONFIG_FROM_ENV_ARGV0}" CACHE FILEPATH "pkg-config executable")
+ endif()
endif()
set(PKG_CONFIG_NAMES "pkg-config")
if(CMAKE_HOST_WIN32)
list(PREPEND PKG_CONFIG_NAMES "pkg-config.bat")
endif()
+list(PREPEND PKG_CONFIG_NAMES "pkgconf")
find_program(PKG_CONFIG_EXECUTABLE
NAMES ${PKG_CONFIG_NAMES}
@@ -43,9 +54,12 @@ find_program(PKG_CONFIG_EXECUTABLE
DOC "pkg-config executable")
mark_as_advanced(PKG_CONFIG_EXECUTABLE)
+set(PKG_CONFIG_ARGN "${PKG_CONFIG_ARGN}" CACHE STRING "Arguments to supply to pkg-config")
+mark_as_advanced(PKG_CONFIG_ARGN)
+
set(_PKG_CONFIG_FAILURE_MESSAGE "")
if (PKG_CONFIG_EXECUTABLE)
- execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --version
+ execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} ${PKG_CONFIG_ARGN} --version
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
@@ -53,14 +67,18 @@ if (PKG_CONFIG_EXECUTABLE)
if (NOT _PKG_CONFIG_VERSION_RESULT EQUAL 0)
string(REPLACE "\n" "\n " _PKG_CONFIG_VERSION_ERROR " ${_PKG_CONFIG_VERSION_ERROR}")
+ if(PKG_CONFIG_ARGN)
+ string(REPLACE ";" " " PKG_CONFIG_ARGN " ${PKG_CONFIG_ARGN}")
+ endif()
string(APPEND _PKG_CONFIG_FAILURE_MESSAGE
"The command\n"
- " \"${PKG_CONFIG_EXECUTABLE}\" --version\n"
+ " \"${PKG_CONFIG_EXECUTABLE}\"${PKG_CONFIG_ARGN} --version\n"
" failed with output:\n${PKG_CONFIG_VERSION_STRING}\n"
" stderr: \n${_PKG_CONFIG_VERSION_ERROR}\n"
" result: \n${_PKG_CONFIG_VERSION_RESULT}"
)
set(PKG_CONFIG_EXECUTABLE "")
+ set(PKG_CONFIG_ARGN "")
unset(PKG_CONFIG_VERSION_STRING)
endif ()
unset(_PKG_CONFIG_VERSION_RESULT)
@@ -99,7 +117,7 @@ macro(_pkgconfig_invoke _pkglist _prefix _varname _regexp)
set(_pkgconfig_invoke_result)
execute_process(
- COMMAND ${PKG_CONFIG_EXECUTABLE} ${ARGN} ${_pkglist}
+ COMMAND ${PKG_CONFIG_EXECUTABLE} ${PKG_CONFIG_ARGN} ${ARGN} ${_pkglist}
OUTPUT_VARIABLE _pkgconfig_invoke_result
RESULT_VARIABLE _pkgconfig_failed
OUTPUT_STRIP_TRAILING_WHITESPACE)
@@ -393,6 +411,14 @@ macro(_pkg_set_path_internal)
unset(_lib_dirs)
unset(_pkgconfig_path)
endif()
+
+ # Tell pkg-config not to strip any -L paths so we can search them all.
+ if(DEFINED ENV{PKG_CONFIG_ALLOW_SYSTEM_LIBS})
+ set(_pkgconfig_allow_system_libs_old "$ENV{PKG_CONFIG_ALLOW_SYSTEM_LIBS}")
+ else()
+ unset(_pkgconfig_allow_system_libs_old)
+ endif()
+ set(ENV{PKG_CONFIG_ALLOW_SYSTEM_LIBS} 0)
endmacro()
macro(_pkg_restore_path_internal)
@@ -400,6 +426,10 @@ macro(_pkg_restore_path_internal)
# Restore the environment variable
set(ENV{PKG_CONFIG_PATH} "${_pkgconfig_path_old}")
endif()
+ if(DEFINED _pkgconfig_allow_system_libs_old)
+ set(ENV{PKG_CONFIG_ALLOW_SYSTEM_LIBS} "${_pkgconfig_allow_system_libs_old}")
+ unset(_pkgconfig_allow_system_libs_old)
+ endif()
unset(_extra_paths)
unset(_pkgconfig_path_old)
@@ -541,7 +571,7 @@ macro(_pkg_check_modules_internal _is_required _is_silent _no_cmake_path _no_cma
# execute the query
execute_process(
- COMMAND ${PKG_CONFIG_EXECUTABLE} ${_pkg_check_modules_exist_query}
+ COMMAND ${PKG_CONFIG_EXECUTABLE} ${PKG_CONFIG_ARGN} ${_pkg_check_modules_exist_query}
RESULT_VARIABLE _pkgconfig_retval
ERROR_VARIABLE _pkgconfig_error
ERROR_STRIP_TRAILING_WHITESPACE)
@@ -900,6 +930,18 @@ Variables Affecting Behavior
.. versionadded:: 3.1
The ``PKG_CONFIG`` environment variable can be used as a hint.
+.. variable:: PKG_CONFIG_ARGN
+
+ .. versionadded:: 3.22
+
+ This can be set to a list of arguments to additionally pass to pkg-config
+ if needed. If not provided, it will be an empty string, however, if the
+ environment variable ``PKG_CONFIG`` is provided, this will be set to the
+ result of splitting the variable.
+
+ The ``PKG_CONFIG`` environment variable can be used to provide both
+ ``PKG_CONFIG_EXECUTABLE`` and ``PKG_CONFIG_ARGN``
+
.. variable:: PKG_CONFIG_USE_CMAKE_PREFIX_PATH
.. versionadded:: 3.1
diff --git a/Modules/FindX11.cmake b/Modules/FindX11.cmake
index d480fc4..fd5ee53 100644
--- a/Modules/FindX11.cmake
+++ b/Modules/FindX11.cmake
@@ -828,6 +828,12 @@ if (UNIX)
X11_Xau_INCLUDE_PATH
X11_xcb_LIB
X11_xcb_INCLUDE_PATH
+ X11_xcb_icccm_LIB
+ X11_xcb_icccm_INCLUDE_PATH
+ X11_xcb_util_LIB
+ X11_xcb_util_INCLUDE_PATH
+ X11_xcb_xfixes_LIB
+ X11_xcb_xfixes_INCLUDE_PATH
X11_xcb_xkb_LIB
X11_X11_xcb_LIB
X11_X11_xcb_INCLUDE_PATH
diff --git a/Modules/GoogleTest.cmake b/Modules/GoogleTest.cmake
index 80d8e23..a483c03 100644
--- a/Modules/GoogleTest.cmake
+++ b/Modules/GoogleTest.cmake
@@ -151,6 +151,7 @@ same as the Google Test name (i.e. ``suite.testcase``); see also
[WORKING_DIRECTORY dir]
[TEST_PREFIX prefix]
[TEST_SUFFIX suffix]
+ [TEST_FILTER expr]
[NO_PRETTY_TYPES] [NO_PRETTY_VALUES]
[PROPERTIES name1 value1...]
[TEST_LIST var]
@@ -204,6 +205,12 @@ same as the Google Test name (i.e. ``suite.testcase``); see also
every discovered test case. Both ``TEST_PREFIX`` and ``TEST_SUFFIX`` may
be specified.
+ ``TEST_FILTER expr``
+ .. versionadded:: 3.22
+
+ Filter expression to pass to ``--gtest_filter`` argument during test
+ discovery.
+
``NO_PRETTY_TYPES``
By default, the type index of type-parameterized tests is replaced by the
actual type name in the CTest test name. If this behavior is undesirable
@@ -411,7 +418,7 @@ function(gtest_discover_tests TARGET)
""
"NO_PRETTY_TYPES;NO_PRETTY_VALUES"
"TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST;DISCOVERY_TIMEOUT;XML_OUTPUT_DIR;DISCOVERY_MODE"
- "EXTRA_ARGS;PROPERTIES"
+ "EXTRA_ARGS;PROPERTIES;TEST_FILTER"
${ARGN}
)
@@ -475,6 +482,7 @@ function(gtest_discover_tests TARGET)
-D "TEST_PROPERTIES=${_PROPERTIES}"
-D "TEST_PREFIX=${_TEST_PREFIX}"
-D "TEST_SUFFIX=${_TEST_SUFFIX}"
+ -D "TEST_FILTER=${_TEST_FILTER}"
-D "NO_PRETTY_TYPES=${_NO_PRETTY_TYPES}"
-D "NO_PRETTY_VALUES=${_NO_PRETTY_VALUES}"
-D "TEST_LIST=${_TEST_LIST}"
@@ -515,6 +523,7 @@ function(gtest_discover_tests TARGET)
" TEST_PROPERTIES" " [==[" "${_PROPERTIES}" "]==]" "\n"
" TEST_PREFIX" " [==[" "${_TEST_PREFIX}" "]==]" "\n"
" TEST_SUFFIX" " [==[" "${_TEST_SUFFIX}" "]==]" "\n"
+ " TEST_FILTER" " [==[" "${_TEST_FILTER}" "]==]" "\n"
" NO_PRETTY_TYPES" " [==[" "${_NO_PRETTY_TYPES}" "]==]" "\n"
" NO_PRETTY_VALUES" " [==[" "${_NO_PRETTY_VALUES}" "]==]" "\n"
" TEST_LIST" " [==[" "${_TEST_LIST}" "]==]" "\n"
diff --git a/Modules/GoogleTestAddTests.cmake b/Modules/GoogleTestAddTests.cmake
index 0f79c9a..6b3bf34 100644
--- a/Modules/GoogleTestAddTests.cmake
+++ b/Modules/GoogleTestAddTests.cmake
@@ -44,7 +44,7 @@ function(gtest_discover_tests_impl)
cmake_parse_arguments(
""
""
- "NO_PRETTY_TYPES;NO_PRETTY_VALUES;TEST_EXECUTABLE;TEST_WORKING_DIR;TEST_PREFIX;TEST_SUFFIX;TEST_LIST;CTEST_FILE;TEST_DISCOVERY_TIMEOUT;TEST_XML_OUTPUT_DIR"
+ "NO_PRETTY_TYPES;NO_PRETTY_VALUES;TEST_EXECUTABLE;TEST_WORKING_DIR;TEST_PREFIX;TEST_SUFFIX;TEST_LIST;CTEST_FILE;TEST_DISCOVERY_TIMEOUT;TEST_XML_OUTPUT_DIR;TEST_FILTER"
"TEST_EXTRA_ARGS;TEST_PROPERTIES;TEST_EXECUTOR"
${ARGN}
)
@@ -58,6 +58,12 @@ function(gtest_discover_tests_impl)
set(tests)
set(tests_buffer)
+ if(_TEST_FILTER)
+ set(filter "--gtest_filter=${_TEST_FILTER}")
+ else()
+ set(filter)
+ endif()
+
# Run test executable to get list of available tests
if(NOT EXISTS "${_TEST_EXECUTABLE}")
message(FATAL_ERROR
@@ -66,7 +72,7 @@ function(gtest_discover_tests_impl)
)
endif()
execute_process(
- COMMAND ${_TEST_EXECUTOR} "${_TEST_EXECUTABLE}" --gtest_list_tests
+ COMMAND ${_TEST_EXECUTOR} "${_TEST_EXECUTABLE}" --gtest_list_tests ${filter}
WORKING_DIRECTORY "${_TEST_WORKING_DIR}"
TIMEOUT ${_TEST_DISCOVERY_TIMEOUT}
OUTPUT_VARIABLE output
@@ -178,6 +184,7 @@ if(CMAKE_SCRIPT_MODE_FILE)
TEST_WORKING_DIR ${TEST_WORKING_DIR}
TEST_PREFIX ${TEST_PREFIX}
TEST_SUFFIX ${TEST_SUFFIX}
+ TEST_FILTER ${TEST_FILTER}
TEST_LIST ${TEST_LIST}
CTEST_FILE ${CTEST_FILE}
TEST_DISCOVERY_TIMEOUT ${TEST_DISCOVERY_TIMEOUT}
diff --git a/Modules/InstallRequiredSystemLibraries.cmake b/Modules/InstallRequiredSystemLibraries.cmake
index fa7b125..b2af6c9 100644
--- a/Modules/InstallRequiredSystemLibraries.cmake
+++ b/Modules/InstallRequiredSystemLibraries.cmake
@@ -80,19 +80,34 @@ foreach(LANG IN ITEMS C CXX Fortran)
set(_Intel_archdir ia32)
endif()
set(_Intel_compiler_ver ${CMAKE_${LANG}_COMPILER_VERSION})
- if(WIN32 AND EXISTS "${_Intel_basedir}/../redist/${_Intel_archdir}_win/compiler")
- get_filename_component(_Intel_redistdir "${_Intel_basedir}/../redist/${_Intel_archdir}_win/compiler" ABSOLUTE)
- elseif(WIN32)
- get_filename_component(_Intel_redistdir "${_Intel_basedir}/../../redist/${_Intel_archdir}/compiler" ABSOLUTE)
+ if(WIN32)
+ set(_Intel_possible_redistdirs
+ "${_Intel_basedir}/../redist/${_Intel_archdir}_win/compiler"
+ "${_Intel_basedir}/../../redist/${_Intel_archdir}/compiler"
+ )
elseif(APPLE)
- get_filename_component(_Intel_redistdir "${_Intel_basedir}/../../compiler/lib" ABSOLUTE)
+ set(_Intel_possible_redistdirs
+ "${_Intel_basedir}/../../compiler/lib"
+ )
else()
- if(EXISTS "${_Intel_basedir}/../lib/${_Intel_archdir}_lin")
- get_filename_component(_Intel_redistdir "${_Intel_basedir}/../lib/${_Intel_archdir}" ABSOLUTE)
- else()
- get_filename_component(_Intel_redistdir "${_Intel_basedir}/../../compiler/lib/${_Intel_archdir}_lin" ABSOLUTE)
+ set(_Intel_possible_redistdirs
+ "${_Intel_basedir}/../lib/${_Intel_archdir}"
+ "${_Intel_basedir}/../../compiler/lib/${_Intel_archdir}_lin"
+ )
+ endif()
+
+ set(_Intel_redistdir NOT-FOUND)
+ foreach(dir IN LISTS _Intel_possible_redistdirs)
+ if(EXISTS "${dir}")
+ set(_Intel_redistdir "${dir}")
+ break()
endif()
+ endforeach()
+ # Fall back to last dir
+ if(NOT _Intel_redistdir)
+ list(POP_BACK _Intel_possible_redistdirs _Intel_redistdir)
endif()
+ unset(_Intel_possible_redistdirs)
set(_IRSL_HAVE_Intel TRUE)
endif()
elseif("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "MSVC")
diff --git a/Modules/Internal/CPack/CPackDeb.cmake b/Modules/Internal/CPack/CPackDeb.cmake
index 967ad7b..c115f00 100644
--- a/Modules/Internal/CPack/CPackDeb.cmake
+++ b/Modules/Internal/CPack/CPackDeb.cmake
@@ -662,10 +662,12 @@ function(cpack_deb_prepare_package_vars)
# add ldconfig call in default postrm and postint
set(CPACK_ADD_LDCONFIG_CALL 0)
+ # all files in CPACK_DEB_SHARED_OBJECT_FILES have dot at the beginning
+ set(_LDCONF_DEFAULTS "./lib" "./usr/lib")
foreach(_FILE IN LISTS CPACK_DEB_SHARED_OBJECT_FILES)
get_filename_component(_DIR ${_FILE} DIRECTORY)
- # all files in CPACK_DEB_SHARED_OBJECT_FILES have dot at the beginning
- if(_DIR STREQUAL "./lib" OR _DIR STREQUAL "./usr/lib")
+ get_filename_component(_PARENT_DIR ${_DIR} DIRECTORY)
+ if(_DIR IN_LIST _LDCONF_DEFAULTS OR _PARENT_DIR IN_LIST _LDCONF_DEFAULTS)
set(CPACK_ADD_LDCONFIG_CALL 1)
endif()
endforeach()
diff --git a/Modules/Internal/CPack/CPackRPM.cmake b/Modules/Internal/CPack/CPackRPM.cmake
index cbd748b..c72bf6d 100644
--- a/Modules/Internal/CPack/CPackRPM.cmake
+++ b/Modules/Internal/CPack/CPackRPM.cmake
@@ -1160,6 +1160,16 @@ function(cpack_rpm_generate_package)
set(TMP_RPM_SPEC_INSTALL_POST "%define __spec_install_post ${CPACK_RPM_SPEC_INSTALL_POST}")
endif()
+ # CPACK_RPM_REQUIRES_EXCLUDE_FROM
+ # May be defined to keep the dependency generator from
+ # scanning specific files or directories for deps.
+ if(CPACK_RPM_REQUIRES_EXCLUDE_FROM)
+ if(CPACK_RPM_PACKAGE_DEBUG)
+ message("CPackRPM:Debug: User defined CPACK_RPM_REQUIRES_EXCLUDE_FROM = ${CPACK_RPM_REQUIRES_EXCLUDE_FROM}")
+ endif()
+ set(TMP_RPM_REQUIRES_EXCLUDE_FROM "%global __requires_exclude_from ${CPACK_RPM_REQUIRES_EXCLUDE_FROM}")
+ endif()
+
# 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)
# CPACK_RPM_POST_TRANS_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_POST_TRANS_SCRIPT_FILE)
@@ -1648,6 +1658,7 @@ Vendor: \@CPACK_RPM_PACKAGE_VENDOR\@
\@FILE_NAME_DEFINE\@
%define _unpackaged_files_terminate_build 0
\@TMP_RPM_SPEC_INSTALL_POST\@
+\@TMP_RPM_REQUIRES_EXCLUDE_FROM\@
\@CPACK_RPM_SPEC_MORE_DEFINE\@
\@CPACK_RPM_COMPRESSION_TYPE_TMP\@
@@ -1782,6 +1793,7 @@ Vendor: \@CPACK_RPM_PACKAGE_VENDOR\@
\@FILE_NAME_DEFINE\@
%define _unpackaged_files_terminate_build 0
\@TMP_RPM_SPEC_INSTALL_POST\@
+\@TMP_RPM_REQUIRES_EXCLUDE_FROM\@
\@CPACK_RPM_SPEC_MORE_DEFINE\@
\@CPACK_RPM_COMPRESSION_TYPE_TMP\@
diff --git a/Modules/Internal/CPack/NSIS.template.in b/Modules/Internal/CPack/NSIS.template.in
index 0a9c487..1df8a58 100644
--- a/Modules/Internal/CPack/NSIS.template.in
+++ b/Modules/Internal/CPack/NSIS.template.in
@@ -540,7 +540,7 @@ FunctionEnd
@CPACK_NSIS_INSTALLER_WELCOME_TITLE_3LINES_CODE@
!insertmacro MUI_PAGE_WELCOME
- !insertmacro MUI_PAGE_LICENSE "@CPACK_RESOURCE_FILE_LICENSE@"
+ @CPACK_NSIS_LICENSE_PAGE@
Page custom InstallOptionsPage
!insertmacro MUI_PAGE_DIRECTORY
@@ -564,21 +564,27 @@ FunctionEnd
;Languages
!insertmacro MUI_LANGUAGE "English" ;first language is the default language
+ !insertmacro MUI_LANGUAGE "Afrikaans"
!insertmacro MUI_LANGUAGE "Albanian"
!insertmacro MUI_LANGUAGE "Arabic"
+ !insertmacro MUI_LANGUAGE "Asturian"
!insertmacro MUI_LANGUAGE "Basque"
!insertmacro MUI_LANGUAGE "Belarusian"
!insertmacro MUI_LANGUAGE "Bosnian"
!insertmacro MUI_LANGUAGE "Breton"
!insertmacro MUI_LANGUAGE "Bulgarian"
+ !insertmacro MUI_LANGUAGE "Catalan"
+ !insertmacro MUI_LANGUAGE "Corsican"
!insertmacro MUI_LANGUAGE "Croatian"
!insertmacro MUI_LANGUAGE "Czech"
!insertmacro MUI_LANGUAGE "Danish"
!insertmacro MUI_LANGUAGE "Dutch"
+ !insertmacro MUI_LANGUAGE "Esperanto"
!insertmacro MUI_LANGUAGE "Estonian"
!insertmacro MUI_LANGUAGE "Farsi"
!insertmacro MUI_LANGUAGE "Finnish"
!insertmacro MUI_LANGUAGE "French"
+ !insertmacro MUI_LANGUAGE "Galician"
!insertmacro MUI_LANGUAGE "German"
!insertmacro MUI_LANGUAGE "Greek"
!insertmacro MUI_LANGUAGE "Hebrew"
@@ -597,22 +603,29 @@ FunctionEnd
!insertmacro MUI_LANGUAGE "Malay"
!insertmacro MUI_LANGUAGE "Mongolian"
!insertmacro MUI_LANGUAGE "Norwegian"
+ !insertmacro MUI_LANGUAGE "NorwegianNynorsk"
+ !insertmacro MUI_LANGUAGE "Pashto"
!insertmacro MUI_LANGUAGE "Polish"
!insertmacro MUI_LANGUAGE "Portuguese"
!insertmacro MUI_LANGUAGE "PortugueseBR"
!insertmacro MUI_LANGUAGE "Romanian"
!insertmacro MUI_LANGUAGE "Russian"
+ !insertmacro MUI_LANGUAGE "ScotsGaelic"
!insertmacro MUI_LANGUAGE "Serbian"
!insertmacro MUI_LANGUAGE "SerbianLatin"
!insertmacro MUI_LANGUAGE "SimpChinese"
!insertmacro MUI_LANGUAGE "Slovak"
!insertmacro MUI_LANGUAGE "Slovenian"
!insertmacro MUI_LANGUAGE "Spanish"
+ !insertmacro MUI_LANGUAGE "SpanishInternational"
!insertmacro MUI_LANGUAGE "Swedish"
+ !insertmacro MUI_LANGUAGE "Tatar"
!insertmacro MUI_LANGUAGE "Thai"
!insertmacro MUI_LANGUAGE "TradChinese"
!insertmacro MUI_LANGUAGE "Turkish"
!insertmacro MUI_LANGUAGE "Ukrainian"
+ !insertmacro MUI_LANGUAGE "Uzbek"
+ !insertmacro MUI_LANGUAGE "Vietnamese"
!insertmacro MUI_LANGUAGE "Welsh"
;--------------------------------
diff --git a/Modules/Internal/OSRelease/010-TryOldCentOS.cmake b/Modules/Internal/OSRelease/010-TryOldCentOS.cmake
new file mode 100644
index 0000000..ff35897
--- /dev/null
+++ b/Modules/Internal/OSRelease/010-TryOldCentOS.cmake
@@ -0,0 +1,41 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+# Author: Alex Turbov
+
+if(NOT EXISTS "${CMAKE_SYSROOT}/etc/centos-release")
+ return()
+endif()
+
+# Get the first string only
+file(
+ STRINGS "${CMAKE_SYSROOT}/etc/centos-release" CMAKE_GET_OS_RELEASE_FALLBACK_CONTENT
+ LIMIT_COUNT 1
+ )
+
+#
+# Example:
+# CentOS release 6.10 (Final)
+#
+if(CMAKE_GET_OS_RELEASE_FALLBACK_CONTENT MATCHES "CentOS release ([0-9\.]+) .*")
+
+ set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_NAME CentOS)
+ set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_PRETTY_NAME "${CMAKE_GET_OS_RELEASE_FALLBACK_CONTENT}")
+ set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_ID centos)
+ set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_ID_LIKE rhel)
+ set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION ${CMAKE_MATCH_1})
+ set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION_ID ${CMAKE_MATCH_1})
+
+ list(
+ APPEND CMAKE_GET_OS_RELEASE_FALLBACK_RESULT
+ CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_NAME
+ CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_PRETTY_NAME
+ CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_ID
+ CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_ID_LIKE
+ CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION
+ CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION_ID
+ )
+
+endif()
+
+unset(CMAKE_GET_OS_RELEASE_FALLBACK_CONTENT)
diff --git a/Modules/Internal/OSRelease/020-TryDebianVersion.cmake b/Modules/Internal/OSRelease/020-TryDebianVersion.cmake
new file mode 100644
index 0000000..8ebe19a
--- /dev/null
+++ b/Modules/Internal/OSRelease/020-TryDebianVersion.cmake
@@ -0,0 +1,38 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+# Author: Alex Turbov
+
+if(NOT EXISTS "${CMAKE_SYSROOT}/etc/debian_version")
+ return()
+endif()
+
+# Get the first string only
+file(
+ STRINGS "${CMAKE_SYSROOT}/etc/debian_version" CMAKE_GET_OS_RELEASE_FALLBACK_CONTENT
+ LIMIT_COUNT 1
+ )
+
+#
+# Example:
+# 6.0.10 # Old debian
+# wheezy/sid # Ubuntu
+#
+if(CMAKE_GET_OS_RELEASE_FALLBACK_CONTENT MATCHES "[0-9]+(\.[0-9]+)*")
+
+ set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_NAME Debian)
+ set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_ID debian)
+ set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION ${CMAKE_GET_OS_RELEASE_FALLBACK_CONTENT})
+ set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION_ID ${CMAKE_GET_OS_RELEASE_FALLBACK_CONTENT})
+
+ list(
+ APPEND CMAKE_GET_OS_RELEASE_FALLBACK_RESULT
+ CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_NAME
+ CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_ID
+ CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION
+ CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION_ID
+ )
+
+endif()
+
+unset(CMAKE_GET_OS_RELEASE_FALLBACK_CONTENT)
diff --git a/Modules/UseSWIG.cmake b/Modules/UseSWIG.cmake
index 5c8f152..9808861 100644
--- a/Modules/UseSWIG.cmake
+++ b/Modules/UseSWIG.cmake
@@ -192,12 +192,17 @@ ensure generated files will receive the required settings.
If set to ``TRUE``, implicit dependencies are generated by the ``swig`` tool
itself. This property is only meaningful for
:ref:`Makefile <Makefile Generators>`,
- :ref:`Ninja <Ninja Generators>` and :generator:`Xcode` generators. Default
- value is ``FALSE``.
+ :ref:`Ninja <Ninja Generators>`, :generator:`Xcode`, and
+ :ref:`Visual Studio <Visual Studio Generators>`
+ (:generator:`Visual Studio 11 2012` and above) generators. Default value is
+ ``FALSE``.
.. versionadded:: 3.21
Added the support of :generator:`Xcode` generator.
+ .. versionadded:: 3.22
+ Added the support of :ref:`Visual Studio Generators`.
+
``SWIG_MODULE_NAME``
Specify the actual import name of the module in the target language.
This is required if it cannot be scanned automatically from source
@@ -342,8 +347,10 @@ as well as ``SWIG``:
If set to ``TRUE``, implicit dependencies are generated by the ``swig`` tool
itself. This variable is only meaningful for
:ref:`Makefile <Makefile Generators>`,
- :ref:`Ninja <Ninja Generators>` and :generator:`Xcode` generators. Default
- value is ``FALSE``.
+ :ref:`Ninja <Ninja Generators>`, :generator:`Xcode`, and
+ :ref:`Visual Studio <Visual Studio Generators>`
+ (:generator:`Visual Studio 11 2012` and above) generators. Default value is
+ ``FALSE``.
Source file property ``USE_SWIG_DEPENDENCIES``, if not defined, will be
initialized with the value of this variable.
@@ -351,6 +358,9 @@ as well as ``SWIG``:
.. versionadded:: 3.21
Added the support of :generator:`Xcode` generator.
+ .. versionadded:: 3.22
+ Added the support of :ref:`Visual Studio Generators`.
+
#]=======================================================================]
cmake_policy(PUSH)
@@ -515,7 +525,7 @@ function(SWIG_ADD_SOURCE_TO_MODULE name outfiles infile)
endif()
set (use_swig_dependencies ${SWIG_USE_SWIG_DEPENDENCIES})
- if (CMAKE_GENERATOR MATCHES "Make|Ninja|Xcode")
+ if (CMAKE_GENERATOR MATCHES "Make|Ninja|Xcode|Visual Studio (1[1-9]|[2-9][0-9])")
get_property(use_swig_dependencies_set SOURCE "${infile}" PROPERTY USE_SWIG_DEPENDENCIES SET)
if (use_swig_dependencies_set)
get_property(use_swig_dependencies SOURCE "${infile}" PROPERTY USE_SWIG_DEPENDENCIES)
@@ -840,8 +850,9 @@ function(SWIG_ADD_LIBRARY name)
set(SWIG_SOURCE_FILE_EXTENSIONS ".i")
endif()
- if (CMAKE_GENERATOR MATCHES "Make|Ninja|Xcode")
- # For Makefiles and Ninja generators, use SWIG generated dependencies
+ if (CMAKE_GENERATOR MATCHES "Make|Ninja|Xcode|Visual Studio (1[1-9]|[2-9][0-9])")
+ # For Makefiles, Ninja, Xcode and Visual Studio generators,
+ # use SWIG generated dependencies if requested
if (NOT DEFINED SWIG_USE_SWIG_DEPENDENCIES)
set (SWIG_USE_SWIG_DEPENDENCIES OFF)
endif()
diff --git a/Modules/VTKCompatibility.cmake b/Modules/VTKCompatibility.cmake
index 1b0815e..4ee7643 100644
--- a/Modules/VTKCompatibility.cmake
+++ b/Modules/VTKCompatibility.cmake
@@ -1,6 +1,10 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
+# Not needed for "modern" VTK.
+if (EXISTS "${VTK_SOURCE_DIR}/CMake/vtkModule.cmake")
+ return ()
+endif ()
if(APPLE)
set(CMAKE_CXX_CREATE_SHARED_LIBRARY "${CMAKE_C_CREATE_SHARED_LIBRARY}")
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 9a18184..8dc44a0 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -10,36 +10,6 @@ if (NOT CMAKE_SYSTEM_NAME STREQUAL "QNX")
endif()
include(CheckIncludeFile)
-# Check if we can build support for ELF parsing.
-if(WIN32)
- set(HAVE_ELF_H 0)
-elseif(CMAKE_CXX_PLATFORM_ID MATCHES "OpenBSD")
- CHECK_INCLUDE_FILES("stdint.h;elf_abi.h" HAVE_ELF_H)
-else()
- CHECK_INCLUDE_FILE("elf.h" HAVE_ELF_H)
-endif()
-if(HAVE_ELF_H)
- set(CMake_USE_ELF_PARSER 1)
-elseif(HAIKU)
- # On Haiku, we need to include elf32.h from the private headers
- set(CMake_HAIKU_INCLUDE_DIRS
- /boot/system/develop/headers/private/system
- /boot/system/develop/headers/private/system/arch/x86
- )
-
- set(CMAKE_REQUIRED_INCLUDES ${CMake_HAIKU_INCLUDE_DIRS})
- CHECK_INCLUDE_FILE("elf32.h" HAVE_ELF32_H)
- unset(CMAKE_REQUIRED_INCLUDES)
-
- if(HAVE_ELF32_H)
- set(CMake_USE_ELF_PARSER 1)
- else()
- unset(CMake_HAIKU_INCLUDE_DIRS)
- set(CMake_USE_ELF_PARSER)
- endif()
-else()
- set(CMake_USE_ELF_PARSER)
-endif()
if(NOT CMake_DEFAULT_RECURSION_LIMIT)
if(DEFINED ENV{DASHBOARD_TEST_FROM_CTEST})
@@ -111,11 +81,6 @@ include_directories(
${CMake_HAIKU_INCLUDE_DIRS}
)
-# Check if we can build the ELF parser.
-if(CMake_USE_ELF_PARSER)
- set(ELF_SRCS cmELF.h cmELF.cxx)
-endif()
-
# Check if we can build the Mach-O parser.
if(CMake_USE_MACH_PARSER)
set(MACH_SRCS cmMachO.h cmMachO.cxx)
@@ -245,7 +210,8 @@ set(SRCS
cmDocumentationSection.cxx
cmDynamicLoader.cxx
cmDynamicLoader.h
- ${ELF_SRCS}
+ cmELF.h
+ cmELF.cxx
cmExprParserHelper.cxx
cmExportBuildAndroidMKGenerator.h
cmExportBuildAndroidMKGenerator.cxx
@@ -415,6 +381,7 @@ set(SRCS
cmProcessOutput.h
cmProcessTools.cxx
cmProcessTools.h
+ cmProperty.cxx
cmProperty.h
cmPropertyDefinition.cxx
cmPropertyDefinition.h
@@ -834,7 +801,7 @@ if (WIN32)
endif ()
# Watcom support
-if(WIN32 OR CMAKE_SYSTEM_NAME STREQUAL "Linux")
+if(WIN32 OR CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set_property(SOURCE cmake.cxx APPEND PROPERTY COMPILE_DEFINITIONS CMAKE_USE_WMAKE)
list(APPEND SRCS
cmGlobalWatcomWMakeGenerator.cxx
@@ -994,6 +961,7 @@ set(CTEST_SRCS cmCTest.cxx
CTest/cmCTestSubmitHandler.cxx
CTest/cmCTestTestCommand.cxx
CTest/cmCTestTestHandler.cxx
+ CTest/cmCTestTestMeasurementXMLParser.cxx
CTest/cmCTestUpdateCommand.cxx
CTest/cmCTestUpdateHandler.cxx
CTest/cmCTestUploadCommand.cxx
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 3ed80c3..97b3948 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 21)
-set(CMake_VERSION_PATCH 2)
+set(CMake_VERSION_PATCH 20210903)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx
index 006d66d..829cef4 100644
--- a/Source/CPack/cmCPackDebGenerator.cxx
+++ b/Source/CPack/cmCPackDebGenerator.cxx
@@ -2,11 +2,12 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCPackDebGenerator.h"
-#include <cstdlib>
+#include <algorithm>
#include <cstring>
#include <map>
#include <ostream>
#include <set>
+#include <stdexcept>
#include <utility>
#include "cmsys/Glob.hxx"
@@ -54,7 +55,7 @@ private:
const std::string TopLevelDir;
const std::string TemporaryDir;
const char* DebianArchiveType;
- int NumThreads;
+ long NumThreads;
const std::map<std::string, std::string> ControlValues;
const bool GenShLibs;
const std::string ShLibsFilename;
@@ -98,19 +99,22 @@ DebGenerator::DebGenerator(
debianCompressionType = "gzip";
}
- if (!strcmp(debianCompressionType, "lzma")) {
+ if (!std::strcmp(debianCompressionType, "lzma")) {
this->CompressionSuffix = ".lzma";
this->TarCompressionType = cmArchiveWrite::CompressLZMA;
- } else if (!strcmp(debianCompressionType, "xz")) {
+ } else if (!std::strcmp(debianCompressionType, "xz")) {
this->CompressionSuffix = ".xz";
this->TarCompressionType = cmArchiveWrite::CompressXZ;
- } else if (!strcmp(debianCompressionType, "bzip2")) {
+ } else if (!std::strcmp(debianCompressionType, "bzip2")) {
this->CompressionSuffix = ".bz2";
this->TarCompressionType = cmArchiveWrite::CompressBZip2;
- } else if (!strcmp(debianCompressionType, "gzip")) {
+ } else if (!std::strcmp(debianCompressionType, "gzip")) {
this->CompressionSuffix = ".gz";
this->TarCompressionType = cmArchiveWrite::CompressGZip;
- } else if (!strcmp(debianCompressionType, "none")) {
+ } else if (!std::strcmp(debianCompressionType, "zstd")) {
+ this->CompressionSuffix = ".zst";
+ this->TarCompressionType = cmArchiveWrite::CompressZstd;
+ } else if (!std::strcmp(debianCompressionType, "none")) {
this->CompressionSuffix.clear();
this->TarCompressionType = cmArchiveWrite::CompressNone;
} else {
@@ -119,16 +123,15 @@ DebGenerator::DebGenerator(
<< debianCompressionType << std::endl);
}
- if (numThreads == nullptr) {
- numThreads = "1";
- }
-
- char* endptr;
- this->NumThreads = static_cast<int>(strtol(numThreads, &endptr, 10));
- if (numThreads != endptr && *endptr != '\0') {
- cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Unrecognized number of threads: " << numThreads
- << std::endl);
+ if (numThreads != nullptr) {
+ if (!cmStrToLong(numThreads, &this->NumThreads)) {
+ this->NumThreads = 1;
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Unrecognized number of threads: " << numThreads
+ << std::endl);
+ }
+ } else {
+ this->NumThreads = 1;
}
}
@@ -187,8 +190,15 @@ bool DebGenerator::generateDataTar() const
return false;
}
cmArchiveWrite data_tar(fileStream_data_tar, this->TarCompressionType,
- this->DebianArchiveType, 0, this->NumThreads);
- data_tar.Open();
+ this->DebianArchiveType, 0,
+ static_cast<int>(this->NumThreads));
+ if (!data_tar.Open()) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error opening the archive \""
+ << filename_data_tar
+ << "\", ERROR = " << data_tar.GetError() << std::endl);
+ return false;
+ }
// uid/gid should be the one of the root user, and this root user has
// always uid/gid equal to 0.
@@ -248,11 +258,15 @@ bool DebGenerator::generateDataTar() const
// do not recurse because the loop will do it
if (!data_tar.Add(file, topLevelLength, ".", false)) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Problem adding file to tar:"
- << std::endl
- << "#top level directory: " << this->WorkDir << std::endl
- << "#file: " << file << std::endl
- << "#error:" << data_tar.GetError() << std::endl);
+ "Problem adding file to tar:\n"
+ "#top level directory: "
+ << this->WorkDir
+ << "\n"
+ "#file: "
+ << file
+ << "\n"
+ "#error:"
+ << data_tar.GetError() << std::endl);
return false;
}
}
@@ -309,7 +323,13 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const
cmArchiveWrite control_tar(fileStream_control_tar,
cmArchiveWrite::CompressGZip,
this->DebianArchiveType);
- control_tar.Open();
+ if (!control_tar.Open()) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error opening the archive \""
+ << filename_control_tar
+ << "\", ERROR = " << control_tar.GetError() << std::endl);
+ return false;
+ }
// sets permissions and uid/gid for the files
control_tar.SetUIDAndGID(0u, 0u);
@@ -334,11 +354,13 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const
!control_tar.Add(this->WorkDir + "/control", this->WorkDir.length(),
".")) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Error adding file to tar:"
- << std::endl
- << "#top level directory: " << this->WorkDir << std::endl
- << "#file: \"control\" or \"md5sums\"" << std::endl
- << "#error:" << control_tar.GetError() << std::endl);
+ "Error adding file to tar:\n"
+ "#top level directory: "
+ << this->WorkDir
+ << "\n"
+ "#file: \"control\" or \"md5sums\"\n"
+ "#error:"
+ << control_tar.GetError() << std::endl);
return false;
}
@@ -346,11 +368,13 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const
if (this->GenShLibs) {
if (!control_tar.Add(this->ShLibsFilename, this->WorkDir.length(), ".")) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Error adding file to tar:"
- << std::endl
- << "#top level directory: " << this->WorkDir << std::endl
- << "#file: \"shlibs\"" << std::endl
- << "#error:" << control_tar.GetError() << std::endl);
+ "Error adding file to tar:\n"
+ "#top level directory: "
+ << this->WorkDir
+ << "\n"
+ "#file: \"shlibs\"\n"
+ "#error:"
+ << control_tar.GetError() << std::endl);
return false;
}
}
@@ -360,11 +384,13 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const
control_tar.SetPermissions(permission755);
if (!control_tar.Add(this->PostInst, this->WorkDir.length(), ".")) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Error adding file to tar:"
- << std::endl
- << "#top level directory: " << this->WorkDir << std::endl
- << "#file: \"postinst\"" << std::endl
- << "#error:" << control_tar.GetError() << std::endl);
+ "Error adding file to tar:\n"
+ "#top level directory: "
+ << this->WorkDir
+ << "\n"
+ "#file: \"postinst\"\n"
+ "#error:"
+ << control_tar.GetError() << std::endl);
return false;
}
control_tar.SetPermissions(permission644);
@@ -374,11 +400,13 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const
control_tar.SetPermissions(permission755);
if (!control_tar.Add(this->PostRm, this->WorkDir.length(), ".")) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Error adding file to tar:"
- << std::endl
- << "#top level directory: " << this->WorkDir << std::endl
- << "#file: \"postinst\"" << std::endl
- << "#error:" << control_tar.GetError() << std::endl);
+ "Error adding file to tar:\n"
+ "#top level directory: "
+ << this->WorkDir
+ << "\n"
+ "#file: \"postinst\"\n"
+ "#error:"
+ << control_tar.GetError() << std::endl);
return false;
}
control_tar.SetPermissions(permission644);
@@ -412,11 +440,12 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const
// if we can copy the file, it means it does exist, let's add it:
if (!cmsys::SystemTools::FileExists(i)) {
cmCPackLogger(cmCPackLog::LOG_WARNING,
- "Adding file to tar:" << std::endl
- << "#top level directory: "
- << this->WorkDir << std::endl
- << "#missing file: " << i
- << std::endl);
+ "Adding file to tar:\n"
+ "#top level directory: "
+ << this->WorkDir
+ << "\n"
+ "#missing file: "
+ << i << std::endl);
}
if (cmsys::SystemTools::CopyFileIfDifferent(i, localcopy)) {
@@ -440,7 +469,13 @@ bool DebGenerator::generateDeb() const
cmGeneratedFileStream debStream;
debStream.Open(outputPath, false, true);
cmArchiveWrite deb(debStream, cmArchiveWrite::CompressNone, "arbsd");
- deb.Open();
+ if (!deb.Open()) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Error opening the archive \""
+ << outputPath << "\", ERROR = " << deb.GetError()
+ << std::endl);
+ return false;
+ }
// uid/gid should be the one of the root user, and this root user has
// always uid/gid equal to 0.
@@ -451,17 +486,37 @@ bool DebGenerator::generateDeb() const
!deb.Add(tlDir + "control.tar.gz", tlDir.length()) ||
!deb.Add(tlDir + "data.tar" + this->CompressionSuffix, tlDir.length())) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
- "Error creating debian package:"
- << std::endl
- << "#top level directory: " << this->TopLevelDir
- << std::endl
- << "#file: " << this->OutputName << std::endl
- << "#error:" << deb.GetError() << std::endl);
+ "Error creating debian package:\n"
+ "#top level directory: "
+ << this->TopLevelDir
+ << "\n"
+ "#file: "
+ << this->OutputName
+ << "\n"
+ "#error:"
+ << deb.GetError() << std::endl);
return false;
}
return true;
}
+std::vector<std::string> findFilesIn(const std::string& path)
+{
+ cmsys::Glob gl;
+ std::string findExpr = path + "/*";
+ gl.RecurseOn();
+ gl.SetRecurseListDirs(true);
+ gl.SetRecurseThroughSymlinks(false);
+ if (!gl.FindFiles(findExpr)) {
+ throw std::runtime_error(
+ "Cannot find any files in the installed directory");
+ }
+ std::vector<std::string> files{ gl.GetFiles() };
+ // Sort files so that they have a reproducible order
+ std::sort(files.begin(), files.end());
+ return files;
+}
+
} // end anonymous namespace
cmCPackDebGenerator::cmCPackDebGenerator() = default;
@@ -480,7 +535,6 @@ int cmCPackDebGenerator::InitializeInternal()
int cmCPackDebGenerator::PackageOnePack(std::string const& initialTopLevel,
std::string const& packageName)
{
- int retval = 1;
// Begin the archive for this pack
std::string localToplevel(initialTopLevel);
std::string packageFileName(
@@ -507,101 +561,48 @@ int cmCPackDebGenerator::PackageOnePack(std::string const& initialTopLevel,
if (!this->ReadListFile("Internal/CPack/CPackDeb.cmake")) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Error while execution CPackDeb.cmake" << std::endl);
- retval = 0;
- return retval;
- }
-
- { // Isolate globbing of binaries vs. dbgsyms
- cmsys::Glob gl;
- std::string findExpr(this->GetOption("GEN_WDIR"));
- 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"
- << std::endl);
- return 0;
- }
- this->packageFiles = gl.GetFiles();
- }
-
- int res = this->createDeb();
- if (res != 1) {
- retval = 0;
- }
- // add the generated package to package file names list
- packageFileName = cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), '/',
- this->GetOption("GEN_CPACK_OUTPUT_FILE_NAME"));
- this->packageFileNames.push_back(std::move(packageFileName));
-
- if (this->IsOn("GEN_CPACK_DEBIAN_DEBUGINFO_PACKAGE") &&
- this->GetOption("GEN_DBGSYMDIR")) {
- cmsys::Glob gl;
- std::string findExpr(this->GetOption("GEN_DBGSYMDIR"));
- 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"
- << std::endl);
- return 0;
- }
- this->packageFiles = gl.GetFiles();
-
- res = this->createDbgsymDDeb();
- if (res != 1) {
- retval = 0;
- }
- // add the generated package to package file names list
- packageFileName =
- cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), '/',
- this->GetOption("GEN_CPACK_DBGSYM_OUTPUT_FILE_NAME"));
- this->packageFileNames.push_back(std::move(packageFileName));
+ return 0;
}
- return retval;
+ return this->createDebPackages();
}
int cmCPackDebGenerator::PackageComponents(bool ignoreGroup)
{
- int retval = 1;
- /* Reset package file name list it will be populated during the
- * component packaging run*/
+ // Reset package file name list it will be populated during the
+ // component packaging run
this->packageFileNames.clear();
std::string initialTopLevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY"));
+ int retval = 1;
// The default behavior is to have one package by component group
// unless CPACK_COMPONENTS_IGNORE_GROUP is specified.
- if (!ignoreGroup) {
- for (auto const& compG : this->ComponentGroups) {
- cmCPackLogger(cmCPackLog::LOG_VERBOSE,
- "Packaging component group: " << compG.first << std::endl);
- // Begin the archive for this group
- retval &= this->PackageOnePack(initialTopLevel, compG.first);
- }
- // Handle Orphan components (components not belonging to any groups)
+ if (ignoreGroup) {
+ // CPACK_COMPONENTS_IGNORE_GROUPS is set
+ // We build 1 package per component
for (auto const& comp : this->Components) {
- // Does the component belong to a group?
- if (comp.second.Group == nullptr) {
- cmCPackLogger(
- cmCPackLog::LOG_VERBOSE,
- "Component <"
- << comp.second.Name
- << "> does not belong to any group, package it separately."
- << std::endl);
- // Begin the archive for this orphan component
- retval &= this->PackageOnePack(initialTopLevel, comp.first);
- }
+ retval &= this->PackageOnePack(initialTopLevel, comp.first);
}
+ return retval;
}
- // CPACK_COMPONENTS_IGNORE_GROUPS is set
- // We build 1 package per component
- else {
- for (auto const& comp : this->Components) {
+
+ for (auto const& compG : this->ComponentGroups) {
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE,
+ "Packaging component group: " << compG.first << std::endl);
+ // Begin the archive for this group
+ retval &= this->PackageOnePack(initialTopLevel, compG.first);
+ }
+ // Handle Orphan components (components not belonging to any groups)
+ for (auto const& comp : this->Components) {
+ // Does the component belong to a group?
+ if (comp.second.Group == nullptr) {
+ cmCPackLogger(
+ cmCPackLog::LOG_VERBOSE,
+ "Component <"
+ << comp.second.Name
+ << "> does not belong to any group, package it separately."
+ << std::endl);
+ // Begin the archive for this orphan component
retval &= this->PackageOnePack(initialTopLevel, comp.first);
}
}
@@ -612,7 +613,6 @@ int cmCPackDebGenerator::PackageComponents(bool ignoreGroup)
int cmCPackDebGenerator::PackageComponentsAllInOne(
const std::string& compInstDirName)
{
- int retval = 1;
/* Reset package file name list it will be populated during the
* component packaging run*/
this->packageFileNames.clear();
@@ -655,33 +655,10 @@ int cmCPackDebGenerator::PackageComponentsAllInOne(
if (!this->ReadListFile("Internal/CPack/CPackDeb.cmake")) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"Error while execution CPackDeb.cmake" << std::endl);
- retval = 0;
- return retval;
- }
-
- cmsys::Glob gl;
- std::string findExpr(this->GetOption("GEN_WDIR"));
- 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"
- << std::endl);
return 0;
}
- this->packageFiles = gl.GetFiles();
- int res = this->createDeb();
- if (res != 1) {
- retval = 0;
- }
- // add the generated package to package file names list
- packageFileName = cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), '/',
- this->GetOption("GEN_CPACK_OUTPUT_FILE_NAME"));
- this->packageFileNames.push_back(std::move(packageFileName));
- return retval;
+ return this->createDebPackages();
}
int cmCPackDebGenerator::PackageFiles()
@@ -705,7 +682,40 @@ int cmCPackDebGenerator::PackageFiles()
return this->PackageComponentsAllInOne("");
}
-int cmCPackDebGenerator::createDeb()
+bool cmCPackDebGenerator::createDebPackages()
+{
+ auto make_package = [this](const char* const path,
+ const char* const output_var,
+ bool (cmCPackDebGenerator::*creator)()) -> bool {
+ try {
+ this->packageFiles = findFilesIn(path);
+ } catch (const std::runtime_error& ex) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, ex.what() << std::endl);
+ return false;
+ }
+
+ if ((this->*creator)()) {
+ // add the generated package to package file names list
+ this->packageFileNames.emplace_back(
+ cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), '/',
+ this->GetOption(output_var)));
+ return true;
+ }
+ return false;
+ };
+ bool retval =
+ make_package(this->GetOption("GEN_WDIR"), "GEN_CPACK_OUTPUT_FILE_NAME",
+ &cmCPackDebGenerator::createDeb);
+ const char* const dbgsymdir_path = this->GetOption("GEN_DBGSYMDIR");
+ if (this->IsOn("GEN_CPACK_DEBIAN_DEBUGINFO_PACKAGE") && dbgsymdir_path) {
+ retval = make_package(dbgsymdir_path, "GEN_CPACK_DBGSYM_OUTPUT_FILE_NAME",
+ &cmCPackDebGenerator::createDbgsymDDeb) &&
+ retval;
+ }
+ return int(retval);
+}
+
+bool cmCPackDebGenerator::createDeb()
{
std::map<std::string, std::string> controlValues;
@@ -829,13 +839,10 @@ int cmCPackDebGenerator::createDeb()
this->IsSet("GEN_CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION"),
this->packageFiles);
- if (!gen.generate()) {
- return 0;
- }
- return 1;
+ return gen.generate();
}
-int cmCPackDebGenerator::createDbgsymDDeb()
+bool cmCPackDebGenerator::createDbgsymDDeb()
{
// Packages containing debug symbols follow the same structure as .debs
// but have different metadata and content.
@@ -875,7 +882,6 @@ int cmCPackDebGenerator::createDbgsymDDeb()
DebGenerator gen(
this->Logger, this->GetOption("GEN_CPACK_DBGSYM_OUTPUT_FILE_NAME"),
this->GetOption("GEN_DBGSYMDIR"),
-
this->GetOption("CPACK_TOPLEVEL_DIRECTORY"),
this->GetOption("CPACK_TEMPORARY_DIRECTORY"),
this->GetOption("GEN_CPACK_DEBIAN_COMPRESSION_TYPE"),
@@ -885,10 +891,7 @@ int cmCPackDebGenerator::createDbgsymDDeb()
this->IsSet("GEN_CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION"),
this->packageFiles);
- if (!gen.generate()) {
- return 0;
- }
- return 1;
+ return gen.generate();
}
bool cmCPackDebGenerator::SupportsComponentInstallation() const
diff --git a/Source/CPack/cmCPackDebGenerator.h b/Source/CPack/cmCPackDebGenerator.h
index ee8f39a..61a6616 100644
--- a/Source/CPack/cmCPackDebGenerator.h
+++ b/Source/CPack/cmCPackDebGenerator.h
@@ -63,8 +63,9 @@ protected:
const std::string& componentName) override;
private:
- int createDeb();
- int createDbgsymDDeb();
+ bool createDebPackages();
+ bool createDeb();
+ bool createDbgsymDDeb();
std::vector<std::string> packageFiles;
};
diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx
index 6bd0d1b..395b1df 100644
--- a/Source/CPack/cmCPackNSISGenerator.cxx
+++ b/Source/CPack/cmCPackNSISGenerator.cxx
@@ -235,6 +235,13 @@ int cmCPackNSISGenerator::PackageFiles()
brandingTextCode.c_str());
}
+ if (!this->IsSet("CPACK_NSIS_IGNORE_LICENSE_PAGE")) {
+ std::string licenceCode =
+ cmStrCat("!insertmacro MUI_PAGE_LICENSE \"",
+ this->GetOption("CPACK_RESOURCE_FILE_LICENSE"), "\"\n");
+ this->SetOptionIfNotSet("CPACK_NSIS_LICENSE_PAGE", licenceCode.c_str());
+ }
+
// Setup all of the component sections
if (this->Components.empty()) {
this->SetOptionIfNotSet("CPACK_NSIS_INSTALLATION_TYPES", "");
@@ -487,12 +494,12 @@ int cmCPackNSISGenerator::InitializeInternal()
}
if (versionRex.find(output)) {
double nsisVersion = atof(versionRex.match(1).c_str());
- double minNSISVersion = 3.0;
+ double minNSISVersion = 3.03;
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"NSIS Version: " << nsisVersion << std::endl);
if (nsisVersion < minNSISVersion) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
- "CPack requires NSIS Version 3.0 or greater. "
+ "CPack requires NSIS Version 3.03 or greater. "
"NSIS found on the system was: "
<< nsisVersion << std::endl);
return 0;
diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx
index 125d003..6bb8e79 100644
--- a/Source/CTest/cmCTestMemCheckHandler.cxx
+++ b/Source/CTest/cmCTestMemCheckHandler.cxx
@@ -305,7 +305,7 @@ int cmCTestMemCheckHandler::GetDefectCount() const
return this->DefectCount;
}
-void cmCTestMemCheckHandler::GenerateDartOutput(cmXMLWriter& xml)
+void cmCTestMemCheckHandler::GenerateCTestXML(cmXMLWriter& xml)
{
if (!this->CTest->GetProduceXML()) {
return;
diff --git a/Source/CTest/cmCTestMemCheckHandler.h b/Source/CTest/cmCTestMemCheckHandler.h
index b200c43..a63a24d 100644
--- a/Source/CTest/cmCTestMemCheckHandler.h
+++ b/Source/CTest/cmCTestMemCheckHandler.h
@@ -119,9 +119,9 @@ private:
bool InitializeMemoryChecking();
/**
- * Generate the Dart compatible output
+ * Generate CTest DynamicAnalysis.xml files
*/
- void GenerateDartOutput(cmXMLWriter& xml) override;
+ void GenerateCTestXML(cmXMLWriter& xml) override;
std::vector<std::string> CustomPreMemCheck;
std::vector<std::string> CustomPostMemCheck;
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx
index 86a8e00..d90c4a6 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.cxx
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -1026,6 +1026,11 @@ static Json::Value DumpCTestProperties(
properties.append(DumpCTestProperty(
"ENVIRONMENT", DumpToJsonArray(testProperties.Environment)));
}
+ if (!testProperties.EnvironmentModification.empty()) {
+ properties.append(DumpCTestProperty(
+ "ENVIRONMENT_MODIFICATION",
+ DumpToJsonArray(testProperties.EnvironmentModification)));
+ }
if (!testProperties.ErrorRegularExpressions.empty()) {
properties.append(DumpCTestProperty(
"FAIL_REGULAR_EXPRESSION",
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index a892113..20f0ed3 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -2,17 +2,22 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCTestRunTest.h"
+#include <algorithm>
#include <chrono>
#include <cstddef> // IWYU pragma: keep
#include <cstdint>
#include <cstdio>
#include <cstring>
+#include <functional>
#include <iomanip>
#include <ratio>
#include <sstream>
#include <utility>
#include <cm/memory>
+#include <cm/optional>
+#include <cm/string_view>
+#include <cmext/string_view>
#include "cmsys/RegularExpression.hxx"
@@ -44,7 +49,9 @@ void cmCTestRunTest::CheckOutput(std::string const& line)
// Check for special CTest XML tags in this line of output.
// If any are found, this line is excluded from ProcessOutput.
if (!line.empty() && line.find("<CTest") != std::string::npos) {
+ bool ctest_tag_found = false;
if (this->TestHandler->CustomCompletionStatusRegex.find(line)) {
+ ctest_tag_found = true;
this->TestResult.CustomCompletionStatus =
this->TestHandler->CustomCompletionStatusRegex.match(1);
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
@@ -52,6 +59,20 @@ void cmCTestRunTest::CheckOutput(std::string const& line)
<< "Test Details changed to '"
<< this->TestResult.CustomCompletionStatus
<< "'" << std::endl);
+ } else if (this->TestHandler->CustomLabelRegex.find(line)) {
+ ctest_tag_found = true;
+ auto label = this->TestHandler->CustomLabelRegex.match(1);
+ auto& labels = this->TestProperties->Labels;
+ if (std::find(labels.begin(), labels.end(), label) == labels.end()) {
+ labels.push_back(label);
+ std::sort(labels.begin(), labels.end());
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ this->GetIndex()
+ << ": "
+ << "Test Label added: '" << label << "'" << std::endl);
+ }
+ }
+ if (ctest_tag_found) {
return;
}
}
@@ -245,7 +266,7 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
*this->TestHandler->LogFile << "Test time = " << buf << std::endl;
}
- this->DartProcessing();
+ this->ParseOutputForMeasurements();
// if this is doing MemCheck then all the output needs to be put into
// Output since that is what is parsed by cmCTestMemCheckHandler
@@ -623,6 +644,7 @@ bool cmCTestRunTest::StartTest(size_t completed, size_t total)
return this->ForkProcess(timeout, this->TestProperties->ExplicitTimeout,
&this->TestProperties->Environment,
+ &this->TestProperties->EnvironmentModification,
&this->TestProperties->Affinity);
}
@@ -679,28 +701,45 @@ void cmCTestRunTest::ComputeArguments()
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
this->Index << ": " << env << std::endl);
}
+ if (!this->TestProperties->EnvironmentModification.empty()) {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ this->Index << ": "
+ << "Environment variable modifications: "
+ << std::endl);
+ }
+ for (std::string const& envmod :
+ this->TestProperties->EnvironmentModification) {
+ cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+ this->Index << ": " << envmod << std::endl);
+ }
}
-void cmCTestRunTest::DartProcessing()
+void cmCTestRunTest::ParseOutputForMeasurements()
{
if (!this->ProcessOutput.empty() &&
- this->ProcessOutput.find("<DartMeasurement") != std::string::npos) {
- if (this->TestHandler->DartStuff.find(this->ProcessOutput)) {
- this->TestResult.DartString = this->TestHandler->DartStuff.match(1);
+ (this->ProcessOutput.find("<DartMeasurement") != std::string::npos ||
+ this->ProcessOutput.find("<CTestMeasurement") != std::string::npos)) {
+ if (this->TestHandler->AllTestMeasurementsRegex.find(
+ this->ProcessOutput)) {
+ this->TestResult.TestMeasurementsOutput =
+ this->TestHandler->AllTestMeasurementsRegex.match(1);
// keep searching and replacing until none are left
- while (this->TestHandler->DartStuff1.find(this->ProcessOutput)) {
+ while (this->TestHandler->SingleTestMeasurementRegex.find(
+ this->ProcessOutput)) {
// replace the exact match for the string
cmSystemTools::ReplaceString(
- this->ProcessOutput, this->TestHandler->DartStuff1.match(1).c_str(),
- "");
+ this->ProcessOutput,
+ this->TestHandler->SingleTestMeasurementRegex.match(1).c_str(), "");
}
}
}
}
-bool cmCTestRunTest::ForkProcess(cmDuration testTimeOut, bool explicitTimeout,
- std::vector<std::string>* environment,
- std::vector<size_t>* affinity)
+bool cmCTestRunTest::ForkProcess(
+ cmDuration testTimeOut, bool explicitTimeout,
+ std::vector<std::string>* environment,
+ std::vector<std::string>* environment_modification,
+ std::vector<size_t>* affinity)
{
this->TestProcess->SetId(this->Index);
this->TestProcess->SetWorkingDirectory(this->TestProperties->Directory);
@@ -749,6 +788,127 @@ bool cmCTestRunTest::ForkProcess(cmDuration testTimeOut, bool explicitTimeout,
}
}
+ if (environment_modification && !environment_modification->empty()) {
+ std::map<std::string, cm::optional<std::string>> env_application;
+
+#ifdef _WIN32
+ char path_sep = ';';
+#else
+ char path_sep = ':';
+#endif
+
+ auto apply_diff =
+ [&env_application](const std::string& name,
+ std::function<void(std::string&)> const& apply) {
+ auto entry = env_application.find(name);
+ std::string output;
+ if (entry != env_application.end() && entry->second) {
+ output = *entry->second;
+ }
+ apply(output);
+ entry->second = output;
+ };
+
+ bool err_occurred = false;
+
+ for (auto const& envmod : *environment_modification) {
+ // Split on `=`
+ auto const eq_loc = envmod.find_first_of('=');
+ if (eq_loc == std::string::npos) {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Error: Missing `=` after the variable name in: "
+ << envmod << std::endl);
+ err_occurred = true;
+ continue;
+ }
+ auto const name = envmod.substr(0, eq_loc);
+
+ // Split value on `:`
+ auto const op_value_start = eq_loc + 1;
+ auto const colon_loc = envmod.find_first_of(':', op_value_start);
+ if (colon_loc == std::string::npos) {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Error: Missing `:` after the operation in: " << envmod
+ << std::endl);
+ err_occurred = true;
+ continue;
+ }
+ auto const op =
+ envmod.substr(op_value_start, colon_loc - op_value_start);
+
+ auto const value_start = colon_loc + 1;
+ auto const value = envmod.substr(value_start);
+
+ // Determine what to do with the operation.
+ if (op == "reset"_s) {
+ auto entry = env_application.find(name);
+ if (entry != env_application.end()) {
+ env_application.erase(entry);
+ }
+ } else if (op == "set"_s) {
+ env_application[name] = value;
+ } else if (op == "unset"_s) {
+ env_application[name] = {};
+ } else if (op == "string_append"_s) {
+ apply_diff(name, [&value](std::string& output) { output += value; });
+ } else if (op == "string_prepend"_s) {
+ apply_diff(name,
+ [&value](std::string& output) { output.insert(0, value); });
+ } else if (op == "path_list_append"_s) {
+ apply_diff(name, [&value, path_sep](std::string& output) {
+ if (!output.empty()) {
+ output += path_sep;
+ }
+ output += value;
+ });
+ } else if (op == "path_list_prepend"_s) {
+ apply_diff(name, [&value, path_sep](std::string& output) {
+ if (!output.empty()) {
+ output.insert(output.begin(), path_sep);
+ }
+ output.insert(0, value);
+ });
+ } else if (op == "cmake_list_append"_s) {
+ apply_diff(name, [&value](std::string& output) {
+ if (!output.empty()) {
+ output += ';';
+ }
+ output += value;
+ });
+ } else if (op == "cmake_list_prepend"_s) {
+ apply_diff(name, [&value](std::string& output) {
+ if (!output.empty()) {
+ output.insert(output.begin(), ';');
+ }
+ output.insert(0, value);
+ });
+ } else {
+ cmCTestLog(this->CTest, ERROR_MESSAGE,
+ "Error: Unrecognized environment manipulation argument: "
+ << op << std::endl);
+ err_occurred = true;
+ continue;
+ }
+ }
+
+ if (err_occurred) {
+ return false;
+ }
+
+ for (auto const& env_apply : env_application) {
+ if (env_apply.second) {
+ auto const env_update =
+ cmStrCat(env_apply.first, '=', *env_apply.second);
+ cmSystemTools::PutEnv(env_update);
+ envMeasurement << env_update << std::endl;
+ } else {
+ cmSystemTools::UnsetEnv(env_apply.first.c_str());
+ // Signify that this variable is being actively unset
+ envMeasurement << "#" << env_apply.first << "=" << std::endl;
+ }
+ }
+ }
+
if (this->UseAllocatedResources) {
std::vector<std::string> envLog;
this->SetupResourcesEnvironment(&envLog);
diff --git a/Source/CTest/cmCTestRunTest.h b/Source/CTest/cmCTestRunTest.h
index 863ac1b..2082156 100644
--- a/Source/CTest/cmCTestRunTest.h
+++ b/Source/CTest/cmCTestRunTest.h
@@ -109,10 +109,11 @@ public:
private:
bool NeedsToRepeat();
- void DartProcessing();
+ void ParseOutputForMeasurements();
void ExeNotFound(std::string exe);
bool ForkProcess(cmDuration testTimeOut, bool explicitTimeout,
std::vector<std::string>* environment,
+ std::vector<std::string>* environment_modification,
std::vector<size_t>* affinity);
void WriteLogOutputTop(size_t completed, size_t total);
// Run post processing of the process output for MemCheck
diff --git a/Source/CTest/cmCTestStartCommand.cxx b/Source/CTest/cmCTestStartCommand.cxx
index 53e1b2f..a8c2403 100644
--- a/Source/CTest/cmCTestStartCommand.cxx
+++ b/Source/CTest/cmCTestStartCommand.cxx
@@ -30,8 +30,8 @@ bool cmCTestStartCommand::InitialPass(std::vector<std::string> const& args,
size_t cnt = 0;
const char* smodel = nullptr;
- const std::string* src_dir = nullptr;
- const std::string* bld_dir = nullptr;
+ cmProp src_dir;
+ cmProp bld_dir;
while (cnt < args.size()) {
if (args[cnt] == "GROUP" || args[cnt] == "TRACK") {
@@ -55,10 +55,10 @@ bool cmCTestStartCommand::InitialPass(std::vector<std::string> const& args,
smodel = args[cnt].c_str();
cnt++;
} else if (!src_dir) {
- src_dir = &args[cnt];
+ src_dir = cmProp(args[cnt]);
cnt++;
} else if (!bld_dir) {
- bld_dir = &args[cnt];
+ bld_dir = cmProp(args[cnt]);
cnt++;
} else {
this->SetError("Too many arguments");
diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx
index bdba0e5..7aeb288 100644
--- a/Source/CTest/cmCTestSubmitCommand.cxx
+++ b/Source/CTest/cmCTestSubmitCommand.cxx
@@ -36,8 +36,8 @@ std::unique_ptr<cmCommand> cmCTestSubmitCommand::Clone()
cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler()
{
- const std::string* submitURL = !this->SubmitURL.empty()
- ? &this->SubmitURL
+ cmProp submitURL = !this->SubmitURL.empty()
+ ? cmProp(this->SubmitURL)
: this->Makefile->GetDefinition("CTEST_SUBMIT_URL");
if (submitURL) {
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index 730ec0f..1157d10 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -32,6 +32,7 @@
#include "cmCTest.h"
#include "cmCTestMultiProcessHandler.h"
#include "cmCTestResourceGroupsLexerHelper.h"
+#include "cmCTestTestMeasurementXMLParser.h"
#include "cmDuration.h"
#include "cmExecutionStatus.h"
#include "cmGeneratedFileStream.h"
@@ -303,15 +304,24 @@ cmCTestTestHandler::cmCTestTestHandler()
// Support for JUnit XML output.
this->JUnitXMLFileName = "";
- // regex to detect <DartMeasurement>...</DartMeasurement>
- this->DartStuff.compile("(<DartMeasurement.*/DartMeasurement[a-zA-Z]*>)");
- // regex to detect each individual <DartMeasurement>...</DartMeasurement>
- this->DartStuff1.compile(
- "(<DartMeasurement[^<]*</DartMeasurement[a-zA-Z]*>)");
+ // Regular expressions to scan test output for custom measurements.
- // regex to detect <CTestDetails>...</CTestDetails>
+ // Capture the whole section of test output from the first opening
+ // <(CTest|Dart)Measurement*> tag to the last </(CTest|Dart)Measurement*>
+ // closing tag.
+ this->AllTestMeasurementsRegex.compile(
+ "(<(CTest|Dart)Measurement.*/(CTest|Dart)Measurement[a-zA-Z]*>)");
+
+ // Capture a single <(CTest|Dart)Measurement*> XML element.
+ this->SingleTestMeasurementRegex.compile(
+ "(<(CTest|Dart)Measurement[^<]*</(CTest|Dart)Measurement[a-zA-Z]*>)");
+
+ // Capture content from <CTestDetails>...</CTestDetails>
this->CustomCompletionStatusRegex.compile(
"<CTestDetails>(.*)</CTestDetails>");
+
+ // Capture content from <CTestLabel>...</CTestLabel>
+ this->CustomLabelRegex.compile("<CTestLabel>(.*)</CTestLabel>");
}
void cmCTestTestHandler::Initialize()
@@ -692,7 +702,7 @@ bool cmCTestTestHandler::GenerateXML()
return false;
}
cmXMLWriter xml(xmlfile);
- this->GenerateDartOutput(xml);
+ this->GenerateCTestXML(xml);
}
return true;
@@ -1400,7 +1410,7 @@ void cmCTestTestHandler::GenerateTestCommand(
{
}
-void cmCTestTestHandler::GenerateDartOutput(cmXMLWriter& xml)
+void cmCTestTestHandler::GenerateCTestXML(cmXMLWriter& xml)
{
if (!this->CTest->GetProduceXML()) {
return;
@@ -1436,7 +1446,7 @@ void cmCTestTestHandler::GenerateDartOutput(cmXMLWriter& xml)
xml.Element("Value", result.ReturnValue);
xml.EndElement(); // NamedMeasurement
}
- this->GenerateRegressionImages(xml, result.DartString);
+ this->RecordCustomTestMeasurements(xml, result.TestMeasurementsOutput);
xml.StartElement("NamedMeasurement");
xml.Attribute("type", "numeric/double");
xml.Attribute("name", "Execution Time");
@@ -1976,124 +1986,48 @@ void cmCTestTestHandler::ExpandTestsToRunInformationForRerunFailed()
}
}
-// Just for convenience
-#define SPACE_REGEX "[ \t\r\n]"
-void cmCTestTestHandler::GenerateRegressionImages(cmXMLWriter& xml,
- const std::string& dart)
-{
- cmsys::RegularExpression twoattributes(
- "<DartMeasurement" SPACE_REGEX
- "*(name|type|encoding|compression)=\"([^\"]*)\"" SPACE_REGEX
- "*(name|type|encoding|compression)=\"([^\"]*)\"" SPACE_REGEX
- "*>([^<]*)</DartMeasurement>");
- cmsys::RegularExpression threeattributes(
- "<DartMeasurement" SPACE_REGEX
- "*(name|type|encoding|compression)=\"([^\"]*)\"" SPACE_REGEX
- "*(name|type|encoding|compression)=\"([^\"]*)\"" SPACE_REGEX
- "*(name|type|encoding|compression)=\"([^\"]*)\"" SPACE_REGEX
- "*>([^<]*)</DartMeasurement>");
- cmsys::RegularExpression fourattributes(
- "<DartMeasurement" SPACE_REGEX
- "*(name|type|encoding|compression)=\"([^\"]*)\"" SPACE_REGEX
- "*(name|type|encoding|compression)=\"([^\"]*)\"" SPACE_REGEX
- "*(name|type|encoding|compression)=\"([^\"]*)\"" SPACE_REGEX
- "*(name|type|encoding|compression)=\"([^\"]*)\"" SPACE_REGEX
- "*>([^<]*)</DartMeasurement>");
- cmsys::RegularExpression cdatastart(
- "<DartMeasurement" SPACE_REGEX
- "*(name|type|encoding|compression)=\"([^\"]*)\"" SPACE_REGEX
- "*(name|type|encoding|compression)=\"([^\"]*)\"" SPACE_REGEX
- "*>" SPACE_REGEX "*<!\\[CDATA\\[");
- cmsys::RegularExpression cdataend("]]>" SPACE_REGEX "*</DartMeasurement>");
- cmsys::RegularExpression measurementfile(
- "<DartMeasurementFile" SPACE_REGEX
- "*(name|type|encoding|compression)=\"([^\"]*)\"" SPACE_REGEX
- "*(name|type|encoding|compression)=\"([^\"]*)\"" SPACE_REGEX
- "*>([^<]*)</DartMeasurementFile>");
-
- bool done = false;
- std::string cxml = dart;
- while (!done) {
- if (twoattributes.find(cxml)) {
- xml.StartElement("NamedMeasurement");
- xml.Attribute(twoattributes.match(1).c_str(), twoattributes.match(2));
- xml.Attribute(twoattributes.match(3).c_str(), twoattributes.match(4));
- xml.Element("Value", twoattributes.match(5));
- xml.EndElement();
- cxml.erase(twoattributes.start(),
- twoattributes.end() - twoattributes.start());
- } else if (threeattributes.find(cxml)) {
- xml.StartElement("NamedMeasurement");
- xml.Attribute(threeattributes.match(1).c_str(),
- threeattributes.match(2));
- xml.Attribute(threeattributes.match(3).c_str(),
- threeattributes.match(4));
- xml.Attribute(threeattributes.match(5).c_str(),
- threeattributes.match(6));
- xml.Element("Value", twoattributes.match(7));
- xml.EndElement();
- cxml.erase(threeattributes.start(),
- threeattributes.end() - threeattributes.start());
- } else if (fourattributes.find(cxml)) {
+void cmCTestTestHandler::RecordCustomTestMeasurements(cmXMLWriter& xml,
+ std::string content)
+{
+ while (this->SingleTestMeasurementRegex.find(content)) {
+ // Extract regex match from content and parse it as an XML element.
+ auto measurement_str = this->SingleTestMeasurementRegex.match(1);
+ auto parser = cmCTestTestMeasurementXMLParser();
+ parser.Parse(measurement_str.c_str());
+
+ if (parser.ElementName == "CTestMeasurement" ||
+ parser.ElementName == "DartMeasurement") {
xml.StartElement("NamedMeasurement");
- xml.Attribute(fourattributes.match(1).c_str(), fourattributes.match(2));
- xml.Attribute(fourattributes.match(3).c_str(), fourattributes.match(4));
- xml.Attribute(fourattributes.match(5).c_str(), fourattributes.match(6));
- xml.Attribute(fourattributes.match(7).c_str(), fourattributes.match(8));
- xml.Element("Value", twoattributes.match(9));
+ xml.Attribute("type", parser.MeasurementType);
+ xml.Attribute("name", parser.MeasurementName);
+ xml.Element("Value", parser.CharacterData);
xml.EndElement();
- cxml.erase(fourattributes.start(),
- fourattributes.end() - fourattributes.start());
- } else if (cdatastart.find(cxml) && cdataend.find(cxml)) {
- xml.StartElement("NamedMeasurement");
- xml.Attribute(cdatastart.match(1).c_str(), cdatastart.match(2));
- xml.Attribute(cdatastart.match(3).c_str(), cdatastart.match(4));
- xml.StartElement("Value");
- xml.CData(
- cxml.substr(cdatastart.end(), cdataend.start() - cdatastart.end()));
- xml.EndElement(); // Value
- xml.EndElement(); // NamedMeasurement
- cxml.erase(cdatastart.start(), cdataend.end() - cdatastart.start());
- } else if (measurementfile.find(cxml)) {
- const std::string& filename =
- cmCTest::CleanString(measurementfile.match(5));
- if (cmSystemTools::FileExists(filename)) {
+ } else if (parser.ElementName == "CTestMeasurementFile" ||
+ parser.ElementName == "DartMeasurementFile") {
+ const std::string& filename = cmCTest::CleanString(parser.CharacterData);
+ if (!cmSystemTools::FileExists(filename)) {
+ xml.StartElement("NamedMeasurement");
+ xml.Attribute("name", parser.MeasurementName);
+ xml.Attribute("text", "text/string");
+ xml.Element("Value", "File " + filename + " not found");
+ xml.EndElement();
+ cmCTestOptionalLog(
+ this->CTest, HANDLER_OUTPUT,
+ "File \"" << filename << "\" not found." << std::endl, this->Quiet);
+ } else {
long len = cmSystemTools::FileLength(filename);
- std::string k1 = measurementfile.match(1);
- std::string v1 = measurementfile.match(2);
- std::string k2 = measurementfile.match(3);
- std::string v2 = measurementfile.match(4);
if (len == 0) {
- if (cmSystemTools::LowerCase(k1) == "type") {
- v1 = "text/string";
- }
- if (cmSystemTools::LowerCase(k2) == "type") {
- v2 = "text/string";
- }
-
xml.StartElement("NamedMeasurement");
- xml.Attribute(k1.c_str(), v1);
- xml.Attribute(k2.c_str(), v2);
+ xml.Attribute("name", parser.MeasurementName);
+ xml.Attribute("type", "text/string");
xml.Attribute("encoding", "none");
xml.Element("Value", "Image " + filename + " is empty");
xml.EndElement();
} else {
- std::string type;
- std::string name;
- if (cmSystemTools::LowerCase(k1) == "type") {
- type = v1;
- } else if (cmSystemTools::LowerCase(k2) == "type") {
- type = v2;
- }
- if (cmSystemTools::LowerCase(k1) == "name") {
- name = v1;
- } else if (cmSystemTools::LowerCase(k2) == "name") {
- name = v2;
- }
- if (type == "file") {
+ if (parser.MeasurementType == "file") {
// Treat this measurement like an "ATTACHED_FILE" when the type
// is explicitly "file" (not an image).
- this->AttachFile(xml, filename, name);
+ this->AttachFile(xml, filename, parser.MeasurementName);
} else {
cmsys::ifstream ifs(filename.c_str(),
std::ios::in
@@ -2110,10 +2044,8 @@ void cmCTestTestHandler::GenerateRegressionImages(cmXMLWriter& xml,
encoded_buffer.get(), 1);
xml.StartElement("NamedMeasurement");
- xml.Attribute(measurementfile.match(1).c_str(),
- measurementfile.match(2));
- xml.Attribute(measurementfile.match(3).c_str(),
- measurementfile.match(4));
+ xml.Attribute("name", parser.MeasurementName);
+ xml.Attribute("type", parser.MeasurementType);
xml.Attribute("encoding", "base64");
std::ostringstream ostr;
for (size_t cc = 0; cc < rlen; cc++) {
@@ -2126,25 +2058,11 @@ void cmCTestTestHandler::GenerateRegressionImages(cmXMLWriter& xml,
xml.EndElement(); // NamedMeasurement
}
}
- } else {
- int idx = 4;
- if (measurementfile.match(1) == "name") {
- idx = 2;
- }
- xml.StartElement("NamedMeasurement");
- xml.Attribute("name", measurementfile.match(idx));
- xml.Attribute("text", "text/string");
- xml.Element("Value", "File " + filename + " not found");
- xml.EndElement();
- cmCTestOptionalLog(
- this->CTest, HANDLER_OUTPUT,
- "File \"" << filename << "\" not found." << std::endl, this->Quiet);
}
- cxml.erase(measurementfile.start(),
- measurementfile.end() - measurementfile.start());
- } else {
- done = true;
}
+
+ // Remove this element from content.
+ cmSystemTools::ReplaceString(content, measurement_str.c_str(), "");
}
}
@@ -2247,7 +2165,7 @@ bool cmCTestTestHandler::SetTestsProperties(
// Ensure we have complete triples otherwise the data is corrupt.
if (triples.size() % 3 == 0) {
- cmState state;
+ cmState state(cmState::Unknown);
rt.Backtrace = cmListFileBacktrace(state.CreateBaseSnapshot());
// the first entry represents the top of the trace so we need to
@@ -2327,6 +2245,8 @@ bool cmCTestTestHandler::SetTestsProperties(
cmExpandList(val, rt.Depends);
} else if (key == "ENVIRONMENT"_s) {
cmExpandList(val, rt.Environment);
+ } else if (key == "ENVIRONMENT_MODIFICATION"_s) {
+ cmExpandList(val, rt.EnvironmentModification);
} else if (key == "LABELS"_s) {
std::vector<std::string> Labels = cmExpandedList(val);
rt.Labels.insert(rt.Labels.end(), Labels.begin(), Labels.end());
diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h
index bd51738..f2da320 100644
--- a/Source/CTest/cmCTestTestHandler.h
+++ b/Source/CTest/cmCTestTestHandler.h
@@ -151,6 +151,7 @@ public:
// return code of test which will mark test as "not run"
int SkipReturnCode;
std::vector<std::string> Environment;
+ std::vector<std::string> EnvironmentModification;
std::vector<std::string> Labels;
std::set<std::string> LockedResources;
std::set<std::string> FixturesSetup;
@@ -177,7 +178,7 @@ public:
std::string CompletionStatus;
std::string CustomCompletionStatus;
std::string Output;
- std::string DartString;
+ std::string TestMeasurementsOutput;
int TestCount;
cmCTestTestProperties* Properties;
};
@@ -276,9 +277,9 @@ public:
private:
/**
- * Generate the Dart compatible output
+ * Write test results in CTest's Test.xml format
*/
- virtual void GenerateDartOutput(cmXMLWriter& xml);
+ virtual void GenerateCTestXML(cmXMLWriter& xml);
/**
* Write test results in JUnit XML format
@@ -348,8 +349,7 @@ private:
cmCTestResourceSpec ResourceSpec;
std::string ResourceSpecFile;
- void GenerateRegressionImages(cmXMLWriter& xml, const std::string& dart);
- cmsys::RegularExpression DartStuff1;
+ void RecordCustomTestMeasurements(cmXMLWriter& xml, std::string content);
void CheckLabelFilter(cmCTestTestProperties& it);
void CheckLabelFilterExclude(cmCTestTestProperties& it);
void CheckLabelFilterInclude(cmCTestTestProperties& it);
@@ -358,8 +358,10 @@ private:
bool UseUnion;
ListOfTests TestList;
size_t TotalNumberOfTests;
- cmsys::RegularExpression DartStuff;
+ cmsys::RegularExpression AllTestMeasurementsRegex;
+ cmsys::RegularExpression SingleTestMeasurementRegex;
cmsys::RegularExpression CustomCompletionStatusRegex;
+ cmsys::RegularExpression CustomLabelRegex;
std::ostream* LogFile;
diff --git a/Source/CTest/cmCTestTestMeasurementXMLParser.cxx b/Source/CTest/cmCTestTestMeasurementXMLParser.cxx
new file mode 100644
index 0000000..636be24
--- /dev/null
+++ b/Source/CTest/cmCTestTestMeasurementXMLParser.cxx
@@ -0,0 +1,26 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmCTestTestMeasurementXMLParser.h"
+
+#include <cstring>
+
+void cmCTestTestMeasurementXMLParser::StartElement(const std::string& name,
+ const char** attributes)
+{
+ this->CharacterData.clear();
+ this->ElementName = name;
+ for (const char** attr = attributes; *attr; attr += 2) {
+ if (strcmp(attr[0], "name") == 0) {
+ this->MeasurementName = attr[1];
+ } else if (strcmp(attr[0], "type") == 0) {
+ this->MeasurementType = attr[1];
+ }
+ }
+}
+
+void cmCTestTestMeasurementXMLParser::CharacterDataHandler(const char* data,
+ int length)
+{
+ this->CharacterData.append(data, length);
+}
diff --git a/Source/CTest/cmCTestTestMeasurementXMLParser.h b/Source/CTest/cmCTestTestMeasurementXMLParser.h
new file mode 100644
index 0000000..b2c3eb3
--- /dev/null
+++ b/Source/CTest/cmCTestTestMeasurementXMLParser.h
@@ -0,0 +1,21 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include <string>
+
+#include "cmXMLParser.h"
+
+class cmCTestTestMeasurementXMLParser : public cmXMLParser
+{
+public:
+ cmCTestTestMeasurementXMLParser() {}
+ std::string CharacterData;
+ std::string ElementName;
+ std::string MeasurementName;
+ std::string MeasurementType;
+
+protected:
+ void StartElement(const std::string& name, const char** atts) override;
+ void EndElement(const std::string& /*name*/) override {}
+ void CharacterDataHandler(const char* data, int length) override;
+};
diff --git a/Source/LexerParser/cmFortranParser.cxx b/Source/LexerParser/cmFortranParser.cxx
index 3f3ddde..50e9752 100644
--- a/Source/LexerParser/cmFortranParser.cxx
+++ b/Source/LexerParser/cmFortranParser.cxx
@@ -600,12 +600,12 @@ static const yytype_int8 yytranslate[] =
static const yytype_uint8 yyrline[] =
{
0, 101, 101, 101, 104, 108, 113, 122, 128, 135,
- 140, 144, 149, 157, 162, 167, 172, 177, 182, 187,
- 192, 197, 201, 205, 209, 213, 214, 219, 219, 219,
- 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, 247
+ 140, 144, 149, 161, 166, 171, 176, 181, 186, 191,
+ 196, 201, 205, 209, 213, 217, 218, 223, 223, 223,
+ 224, 224, 225, 225, 226, 226, 227, 227, 228, 228,
+ 229, 229, 230, 230, 231, 231, 232, 232, 235, 236,
+ 237, 238, 239, 240, 241, 242, 243, 244, 245, 246,
+ 247, 248, 249, 250, 251
};
#endif
@@ -1747,142 +1747,146 @@ yyreduce:
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleUse(parser, (yyvsp[-2].string));
}
+ if (cmsysString_strcasecmp((yyvsp[-4].string), "intrinsic") == 0) {
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleUseIntrinsic(parser, (yyvsp[-2].string));
+ }
free((yyvsp[-4].string));
free((yyvsp[-2].string));
}
-#line 1754 "cmFortranParser.cxx"
+#line 1758 "cmFortranParser.cxx"
break;
case 13: /* stmt: INCLUDE STRING other EOSTMT */
-#line 157 "cmFortranParser.y"
+#line 161 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1764 "cmFortranParser.cxx"
+#line 1768 "cmFortranParser.cxx"
break;
case 14: /* stmt: CPP_LINE_DIRECTIVE STRING other EOSTMT */
-#line 162 "cmFortranParser.y"
+#line 166 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleLineDirective(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1774 "cmFortranParser.cxx"
+#line 1778 "cmFortranParser.cxx"
break;
case 15: /* stmt: CPP_INCLUDE_ANGLE other EOSTMT */
-#line 167 "cmFortranParser.y"
+#line 171 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1784 "cmFortranParser.cxx"
+#line 1788 "cmFortranParser.cxx"
break;
case 16: /* stmt: include STRING other EOSTMT */
-#line 172 "cmFortranParser.y"
+#line 176 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1794 "cmFortranParser.cxx"
+#line 1798 "cmFortranParser.cxx"
break;
case 17: /* stmt: define WORD other EOSTMT */
-#line 177 "cmFortranParser.y"
+#line 181 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleDefine(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1804 "cmFortranParser.cxx"
+#line 1808 "cmFortranParser.cxx"
break;
case 18: /* stmt: undef WORD other EOSTMT */
-#line 182 "cmFortranParser.y"
+#line 186 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleUndef(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1814 "cmFortranParser.cxx"
+#line 1818 "cmFortranParser.cxx"
break;
case 19: /* stmt: ifdef WORD other EOSTMT */
-#line 187 "cmFortranParser.y"
+#line 191 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleIfdef(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1824 "cmFortranParser.cxx"
+#line 1828 "cmFortranParser.cxx"
break;
case 20: /* stmt: ifndef WORD other EOSTMT */
-#line 192 "cmFortranParser.y"
+#line 196 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleIfndef(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1834 "cmFortranParser.cxx"
+#line 1838 "cmFortranParser.cxx"
break;
case 21: /* stmt: if other EOSTMT */
-#line 197 "cmFortranParser.y"
+#line 201 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleIf(parser);
}
-#line 1843 "cmFortranParser.cxx"
+#line 1847 "cmFortranParser.cxx"
break;
case 22: /* stmt: elif other EOSTMT */
-#line 201 "cmFortranParser.y"
+#line 205 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleElif(parser);
}
-#line 1852 "cmFortranParser.cxx"
+#line 1856 "cmFortranParser.cxx"
break;
case 23: /* stmt: else other EOSTMT */
-#line 205 "cmFortranParser.y"
+#line 209 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleElse(parser);
}
-#line 1861 "cmFortranParser.cxx"
+#line 1865 "cmFortranParser.cxx"
break;
case 24: /* stmt: endif other EOSTMT */
-#line 209 "cmFortranParser.y"
+#line 213 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleEndif(parser);
}
-#line 1870 "cmFortranParser.cxx"
+#line 1874 "cmFortranParser.cxx"
break;
case 48: /* misc_code: WORD */
-#line 231 "cmFortranParser.y"
+#line 235 "cmFortranParser.y"
{ free ((yyvsp[0].string)); }
-#line 1876 "cmFortranParser.cxx"
+#line 1880 "cmFortranParser.cxx"
break;
case 55: /* misc_code: STRING */
-#line 238 "cmFortranParser.y"
+#line 242 "cmFortranParser.y"
{ free ((yyvsp[0].string)); }
-#line 1882 "cmFortranParser.cxx"
+#line 1886 "cmFortranParser.cxx"
break;
-#line 1886 "cmFortranParser.cxx"
+#line 1890 "cmFortranParser.cxx"
default: break;
}
@@ -2107,6 +2111,6 @@ yyreturn:
return yyresult;
}
-#line 250 "cmFortranParser.y"
+#line 254 "cmFortranParser.y"
/* End of grammar */
diff --git a/Source/LexerParser/cmFortranParser.y b/Source/LexerParser/cmFortranParser.y
index a3e1c24..8ef1903 100644
--- a/Source/LexerParser/cmFortranParser.y
+++ b/Source/LexerParser/cmFortranParser.y
@@ -151,6 +151,10 @@ stmt:
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleUse(parser, $5);
}
+ if (cmsysString_strcasecmp($3, "intrinsic") == 0) {
+ cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
+ cmFortranParser_RuleUseIntrinsic(parser, $5);
+ }
free($3);
free($5);
}
diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx
index e6faef4..41e8a55 100644
--- a/Source/QtDialog/QCMake.cxx
+++ b/Source/QtDialog/QCMake.cxx
@@ -128,11 +128,11 @@ void QCMake::setBinaryDirectory(const QString& _dir)
}
cmProp gen = state->GetCacheEntryValue("CMAKE_GENERATOR");
if (gen) {
- const std::string* extraGen =
+ cmProp extraGen =
state->GetInitializedCacheValue("CMAKE_EXTRA_GENERATOR");
std::string curGen =
- cmExternalMakefileProjectGenerator::CreateFullGeneratorName(
- *gen, extraGen ? *extraGen : "");
+ cmExternalMakefileProjectGenerator::CreateFullGeneratorName(*gen,
+ *extraGen);
this->setGenerator(QString::fromLocal8Bit(curGen.c_str()));
}
@@ -550,17 +550,14 @@ void QCMake::loadPresets()
}
QCMakePreset preset;
- preset.name = std::move(QString::fromLocal8Bit(p.Name.data()));
- preset.displayName =
- std::move(QString::fromLocal8Bit(p.DisplayName.data()));
- preset.description =
- std::move(QString::fromLocal8Bit(p.Description.data()));
- preset.generator = std::move(QString::fromLocal8Bit(p.Generator.data()));
- preset.architecture =
- std::move(QString::fromLocal8Bit(p.Architecture.data()));
+ preset.name = QString::fromLocal8Bit(p.Name.data());
+ preset.displayName = QString::fromLocal8Bit(p.DisplayName.data());
+ preset.description = QString::fromLocal8Bit(p.Description.data());
+ preset.generator = QString::fromLocal8Bit(p.Generator.data());
+ preset.architecture = QString::fromLocal8Bit(p.Architecture.data());
preset.setArchitecture = !p.ArchitectureStrategy ||
p.ArchitectureStrategy == cmCMakePresetsFile::ArchToolsetStrategy::Set;
- preset.toolset = std::move(QString::fromLocal8Bit(p.Toolset.data()));
+ preset.toolset = QString::fromLocal8Bit(p.Toolset.data());
preset.setToolset = !p.ToolsetStrategy ||
p.ToolsetStrategy == cmCMakePresetsFile::ArchToolsetStrategy::Set;
preset.enabled = it.Expanded && it.Expanded->ConditionResult &&
diff --git a/Source/cmAddTestCommand.cxx b/Source/cmAddTestCommand.cxx
index 205c1c7..a0d5732 100644
--- a/Source/cmAddTestCommand.cxx
+++ b/Source/cmAddTestCommand.cxx
@@ -140,7 +140,7 @@ bool cmAddTestCommandHandleNameMode(std::vector<std::string> const& args,
test->SetOldStyle(false);
test->SetCommand(command);
if (!working_directory.empty()) {
- test->SetProperty("WORKING_DIRECTORY", working_directory.c_str());
+ test->SetProperty("WORKING_DIRECTORY", working_directory);
}
test->SetCommandExpandLists(command_expand_lists);
mf.AddTestGenerator(cm::make_unique<cmTestGenerator>(test, configurations));
diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx
index 54b2998..9e0d80c 100644
--- a/Source/cmArchiveWrite.cxx
+++ b/Source/cmArchiveWrite.cxx
@@ -250,6 +250,9 @@ cmArchiveWrite::cmArchiveWrite(std::ostream& os, Compress c,
bool cmArchiveWrite::Open()
{
+ if (!this->Error.empty()) {
+ return false;
+ }
if (archive_write_open(
this->Archive, this, nullptr,
reinterpret_cast<archive_write_callback*>(&Callback::Write),
diff --git a/Source/cmBinUtilsLinuxELFLinker.cxx b/Source/cmBinUtilsLinuxELFLinker.cxx
index 99707a3..a69c00d 100644
--- a/Source/cmBinUtilsLinuxELFLinker.cxx
+++ b/Source/cmBinUtilsLinuxELFLinker.cxx
@@ -11,6 +11,7 @@
#include <cmsys/RegularExpression.hxx>
#include "cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.h"
+#include "cmELF.h"
#include "cmLDConfigLDConfigTool.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -18,10 +19,6 @@
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
-#ifdef CMake_USE_ELF_PARSER
-# include "cmELF.h"
-#endif
-
static std::string ReplaceOrigin(const std::string& rpath,
const std::string& origin)
{
@@ -91,7 +88,6 @@ bool cmBinUtilsLinuxELFLinker::ScanDependencies(
{
std::vector<std::string> parentRpaths;
-#ifdef CMake_USE_ELF_PARSER
cmELF elf(file.c_str());
if (!elf) {
return false;
@@ -106,7 +102,6 @@ bool cmBinUtilsLinuxELFLinker::ScanDependencies(
this->Machine = elf.GetMachine();
}
}
-#endif
return this->ScanDependencies(file, parentRpaths);
}
@@ -175,15 +170,11 @@ bool cmBinUtilsLinuxELFLinker::ScanDependencies(
namespace {
bool FileHasArchitecture(const char* filename, std::uint16_t machine)
{
-#ifdef CMake_USE_ELF_PARSER
cmELF elf(filename);
if (!elf) {
return false;
}
return machine == 0 || machine == elf.GetMachine();
-#else
- return true;
-#endif
}
}
diff --git a/Source/cmCMakeHostSystemInformationCommand.cxx b/Source/cmCMakeHostSystemInformationCommand.cxx
index 0550568..74071ff 100644
--- a/Source/cmCMakeHostSystemInformationCommand.cxx
+++ b/Source/cmCMakeHostSystemInformationCommand.cxx
@@ -2,214 +2,510 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCMakeHostSystemInformationCommand.h"
-#include <cstddef>
+#include <algorithm>
+#include <cassert>
+#include <cctype>
+#include <initializer_list>
+#include <map>
+#include <string>
+#include <type_traits>
+#include <utility>
+#include <cm/optional>
+#include <cm/string_view>
+#include <cmext/string_view>
+
+#include "cmsys/FStream.hxx"
+#include "cmsys/Glob.hxx"
#include "cmsys/SystemInformation.hxx"
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
-#if defined(_WIN32)
+#ifdef _WIN32
# include "cmAlgorithms.h"
# include "cmGlobalGenerator.h"
# include "cmGlobalVisualStudioVersionedGenerator.h"
-# include "cmSystemTools.h"
# include "cmVSSetupHelper.h"
# define HAVE_VS_SETUP_HELPER
#endif
namespace {
-bool GetValue(cmExecutionStatus& status, cmsys::SystemInformation& info,
- std::string const& key, std::string& value);
-std::string ValueToString(size_t value);
-std::string ValueToString(const char* value);
-std::string ValueToString(std::string const& value);
-}
+std::string const DELIM[2] = { {}, ";" };
-// cmCMakeHostSystemInformation
-bool cmCMakeHostSystemInformationCommand(std::vector<std::string> const& args,
- cmExecutionStatus& status)
+// BEGIN Private functions
+std::string ValueToString(std::size_t const value)
{
- size_t current_index = 0;
-
- if (args.size() < (current_index + 2) || args[current_index] != "RESULT") {
- status.SetError("missing RESULT specification.");
- return false;
- }
-
- std::string const& variable = args[current_index + 1];
- current_index += 2;
-
- if (args.size() < (current_index + 2) || args[current_index] != "QUERY") {
- status.SetError("missing QUERY specification");
- return false;
- }
-
- cmsys::SystemInformation info;
- info.RunCPUCheck();
- info.RunOSCheck();
- info.RunMemoryCheck();
-
- std::string result_list;
- for (size_t i = current_index + 1; i < args.size(); ++i) {
- std::string const& key = args[i];
- if (i != current_index + 1) {
- result_list += ";";
- }
- std::string value;
- if (!GetValue(status, info, key, value)) {
- return false;
- }
- result_list += value;
- }
-
- status.GetMakefile().AddDefinition(variable, result_list);
+ return std::to_string(value);
+}
- return true;
+std::string ValueToString(const char* const value)
+{
+ return value ? value : std::string{};
}
-namespace {
+std::string ValueToString(std::string const& value)
+{
+ return value;
+}
-bool GetValue(cmExecutionStatus& status, cmsys::SystemInformation& info,
- std::string const& key, std::string& value)
+cm::optional<std::string> GetValue(cmsys::SystemInformation& info,
+ std::string const& key)
{
- if (key == "NUMBER_OF_LOGICAL_CORES") {
- value = ValueToString(info.GetNumberOfLogicalCPU());
- } else if (key == "NUMBER_OF_PHYSICAL_CORES") {
- value = ValueToString(info.GetNumberOfPhysicalCPU());
- } else if (key == "HOSTNAME") {
- value = ValueToString(info.GetHostname());
- } else if (key == "FQDN") {
- value = ValueToString(info.GetFullyQualifiedDomainName());
- } else if (key == "TOTAL_VIRTUAL_MEMORY") {
- value = ValueToString(info.GetTotalVirtualMemory());
- } else if (key == "AVAILABLE_VIRTUAL_MEMORY") {
- value = ValueToString(info.GetAvailableVirtualMemory());
- } else if (key == "TOTAL_PHYSICAL_MEMORY") {
- value = ValueToString(info.GetTotalPhysicalMemory());
- } else if (key == "AVAILABLE_PHYSICAL_MEMORY") {
- value = ValueToString(info.GetAvailablePhysicalMemory());
- } else if (key == "IS_64BIT") {
- value = ValueToString(info.Is64Bits());
- } else if (key == "HAS_FPU") {
- value = ValueToString(
+ if (key == "NUMBER_OF_LOGICAL_CORES"_s) {
+ return ValueToString(info.GetNumberOfLogicalCPU());
+ }
+ if (key == "NUMBER_OF_PHYSICAL_CORES"_s) {
+ return ValueToString(info.GetNumberOfPhysicalCPU());
+ }
+ if (key == "HOSTNAME"_s) {
+ return ValueToString(info.GetHostname());
+ }
+ if (key == "FQDN"_s) {
+ return ValueToString(info.GetFullyQualifiedDomainName());
+ }
+ if (key == "TOTAL_VIRTUAL_MEMORY"_s) {
+ return ValueToString(info.GetTotalVirtualMemory());
+ }
+ if (key == "AVAILABLE_VIRTUAL_MEMORY"_s) {
+ return ValueToString(info.GetAvailableVirtualMemory());
+ }
+ if (key == "TOTAL_PHYSICAL_MEMORY"_s) {
+ return ValueToString(info.GetTotalPhysicalMemory());
+ }
+ if (key == "AVAILABLE_PHYSICAL_MEMORY"_s) {
+ return ValueToString(info.GetAvailablePhysicalMemory());
+ }
+ if (key == "IS_64BIT"_s) {
+ return ValueToString(info.Is64Bits());
+ }
+ if (key == "HAS_FPU"_s) {
+ return ValueToString(
info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_FPU));
- } else if (key == "HAS_MMX") {
- value = ValueToString(
+ }
+ if (key == "HAS_MMX"_s) {
+ return ValueToString(
info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_MMX));
- } else if (key == "HAS_MMX_PLUS") {
- value = ValueToString(info.DoesCPUSupportFeature(
+ }
+ if (key == "HAS_MMX_PLUS"_s) {
+ return ValueToString(info.DoesCPUSupportFeature(
cmsys::SystemInformation::CPU_FEATURE_MMX_PLUS));
- } else if (key == "HAS_SSE") {
- value = ValueToString(
+ }
+ if (key == "HAS_SSE"_s) {
+ return ValueToString(
info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_SSE));
- } else if (key == "HAS_SSE2") {
- value = ValueToString(
+ }
+ if (key == "HAS_SSE2"_s) {
+ return ValueToString(
info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_SSE2));
- } else if (key == "HAS_SSE_FP") {
- value = ValueToString(info.DoesCPUSupportFeature(
+ }
+ if (key == "HAS_SSE_FP"_s) {
+ return ValueToString(info.DoesCPUSupportFeature(
cmsys::SystemInformation::CPU_FEATURE_SSE_FP));
- } else if (key == "HAS_SSE_MMX") {
- value = ValueToString(info.DoesCPUSupportFeature(
+ }
+ if (key == "HAS_SSE_MMX"_s) {
+ return ValueToString(info.DoesCPUSupportFeature(
cmsys::SystemInformation::CPU_FEATURE_SSE_MMX));
- } else if (key == "HAS_AMD_3DNOW") {
- value = ValueToString(info.DoesCPUSupportFeature(
+ }
+ if (key == "HAS_AMD_3DNOW"_s) {
+ return ValueToString(info.DoesCPUSupportFeature(
cmsys::SystemInformation::CPU_FEATURE_AMD_3DNOW));
- } else if (key == "HAS_AMD_3DNOW_PLUS") {
- value = ValueToString(info.DoesCPUSupportFeature(
+ }
+ if (key == "HAS_AMD_3DNOW_PLUS"_s) {
+ return ValueToString(info.DoesCPUSupportFeature(
cmsys::SystemInformation::CPU_FEATURE_AMD_3DNOW_PLUS));
- } else if (key == "HAS_IA64") {
- value = ValueToString(
+ }
+ if (key == "HAS_IA64"_s) {
+ return ValueToString(
info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_IA64));
- } else if (key == "HAS_SERIAL_NUMBER") {
- value = ValueToString(info.DoesCPUSupportFeature(
+ }
+ if (key == "HAS_SERIAL_NUMBER"_s) {
+ return ValueToString(info.DoesCPUSupportFeature(
cmsys::SystemInformation::CPU_FEATURE_SERIALNUMBER));
- } else if (key == "PROCESSOR_NAME") {
- value = ValueToString(info.GetExtendedProcessorName());
- } else if (key == "PROCESSOR_DESCRIPTION") {
- value = info.GetCPUDescription();
- } else if (key == "PROCESSOR_SERIAL_NUMBER") {
- value = ValueToString(info.GetProcessorSerialNumber());
- } else if (key == "OS_NAME") {
- value = ValueToString(info.GetOSName());
- } else if (key == "OS_RELEASE") {
- value = ValueToString(info.GetOSRelease());
- } else if (key == "OS_VERSION") {
- value = ValueToString(info.GetOSVersion());
- } else if (key == "OS_PLATFORM") {
- value = ValueToString(info.GetOSPlatform());
-#ifdef HAVE_VS_SETUP_HELPER
- } else if (key == "VS_15_DIR") {
- // If generating for the VS 15 IDE, use the same instance.
- cmGlobalGenerator* gg = status.GetMakefile().GetGlobalGenerator();
- if (cmHasLiteralPrefix(gg->GetName(), "Visual Studio 15 ")) {
- cmGlobalVisualStudioVersionedGenerator* vs15gen =
- static_cast<cmGlobalVisualStudioVersionedGenerator*>(gg);
- if (vs15gen->GetVSInstance(value)) {
- return true;
- }
+ }
+ if (key == "PROCESSOR_NAME"_s) {
+ return ValueToString(info.GetExtendedProcessorName());
+ }
+ if (key == "PROCESSOR_DESCRIPTION"_s) {
+ return info.GetCPUDescription();
+ }
+ if (key == "PROCESSOR_SERIAL_NUMBER"_s) {
+ return ValueToString(info.GetProcessorSerialNumber());
+ }
+ if (key == "OS_NAME"_s) {
+ return ValueToString(info.GetOSName());
+ }
+ if (key == "OS_RELEASE"_s) {
+ return ValueToString(info.GetOSRelease());
+ }
+ if (key == "OS_VERSION"_s) {
+ return ValueToString(info.GetOSVersion());
+ }
+ if (key == "OS_PLATFORM"_s) {
+ return ValueToString(info.GetOSPlatform());
+ }
+ return {};
+}
+
+cm::optional<std::pair<std::string, std::string>> ParseOSReleaseLine(
+ std::string const& line)
+{
+ std::string key;
+ std::string value;
+
+ char prev = 0;
+ enum ParserState
+ {
+ PARSE_KEY_1ST,
+ PARSE_KEY,
+ FOUND_EQ,
+ PARSE_SINGLE_QUOTE_VALUE,
+ PARSE_DBL_QUOTE_VALUE,
+ PARSE_VALUE,
+ IGNORE_REST
+ } state = PARSE_KEY_1ST;
+
+ for (auto ch : line) {
+ switch (state) {
+ case PARSE_KEY_1ST:
+ if (std::isalpha(ch) || ch == '_') {
+ key += ch;
+ state = PARSE_KEY;
+ } else if (!std::isspace(ch)) {
+ state = IGNORE_REST;
+ }
+ break;
+
+ case PARSE_KEY:
+ if (ch == '=') {
+ state = FOUND_EQ;
+ } else if (std::isalnum(ch) || ch == '_') {
+ key += ch;
+ } else {
+ state = IGNORE_REST;
+ }
+ break;
+
+ case FOUND_EQ:
+ switch (ch) {
+ case '\'':
+ state = PARSE_SINGLE_QUOTE_VALUE;
+ break;
+ case '"':
+ state = PARSE_DBL_QUOTE_VALUE;
+ break;
+ case '#':
+ case '\\':
+ state = IGNORE_REST;
+ break;
+ default:
+ value += ch;
+ state = PARSE_VALUE;
+ }
+ break;
+
+ case PARSE_SINGLE_QUOTE_VALUE:
+ if (ch == '\'') {
+ if (prev != '\\') {
+ state = IGNORE_REST;
+ } else {
+ assert(!value.empty());
+ value[value.size() - 1] = ch;
+ }
+ } else {
+ value += ch;
+ }
+ break;
+
+ case PARSE_DBL_QUOTE_VALUE:
+ if (ch == '"') {
+ if (prev != '\\') {
+ state = IGNORE_REST;
+ } else {
+ assert(!value.empty());
+ value[value.size() - 1] = ch;
+ }
+ } else {
+ value += ch;
+ }
+ break;
+
+ case PARSE_VALUE:
+ if (ch == '#' || std::isspace(ch)) {
+ state = IGNORE_REST;
+ } else {
+ value += ch;
+ }
+ break;
+
+ default:
+ // Unexpected os-release parser state!
+ state = IGNORE_REST;
+ break;
}
- // Otherwise, find a VS 15 instance ourselves.
- cmVSSetupAPIHelper vsSetupAPIHelper(15);
- if (vsSetupAPIHelper.GetVSInstanceInfo(value)) {
- cmSystemTools::ConvertToUnixSlashes(value);
+ if (state == IGNORE_REST) {
+ break;
}
- } else if (key == "VS_16_DIR") {
- // If generating for the VS 16 IDE, use the same instance.
- cmGlobalGenerator* gg = status.GetMakefile().GetGlobalGenerator();
- if (cmHasLiteralPrefix(gg->GetName(), "Visual Studio 16 ")) {
- cmGlobalVisualStudioVersionedGenerator* vs16gen =
- static_cast<cmGlobalVisualStudioVersionedGenerator*>(gg);
- if (vs16gen->GetVSInstance(value)) {
- return true;
+ prev = ch;
+ }
+ if (!(key.empty() || value.empty())) {
+ return std::make_pair(key, value);
+ }
+ return {};
+}
+
+std::map<std::string, std::string> GetOSReleaseVariables(
+ cmExecutionStatus& status)
+{
+ auto& makefile = status.GetMakefile();
+ const auto& sysroot = makefile.GetSafeDefinition("CMAKE_SYSROOT");
+
+ std::map<std::string, std::string> data;
+ // Based on
+ // https://www.freedesktop.org/software/systemd/man/os-release.html
+ for (auto name : { "/etc/os-release"_s, "/usr/lib/os-release"_s }) {
+ const auto& filename = cmStrCat(sysroot, name);
+ if (cmSystemTools::FileExists(filename)) {
+ cmsys::ifstream fin(filename.c_str());
+ for (std::string line; !std::getline(fin, line).fail();) {
+ auto kv = ParseOSReleaseLine(line);
+ if (kv.has_value()) {
+ data.emplace(kv.value());
+ }
}
+ break;
}
+ }
+ // Got smth?
+ if (!data.empty()) {
+ return data;
+ }
+
+ // Ugh, it could be some pre-os-release distro.
+ // Lets try some fallback getters.
+ // See also:
+ // - http://linuxmafia.com/faq/Admin/release-files.html
+
+ // 1. CMake provided
+ cmsys::Glob gl;
+ std::vector<std::string> scripts;
+ auto const findExpr = cmStrCat(cmSystemTools::GetCMakeRoot(),
+ "/Modules/Internal/OSRelease/*.cmake");
+ if (gl.FindFiles(findExpr)) {
+ scripts = gl.GetFiles();
+ }
+
+ // 2. User provided (append to the CMake prvided)
+ makefile.GetDefExpandList("CMAKE_GET_OS_RELEASE_FALLBACK_SCRIPTS", scripts);
+
+ // Filter out files that are not in format `NNN-name.cmake`
+ auto checkName = [](std::string const& filepath) -> bool {
+ auto const& filename = cmSystemTools::GetFilenameName(filepath);
+ // NOTE Minimum filename length expected:
+ // NNN-<at-least-one-char-name>.cmake --> 11
+ return (filename.size() < 11) || !std::isdigit(filename[0]) ||
+ !std::isdigit(filename[1]) || !std::isdigit(filename[2]) ||
+ filename[3] != '-';
+ };
+ scripts.erase(std::remove_if(scripts.begin(), scripts.end(), checkName),
+ scripts.end());
- // Otherwise, find a VS 16 instance ourselves.
- cmVSSetupAPIHelper vsSetupAPIHelper(16);
- if (vsSetupAPIHelper.GetVSInstanceInfo(value)) {
- cmSystemTools::ConvertToUnixSlashes(value);
+ // Make sure scripts are running in desired order
+ std::sort(scripts.begin(), scripts.end(),
+ [](std::string const& lhs, std::string const& rhs) -> bool {
+ long lhs_order;
+ cmStrToLong(cmSystemTools::GetFilenameName(lhs).substr(0u, 3u),
+ &lhs_order);
+ long rhs_order;
+ cmStrToLong(cmSystemTools::GetFilenameName(rhs).substr(0u, 3u),
+ &rhs_order);
+ return lhs_order < rhs_order;
+ });
+
+ // Name of the variable to put the results
+ auto const result_variable = "CMAKE_GET_OS_RELEASE_FALLBACK_RESULT"_s;
+
+ for (auto const& script : scripts) {
+ // Unset the result variable
+ makefile.RemoveDefinition(result_variable.data());
+
+ // include FATAL_ERROR and ERROR in the return status
+ if (!makefile.ReadListFile(script) ||
+ cmSystemTools::GetErrorOccuredFlag()) {
+ // Ok, no worries... go try the next script.
+ continue;
+ }
+
+ std::vector<std::string> variables;
+ if (!makefile.GetDefExpandList(result_variable.data(), variables)) {
+ // Heh, this script didn't found anything... go try the next one.
+ continue;
}
- } else if (key == "VS_17_DIR") {
- // If generating for the VS 17 IDE, use the same instance.
- cmGlobalGenerator* gg = status.GetMakefile().GetGlobalGenerator();
- if (cmHasLiteralPrefix(gg->GetName(), "Visual Studio 17 ")) {
- cmGlobalVisualStudioVersionedGenerator* vs17gen =
- static_cast<cmGlobalVisualStudioVersionedGenerator*>(gg);
- if (vs17gen->GetVSInstance(value)) {
- return true;
+
+ for (auto const& variable : variables) {
+ auto value = makefile.GetSafeDefinition(variable);
+ makefile.RemoveDefinition(variable);
+
+ if (!cmHasPrefix(variable, cmStrCat(result_variable, '_'))) {
+ // Ignore unknown variable set by the script
+ continue;
}
+
+ auto key = variable.substr(result_variable.size() + 1,
+ variable.size() - result_variable.size() - 1);
+ data.emplace(std::move(key), std::move(value));
}
- // Otherwise, find a VS 17 instance ourselves.
- cmVSSetupAPIHelper vsSetupAPIHelper(17);
- if (vsSetupAPIHelper.GetVSInstanceInfo(value)) {
- cmSystemTools::ConvertToUnixSlashes(value);
+ // Try 'till some script can get anything
+ if (!data.empty()) {
+ data.emplace("USED_FALLBACK_SCRIPT", script);
+ break;
}
-#endif
- } else {
- std::string e = "does not recognize <key> " + key;
- status.SetError(e);
- return false;
}
- return true;
+ makefile.RemoveDefinition(result_variable.data());
+
+ return data;
}
-std::string ValueToString(size_t value)
+cm::optional<std::string> GetValue(cmExecutionStatus& status,
+ std::string const& key,
+ std::string const& variable)
{
- return std::to_string(value);
+ const auto prefix = "DISTRIB_"_s;
+ if (!cmHasPrefix(key, prefix)) {
+ return {};
+ }
+
+ static const std::map<std::string, std::string> s_os_release =
+ GetOSReleaseVariables(status);
+
+ auto& makefile = status.GetMakefile();
+
+ const std::string subkey =
+ key.substr(prefix.size(), key.size() - prefix.size());
+ if (subkey == "INFO"_s) {
+ std::string vars;
+ for (const auto& kv : s_os_release) {
+ auto cmake_var_name = cmStrCat(variable, '_', kv.first);
+ vars += DELIM[!vars.empty()] + cmake_var_name;
+ makefile.AddDefinition(cmake_var_name, kv.second);
+ }
+ return cm::optional<std::string>(std::move(vars));
+ }
+
+ // Query individual variable
+ const auto it = s_os_release.find(subkey);
+ if (it != s_os_release.cend()) {
+ return it->second;
+ }
+
+ // NOTE Empty string means requested variable not set
+ return std::string{};
+}
+
+#ifdef HAVE_VS_SETUP_HELPER
+cm::optional<std::string> GetValue(cmExecutionStatus& status,
+ std::string const& key)
+{
+ auto* const gg = status.GetMakefile().GetGlobalGenerator();
+ for (auto vs : { 15, 16, 17 }) {
+ if (key == cmStrCat("VS_"_s, vs, "_DIR"_s)) {
+ std::string value;
+ // If generating for the VS nn IDE, use the same instance.
+
+ if (cmHasPrefix(gg->GetName(), cmStrCat("Visual Studio "_s, vs, ' '))) {
+ cmGlobalVisualStudioVersionedGenerator* vsNNgen =
+ static_cast<cmGlobalVisualStudioVersionedGenerator*>(gg);
+ if (vsNNgen->GetVSInstance(value)) {
+ return value;
+ }
+ }
+
+ // Otherwise, find a VS nn instance ourselves.
+ cmVSSetupAPIHelper vsSetupAPIHelper(vs);
+ if (vsSetupAPIHelper.GetVSInstanceInfo(value)) {
+ cmSystemTools::ConvertToUnixSlashes(value);
+ }
+ return value;
+ }
+ }
+
+ return {};
}
+#endif
-std::string ValueToString(const char* value)
+cm::optional<std::string> GetValueChained()
{
- std::string safe_string = value ? value : "";
- return safe_string;
+ return {};
}
-std::string ValueToString(std::string const& value)
+template <typename GetterFn, typename... Next>
+cm::optional<std::string> GetValueChained(GetterFn current, Next... chain)
{
- return value;
+ auto value = current();
+ if (value.has_value()) {
+ return value;
+ }
+ return GetValueChained(chain...);
}
+// END Private functions
+} // anonymous namespace
+
+// cmCMakeHostSystemInformation
+bool cmCMakeHostSystemInformationCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ std::size_t current_index = 0;
+
+ if (args.size() < (current_index + 2) || args[current_index] != "RESULT"_s) {
+ status.SetError("missing RESULT specification.");
+ return false;
+ }
+
+ auto const& variable = args[current_index + 1];
+ current_index += 2;
+
+ if (args.size() < (current_index + 2) || args[current_index] != "QUERY"_s) {
+ status.SetError("missing QUERY specification");
+ return false;
+ }
+
+ static cmsys::SystemInformation info;
+ static auto initialized = false;
+ if (!initialized) {
+ info.RunCPUCheck();
+ info.RunOSCheck();
+ info.RunMemoryCheck();
+ initialized = true;
+ }
+
+ std::string result_list;
+ for (auto i = current_index + 1; i < args.size(); ++i) {
+ result_list += DELIM[!result_list.empty()];
+
+ auto const& key = args[i];
+ // clang-format off
+ auto value =
+ GetValueChained(
+ [&]() { return GetValue(info, key); }
+ , [&]() { return GetValue(status, key, variable); }
+#ifdef HAVE_VS_SETUP_HELPER
+ , [&]() { return GetValue(status, key); }
+#endif
+ );
+ // clang-format on
+ if (!value) {
+ status.SetError("does not recognize <key> " + key);
+ return false;
+ }
+ result_list += value.value();
+ }
+
+ status.GetMakefile().AddDefinition(variable, result_list);
+
+ return true;
}
diff --git a/Source/cmCMakePolicyCommand.cxx b/Source/cmCMakePolicyCommand.cxx
index 1f99043..b2830e2 100644
--- a/Source/cmCMakePolicyCommand.cxx
+++ b/Source/cmCMakePolicyCommand.cxx
@@ -6,6 +6,7 @@
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
+#include "cmProperty.h"
#include "cmState.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx
index 1a950df..8fefaa6 100644
--- a/Source/cmCacheManager.cxx
+++ b/Source/cmCacheManager.cxx
@@ -500,7 +500,7 @@ cmProp cmCacheManager::GetInitializedCacheValue(const std::string& key) const
{
if (const auto* entry = this->GetCacheEntry(key)) {
if (entry->Initialized) {
- return &entry->GetValue();
+ return cmProp(entry->GetValue());
}
}
return nullptr;
@@ -568,10 +568,10 @@ std::vector<std::string> cmCacheManager::CacheEntry::GetPropertyList() const
cmProp cmCacheManager::CacheEntry::GetProperty(const std::string& prop) const
{
if (prop == "TYPE") {
- return &cmState::CacheEntryTypeToString(this->Type);
+ return cmProp(cmState::CacheEntryTypeToString(this->Type));
}
if (prop == "VALUE") {
- return &this->Value;
+ return cmProp(this->Value);
}
return this->Properties.GetPropertyValue(prop);
}
diff --git a/Source/cmCacheManager.h b/Source/cmCacheManager.h
index 7a9a7dc..0238fb8 100644
--- a/Source/cmCacheManager.h
+++ b/Source/cmCacheManager.h
@@ -75,7 +75,7 @@ public:
cmProp GetCacheEntryValue(const std::string& key) const
{
if (const auto* entry = this->GetCacheEntry(key)) {
- return &entry->GetValue();
+ return cmProp(entry->GetValue());
}
return nullptr;
}
diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx
index deddba8..415f0c0 100644
--- a/Source/cmCommandArgumentParserHelper.cxx
+++ b/Source/cmCommandArgumentParserHelper.cxx
@@ -113,7 +113,7 @@ const char* cmCommandArgumentParserHelper::ExpandVariable(const char* var)
if (this->EscapeQuotes && value) {
return this->AddString(cmEscapeQuotes(*value));
}
- return this->AddString(cmToCStrSafe(value));
+ return this->AddString(value);
}
const char* cmCommandArgumentParserHelper::ExpandVariableForAt(const char* var)
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
index 7c2e20c..59e4141 100644
--- a/Source/cmCommonTargetGenerator.cxx
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -39,10 +39,10 @@ std::vector<std::string> const& cmCommonTargetGenerator::GetConfigNames() const
return this->ConfigNames;
}
-const char* cmCommonTargetGenerator::GetFeature(const std::string& feature,
- const std::string& config)
+cmProp cmCommonTargetGenerator::GetFeature(const std::string& feature,
+ const std::string& config)
{
- return this->GeneratorTarget->GetFeature(feature, config)->c_str();
+ return this->GeneratorTarget->GetFeature(feature, config);
}
void cmCommonTargetGenerator::AddModuleDefinitionFlag(
diff --git a/Source/cmCommonTargetGenerator.h b/Source/cmCommonTargetGenerator.h
index a156a41..463a445 100644
--- a/Source/cmCommonTargetGenerator.h
+++ b/Source/cmCommonTargetGenerator.h
@@ -8,6 +8,8 @@
#include <string>
#include <vector>
+#include "cmProperty.h"
+
class cmGeneratorTarget;
class cmGlobalCommonGenerator;
class cmLinkLineComputer;
@@ -28,8 +30,7 @@ public:
protected:
// Feature query methods.
- const char* GetFeature(const std::string& feature,
- const std::string& config);
+ cmProp GetFeature(const std::string& feature, const std::string& config);
// Helper to add flag for windows .def file.
void AddModuleDefinitionFlag(cmLinkLineComputer* linkLineComputer,
@@ -40,6 +41,7 @@ protected:
cmLocalCommonGenerator* LocalCommonGenerator;
cmGlobalCommonGenerator* GlobalCommonGenerator;
std::vector<std::string> ConfigNames;
+ bool UseLWYU = false;
void AppendFortranFormatFlags(std::string& flags,
cmSourceFile const& source);
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index d15da0c..eda0722 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -278,13 +278,11 @@ cmComputeLinkInformation::cmComputeLinkInformation(
// On platforms without import libraries there may be a special flag
// to use when creating a plugin (module) that obtains symbols from
// the program that will load it.
- this->LoaderFlag = nullptr;
if (!this->Target->IsDLLPlatform() &&
this->Target->GetType() == cmStateEnums::MODULE_LIBRARY) {
std::string loader_flag_var =
cmStrCat("CMAKE_SHARED_MODULE_LOADER_", this->LinkLanguage, "_FLAG");
- this->LoaderFlag =
- cmToCStr(this->Makefile->GetDefinition(loader_flag_var));
+ this->LoaderFlag = this->Makefile->GetDefinition(loader_flag_var);
}
// Get options needed to link libraries.
@@ -660,8 +658,7 @@ void cmComputeLinkInformation::AddItem(BT<std::string> const& item,
// This link item is an executable that may provide symbols
// used by this target. A special flag is needed on this
// platform. Add it now.
- std::string linkItem;
- linkItem = this->LoaderFlag;
+ std::string linkItem = this->LoaderFlag;
cmStateEnums::ArtifactType artifact = tgt->HasImportLibrary(config)
? cmStateEnums::ImportLibraryArtifact
: cmStateEnums::RuntimeBinaryArtifact;
diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h
index 7fe30b3..c3ae345 100644
--- a/Source/cmComputeLinkInformation.h
+++ b/Source/cmComputeLinkInformation.h
@@ -14,6 +14,7 @@
#include "cmsys/RegularExpression.hxx"
#include "cmListFileCache.h"
+#include "cmProperty.h"
class cmGeneratorTarget;
class cmGlobalGenerator;
@@ -137,7 +138,7 @@ private:
SharedDepModeLink // List file on link line
};
- const char* LoaderFlag;
+ cmProp LoaderFlag;
std::string LibLinkFlag;
std::string LibLinkFileFlag;
std::string ObjLinkFileFlag;
diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx
index f99592c..68bc4d8 100644
--- a/Source/cmConditionEvaluator.cxx
+++ b/Source/cmConditionEvaluator.cxx
@@ -2,16 +2,21 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmConditionEvaluator.h"
+#include <array>
#include <cstdio>
#include <cstdlib>
#include <functional>
+#include <iterator>
+#include <list>
#include <sstream>
#include <utility>
+#include <cm/string_view>
#include <cmext/algorithm>
#include "cmsys/RegularExpression.hxx"
+#include "cmExpandedCommandArgument.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmProperty.h"
@@ -20,40 +25,184 @@
#include "cmSystemTools.h"
#include "cmake.h"
-class cmTest;
-
-static std::string const keyAND = "AND";
-static std::string const keyCOMMAND = "COMMAND";
-static std::string const keyDEFINED = "DEFINED";
-static std::string const keyEQUAL = "EQUAL";
-static std::string const keyEXISTS = "EXISTS";
-static std::string const keyGREATER = "GREATER";
-static std::string const keyGREATER_EQUAL = "GREATER_EQUAL";
-static std::string const keyIN_LIST = "IN_LIST";
-static std::string const keyIS_ABSOLUTE = "IS_ABSOLUTE";
-static std::string const keyIS_DIRECTORY = "IS_DIRECTORY";
-static std::string const keyIS_NEWER_THAN = "IS_NEWER_THAN";
-static std::string const keyIS_SYMLINK = "IS_SYMLINK";
-static std::string const keyLESS = "LESS";
-static std::string const keyLESS_EQUAL = "LESS_EQUAL";
-static std::string const keyMATCHES = "MATCHES";
-static std::string const keyNOT = "NOT";
-static std::string const keyOR = "OR";
-static std::string const keyParenL = "(";
-static std::string const keyParenR = ")";
-static std::string const keyPOLICY = "POLICY";
-static std::string const keySTREQUAL = "STREQUAL";
-static std::string const keySTRGREATER = "STRGREATER";
-static std::string const keySTRGREATER_EQUAL = "STRGREATER_EQUAL";
-static std::string const keySTRLESS = "STRLESS";
-static std::string const keySTRLESS_EQUAL = "STRLESS_EQUAL";
-static std::string const keyTARGET = "TARGET";
-static std::string const keyTEST = "TEST";
-static std::string const keyVERSION_EQUAL = "VERSION_EQUAL";
-static std::string const keyVERSION_GREATER = "VERSION_GREATER";
-static std::string const keyVERSION_GREATER_EQUAL = "VERSION_GREATER_EQUAL";
-static std::string const keyVERSION_LESS = "VERSION_LESS";
-static std::string const keyVERSION_LESS_EQUAL = "VERSION_LESS_EQUAL";
+namespace {
+auto const keyAND = "AND"_s;
+auto const keyCOMMAND = "COMMAND"_s;
+auto const keyDEFINED = "DEFINED"_s;
+auto const keyEQUAL = "EQUAL"_s;
+auto const keyEXISTS = "EXISTS"_s;
+auto const keyGREATER = "GREATER"_s;
+auto const keyGREATER_EQUAL = "GREATER_EQUAL"_s;
+auto const keyIN_LIST = "IN_LIST"_s;
+auto const keyIS_ABSOLUTE = "IS_ABSOLUTE"_s;
+auto const keyIS_DIRECTORY = "IS_DIRECTORY"_s;
+auto const keyIS_NEWER_THAN = "IS_NEWER_THAN"_s;
+auto const keyIS_SYMLINK = "IS_SYMLINK"_s;
+auto const keyLESS = "LESS"_s;
+auto const keyLESS_EQUAL = "LESS_EQUAL"_s;
+auto const keyMATCHES = "MATCHES"_s;
+auto const keyNOT = "NOT"_s;
+auto const keyOR = "OR"_s;
+auto const keyParenL = "("_s;
+auto const keyParenR = ")"_s;
+auto const keyPOLICY = "POLICY"_s;
+auto const keySTREQUAL = "STREQUAL"_s;
+auto const keySTRGREATER = "STRGREATER"_s;
+auto const keySTRGREATER_EQUAL = "STRGREATER_EQUAL"_s;
+auto const keySTRLESS = "STRLESS"_s;
+auto const keySTRLESS_EQUAL = "STRLESS_EQUAL"_s;
+auto const keyTARGET = "TARGET"_s;
+auto const keyTEST = "TEST"_s;
+auto const keyVERSION_EQUAL = "VERSION_EQUAL"_s;
+auto const keyVERSION_GREATER = "VERSION_GREATER"_s;
+auto const keyVERSION_GREATER_EQUAL = "VERSION_GREATER_EQUAL"_s;
+auto const keyVERSION_LESS = "VERSION_LESS"_s;
+auto const keyVERSION_LESS_EQUAL = "VERSION_LESS_EQUAL"_s;
+
+cmSystemTools::CompareOp const MATCH2CMPOP[5] = {
+ cmSystemTools::OP_LESS, cmSystemTools::OP_LESS_EQUAL,
+ cmSystemTools::OP_GREATER, cmSystemTools::OP_GREATER_EQUAL,
+ cmSystemTools::OP_EQUAL
+};
+
+// Run-Time to Compile-Time template selector
+template <template <typename> class Comp, template <typename> class... Ops>
+struct cmRt2CtSelector
+{
+ template <typename T>
+ static bool eval(int r, T lhs, T rhs)
+ {
+ switch (r) {
+ case 0:
+ return false;
+ case 1:
+ return Comp<T>()(lhs, rhs);
+ default:
+ return cmRt2CtSelector<Ops...>::eval(r - 1, lhs, rhs);
+ }
+ }
+};
+
+template <template <typename> class Comp>
+struct cmRt2CtSelector<Comp>
+{
+ template <typename T>
+ static bool eval(int r, T lhs, T rhs)
+ {
+ return r == 1 && Comp<T>()(lhs, rhs);
+ }
+};
+
+std::string bool2string(bool const value)
+{
+ return std::string(std::size_t(1), static_cast<char>('0' + int(value)));
+}
+
+bool looksLikeSpecialVariable(const std::string& var,
+ cm::static_string_view prefix,
+ const std::size_t varNameLen)
+{
+ // NOTE Expecting a variable name at least 1 char length:
+ // <prefix> + `{` + <varname> + `}`
+ return ((prefix.size() + 3) <= varNameLen) &&
+ cmHasPrefix(var, cmStrCat(prefix, '{')) && var[varNameLen - 1] == '}';
+}
+} // anonymous namespace
+
+#if defined(__SUNPRO_CC)
+# define CM_INHERIT_CTOR(Class, Base, Tpl) \
+ template <typename... Args> \
+ Class(Args&&... args) \
+ : Base Tpl(std::forward<Args>(args)...) \
+ { \
+ }
+#else
+# define CM_INHERIT_CTOR(Class, Base, Tpl) using Base Tpl ::Base;
+#endif
+
+// BEGIN cmConditionEvaluator::cmArgumentList
+class cmConditionEvaluator::cmArgumentList
+ : public std::list<cmExpandedCommandArgument>
+{
+ using base_t = std::list<cmExpandedCommandArgument>;
+
+public:
+ CM_INHERIT_CTOR(cmArgumentList, list, <cmExpandedCommandArgument>);
+
+ class CurrentAndNextIter
+ {
+ friend class cmConditionEvaluator::cmArgumentList;
+
+ public:
+ base_t::iterator current;
+ base_t::iterator next;
+
+ CurrentAndNextIter advance(base_t& args)
+ {
+ this->current = std::next(this->current);
+ this->next =
+ std::next(this->current, difference_type(this->current != args.end()));
+ return *this;
+ }
+
+ private:
+ CurrentAndNextIter(base_t& args)
+ : current(args.begin())
+ , next(std::next(this->current,
+ difference_type(this->current != args.end())))
+ {
+ }
+ };
+
+ class CurrentAndTwoMoreIter
+ {
+ friend class cmConditionEvaluator::cmArgumentList;
+
+ public:
+ base_t::iterator current;
+ base_t::iterator next;
+ base_t::iterator nextnext;
+
+ CurrentAndTwoMoreIter advance(base_t& args)
+ {
+ this->current = std::next(this->current);
+ this->next =
+ std::next(this->current, difference_type(this->current != args.end()));
+ this->nextnext =
+ std::next(this->next, difference_type(this->next != args.end()));
+ return *this;
+ }
+
+ private:
+ CurrentAndTwoMoreIter(base_t& args)
+ : current(args.begin())
+ , next(std::next(this->current,
+ difference_type(this->current != args.end())))
+ , nextnext(
+ std::next(this->next, difference_type(this->next != args.end())))
+ {
+ }
+ };
+
+ CurrentAndNextIter make2ArgsIterator() { return *this; }
+ CurrentAndTwoMoreIter make3ArgsIterator() { return *this; }
+
+ template <typename Iter>
+ void ReduceOneArg(const bool value, Iter args)
+ {
+ *args.current = cmExpandedCommandArgument(bool2string(value), true);
+ this->erase(args.next);
+ }
+
+ void ReduceTwoArgs(const bool value, CurrentAndTwoMoreIter args)
+ {
+ *args.current = cmExpandedCommandArgument(bool2string(value), true);
+ this->erase(args.nextnext);
+ this->erase(args.next);
+ }
+};
+
+// END cmConditionEvaluator::cmArgumentList
cmConditionEvaluator::cmConditionEvaluator(cmMakefile& makefile,
cmListFileBacktrace bt)
@@ -99,25 +248,29 @@ bool cmConditionEvaluator::IsTrue(
// now loop through the arguments and see if we can reduce any of them
// we do this multiple times. Once for each level of precedence
// parens
- if (!this->HandleLevel0(newArgs, errorString, status)) {
- return false;
- }
- // predicates
- if (!this->HandleLevel1(newArgs, errorString, status)) {
- return false;
- }
- // binary ops
- if (!this->HandleLevel2(newArgs, errorString, status)) {
- return false;
- }
+ using handlerFn_t = bool (cmConditionEvaluator::*)(
+ cmArgumentList&, std::string&, MessageType&);
+ const std::array<handlerFn_t, 5> handlers = { {
+ &cmConditionEvaluator::HandleLevel0, // parenthesis
+ &cmConditionEvaluator::HandleLevel1, // predicates
+ &cmConditionEvaluator::HandleLevel2, // binary ops
+ &cmConditionEvaluator::HandleLevel3, // NOT
+ &cmConditionEvaluator::HandleLevel4 // AND OR
+ } };
+ for (auto fn : handlers) {
+ // Call the reducer 'till there is anything to reduce...
+ // (i.e., if after an iteration the size becomes smaller)
+ auto levelResult = true;
+ for (auto beginSize = newArgs.size();
+ (levelResult = (this->*fn)(newArgs, errorString, status)) &&
+ newArgs.size() < beginSize;
+ beginSize = newArgs.size()) {
+ }
- // NOT
- if (!this->HandleLevel3(newArgs, errorString, status)) {
- return false;
- }
- // AND OR
- if (!this->HandleLevel4(newArgs, errorString, status)) {
- return false;
+ if (!levelResult) {
+ // NOTE `errorString` supposed to be set already
+ return false;
+ }
}
// now at the end there should only be one argument left
@@ -147,11 +300,13 @@ cmProp cmConditionEvaluator::GetDefinitionIfUnquoted(
this->Policy54Status == cmPolicies::WARN) {
if (!this->Makefile.HasCMP0054AlreadyBeenReported(this->Backtrace.Top())) {
std::ostringstream e;
- e << (cmPolicies::GetPolicyWarning(cmPolicies::CMP0054)) << "\n";
- e << "Quoted variables like \"" << argument.GetValue()
- << "\" will no longer be dereferenced "
- "when the policy is set to NEW. "
+ // clang-format off
+ e << (cmPolicies::GetPolicyWarning(cmPolicies::CMP0054))
+ << "\n"
+ "Quoted variables like \"" << argument.GetValue() << "\" "
+ "will no longer be dereferenced when the policy is set to NEW. "
"Since the policy is not set the OLD behavior will be used.";
+ // clang-format on
this->Makefile.GetCMakeInstance()->IssueMessage(
MessageType::AUTHOR_WARNING, e.str(), this->Backtrace);
@@ -168,15 +323,16 @@ cmProp cmConditionEvaluator::GetVariableOrString(
cmProp def = this->GetDefinitionIfUnquoted(argument);
if (!def) {
- def = &argument.GetValue();
+ def = cmProp(argument.GetValue());
}
return def;
}
//=========================================================================
-bool cmConditionEvaluator::IsKeyword(std::string const& keyword,
- cmExpandedCommandArgument& argument) const
+bool cmConditionEvaluator::IsKeyword(
+ cm::static_string_view keyword,
+ const cmExpandedCommandArgument& argument) const
{
if ((this->Policy54Status != cmPolicies::WARN &&
this->Policy54Status != cmPolicies::OLD) &&
@@ -184,17 +340,20 @@ bool cmConditionEvaluator::IsKeyword(std::string const& keyword,
return false;
}
- bool isKeyword = argument.GetValue() == keyword;
+ const auto isKeyword = argument.GetValue() == keyword;
if (isKeyword && argument.WasQuoted() &&
this->Policy54Status == cmPolicies::WARN) {
if (!this->Makefile.HasCMP0054AlreadyBeenReported(this->Backtrace.Top())) {
std::ostringstream e;
- e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0054) << "\n";
- e << "Quoted keywords like \"" << argument.GetValue()
- << "\" will no longer be interpreted as keywords "
+ // clang-format off
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0054)
+ << "\n"
+ "Quoted keywords like \"" << argument.GetValue() << "\" "
+ "will no longer be interpreted as keywords "
"when the policy is set to NEW. "
"Since the policy is not set the OLD behavior will be used.";
+ // clang-format on
this->Makefile.GetCMakeInstance()->IssueMessage(
MessageType::AUTHOR_WARNING, e.str(), this->Backtrace);
@@ -208,15 +367,7 @@ bool cmConditionEvaluator::IsKeyword(std::string const& keyword,
bool cmConditionEvaluator::GetBooleanValue(
cmExpandedCommandArgument& arg) const
{
- // Check basic constants.
- if (arg == "0") {
- return false;
- }
- if (arg == "1") {
- return true;
- }
-
- // Check named constants.
+ // Check basic and named constants.
if (cmIsOn(arg.GetValue())) {
return true;
}
@@ -227,7 +378,7 @@ bool cmConditionEvaluator::GetBooleanValue(
// Check for numbers.
if (!arg.empty()) {
char* end;
- double d = strtod(arg.GetValue().c_str(), &end);
+ const double d = std::strtod(arg.GetValue().c_str(), &end);
if (*end == '\0') {
// The whole string is a number. Use C conversion to bool.
return static_cast<bool>(d);
@@ -242,7 +393,7 @@ bool cmConditionEvaluator::GetBooleanValue(
//=========================================================================
// Boolean value behavior from CMake 2.6.4 and below.
bool cmConditionEvaluator::GetBooleanValueOld(
- cmExpandedCommandArgument const& arg, bool one) const
+ cmExpandedCommandArgument const& arg, bool const one) const
{
if (one) {
// Old IsTrue behavior for single argument.
@@ -257,8 +408,8 @@ bool cmConditionEvaluator::GetBooleanValueOld(
}
// Old GetVariableOrNumber behavior.
cmProp def = this->GetDefinitionIfUnquoted(arg);
- if (!def && atoi(arg.GetValue().c_str())) {
- def = &arg.GetValue();
+ if (!def && std::atoi(arg.GetValue().c_str())) {
+ def = cmProp(arg.GetValue());
}
return !cmIsOff(def);
}
@@ -267,7 +418,7 @@ bool cmConditionEvaluator::GetBooleanValueOld(
// returns the resulting boolean value
bool cmConditionEvaluator::GetBooleanValueWithAutoDereference(
cmExpandedCommandArgument& newArg, std::string& errorString,
- MessageType& status, bool oneArg) const
+ MessageType& status, bool const oneArg) const
{
// Use the policy if it is set.
if (this->Policy12Status == cmPolicies::NEW) {
@@ -278,8 +429,8 @@ bool cmConditionEvaluator::GetBooleanValueWithAutoDereference(
}
// Check policy only if old and new results differ.
- bool newResult = this->GetBooleanValue(newArg);
- bool oldResult = this->GetBooleanValueOld(newArg, oneArg);
+ const auto newResult = this->GetBooleanValue(newArg);
+ const auto oldResult = this->GetBooleanValueOld(newArg, oneArg);
if (newResult != oldResult) {
switch (this->Policy12Status) {
case cmPolicies::WARN:
@@ -304,56 +455,31 @@ bool cmConditionEvaluator::GetBooleanValueWithAutoDereference(
return newResult;
}
-//=========================================================================
-void cmConditionEvaluator::IncrementArguments(
- cmArgumentList& newArgs, cmArgumentList::iterator& argP1,
- cmArgumentList::iterator& argP2) const
+template <int N>
+inline int cmConditionEvaluator::matchKeysImpl(
+ const cmExpandedCommandArgument&)
{
- if (argP1 != newArgs.end()) {
- argP1++;
- argP2 = argP1;
- if (argP1 != newArgs.end()) {
- argP2++;
- }
- }
+ // Zero means "not found"
+ return 0;
}
-//=========================================================================
-// helper function to reduce code duplication
-void cmConditionEvaluator::HandlePredicate(
- bool value, int& reducible, cmArgumentList::iterator& arg,
- cmArgumentList& newArgs, cmArgumentList::iterator& argP1,
- cmArgumentList::iterator& argP2) const
+template <int N, typename T, typename... Keys>
+inline int cmConditionEvaluator::matchKeysImpl(
+ const cmExpandedCommandArgument& arg, T current, Keys... key)
{
- if (value) {
- *arg = cmExpandedCommandArgument("1", true);
- } else {
- *arg = cmExpandedCommandArgument("0", true);
+ if (this->IsKeyword(current, arg)) {
+ // Stop searching as soon as smth has found
+ return N;
}
- newArgs.erase(argP1);
- argP1 = arg;
- this->IncrementArguments(newArgs, argP1, argP2);
- reducible = 1;
+ return matchKeysImpl<N + 1>(arg, key...);
}
-//=========================================================================
-// helper function to reduce code duplication
-void cmConditionEvaluator::HandleBinaryOp(bool value, int& reducible,
- cmArgumentList::iterator& arg,
- cmArgumentList& newArgs,
- cmArgumentList::iterator& argP1,
- cmArgumentList::iterator& argP2)
+template <typename... Keys>
+inline int cmConditionEvaluator::matchKeys(
+ const cmExpandedCommandArgument& arg, Keys... key)
{
- if (value) {
- *arg = cmExpandedCommandArgument("1", true);
- } else {
- *arg = cmExpandedCommandArgument("0", true);
- }
- newArgs.erase(argP2);
- newArgs.erase(argP1);
- argP1 = arg;
- this->IncrementArguments(newArgs, argP1, argP2);
- reducible = 1;
+ // Get index of the matched key (1-based)
+ return matchKeysImpl<1>(arg, key...);
}
//=========================================================================
@@ -362,55 +488,35 @@ bool cmConditionEvaluator::HandleLevel0(cmArgumentList& newArgs,
std::string& errorString,
MessageType& status)
{
- int reducible;
- do {
- reducible = 0;
- auto arg = newArgs.begin();
- while (arg != newArgs.end()) {
- if (this->IsKeyword(keyParenL, *arg)) {
- // search for the closing paren for this opening one
- cmArgumentList::iterator argClose;
- argClose = arg;
- argClose++;
- unsigned int depth = 1;
- while (argClose != newArgs.end() && depth) {
- if (this->IsKeyword(keyParenL, *argClose)) {
- depth++;
- }
- if (this->IsKeyword(keyParenR, *argClose)) {
- depth--;
- }
- argClose++;
- }
- if (depth) {
- errorString = "mismatched parenthesis in condition";
- status = MessageType::FATAL_ERROR;
- return false;
- }
- // store the reduced args in this vector
- std::vector<cmExpandedCommandArgument> newArgs2;
-
- // copy to the list structure
- auto argP1 = arg;
- argP1++;
- cm::append(newArgs2, argP1, argClose);
- newArgs2.pop_back();
- // now recursively invoke IsTrue to handle the values inside the
- // parenthetical expression
- bool value = this->IsTrue(newArgs2, errorString, status);
- if (value) {
- *arg = cmExpandedCommandArgument("1", true);
- } else {
- *arg = cmExpandedCommandArgument("0", true);
- }
- argP1 = arg;
- argP1++;
- // remove the now evaluated parenthetical expression
- newArgs.erase(argP1, argClose);
+ for (auto arg = newArgs.begin(); arg != newArgs.end(); ++arg) {
+ if (this->IsKeyword(keyParenL, *arg)) {
+ // search for the closing paren for this opening one
+ auto depth = 1;
+ auto argClose = std::next(arg);
+ for (; argClose != newArgs.end() && depth; ++argClose) {
+ depth += int(this->IsKeyword(keyParenL, *argClose)) -
+ int(this->IsKeyword(keyParenR, *argClose));
}
- ++arg;
+ if (depth) {
+ errorString = "mismatched parenthesis in condition";
+ status = MessageType::FATAL_ERROR;
+ return false;
+ }
+
+ // store the reduced args in this vector
+ auto argOpen = std::next(arg);
+ const std::vector<cmExpandedCommandArgument> subExpr(
+ argOpen, std::prev(argClose));
+
+ // now recursively invoke IsTrue to handle the values inside the
+ // parenthetical expression
+ const auto value = this->IsTrue(subExpr, errorString, status);
+ *arg = cmExpandedCommandArgument(bool2string(value), true);
+ argOpen = std::next(arg);
+ // remove the now evaluated parenthetical expression
+ newArgs.erase(argOpen, argClose);
}
- } while (reducible);
+ }
return true;
}
@@ -419,96 +525,104 @@ bool cmConditionEvaluator::HandleLevel0(cmArgumentList& newArgs,
bool cmConditionEvaluator::HandleLevel1(cmArgumentList& newArgs, std::string&,
MessageType&)
{
- int reducible;
- do {
- reducible = 0;
- auto arg = newArgs.begin();
- cmArgumentList::iterator argP1;
- cmArgumentList::iterator argP2;
- while (arg != newArgs.end()) {
- argP1 = arg;
- this->IncrementArguments(newArgs, argP1, argP2);
- // does a file exist
- if (this->IsKeyword(keyEXISTS, *arg) && argP1 != newArgs.end()) {
- this->HandlePredicate(cmSystemTools::FileExists(argP1->GetValue()),
- reducible, arg, newArgs, argP1, argP2);
- }
- // does a directory with this name exist
- if (this->IsKeyword(keyIS_DIRECTORY, *arg) && argP1 != newArgs.end()) {
- this->HandlePredicate(
- cmSystemTools::FileIsDirectory(argP1->GetValue()), reducible, arg,
- newArgs, argP1, argP2);
- }
- // does a symlink with this name exist
- if (this->IsKeyword(keyIS_SYMLINK, *arg) && argP1 != newArgs.end()) {
- this->HandlePredicate(cmSystemTools::FileIsSymlink(argP1->GetValue()),
- reducible, arg, newArgs, argP1, argP2);
- }
- // is the given path an absolute path ?
- if (this->IsKeyword(keyIS_ABSOLUTE, *arg) && argP1 != newArgs.end()) {
- this->HandlePredicate(cmSystemTools::FileIsFullPath(argP1->GetValue()),
- reducible, arg, newArgs, argP1, argP2);
- }
- // does a command exist
- if (this->IsKeyword(keyCOMMAND, *arg) && argP1 != newArgs.end()) {
- cmState::Command command =
- this->Makefile.GetState()->GetCommand(argP1->GetValue());
- this->HandlePredicate(command != nullptr, reducible, arg, newArgs,
- argP1, argP2);
- }
- // does a policy exist
- if (this->IsKeyword(keyPOLICY, *arg) && argP1 != newArgs.end()) {
- cmPolicies::PolicyID pid;
- this->HandlePredicate(
- cmPolicies::GetPolicyID(argP1->GetValue().c_str(), pid), reducible,
- arg, newArgs, argP1, argP2);
- }
- // does a target exist
- if (this->IsKeyword(keyTARGET, *arg) && argP1 != newArgs.end()) {
- this->HandlePredicate(
- this->Makefile.FindTargetToUse(argP1->GetValue()) != nullptr,
- reducible, arg, newArgs, argP1, argP2);
- }
- // does a test exist
- if (this->Policy64Status != cmPolicies::OLD &&
- this->Policy64Status != cmPolicies::WARN) {
- if (this->IsKeyword(keyTEST, *arg) && argP1 != newArgs.end()) {
- const cmTest* haveTest = this->Makefile.GetTest(argP1->GetValue());
- this->HandlePredicate(haveTest != nullptr, reducible, arg, newArgs,
- argP1, argP2);
- }
- } else if (this->Policy64Status == cmPolicies::WARN &&
- this->IsKeyword(keyTEST, *arg)) {
+ const auto policy64IsOld = this->Policy64Status == cmPolicies::OLD ||
+ this->Policy64Status == cmPolicies::WARN;
+
+ for (auto args = newArgs.make2ArgsIterator(); args.current != newArgs.end();
+ args.advance(newArgs)) {
+
+ auto policyCheck = [&, this](const cmPolicies::PolicyID id,
+ const cmPolicies::PolicyStatus status,
+ const cm::static_string_view kw) {
+ if (status == cmPolicies::WARN && this->IsKeyword(kw, *args.current)) {
std::ostringstream e;
- e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0064) << "\n";
- e << "TEST will be interpreted as an operator "
+ e << cmPolicies::GetPolicyWarning(id) << "\n"
+ << kw
+ << " will be interpreted as an operator "
"when the policy is set to NEW. "
"Since the policy is not set the OLD behavior will be used.";
this->Makefile.IssueMessage(MessageType::AUTHOR_WARNING, e.str());
}
- // is a variable defined
- if (this->IsKeyword(keyDEFINED, *arg) && argP1 != newArgs.end()) {
- size_t argP1len = argP1->GetValue().size();
- bool bdef = false;
- 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 &&
- cmHasLiteralPrefix(argP1->GetValue(), "CACHE{") &&
- argP1->GetValue().operator[](argP1len - 1) == '}') {
- std::string cache = argP1->GetValue().substr(6, argP1len - 7);
- bdef =
- this->Makefile.GetState()->GetCacheEntryValue(cache) != nullptr;
- } else {
- bdef = this->Makefile.IsDefinitionSet(argP1->GetValue());
- }
- this->HandlePredicate(bdef, reducible, arg, newArgs, argP1, argP2);
+ };
+
+ // NOTE Checking policies for warnings are not require an access to the
+ // next arg. Check them first!
+ policyCheck(cmPolicies::CMP0064, this->Policy64Status, keyTEST);
+
+ // NOTE Fail fast: All the predicates below require the next arg to be
+ // valid
+ if (args.next == newArgs.end()) {
+ continue;
+ }
+
+ // does a file exist
+ if (this->IsKeyword(keyEXISTS, *args.current)) {
+ newArgs.ReduceOneArg(cmSystemTools::FileExists(args.next->GetValue()),
+ args);
+ }
+ // does a directory with this name exist
+ else if (this->IsKeyword(keyIS_DIRECTORY, *args.current)) {
+ newArgs.ReduceOneArg(
+ cmSystemTools::FileIsDirectory(args.next->GetValue()), args);
+ }
+ // does a symlink with this name exist
+ else if (this->IsKeyword(keyIS_SYMLINK, *args.current)) {
+ newArgs.ReduceOneArg(cmSystemTools::FileIsSymlink(args.next->GetValue()),
+ args);
+ }
+ // is the given path an absolute path ?
+ else if (this->IsKeyword(keyIS_ABSOLUTE, *args.current)) {
+ newArgs.ReduceOneArg(
+ cmSystemTools::FileIsFullPath(args.next->GetValue()), args);
+ }
+ // does a command exist
+ else if (this->IsKeyword(keyCOMMAND, *args.current)) {
+ newArgs.ReduceOneArg(
+ bool(this->Makefile.GetState()->GetCommand(args.next->GetValue())),
+ args);
+ }
+ // does a policy exist
+ else if (this->IsKeyword(keyPOLICY, *args.current)) {
+ cmPolicies::PolicyID pid;
+ newArgs.ReduceOneArg(
+ cmPolicies::GetPolicyID(args.next->GetValue().c_str(), pid), args);
+ }
+ // does a target exist
+ else if (this->IsKeyword(keyTARGET, *args.current)) {
+ newArgs.ReduceOneArg(
+ bool(this->Makefile.FindTargetToUse(args.next->GetValue())), args);
+ }
+ // is a variable defined
+ else if (this->IsKeyword(keyDEFINED, *args.current)) {
+ const auto& var = args.next->GetValue();
+ const auto varNameLen = var.size();
+
+ auto result = false;
+ if (looksLikeSpecialVariable(var, "ENV"_s, varNameLen)) {
+ const auto env = args.next->GetValue().substr(4, varNameLen - 5);
+ result = cmSystemTools::HasEnv(env);
+ }
+
+ else if (looksLikeSpecialVariable(var, "CACHE"_s, varNameLen)) {
+ const auto cache = args.next->GetValue().substr(6, varNameLen - 7);
+ result = bool(this->Makefile.GetState()->GetCacheEntryValue(cache));
}
- ++arg;
+
+ else {
+ result = this->Makefile.IsDefinitionSet(args.next->GetValue());
+ }
+ newArgs.ReduceOneArg(result, args);
+ }
+ // does a test exist
+ else if (this->IsKeyword(keyTEST, *args.current)) {
+ if (policy64IsOld) {
+ continue;
+ }
+ newArgs.ReduceOneArg(bool(this->Makefile.GetTest(args.next->GetValue())),
+ args);
}
- } while (reducible);
+ }
return true;
}
@@ -518,178 +632,143 @@ bool cmConditionEvaluator::HandleLevel2(cmArgumentList& newArgs,
std::string& errorString,
MessageType& status)
{
- int reducible;
- std::string def_buf;
- cmProp def;
- cmProp def2;
- do {
- reducible = 0;
- auto arg = newArgs.begin();
- cmArgumentList::iterator argP1;
- cmArgumentList::iterator argP2;
- while (arg != newArgs.end()) {
- argP1 = arg;
- this->IncrementArguments(newArgs, argP1, argP2);
- if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
- this->IsKeyword(keyMATCHES, *argP1)) {
- def = this->GetDefinitionIfUnquoted(*arg);
- if (!def) {
- def = &arg->GetValue();
- } else if (cmHasLiteralPrefix(arg->GetValue(), "CMAKE_MATCH_")) {
- // The string to match is owned by our match result variables.
- // Move it to our own buffer before clearing them.
- def_buf = *def;
- def = &def_buf;
- }
- const std::string& rex = argP2->GetValue();
- this->Makefile.ClearMatches();
- cmsys::RegularExpression regEntry;
- if (!regEntry.compile(rex)) {
- std::ostringstream error;
- error << "Regular expression \"" << rex << "\" cannot compile";
- errorString = error.str();
- status = MessageType::FATAL_ERROR;
- return false;
- }
- if (regEntry.find(*def)) {
- this->Makefile.StoreMatches(regEntry);
- *arg = cmExpandedCommandArgument("1", true);
- } else {
- *arg = cmExpandedCommandArgument("0", true);
- }
- newArgs.erase(argP2);
- newArgs.erase(argP1);
- argP1 = arg;
- this->IncrementArguments(newArgs, argP1, argP2);
- reducible = 1;
- }
+ for (auto args = newArgs.make3ArgsIterator(); args.current != newArgs.end();
+ args.advance(newArgs)) {
- if (argP1 != newArgs.end() && this->IsKeyword(keyMATCHES, *arg)) {
- *arg = cmExpandedCommandArgument("0", true);
- newArgs.erase(argP1);
- argP1 = arg;
- this->IncrementArguments(newArgs, argP1, argP2);
- reducible = 1;
- }
+ int matchNo;
- if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
- (this->IsKeyword(keyLESS, *argP1) ||
- this->IsKeyword(keyLESS_EQUAL, *argP1) ||
- this->IsKeyword(keyGREATER, *argP1) ||
- this->IsKeyword(keyGREATER_EQUAL, *argP1) ||
- this->IsKeyword(keyEQUAL, *argP1))) {
- def = this->GetVariableOrString(*arg);
- def2 = this->GetVariableOrString(*argP2);
- double lhs;
- double rhs;
- bool result;
- if (sscanf(def->c_str(), "%lg", &lhs) != 1 ||
- sscanf(def2->c_str(), "%lg", &rhs) != 1) {
- result = false;
- } else if (*(argP1) == keyLESS) {
- result = (lhs < rhs);
- } else if (*(argP1) == keyLESS_EQUAL) {
- result = (lhs <= rhs);
- } else if (*(argP1) == keyGREATER) {
- result = (lhs > rhs);
- } else if (*(argP1) == keyGREATER_EQUAL) {
- result = (lhs >= rhs);
- } else {
- result = (lhs == rhs);
- }
- this->HandleBinaryOp(result, reducible, arg, newArgs, argP1, argP2);
- }
+ // NOTE Handle special case `if(... BLAH_BLAH MATCHES)`
+ // (i.e., w/o regex to match which is possibly result of
+ // variable expansion to an empty string)
+ if (args.next != newArgs.end() &&
+ this->IsKeyword(keyMATCHES, *args.current)) {
+ newArgs.ReduceOneArg(false, args);
+ }
+
+ // NOTE Fail fast: All the binary ops below require 2 arguments.
+ else if (args.next == newArgs.end() || args.nextnext == newArgs.end()) {
+ continue;
+ }
- if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
- (this->IsKeyword(keySTRLESS, *argP1) ||
- this->IsKeyword(keySTRLESS_EQUAL, *argP1) ||
- this->IsKeyword(keySTRGREATER, *argP1) ||
- this->IsKeyword(keySTRGREATER_EQUAL, *argP1) ||
- this->IsKeyword(keySTREQUAL, *argP1))) {
- def = this->GetVariableOrString(*arg);
- def2 = this->GetVariableOrString(*argP2);
- int val = (*def).compare(*def2);
- bool result;
- if (*(argP1) == keySTRLESS) {
- result = (val < 0);
- } else if (*(argP1) == keySTRLESS_EQUAL) {
- result = (val <= 0);
- } else if (*(argP1) == keySTRGREATER) {
- result = (val > 0);
- } else if (*(argP1) == keySTRGREATER_EQUAL) {
- result = (val >= 0);
- } else // strequal
- {
- result = (val == 0);
- }
- this->HandleBinaryOp(result, reducible, arg, newArgs, argP1, argP2);
+ else if (this->IsKeyword(keyMATCHES, *args.next)) {
+ cmProp def = this->GetDefinitionIfUnquoted(*args.current);
+
+ std::string def_buf;
+ if (!def) {
+ def = cmProp(args.current->GetValue());
+ } else if (cmHasLiteralPrefix(args.current->GetValue(),
+ "CMAKE_MATCH_")) {
+ // The string to match is owned by our match result variables.
+ // Move it to our own buffer before clearing them.
+ def_buf = *def;
+ def = cmProp(def_buf);
}
- if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
- (this->IsKeyword(keyVERSION_LESS, *argP1) ||
- this->IsKeyword(keyVERSION_LESS_EQUAL, *argP1) ||
- this->IsKeyword(keyVERSION_GREATER, *argP1) ||
- this->IsKeyword(keyVERSION_GREATER_EQUAL, *argP1) ||
- this->IsKeyword(keyVERSION_EQUAL, *argP1))) {
- def = this->GetVariableOrString(*arg);
- def2 = this->GetVariableOrString(*argP2);
- cmSystemTools::CompareOp op;
- if (*argP1 == keyVERSION_LESS) {
- op = cmSystemTools::OP_LESS;
- } else if (*argP1 == keyVERSION_LESS_EQUAL) {
- op = cmSystemTools::OP_LESS_EQUAL;
- } else if (*argP1 == keyVERSION_GREATER) {
- op = cmSystemTools::OP_GREATER;
- } else if (*argP1 == keyVERSION_GREATER_EQUAL) {
- op = cmSystemTools::OP_GREATER_EQUAL;
- } else { // version_equal
- op = cmSystemTools::OP_EQUAL;
- }
- bool result =
- cmSystemTools::VersionCompare(op, def->c_str(), def2->c_str());
- this->HandleBinaryOp(result, reducible, arg, newArgs, argP1, argP2);
+ this->Makefile.ClearMatches();
+
+ const auto& rex = args.nextnext->GetValue();
+ cmsys::RegularExpression regEntry;
+ if (!regEntry.compile(rex)) {
+ std::ostringstream error;
+ error << "Regular expression \"" << rex << "\" cannot compile";
+ errorString = error.str();
+ status = MessageType::FATAL_ERROR;
+ return false;
}
- // is file A newer than file B
- if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
- this->IsKeyword(keyIS_NEWER_THAN, *argP1)) {
- int fileIsNewer = 0;
- cmsys::Status ftcStatus = cmSystemTools::FileTimeCompare(
- arg->GetValue(), (argP2)->GetValue(), &fileIsNewer);
- this->HandleBinaryOp(
- (!ftcStatus || fileIsNewer == 1 || fileIsNewer == 0), reducible, arg,
- newArgs, argP1, argP2);
+ const auto match = regEntry.find(*def);
+ if (match) {
+ this->Makefile.StoreMatches(regEntry);
}
+ newArgs.ReduceTwoArgs(match, args);
+ }
+
+ else if ((matchNo =
+ this->matchKeys(*args.next, keyLESS, keyLESS_EQUAL, keyGREATER,
+ keyGREATER_EQUAL, keyEQUAL))) {
+
+ cmProp ldef = this->GetVariableOrString(*args.current);
+ cmProp rdef = this->GetVariableOrString(*args.nextnext);
+
+ double lhs;
+ double rhs;
+ auto parseDoubles = [&]() {
+ return std::sscanf(ldef->c_str(), "%lg", &lhs) == 1 &&
+ std::sscanf(rdef->c_str(), "%lg", &rhs) == 1;
+ };
+ // clang-format off
+ const auto result = parseDoubles() &&
+ cmRt2CtSelector<
+ std::less, std::less_equal,
+ std::greater, std::greater_equal,
+ std::equal_to
+ >::eval(matchNo, lhs, rhs);
+ // clang-format on
+ newArgs.ReduceTwoArgs(result, args);
+ }
+
+ else if ((matchNo = this->matchKeys(*args.next, keySTRLESS,
+ keySTRLESS_EQUAL, keySTRGREATER,
+ keySTRGREATER_EQUAL, keySTREQUAL))) {
+
+ const cmProp lhs = this->GetVariableOrString(*args.current);
+ const cmProp rhs = this->GetVariableOrString(*args.nextnext);
+ const auto val = (*lhs).compare(*rhs);
+ // clang-format off
+ const auto result = cmRt2CtSelector<
+ std::less, std::less_equal,
+ std::greater, std::greater_equal,
+ std::equal_to
+ >::eval(matchNo, val, 0);
+ // clang-format on
+ newArgs.ReduceTwoArgs(result, args);
+ }
+
+ else if ((matchNo =
+ this->matchKeys(*args.next, keyVERSION_LESS,
+ keyVERSION_LESS_EQUAL, keyVERSION_GREATER,
+ keyVERSION_GREATER_EQUAL, keyVERSION_EQUAL))) {
+ const auto op = MATCH2CMPOP[matchNo - 1];
+ const cmProp lhs = this->GetVariableOrString(*args.current);
+ const cmProp rhs = this->GetVariableOrString(*args.nextnext);
+ const auto result =
+ cmSystemTools::VersionCompare(op, lhs->c_str(), rhs->c_str());
+ newArgs.ReduceTwoArgs(result, args);
+ }
+
+ // is file A newer than file B
+ else if (this->IsKeyword(keyIS_NEWER_THAN, *args.next)) {
+ auto fileIsNewer = 0;
+ cmsys::Status ftcStatus = cmSystemTools::FileTimeCompare(
+ args.current->GetValue(), args.nextnext->GetValue(), &fileIsNewer);
+ newArgs.ReduceTwoArgs(
+ (!ftcStatus || fileIsNewer == 1 || fileIsNewer == 0), args);
+ }
+
+ else if (this->IsKeyword(keyIN_LIST, *args.next)) {
- if (argP1 != newArgs.end() && argP2 != newArgs.end() &&
- this->IsKeyword(keyIN_LIST, *argP1)) {
- if (this->Policy57Status != cmPolicies::OLD &&
- this->Policy57Status != cmPolicies::WARN) {
- bool result = false;
-
- def = this->GetVariableOrString(*arg);
- def2 = this->Makefile.GetDefinition(argP2->GetValue());
-
- if (def2) {
- std::vector<std::string> list = cmExpandedList(*def2, true);
- result = cm::contains(list, *def);
- }
-
- this->HandleBinaryOp(result, reducible, arg, newArgs, argP1, argP2);
- } else if (this->Policy57Status == cmPolicies::WARN) {
- std::ostringstream e;
- e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0057) << "\n";
- e << "IN_LIST will be interpreted as an operator "
- "when the policy is set to NEW. "
- "Since the policy is not set the OLD behavior will be used.";
-
- this->Makefile.IssueMessage(MessageType::AUTHOR_WARNING, e.str());
- }
+ if (this->Policy57Status != cmPolicies::OLD &&
+ this->Policy57Status != cmPolicies::WARN) {
+
+ cmProp lhs = this->GetVariableOrString(*args.current);
+ cmProp rhs = this->Makefile.GetDefinition(args.nextnext->GetValue());
+
+ newArgs.ReduceTwoArgs(
+ rhs && cm::contains(cmExpandedList(*rhs, true), *lhs), args);
}
- ++arg;
+ else if (this->Policy57Status == cmPolicies::WARN) {
+ std::ostringstream e;
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0057)
+ << "\n"
+ "IN_LIST will be interpreted as an operator "
+ "when the policy is set to NEW. "
+ "Since the policy is not set the OLD behavior will be used.";
+
+ this->Makefile.IssueMessage(MessageType::AUTHOR_WARNING, e.str());
+ }
}
- } while (reducible);
+ }
return true;
}
@@ -699,23 +778,14 @@ bool cmConditionEvaluator::HandleLevel3(cmArgumentList& newArgs,
std::string& errorString,
MessageType& status)
{
- int reducible;
- do {
- reducible = 0;
- auto arg = newArgs.begin();
- cmArgumentList::iterator argP1;
- cmArgumentList::iterator argP2;
- while (arg != newArgs.end()) {
- argP1 = arg;
- this->IncrementArguments(newArgs, argP1, argP2);
- if (argP1 != newArgs.end() && this->IsKeyword(keyNOT, *arg)) {
- bool rhs = this->GetBooleanValueWithAutoDereference(
- *argP1, errorString, status);
- this->HandlePredicate(!rhs, reducible, arg, newArgs, argP1, argP2);
- }
- ++arg;
+ for (auto args = newArgs.make2ArgsIterator(); args.next != newArgs.end();
+ args.advance(newArgs)) {
+ if (this->IsKeyword(keyNOT, *args.current)) {
+ const auto rhs = this->GetBooleanValueWithAutoDereference(
+ *args.next, errorString, status);
+ newArgs.ReduceOneArg(!rhs, args);
}
- } while (reducible);
+ }
return true;
}
@@ -725,38 +795,24 @@ bool cmConditionEvaluator::HandleLevel4(cmArgumentList& newArgs,
std::string& errorString,
MessageType& status)
{
- int reducible;
- bool lhs;
- bool rhs;
- do {
- reducible = 0;
- auto arg = newArgs.begin();
- cmArgumentList::iterator argP1;
- cmArgumentList::iterator argP2;
- while (arg != newArgs.end()) {
- argP1 = arg;
- this->IncrementArguments(newArgs, argP1, argP2);
- if (argP1 != newArgs.end() && this->IsKeyword(keyAND, *argP1) &&
- argP2 != newArgs.end()) {
- lhs =
- this->GetBooleanValueWithAutoDereference(*arg, errorString, status);
- rhs = this->GetBooleanValueWithAutoDereference(*argP2, errorString,
- status);
- this->HandleBinaryOp((lhs && rhs), reducible, arg, newArgs, argP1,
- argP2);
- }
-
- if (argP1 != newArgs.end() && this->IsKeyword(keyOR, *argP1) &&
- argP2 != newArgs.end()) {
- lhs =
- this->GetBooleanValueWithAutoDereference(*arg, errorString, status);
- rhs = this->GetBooleanValueWithAutoDereference(*argP2, errorString,
- status);
- this->HandleBinaryOp((lhs || rhs), reducible, arg, newArgs, argP1,
- argP2);
- }
- ++arg;
+ for (auto args = newArgs.make3ArgsIterator(); args.nextnext != newArgs.end();
+ args.advance(newArgs)) {
+
+ int matchNo;
+
+ if ((matchNo = this->matchKeys(*args.next, keyAND, keyOR))) {
+ const auto lhs = this->GetBooleanValueWithAutoDereference(
+ *args.current, errorString, status);
+ const auto rhs = this->GetBooleanValueWithAutoDereference(
+ *args.nextnext, errorString, status);
+ // clang-format off
+ const auto result =
+ cmRt2CtSelector<
+ std::logical_and, std::logical_or
+ >::eval(matchNo, lhs, rhs);
+ // clang-format on
+ newArgs.ReduceTwoArgs(result, args);
}
- } while (reducible);
+ }
return true;
}
diff --git a/Source/cmConditionEvaluator.h b/Source/cmConditionEvaluator.h
index cf00ede..00d896b 100644
--- a/Source/cmConditionEvaluator.h
+++ b/Source/cmConditionEvaluator.h
@@ -4,23 +4,22 @@
#include "cmConfigure.h" // IWYU pragma: keep
-#include <list>
#include <string>
#include <vector>
-#include "cmExpandedCommandArgument.h"
+#include <cmext/string_view>
+
#include "cmListFileCache.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmProperty.h"
+class cmExpandedCommandArgument;
class cmMakefile;
class cmConditionEvaluator
{
public:
- using cmArgumentList = std::list<cmExpandedCommandArgument>;
-
cmConditionEvaluator(cmMakefile& makefile, cmListFileBacktrace bt);
// this is a shared function for both If and Else to determine if the
@@ -30,14 +29,16 @@ public:
std::string& errorString, MessageType& status);
private:
+ class cmArgumentList;
+
// Filter the given variable definition based on policy CMP0054.
cmProp GetDefinitionIfUnquoted(
const cmExpandedCommandArgument& argument) const;
cmProp GetVariableOrString(const cmExpandedCommandArgument& argument) const;
- bool IsKeyword(std::string const& keyword,
- cmExpandedCommandArgument& argument) const;
+ bool IsKeyword(cm::static_string_view keyword,
+ const cmExpandedCommandArgument& argument) const;
bool GetBooleanValue(cmExpandedCommandArgument& arg) const;
@@ -49,19 +50,14 @@ private:
MessageType& status,
bool oneArg = false) const;
- void IncrementArguments(cmArgumentList& newArgs,
- cmArgumentList::iterator& argP1,
- cmArgumentList::iterator& argP2) const;
+ template <int N>
+ int matchKeysImpl(const cmExpandedCommandArgument&);
- void HandlePredicate(bool value, int& reducible,
- cmArgumentList::iterator& arg, cmArgumentList& newArgs,
- cmArgumentList::iterator& argP1,
- cmArgumentList::iterator& argP2) const;
+ template <int N, typename T, typename... Keys>
+ int matchKeysImpl(const cmExpandedCommandArgument&, T, Keys...);
- void HandleBinaryOp(bool value, int& reducible,
- cmArgumentList::iterator& arg, cmArgumentList& newArgs,
- cmArgumentList::iterator& argP1,
- cmArgumentList::iterator& argP2);
+ template <typename... Keys>
+ int matchKeys(const cmExpandedCommandArgument&, Keys...);
bool HandleLevel0(cmArgumentList& newArgs, std::string& errorString,
MessageType& status);
diff --git a/Source/cmConfigure.cmake.h.in b/Source/cmConfigure.cmake.h.in
index aeca6b4..6a419f6 100644
--- a/Source/cmConfigure.cmake.h.in
+++ b/Source/cmConfigure.cmake.h.in
@@ -16,7 +16,6 @@
#cmakedefine HAVE_ENVIRON_NOT_REQUIRE_PROTOTYPE
#cmakedefine HAVE_UNSETENV
-#cmakedefine CMake_USE_ELF_PARSER
#cmakedefine CMake_USE_MACH_PARSER
#cmakedefine CMake_USE_XCOFF_PARSER
#define CMake_DEFAULT_RECURSION_LIMIT @CMake_DEFAULT_RECURSION_LIMIT@
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index bf18143..0fd48f0 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -606,7 +606,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
std::string langFlags = "CMAKE_" + li + "_FLAGS";
cmProp flags = this->Makefile->GetDefinition(langFlags);
fprintf(fout, "set(CMAKE_%s_FLAGS %s)\n", li.c_str(),
- cmOutputConverter::EscapeForCMake(cmToCStrSafe(flags)).c_str());
+ cmOutputConverter::EscapeForCMake(flags).c_str());
fprintf(fout,
"set(CMAKE_%s_FLAGS \"${CMAKE_%s_FLAGS}"
" ${COMPILE_DEFINITIONS}\")\n",
@@ -644,9 +644,8 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
std::string const langFlagsCfg =
cmStrCat("CMAKE_", li, "_FLAGS_", cfg);
cmProp flagsCfg = this->Makefile->GetDefinition(langFlagsCfg);
- fprintf(
- fout, "set(%s %s)\n", langFlagsCfg.c_str(),
- cmOutputConverter::EscapeForCMake(cmToCStrSafe(flagsCfg)).c_str());
+ fprintf(fout, "set(%s %s)\n", langFlagsCfg.c_str(),
+ cmOutputConverter::EscapeForCMake(flagsCfg).c_str());
}
} break;
}
@@ -679,8 +678,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
cmProp exeLinkFlags =
this->Makefile->GetDefinition("CMAKE_EXE_LINKER_FLAGS");
fprintf(fout, "set(CMAKE_EXE_LINKER_FLAGS %s)\n",
- cmOutputConverter::EscapeForCMake(cmToCStrSafe(exeLinkFlags))
- .c_str());
+ cmOutputConverter::EscapeForCMake(exeLinkFlags).c_str());
}
break;
}
diff --git a/Source/cmDefinitions.cxx b/Source/cmDefinitions.cxx
index 4a4f87d..9e2d7b9 100644
--- a/Source/cmDefinitions.cxx
+++ b/Source/cmDefinitions.cxx
@@ -34,11 +34,11 @@ cmDefinitions::Def const& cmDefinitions::GetInternal(const std::string& key,
return begin->Map.emplace(key, def).first->second;
}
-const std::string* cmDefinitions::Get(const std::string& key, StackIter begin,
- StackIter end)
+cmProp cmDefinitions::Get(const std::string& key, StackIter begin,
+ StackIter end)
{
Def const& def = cmDefinitions::GetInternal(key, begin, end, false);
- return def.Value ? def.Value.str_if_stable() : nullptr;
+ return def.Value ? cmProp(def.Value.str_if_stable()) : nullptr;
}
void cmDefinitions::Raise(const std::string& key, StackIter begin,
diff --git a/Source/cmDefinitions.h b/Source/cmDefinitions.h
index b650aa8..ee1db7a 100644
--- a/Source/cmDefinitions.h
+++ b/Source/cmDefinitions.h
@@ -12,6 +12,7 @@
#include <cm/string_view>
#include "cmLinkedTree.h"
+#include "cmProperty.h"
#include "cmString.hxx"
/** \class cmDefinitions
@@ -28,8 +29,7 @@ class cmDefinitions
public:
// -- Static member functions
- static const std::string* Get(const std::string& key, StackIter begin,
- StackIter end);
+ static cmProp Get(const std::string& key, StackIter begin, StackIter end);
static void Raise(const std::string& key, StackIter begin, StackIter end);
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx
index bca26b9..6024cf6 100644
--- a/Source/cmDependsFortran.cxx
+++ b/Source/cmDependsFortran.cxx
@@ -163,12 +163,17 @@ bool cmDependsFortran::Finalize(std::ostream& makeDepends,
mod_dir = this->LocalGenerator->GetCurrentBinaryDirectory();
}
+ bool building_intrinsics =
+ !mf->GetSafeDefinition("CMAKE_Fortran_TARGET_BUILDING_INSTRINSIC_MODULES")
+ .empty();
+
// Actually write dependencies to the streams.
using ObjectInfoMap = cmDependsFortranInternals::ObjectInfoMap;
ObjectInfoMap const& objInfo = this->Internal->ObjectInfo;
for (auto const& i : objInfo) {
if (!this->WriteDependenciesReal(i.first, i.second, mod_dir, stamp_dir,
- makeDepends, internalDepends)) {
+ makeDepends, internalDepends,
+ building_intrinsics)) {
return false;
}
}
@@ -307,7 +312,8 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj,
std::string const& mod_dir,
std::string const& stamp_dir,
std::ostream& makeDepends,
- std::ostream& internalDepends)
+ std::ostream& internalDepends,
+ bool buildingIntrinsics)
{
// Get the source file for this object.
std::string const& src = info.Source;
@@ -339,8 +345,13 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj,
makeDepends << '\n';
}
+ std::set<std::string> req = info.Requires;
+ if (buildingIntrinsics) {
+ req.insert(info.Intrinsics.begin(), info.Intrinsics.end());
+ }
+
// Write module requirements to the output stream.
- for (std::string const& i : info.Requires) {
+ for (std::string const& i : req) {
// Require only modules not provided in the same source.
if (info.Provides.find(i) != info.Provides.cend()) {
continue;
diff --git a/Source/cmDependsFortran.h b/Source/cmDependsFortran.h
index 0d407bc..a74db91 100644
--- a/Source/cmDependsFortran.h
+++ b/Source/cmDependsFortran.h
@@ -72,7 +72,8 @@ protected:
std::string const& mod_dir,
std::string const& stamp_dir,
std::ostream& makeDepends,
- std::ostream& internalDepends);
+ std::ostream& internalDepends,
+ bool buildingIntrinsics);
// The source file from which to start scanning.
std::string SourceFile;
diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx
index 9a474e3..1678ce8 100644
--- a/Source/cmELF.cxx
+++ b/Source/cmELF.cxx
@@ -17,41 +17,9 @@
#include "cmsys/FStream.hxx"
-// Include the ELF format information system header.
-#if defined(__OpenBSD__)
-# include <elf_abi.h>
-#elif defined(__HAIKU__)
-# include <elf32.h>
-# include <elf64.h>
-using Elf32_Ehdr = struct Elf32_Ehdr;
-using Elf32_Shdr = struct Elf32_Shdr;
-using Elf32_Sym = struct Elf32_Sym;
-using Elf32_Rel = struct Elf32_Rel;
-using Elf32_Rela = struct Elf32_Rela;
-# define ELFMAG0 0x7F
-# define ELFMAG1 'E'
-# define ELFMAG2 'L'
-# define ELFMAG3 'F'
-# define ET_NONE 0
-# define ET_REL 1
-# define ET_EXEC 2
-# define ET_DYN 3
-# define ET_CORE 4
-# define EM_386 3
-# define EM_SPARC 2
-# define EM_PPC 20
-#else
-# include <elf.h>
-#endif
-#if defined(__sun)
-# include <sys/link.h> // For dynamic section information
-#endif
-#ifdef _SCO_DS
-# include <link.h> // For DT_SONAME etc.
-#endif
-#ifndef DT_RUNPATH
-# define DT_RUNPATH 29
-#endif
+#include "cmelf/elf32.h"
+#include "cmelf/elf64.h"
+#include "cmelf/elf_common.h"
// Low-level byte swapping implementation.
template <size_t s>
@@ -145,6 +113,7 @@ public:
virtual std::vector<char> EncodeDynamicEntries(
const cmELF::DynamicEntryList&) = 0;
virtual StringEntry const* GetDynamicSectionString(unsigned int tag) = 0;
+ virtual bool IsMips() const = 0;
virtual void PrintInfo(std::ostream& os) const = 0;
// Lookup the SONAME in the DYNAMIC section.
@@ -218,7 +187,6 @@ struct cmELFTypes32
};
// Configure the implementation template for 64-bit ELF files.
-#ifndef _SCO_DS
struct cmELFTypes64
{
using ELF_Ehdr = Elf64_Ehdr;
@@ -228,7 +196,6 @@ struct cmELFTypes64
using tagtype = ::uint64_t;
static const char* GetName() { return "64-bit"; }
};
-#endif
// Parser implementation template.
template <class Types>
@@ -262,6 +229,8 @@ public:
// Lookup a string from the dynamic section with the given tag.
StringEntry const* GetDynamicSectionString(unsigned int tag) override;
+ bool IsMips() const override { return this->ELFHeader.e_machine == EM_MIPS; }
+
// Print information about the ELF file.
void PrintInfo(std::ostream& os) const override
{
@@ -345,16 +314,12 @@ private:
eti == ET_CORE) {
return true;
}
-#if defined(ET_LOOS) && defined(ET_HIOS)
if (eti >= ET_LOOS && eti <= ET_HIOS) {
return true;
}
-#endif
-#if defined(ET_LOPROC) && defined(ET_HIPROC)
if (eti >= ET_LOPROC && eti <= ET_HIPROC) {
return true;
}
-#endif
return false;
}
@@ -465,18 +430,14 @@ cmELFInternalImpl<Types>::cmELFInternalImpl(cmELF* external,
break;
default: {
unsigned int eti = static_cast<unsigned int>(this->ELFHeader.e_type);
-#if defined(ET_LOOS) && defined(ET_HIOS)
if (eti >= ET_LOOS && eti <= ET_HIOS) {
this->ELFType = cmELF::FileTypeSpecificOS;
break;
}
-#endif
-#if defined(ET_LOPROC) && defined(ET_HIPROC)
if (eti >= ET_LOPROC && eti <= ET_HIPROC) {
this->ELFType = cmELF::FileTypeSpecificProc;
break;
}
-#endif
std::ostringstream e;
e << "Unknown ELF file type " << eti;
this->SetErrorMessage(e.str().c_str());
@@ -681,17 +642,12 @@ cmELF::StringEntry const* cmELFInternalImpl<Types>::GetDynamicSectionString(
const long cmELF::TagRPath = DT_RPATH;
const long cmELF::TagRunPath = DT_RUNPATH;
-
-#ifdef DT_MIPS_RLD_MAP_REL
const long cmELF::TagMipsRldMapRel = DT_MIPS_RLD_MAP_REL;
-#else
-const long cmELF::TagMipsRldMapRel = 0;
-#endif
cmELF::cmELF(const char* fname)
{
// Try to open the file.
- auto fin = cm::make_unique<cmsys::ifstream>(fname);
+ auto fin = cm::make_unique<cmsys::ifstream>(fname, std::ios::binary);
// Quit now if the file could not be opened.
if (!fin || !*fin) {
@@ -736,15 +692,11 @@ cmELF::cmELF(const char* fname)
// 32-bit ELF
this->Internal = cm::make_unique<cmELFInternalImpl<cmELFTypes32>>(
this, std::move(fin), order);
- }
-#ifndef _SCO_DS
- else if (ident[EI_CLASS] == ELFCLASS64) {
+ } else if (ident[EI_CLASS] == ELFCLASS64) {
// 64-bit ELF
this->Internal = cm::make_unique<cmELFInternalImpl<cmELFTypes64>>(
this, std::move(fin), order);
- }
-#endif
- else {
+ } else {
this->ErrorMessage = "ELF file class is not 32-bit or 64-bit.";
return;
}
@@ -846,6 +798,14 @@ cmELF::StringEntry const* cmELF::GetRunPath()
return nullptr;
}
+bool cmELF::IsMIPS() const
+{
+ if (this->Valid()) {
+ return this->Internal->IsMips();
+ }
+ return false;
+}
+
void cmELF::PrintInfo(std::ostream& os) const
{
if (this->Valid()) {
diff --git a/Source/cmELF.h b/Source/cmELF.h
index f88ebe9..ce8bd7f 100644
--- a/Source/cmELF.h
+++ b/Source/cmELF.h
@@ -11,10 +11,6 @@
#include <utility>
#include <vector>
-#if !defined(CMake_USE_ELF_PARSER)
-# error "This file may be included only if CMake_USE_ELF_PARSER is enabled."
-#endif
-
class cmELFInternal;
/** \class cmELF
@@ -102,6 +98,9 @@ public:
/** Get the RUNPATH field if any. */
StringEntry const* GetRunPath();
+ /** Returns true if the ELF file targets a MIPS CPU. */
+ bool IsMIPS() const;
+
/** Print human-readable information about the ELF file. */
void PrintInfo(std::ostream& os) const;
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index 1a31ae4..6e3f918 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -18,6 +18,7 @@
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
+#include "cmProperty.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmTarget.h"
@@ -254,7 +255,7 @@ void cmExportBuildFileGenerator::SetImportLocationProperty(
void cmExportBuildFileGenerator::HandleMissingTarget(
std::string& link_libs, std::vector<std::string>& missingTargets,
- cmGeneratorTarget* depender, cmGeneratorTarget* dependee)
+ cmGeneratorTarget const* depender, cmGeneratorTarget* dependee)
{
// The target is not in the export.
if (!this->AppendMode) {
@@ -321,7 +322,7 @@ cmExportBuildFileGenerator::FindBuildExportInfo(cmGlobalGenerator* gg,
}
void cmExportBuildFileGenerator::ComplainAboutMissingTarget(
- cmGeneratorTarget* depender, cmGeneratorTarget* dependee,
+ cmGeneratorTarget const* depender, cmGeneratorTarget const* dependee,
std::vector<std::string> const& exportFiles)
{
std::ostringstream e;
@@ -344,7 +345,7 @@ void cmExportBuildFileGenerator::ComplainAboutMissingTarget(
}
std::string cmExportBuildFileGenerator::InstallNameDir(
- cmGeneratorTarget* target, const std::string& config)
+ cmGeneratorTarget const* target, const std::string& config)
{
std::string install_name_dir;
diff --git a/Source/cmExportBuildFileGenerator.h b/Source/cmExportBuildFileGenerator.h
index 264494d..244f526 100644
--- a/Source/cmExportBuildFileGenerator.h
+++ b/Source/cmExportBuildFileGenerator.h
@@ -60,11 +60,11 @@ protected:
cmGeneratorTarget const* target) const;
void HandleMissingTarget(std::string& link_libs,
std::vector<std::string>& missingTargets,
- cmGeneratorTarget* depender,
+ cmGeneratorTarget const* depender,
cmGeneratorTarget* dependee) override;
- void ComplainAboutMissingTarget(cmGeneratorTarget* depender,
- cmGeneratorTarget* dependee,
+ void ComplainAboutMissingTarget(cmGeneratorTarget const* depender,
+ cmGeneratorTarget const* dependee,
std::vector<std::string> const& namespaces);
/** Fill in properties indicating built file locations. */
@@ -73,7 +73,7 @@ protected:
cmGeneratorTarget* target,
ImportPropertyMap& properties);
- std::string InstallNameDir(cmGeneratorTarget* target,
+ std::string InstallNameDir(cmGeneratorTarget const* target,
const std::string& config) override;
std::pair<std::vector<std::string>, std::string> FindBuildExportInfo(
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index dd611de..8b06a15 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -27,7 +27,6 @@
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
-#include "cmTargetExport.h"
static std::string cmExportFileGeneratorEscape(std::string const& str)
{
@@ -123,7 +122,7 @@ void cmExportFileGenerator::GenerateImportConfig(
}
void cmExportFileGenerator::PopulateInterfaceProperty(
- const std::string& propName, cmGeneratorTarget* target,
+ const std::string& propName, cmGeneratorTarget const* target,
ImportPropertyMap& properties)
{
cmProp input = target->GetProperty(propName);
@@ -134,7 +133,7 @@ void cmExportFileGenerator::PopulateInterfaceProperty(
void cmExportFileGenerator::PopulateInterfaceProperty(
const std::string& propName, const std::string& outputName,
- cmGeneratorTarget* target,
+ cmGeneratorTarget const* target,
cmGeneratorExpression::PreprocessContext preprocessRule,
ImportPropertyMap& properties, std::vector<std::string>& missingTargets)
{
@@ -168,7 +167,7 @@ void cmExportFileGenerator::GenerateRequiredCMakeVersion(
}
bool cmExportFileGenerator::PopulateInterfaceLinkLibrariesProperty(
- cmGeneratorTarget* target,
+ cmGeneratorTarget const* target,
cmGeneratorExpression::PreprocessContext preprocessRule,
ImportPropertyMap& properties, std::vector<std::string>& missingTargets)
{
@@ -196,7 +195,7 @@ static bool isSubDirectory(std::string const& a, std::string const& b)
}
static bool checkInterfaceDirs(const std::string& prepro,
- cmGeneratorTarget* target,
+ cmGeneratorTarget const* target,
const std::string& prop)
{
std::string const& installDir =
@@ -335,10 +334,10 @@ static void prefixItems(std::string& exportDirs)
}
void cmExportFileGenerator::PopulateSourcesInterface(
- cmTargetExport* tei, cmGeneratorExpression::PreprocessContext preprocessRule,
+ cmGeneratorTarget const* gt,
+ cmGeneratorExpression::PreprocessContext preprocessRule,
ImportPropertyMap& properties, std::vector<std::string>& missingTargets)
{
- cmGeneratorTarget* gt = tei->Target;
assert(preprocessRule == cmGeneratorExpression::InstallInterface);
const char* propName = "INTERFACE_SOURCES";
@@ -366,10 +365,10 @@ void cmExportFileGenerator::PopulateSourcesInterface(
}
void cmExportFileGenerator::PopulateIncludeDirectoriesInterface(
- cmTargetExport* tei, cmGeneratorExpression::PreprocessContext preprocessRule,
+ cmGeneratorTarget const* target,
+ cmGeneratorExpression::PreprocessContext preprocessRule,
ImportPropertyMap& properties, std::vector<std::string>& missingTargets)
{
- cmGeneratorTarget* target = tei->Target;
assert(preprocessRule == cmGeneratorExpression::InstallInterface);
const char* propName = "INTERFACE_INCLUDE_DIRECTORIES";
@@ -378,7 +377,8 @@ void cmExportFileGenerator::PopulateIncludeDirectoriesInterface(
cmGeneratorExpression ge;
std::string dirs = cmGeneratorExpression::Preprocess(
- tei->InterfaceIncludeDirectories, preprocessRule, true);
+ cmJoin(target->Target->GetInstallIncludeDirectoriesEntries(), ";"),
+ preprocessRule, true);
this->ReplaceInstallPrefix(dirs);
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(dirs);
std::string exportDirs =
@@ -424,10 +424,10 @@ void cmExportFileGenerator::PopulateIncludeDirectoriesInterface(
}
void cmExportFileGenerator::PopulateLinkDependsInterface(
- cmTargetExport* tei, cmGeneratorExpression::PreprocessContext preprocessRule,
+ cmGeneratorTarget const* gt,
+ cmGeneratorExpression::PreprocessContext preprocessRule,
ImportPropertyMap& properties, std::vector<std::string>& missingTargets)
{
- cmGeneratorTarget* gt = tei->Target;
assert(preprocessRule == cmGeneratorExpression::InstallInterface);
const char* propName = "INTERFACE_LINK_DEPENDS";
@@ -455,10 +455,10 @@ void cmExportFileGenerator::PopulateLinkDependsInterface(
}
void cmExportFileGenerator::PopulateLinkDirectoriesInterface(
- cmTargetExport* tei, cmGeneratorExpression::PreprocessContext preprocessRule,
+ cmGeneratorTarget const* gt,
+ cmGeneratorExpression::PreprocessContext preprocessRule,
ImportPropertyMap& properties, std::vector<std::string>& missingTargets)
{
- cmGeneratorTarget* gt = tei->Target;
assert(preprocessRule == cmGeneratorExpression::InstallInterface);
const char* propName = "INTERFACE_LINK_DIRECTORIES";
@@ -486,7 +486,7 @@ void cmExportFileGenerator::PopulateLinkDirectoriesInterface(
}
void cmExportFileGenerator::PopulateInterfaceProperty(
- const std::string& propName, cmGeneratorTarget* target,
+ const std::string& propName, cmGeneratorTarget const* target,
cmGeneratorExpression::PreprocessContext preprocessRule,
ImportPropertyMap& properties, std::vector<std::string>& missingTargets)
{
@@ -505,7 +505,7 @@ void getPropertyContents(cmGeneratorTarget const* tgt, const std::string& prop,
ifaceProperties.insert(content.begin(), content.end());
}
-void getCompatibleInterfaceProperties(cmGeneratorTarget* target,
+void getCompatibleInterfaceProperties(cmGeneratorTarget const* target,
std::set<std::string>& ifaceProperties,
const std::string& config)
{
@@ -544,7 +544,7 @@ void getCompatibleInterfaceProperties(cmGeneratorTarget* target,
}
void cmExportFileGenerator::PopulateCompatibleInterfaceProperties(
- cmGeneratorTarget* gtarget, ImportPropertyMap& properties)
+ cmGeneratorTarget const* gtarget, ImportPropertyMap& properties)
{
this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_BOOL", gtarget,
properties);
@@ -596,7 +596,7 @@ void cmExportFileGenerator::GenerateInterfaceProperties(
}
bool cmExportFileGenerator::AddTargetNamespace(
- std::string& input, cmGeneratorTarget* target,
+ std::string& input, cmGeneratorTarget const* target,
std::vector<std::string>& missingTargets)
{
cmGeneratorTarget::TargetOrString resolved =
@@ -627,7 +627,7 @@ bool cmExportFileGenerator::AddTargetNamespace(
}
void cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
- std::string& input, cmGeneratorTarget* target,
+ std::string& input, cmGeneratorTarget const* target,
std::vector<std::string>& missingTargets, FreeTargetsReplace replace)
{
if (replace == NoReplaceFreeTargets) {
@@ -654,7 +654,7 @@ void cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
}
void cmExportFileGenerator::ResolveTargetsInGeneratorExpression(
- std::string& input, cmGeneratorTarget* target,
+ std::string& input, cmGeneratorTarget const* target,
std::vector<std::string>& missingTargets)
{
std::string::size_type pos = 0;
@@ -744,7 +744,7 @@ void cmExportFileGenerator::ReplaceInstallPrefix(std::string& /*unused*/)
void cmExportFileGenerator::SetImportLinkInterface(
const std::string& config, std::string const& suffix,
cmGeneratorExpression::PreprocessContext preprocessRule,
- cmGeneratorTarget* target, ImportPropertyMap& properties,
+ cmGeneratorTarget const* target, ImportPropertyMap& properties,
std::vector<std::string>& missingTargets)
{
// Add the transitive link dependencies for this configuration.
@@ -880,7 +880,7 @@ static std::string const& asString(cmLinkItem const& l)
template <typename T>
void cmExportFileGenerator::SetImportLinkProperty(
- std::string const& suffix, cmGeneratorTarget* target,
+ std::string const& suffix, cmGeneratorTarget const* target,
const std::string& propName, std::vector<T> const& entries,
ImportPropertyMap& properties, std::vector<std::string>& missingTargets,
ImportLinkPropertyTargetNames targetNames)
@@ -917,20 +917,20 @@ void cmExportFileGenerator::GeneratePolicyHeaderCode(std::ostream& os)
// Protect that file against use with older CMake versions.
/* clang-format off */
os << "# Generated by CMake\n\n";
- os << "if(\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" LESS 2.5)\n"
+ os << "if(\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" LESS 2.6)\n"
<< " message(FATAL_ERROR \"CMake >= 2.6.0 required\")\n"
<< "endif()\n";
/* clang-format on */
// Isolate the file policy level.
// Support CMake versions as far back as 2.6 but also support using NEW
- // policy settings for up to CMake 3.19 (this upper limit may be reviewed
+ // policy settings for up to CMake 3.20 (this upper limit may be reviewed
// and increased from time to time). This reduces the opportunity for CMake
// warnings when an older export file is later used with newer CMake
// versions.
/* clang-format off */
os << "cmake_policy(PUSH)\n"
- << "cmake_policy(VERSION 2.6...3.19)\n";
+ << "cmake_policy(VERSION 2.6...3.20)\n";
/* clang-format on */
}
@@ -1211,7 +1211,7 @@ void cmExportFileGenerator::GenerateImportedFileChecksCode(
}
bool cmExportFileGenerator::PopulateExportProperties(
- cmGeneratorTarget* gte, ImportPropertyMap& properties,
+ cmGeneratorTarget const* gte, ImportPropertyMap& properties,
std::string& errorMessage)
{
const auto& targetProperties = gte->Target->GetProperties();
diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h
index 45eaed0..24e048b 100644
--- a/Source/cmExportFileGenerator.h
+++ b/Source/cmExportFileGenerator.h
@@ -27,8 +27,6 @@ class cmGeneratorTarget;
CMake_VERSION_MINOR) "." STRINGIFY(CMake_VERSION_PATCH) \
: #major "." #minor ".0")
-class cmTargetExport;
-
/** \class cmExportFileGenerator
* \brief Generate a file exporting targets from a build or install tree.
*
@@ -108,7 +106,7 @@ protected:
};
template <typename T>
void SetImportLinkProperty(std::string const& suffix,
- cmGeneratorTarget* target,
+ cmGeneratorTarget const* target,
const std::string& propName,
std::vector<T> const& entries,
ImportPropertyMap& properties,
@@ -127,44 +125,45 @@ protected:
* export set. */
virtual void HandleMissingTarget(std::string& link_libs,
std::vector<std::string>& missingTargets,
- cmGeneratorTarget* depender,
+ cmGeneratorTarget const* depender,
cmGeneratorTarget* dependee) = 0;
- void PopulateInterfaceProperty(const std::string&, cmGeneratorTarget* target,
+ void PopulateInterfaceProperty(const std::string&,
+ cmGeneratorTarget const* target,
cmGeneratorExpression::PreprocessContext,
ImportPropertyMap& properties,
std::vector<std::string>& missingTargets);
bool PopulateInterfaceLinkLibrariesProperty(
- cmGeneratorTarget* target, cmGeneratorExpression::PreprocessContext,
+ cmGeneratorTarget const* target, cmGeneratorExpression::PreprocessContext,
ImportPropertyMap& properties, std::vector<std::string>& missingTargets);
void PopulateInterfaceProperty(const std::string& propName,
- cmGeneratorTarget* target,
+ cmGeneratorTarget const* target,
ImportPropertyMap& properties);
- void PopulateCompatibleInterfaceProperties(cmGeneratorTarget* target,
+ void PopulateCompatibleInterfaceProperties(cmGeneratorTarget const* target,
ImportPropertyMap& properties);
virtual void GenerateInterfaceProperties(
cmGeneratorTarget const* target, std::ostream& os,
const ImportPropertyMap& properties);
void PopulateIncludeDirectoriesInterface(
- cmTargetExport* target,
+ cmGeneratorTarget const* target,
cmGeneratorExpression::PreprocessContext preprocessRule,
ImportPropertyMap& properties, std::vector<std::string>& missingTargets);
void PopulateSourcesInterface(
- cmTargetExport* target,
+ cmGeneratorTarget const* target,
cmGeneratorExpression::PreprocessContext preprocessRule,
ImportPropertyMap& properties, std::vector<std::string>& missingTargets);
void PopulateLinkDirectoriesInterface(
- cmTargetExport* target,
+ cmGeneratorTarget const* target,
cmGeneratorExpression::PreprocessContext preprocessRule,
ImportPropertyMap& properties, std::vector<std::string>& missingTargets);
void PopulateLinkDependsInterface(
- cmTargetExport* target,
+ cmGeneratorTarget const* target,
cmGeneratorExpression::PreprocessContext preprocessRule,
ImportPropertyMap& properties, std::vector<std::string>& missingTargets);
void SetImportLinkInterface(
const std::string& config, std::string const& suffix,
cmGeneratorExpression::PreprocessContext preprocessRule,
- cmGeneratorTarget* target, ImportPropertyMap& properties,
+ cmGeneratorTarget const* target, ImportPropertyMap& properties,
std::vector<std::string>& missingTargets);
enum FreeTargetsReplace
@@ -174,14 +173,14 @@ protected:
};
void ResolveTargetsInGeneratorExpressions(
- std::string& input, cmGeneratorTarget* target,
+ std::string& input, cmGeneratorTarget const* target,
std::vector<std::string>& missingTargets,
FreeTargetsReplace replace = NoReplaceFreeTargets);
virtual void GenerateRequiredCMakeVersion(std::ostream& os,
const char* versionString);
- bool PopulateExportProperties(cmGeneratorTarget* gte,
+ bool PopulateExportProperties(cmGeneratorTarget const* gte,
ImportPropertyMap& properties,
std::string& errorMessage);
@@ -205,20 +204,20 @@ protected:
private:
void PopulateInterfaceProperty(const std::string&, const std::string&,
- cmGeneratorTarget* target,
+ cmGeneratorTarget const* target,
cmGeneratorExpression::PreprocessContext,
ImportPropertyMap& properties,
std::vector<std::string>& missingTargets);
- bool AddTargetNamespace(std::string& input, cmGeneratorTarget* target,
+ bool AddTargetNamespace(std::string& input, cmGeneratorTarget const* target,
std::vector<std::string>& missingTargets);
void ResolveTargetsInGeneratorExpression(
- std::string& input, cmGeneratorTarget* target,
+ std::string& input, cmGeneratorTarget const* target,
std::vector<std::string>& missingTargets);
virtual void ReplaceInstallPrefix(std::string& input);
- virtual std::string InstallNameDir(cmGeneratorTarget* target,
+ virtual std::string InstallNameDir(cmGeneratorTarget const* target,
const std::string& config) = 0;
};
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index 3c69c50..46d2d31 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -16,6 +16,7 @@
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmPolicies.h"
+#include "cmProperty.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -85,8 +86,8 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
ImportPropertyMap properties;
this->PopulateIncludeDirectoriesInterface(
- te, cmGeneratorExpression::InstallInterface, properties, missingTargets);
- this->PopulateSourcesInterface(te, cmGeneratorExpression::InstallInterface,
+ gt, cmGeneratorExpression::InstallInterface, properties, missingTargets);
+ this->PopulateSourcesInterface(gt, cmGeneratorExpression::InstallInterface,
properties, missingTargets);
this->PopulateInterfaceProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES", gt,
cmGeneratorExpression::InstallInterface,
@@ -110,9 +111,9 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
cmGeneratorExpression::InstallInterface,
properties, missingTargets);
this->PopulateLinkDirectoriesInterface(
- te, cmGeneratorExpression::InstallInterface, properties, missingTargets);
+ gt, cmGeneratorExpression::InstallInterface, properties, missingTargets);
this->PopulateLinkDependsInterface(
- te, cmGeneratorExpression::InstallInterface, properties, missingTargets);
+ gt, cmGeneratorExpression::InstallInterface, properties, missingTargets);
std::string errorMessage;
if (!this->PopulateExportProperties(gt, properties, errorMessage)) {
@@ -447,7 +448,7 @@ cmStateEnums::TargetType cmExportInstallFileGenerator::GetExportTargetType(
void cmExportInstallFileGenerator::HandleMissingTarget(
std::string& link_libs, std::vector<std::string>& missingTargets,
- cmGeneratorTarget* depender, cmGeneratorTarget* dependee)
+ cmGeneratorTarget const* depender, cmGeneratorTarget* dependee)
{
const std::string name = dependee->GetName();
cmGlobalGenerator* gg = dependee->GetLocalGenerator()->GetGlobalGenerator();
@@ -499,7 +500,7 @@ cmExportInstallFileGenerator::FindNamespaces(cmGlobalGenerator* gg,
}
void cmExportInstallFileGenerator::ComplainAboutMissingTarget(
- cmGeneratorTarget* depender, cmGeneratorTarget* dependee,
+ cmGeneratorTarget const* depender, cmGeneratorTarget const* dependee,
std::vector<std::string> const& exportFiles)
{
std::ostringstream e;
@@ -521,7 +522,7 @@ void cmExportInstallFileGenerator::ComplainAboutMissingTarget(
}
std::string cmExportInstallFileGenerator::InstallNameDir(
- cmGeneratorTarget* target, const std::string& config)
+ cmGeneratorTarget const* target, const std::string& config)
{
std::string install_name_dir;
diff --git a/Source/cmExportInstallFileGenerator.h b/Source/cmExportInstallFileGenerator.h
index 2d8de9d..5cec2e0 100644
--- a/Source/cmExportInstallFileGenerator.h
+++ b/Source/cmExportInstallFileGenerator.h
@@ -63,13 +63,13 @@ protected:
cmTargetExport const* targetExport) const;
void HandleMissingTarget(std::string& link_libs,
std::vector<std::string>& missingTargets,
- cmGeneratorTarget* depender,
+ cmGeneratorTarget const* depender,
cmGeneratorTarget* dependee) override;
void ReplaceInstallPrefix(std::string& input) override;
- void ComplainAboutMissingTarget(cmGeneratorTarget* depender,
- cmGeneratorTarget* dependee,
+ void ComplainAboutMissingTarget(cmGeneratorTarget const* depender,
+ cmGeneratorTarget const* dependee,
std::vector<std::string> const& exportFiles);
std::pair<std::vector<std::string>, std::string> FindNamespaces(
@@ -94,7 +94,7 @@ protected:
ImportPropertyMap& properties,
std::set<std::string>& importedLocations);
- std::string InstallNameDir(cmGeneratorTarget* target,
+ std::string InstallNameDir(cmGeneratorTarget const* target,
const std::string& config) override;
cmInstallExportGenerator* IEGen;
diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx
index cac60e1..f89d0ad 100644
--- a/Source/cmExportTryCompileFileGenerator.cxx
+++ b/Source/cmExportTryCompileFileGenerator.cxx
@@ -126,7 +126,7 @@ void cmExportTryCompileFileGenerator::PopulateProperties(
}
std::string cmExportTryCompileFileGenerator::InstallNameDir(
- cmGeneratorTarget* target, const std::string& config)
+ cmGeneratorTarget const* target, const std::string& config)
{
std::string install_name_dir;
diff --git a/Source/cmExportTryCompileFileGenerator.h b/Source/cmExportTryCompileFileGenerator.h
index 6bf5781..127b8df 100644
--- a/Source/cmExportTryCompileFileGenerator.h
+++ b/Source/cmExportTryCompileFileGenerator.h
@@ -36,7 +36,8 @@ protected:
{
}
void HandleMissingTarget(std::string&, std::vector<std::string>&,
- cmGeneratorTarget*, cmGeneratorTarget*) override
+ cmGeneratorTarget const*,
+ cmGeneratorTarget*) override
{
}
@@ -44,7 +45,7 @@ protected:
ImportPropertyMap& properties,
std::set<const cmGeneratorTarget*>& emitted);
- std::string InstallNameDir(cmGeneratorTarget* target,
+ std::string InstallNameDir(cmGeneratorTarget const* target,
const std::string& config) override;
private:
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx
index a2b5460..adeba74 100644
--- a/Source/cmFileAPICodemodel.cxx
+++ b/Source/cmFileAPICodemodel.cxx
@@ -813,8 +813,7 @@ Json::Value CodemodelConfig::DumpProject(Project& p)
Json::Value CodemodelConfig::DumpMinimumCMakeVersion(cmStateSnapshot s)
{
Json::Value minimumCMakeVersion;
- if (std::string const* def =
- s.GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION")) {
+ if (cmProp def = s.GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION")) {
minimumCMakeVersion = Json::objectValue;
minimumCMakeVersion["string"] = *def;
}
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 0ad59c7..2730a07 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -31,6 +31,7 @@
#include "cmArgumentParser.h"
#include "cmCMakePath.h"
#include "cmCryptoHash.h"
+#include "cmELF.h"
#include "cmExecutionStatus.h"
#include "cmFSPermissions.h"
#include "cmFileCopier.h"
@@ -64,10 +65,6 @@
# include "cmFileLockResult.h"
#endif
-#if defined(CMake_USE_ELF_PARSER)
-# include "cmELF.h"
-#endif
-
#if defined(_WIN32)
# include <windows.h>
#endif
@@ -1242,8 +1239,12 @@ bool HandleReadElfCommand(std::vector<std::string> const& args,
return false;
}
-#if defined(CMake_USE_ELF_PARSER)
cmELF elf(fileNameArg.c_str());
+ if (!elf) {
+ status.SetError(cmStrCat("READ_ELF given FILE \"", fileNameArg,
+ "\" that is not a valid ELF file."));
+ return false;
+ }
if (!arguments.RPath.empty()) {
if (cmELF::StringEntry const* se_rpath = elf.GetRPath()) {
@@ -1261,15 +1262,6 @@ bool HandleReadElfCommand(std::vector<std::string> const& args,
}
return true;
-#else
- std::string error = "ELF parser not available on this platform.";
- if (arguments.Error.empty()) {
- status.SetError(error);
- return false;
- }
- status.GetMakefile().AddDefinition(arguments.Error, error);
- return true;
-#endif
}
bool HandleInstallCommand(std::vector<std::string> const& args,
@@ -1858,7 +1850,7 @@ bool HandleDownloadCommand(std::vector<std::string> const& args,
} else if (*i == "TLS_CAINFO") {
++i;
if (i != args.end()) {
- cainfo = &(*i);
+ cainfo = cmProp(*i);
} else {
status.SetError("DOWNLOAD missing file value for TLS_CAINFO.");
return false;
@@ -2244,7 +2236,7 @@ bool HandleUploadCommand(std::vector<std::string> const& args,
} else if (*i == "TLS_CAINFO") {
++i;
if (i != args.end()) {
- cainfo = &(*i);
+ cainfo = cmProp(*i);
} else {
status.SetError("UPLOAD missing file value for TLS_CAINFO.");
return false;
diff --git a/Source/cmFileCopier.h b/Source/cmFileCopier.h
index 217d58d..ee9872d 100644
--- a/Source/cmFileCopier.h
+++ b/Source/cmFileCopier.h
@@ -67,8 +67,9 @@ protected:
bool InstallSymlinkChain(std::string& fromFile, std::string& toFile);
bool InstallSymlink(const std::string& fromFile, const std::string& toFile);
- bool InstallFile(const std::string& fromFile, const std::string& toFile,
- MatchProperties match_properties);
+ virtual bool InstallFile(const std::string& fromFile,
+ const std::string& toFile,
+ MatchProperties match_properties);
bool InstallDirectory(const std::string& source,
const std::string& destination,
MatchProperties match_properties);
diff --git a/Source/cmFileInstaller.cxx b/Source/cmFileInstaller.cxx
index c89be96..0d8ba2d 100644
--- a/Source/cmFileInstaller.cxx
+++ b/Source/cmFileInstaller.cxx
@@ -3,7 +3,12 @@
#include "cmFileInstaller.h"
+#include <map>
#include <sstream>
+#include <utility>
+
+#include <cm/string_view>
+#include <cmext/string_view>
#include "cm_sys_stat.h"
@@ -18,6 +23,7 @@ using namespace cmFSPermissions;
cmFileInstaller::cmFileInstaller(cmExecutionStatus& status)
: cmFileCopier(status, "INSTALL")
, InstallType(cmInstallType_FILES)
+ , InstallMode(cmInstallMode::COPY)
, Optional(false)
, MessageAlways(false)
, MessageLazy(false)
@@ -82,6 +88,93 @@ bool cmFileInstaller::Install(const std::string& fromFile,
return this->cmFileCopier::Install(fromFile, toFile);
}
+bool cmFileInstaller::InstallFile(const std::string& fromFile,
+ const std::string& toFile,
+ MatchProperties match_properties)
+{
+ if (this->InstallMode == cmInstallMode::COPY) {
+ return this->cmFileCopier::InstallFile(fromFile, toFile, match_properties);
+ }
+
+ std::string newFromFile;
+
+ if (this->InstallMode == cmInstallMode::REL_SYMLINK ||
+ this->InstallMode == cmInstallMode::REL_SYMLINK_OR_COPY ||
+ this->InstallMode == cmInstallMode::SYMLINK ||
+ this->InstallMode == cmInstallMode::SYMLINK_OR_COPY) {
+ // Try to get a relative path.
+ std::string toDir = cmSystemTools::GetParentDirectory(toFile);
+ newFromFile = cmSystemTools::ForceToRelativePath(toDir, fromFile);
+
+ // Double check that we can restore the original path.
+ std::string reassembled =
+ cmSystemTools::CollapseFullPath(newFromFile, toDir);
+ if (!cmSystemTools::ComparePath(reassembled, fromFile)) {
+ if (this->InstallMode == cmInstallMode::SYMLINK ||
+ this->InstallMode == cmInstallMode::SYMLINK_OR_COPY) {
+ // User does not mind, silently proceed with absolute path.
+ newFromFile = fromFile;
+ } else if (this->InstallMode == cmInstallMode::REL_SYMLINK_OR_COPY) {
+ // User expects a relative symbolic link or a copy.
+ // Since an absolute symlink won't do, copy instead.
+ return this->cmFileCopier::InstallFile(fromFile, toFile,
+ match_properties);
+ } else {
+ // We cannot meet user's expectation (REL_SYMLINK)
+ auto e = cmStrCat(this->Name,
+ " cannot determine relative path for symlink to \"",
+ newFromFile, "\" at \"", toFile, "\".");
+ this->Status.SetError(e);
+ return false;
+ }
+ }
+ } else {
+ newFromFile = fromFile; // stick with absolute path
+ }
+
+ // Compare the symlink value to that at the destination if not
+ // always installing.
+ bool copy = true;
+ if (!this->Always) {
+ std::string oldSymlinkTarget;
+ if (cmSystemTools::ReadSymlink(toFile, oldSymlinkTarget)) {
+ if (newFromFile == oldSymlinkTarget) {
+ copy = false;
+ }
+ }
+ }
+
+ // Inform the user about this file installation.
+ this->ReportCopy(toFile, TypeLink, copy);
+
+ if (copy) {
+ // Remove the destination file so we can always create the symlink.
+ cmSystemTools::RemoveFile(toFile);
+
+ // Create destination directory if it doesn't exist
+ cmSystemTools::MakeDirectory(cmSystemTools::GetFilenamePath(toFile));
+
+ // Create the symlink.
+ if (!cmSystemTools::CreateSymlink(newFromFile, toFile)) {
+ if (this->InstallMode == cmInstallMode::ABS_SYMLINK_OR_COPY ||
+ this->InstallMode == cmInstallMode::REL_SYMLINK_OR_COPY ||
+ this->InstallMode == cmInstallMode::SYMLINK_OR_COPY) {
+ // Failed to create a symbolic link, fall back to copying.
+ return this->cmFileCopier::InstallFile(newFromFile, toFile,
+ match_properties);
+ }
+
+ auto e = cmStrCat(this->Name, " cannot create symlink to \"",
+ newFromFile, "\" at \"", toFile,
+ "\": ", cmSystemTools::GetLastSystemError(), "\".");
+ this->Status.SetError(e);
+ return false;
+ }
+ }
+
+ return true;
+}
+
void cmFileInstaller::DefaultFilePermissions()
{
this->cmFileCopier::DefaultFilePermissions();
@@ -141,6 +234,31 @@ bool cmFileInstaller::Parse(std::vector<std::string> const& args)
return false;
}
+ static const std::map<cm::string_view, cmInstallMode> install_mode_dict{
+ { "ABS_SYMLINK"_s, cmInstallMode::ABS_SYMLINK },
+ { "ABS_SYMLINK_OR_COPY"_s, cmInstallMode::ABS_SYMLINK_OR_COPY },
+ { "REL_SYMLINK"_s, cmInstallMode::REL_SYMLINK },
+ { "REL_SYMLINK_OR_COPY"_s, cmInstallMode::REL_SYMLINK_OR_COPY },
+ { "SYMLINK"_s, cmInstallMode::SYMLINK },
+ { "SYMLINK_OR_COPY"_s, cmInstallMode::SYMLINK_OR_COPY }
+ };
+
+ std::string install_mode;
+ cmSystemTools::GetEnv("CMAKE_INSTALL_MODE", install_mode);
+ if (install_mode.empty() || install_mode == "COPY"_s) {
+ this->InstallMode = cmInstallMode::COPY;
+ } else {
+ auto it = install_mode_dict.find(install_mode);
+ if (it != install_mode_dict.end()) {
+ this->InstallMode = it->second;
+ } else {
+ auto e = cmStrCat("Unrecognized value '", install_mode,
+ "' for environment variable CMAKE_INSTALL_MODE");
+ this->Status.SetError(e);
+ return false;
+ }
+ }
+
return true;
}
diff --git a/Source/cmFileInstaller.h b/Source/cmFileInstaller.h
index 3a905d3..3f6bd45 100644
--- a/Source/cmFileInstaller.h
+++ b/Source/cmFileInstaller.h
@@ -8,6 +8,7 @@
#include <vector>
#include "cmFileCopier.h"
+#include "cmInstallMode.h"
#include "cmInstallType.h"
class cmExecutionStatus;
@@ -19,6 +20,7 @@ struct cmFileInstaller : public cmFileCopier
protected:
cmInstallType InstallType;
+ cmInstallMode InstallMode;
bool Optional;
bool MessageAlways;
bool MessageLazy;
@@ -35,7 +37,8 @@ protected:
bool ReportMissing(const std::string& fromFile) override;
bool Install(const std::string& fromFile,
const std::string& toFile) override;
-
+ bool InstallFile(const std::string& fromFile, const std::string& toFile,
+ MatchProperties match_properties) override;
bool Parse(std::vector<std::string> const& args) override;
enum
{
diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx
index 1038ac2..f4e1763 100644
--- a/Source/cmFindBase.cxx
+++ b/Source/cmFindBase.cxx
@@ -311,7 +311,7 @@ bool cmFindBase::CheckForVariableDefined()
if (cached && cacheType != cmStateEnums::UNINITIALIZED) {
this->VariableType = cacheType;
- if (const auto* hs =
+ if (const auto& hs =
state->GetCacheEntryProperty(this->VariableName, "HELPSTRING")) {
this->VariableDocumentation = *hs;
}
@@ -336,7 +336,7 @@ void cmFindBase::NormalizeFindResult()
if (this->Makefile->GetPolicyStatus(cmPolicies::CMP0125) ==
cmPolicies::NEW) {
// ensure the path returned by find_* command is absolute
- const auto* existingValue =
+ const auto& existingValue =
this->Makefile->GetDefinition(this->VariableName);
std::string value;
if (!existingValue->empty()) {
diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx
index 0cbe637..ef960d1 100644
--- a/Source/cmFindLibraryCommand.cxx
+++ b/Source/cmFindLibraryCommand.cxx
@@ -259,6 +259,34 @@ struct cmFindLibraryHelper
};
};
+namespace {
+
+std::string const& get_prefixes(cmMakefile* mf)
+{
+#ifdef _WIN32
+ static std::string defaultPrefix = ";lib";
+#else
+ static std::string defaultPrefix = "lib";
+#endif
+ cmProp prefixProp = mf->GetDefinition("CMAKE_FIND_LIBRARY_PREFIXES");
+ return (prefixProp) ? *prefixProp : defaultPrefix;
+}
+
+std::string const& get_suffixes(cmMakefile* mf)
+{
+#ifdef _WIN32
+ static std::string defaultSuffix = ".lib;.dll.a;.a";
+#elif defined(__APPLE__)
+ static std::string defaultSuffix = ".tbd;.dylib;.so;.a";
+#elif defined(__hpux)
+ static std::string defaultSuffix = ".sl;.so;.a";
+#else
+ static std::string defaultSuffix = ".so;.a";
+#endif
+ cmProp suffixProp = mf->GetDefinition("CMAKE_FIND_LIBRARY_SUFFIXES");
+ return (suffixProp) ? *suffixProp : defaultSuffix;
+}
+}
cmFindLibraryHelper::cmFindLibraryHelper(std::string debugName, cmMakefile* mf,
cmFindBase const* base)
: Makefile(mf)
@@ -268,10 +296,9 @@ cmFindLibraryHelper::cmFindLibraryHelper(std::string debugName, cmMakefile* mf,
this->GG = this->Makefile->GetGlobalGenerator();
// Collect the list of library name prefixes/suffixes to try.
- std::string const& prefixes_list =
- this->Makefile->GetRequiredDefinition("CMAKE_FIND_LIBRARY_PREFIXES");
- std::string const& suffixes_list =
- this->Makefile->GetRequiredDefinition("CMAKE_FIND_LIBRARY_SUFFIXES");
+ std::string const& prefixes_list = get_prefixes(this->Makefile);
+ std::string const& suffixes_list = get_suffixes(this->Makefile);
+
cmExpandList(prefixes_list, this->Prefixes, true);
cmExpandList(suffixes_list, this->Suffixes, true);
this->RegexFromList(this->PrefixRegexStr, this->Prefixes);
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index fba736e..a0de74c 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -478,17 +478,35 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
this->VersionMaxPatch, this->VersionMaxTweak);
}
+ const std::string makePackageRequiredVar =
+ cmStrCat("CMAKE_REQUIRE_FIND_PACKAGE_", this->Name);
+ const bool makePackageRequiredSet =
+ this->Makefile->IsOn(makePackageRequiredVar);
+ if (makePackageRequiredSet) {
+ if (this->Required) {
+ this->Makefile->IssueMessage(
+ MessageType::WARNING,
+ cmStrCat("for module ", this->Name,
+ " already called with REQUIRED, thus ",
+ makePackageRequiredVar, " has no effect."));
+ } else {
+ this->Required = true;
+ }
+ }
+
std::string disableFindPackageVar =
cmStrCat("CMAKE_DISABLE_FIND_PACKAGE_", this->Name);
if (this->Makefile->IsOn(disableFindPackageVar)) {
if (this->Required) {
this->SetError(
- cmStrCat("for module ", this->Name, " called with REQUIRED, but ",
- disableFindPackageVar,
+ cmStrCat("for module ", this->Name,
+ (makePackageRequiredSet
+ ? " was made REQUIRED with " + makePackageRequiredVar
+ : " called with REQUIRED, "),
+ " but ", disableFindPackageVar,
" is enabled. A REQUIRED package cannot be disabled."));
return false;
}
-
return true;
}
diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx
index 4845a6d..b44f797 100644
--- a/Source/cmForEachCommand.cxx
+++ b/Source/cmForEachCommand.cxx
@@ -27,6 +27,7 @@
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
+#include "cmProperty.h"
#include "cmRange.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
diff --git a/Source/cmFortranParser.h b/Source/cmFortranParser.h
index 1b14d17..70fe537 100644
--- a/Source/cmFortranParser.h
+++ b/Source/cmFortranParser.h
@@ -40,6 +40,8 @@ int cmFortranParser_GetOldStartcond(cmFortranParser* parser);
/* Callbacks for parser. */
void cmFortranParser_Error(cmFortranParser* parser, const char* message);
void cmFortranParser_RuleUse(cmFortranParser* parser, const char* module_name);
+void cmFortranParser_RuleUseIntrinsic(cmFortranParser* parser,
+ const char* module_name);
void cmFortranParser_RuleLineDirective(cmFortranParser* parser,
const char* filename);
void cmFortranParser_RuleInclude(cmFortranParser* parser, const char* name);
@@ -99,6 +101,9 @@ public:
std::set<std::string> Provides;
std::set<std::string> Requires;
+ // Set of intrinsic modules.
+ std::set<std::string> Intrinsics;
+
// Set of files included in the translation unit.
std::set<std::string> Includes;
};
diff --git a/Source/cmFortranParserImpl.cxx b/Source/cmFortranParserImpl.cxx
index 054a2a9..efcc5bb 100644
--- a/Source/cmFortranParserImpl.cxx
+++ b/Source/cmFortranParserImpl.cxx
@@ -197,6 +197,19 @@ void cmFortranParser_RuleUse(cmFortranParser* parser, const char* module_name)
parser->Info.Requires.insert(parser->ModName(mod_name));
}
+void cmFortranParser_RuleUseIntrinsic(cmFortranParser* parser,
+ const char* module_name)
+{
+ if (parser->InPPFalseBranch) {
+ return;
+ }
+
+ // syntax: "use, intrinsic:: module_name"
+ // requires: "module_name.mod"
+ std::string const& mod_name = cmSystemTools::LowerCase(module_name);
+ parser->Info.Intrinsics.insert(parser->ModName(mod_name));
+}
+
void cmFortranParser_RuleLineDirective(cmFortranParser* parser,
const char* filename)
{
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 217ebe5..3e90ead 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -1777,7 +1777,7 @@ static const struct CompileFeaturesNode : public cmGeneratorExpressionNode
testedFeatures[lang].push_back(p);
if (availableFeatures.find(lang) == availableFeatures.end()) {
- const char* featuresKnown =
+ cmProp featuresKnown =
standardResolver.CompileFeaturesAvailable(lang, &error);
if (!featuresKnown) {
reportError(context, content->GetOriginalExpression(), error);
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index f1ef130..3201ae3 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -62,7 +62,7 @@ cmProp cmTargetPropertyComputer::GetSources<cmGeneratorTarget>(
cmGeneratorTarget const* tgt, cmMessenger* /* messenger */,
cmListFileBacktrace const& /* context */)
{
- return &tgt->GetSourcesProperty();
+ return tgt->GetSourcesProperty();
}
template <>
@@ -332,7 +332,7 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
cmGeneratorTarget::~cmGeneratorTarget() = default;
-const std::string& cmGeneratorTarget::GetSourcesProperty() const
+cmProp cmGeneratorTarget::GetSourcesProperty() const
{
std::vector<std::string> values;
for (auto const& se : this->SourceEntries) {
@@ -341,7 +341,7 @@ const std::string& cmGeneratorTarget::GetSourcesProperty() const
static std::string value;
value.clear();
value = cmJoin(values, ";");
- return value;
+ return cmProp(value);
}
cmGlobalGenerator* cmGeneratorTarget::GetGlobalGenerator() const
@@ -396,13 +396,7 @@ cmProp cmGeneratorTarget::GetProperty(const std::string& prop) const
std::string const& cmGeneratorTarget::GetSafeProperty(
std::string const& prop) const
{
- cmProp ret = this->GetProperty(prop);
- if (ret) {
- return *ret;
- }
-
- static std::string const s_empty;
- return s_empty;
+ return this->GetProperty(prop);
}
const char* cmGeneratorTarget::GetOutputTargetType(
@@ -564,7 +558,7 @@ std::string cmGeneratorTarget::GetFilePostfix(const std::string& config) const
// framework postfix.
frameworkPostfix = this->GetFrameworkMultiConfigPostfix(config);
if (!frameworkPostfix.empty()) {
- postfix = &frameworkPostfix;
+ postfix = cmProp(frameworkPostfix);
}
}
return postfix ? *postfix : std::string();
@@ -966,7 +960,7 @@ cmProp cmGeneratorTarget::GetLanguageStandard(std::string const& lang,
this->GetLanguageStandardProperty(lang, config);
if (languageStandard) {
- return &(languageStandard->Value);
+ return cmProp(languageStandard->Value);
}
return nullptr;
@@ -2142,7 +2136,6 @@ bool cmGeneratorTarget::IsChrpathUsed(const std::string& config) const
return true;
}
-#if defined(CMake_USE_ELF_PARSER) || defined(CMake_USE_XCOFF_PARSER)
// Enable if the rpath flag uses a separator and the target uses
// binaries we know how to edit.
std::string ll = this->GetLinkerLanguage(config);
@@ -2155,21 +2148,17 @@ bool cmGeneratorTarget::IsChrpathUsed(const std::string& config) const
// CMAKE_EXECUTABLE_FORMAT.
if (cmProp fmt =
this->Makefile->GetDefinition("CMAKE_EXECUTABLE_FORMAT")) {
-# if defined(CMake_USE_ELF_PARSER)
if (*fmt == "ELF") {
return true;
}
-# endif
-# if defined(CMake_USE_XCOFF_PARSER)
+#if defined(CMake_USE_XCOFF_PARSER)
if (*fmt == "XCOFF") {
return true;
}
-# endif
+#endif
}
}
}
-#endif
- static_cast<void>(config);
return false;
}
@@ -4466,6 +4455,13 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions(
// Last step: replace "LINKER:" prefixed elements by
// actual linker wrapper
+ return this->ResolveLinkerWrapper(result, language);
+}
+
+std::vector<BT<std::string>>& cmGeneratorTarget::ResolveLinkerWrapper(
+ std::vector<BT<std::string>>& result, const std::string& language) const
+{
+ // replace "LINKER:" prefixed elements by actual linker wrapper
const std::string wrapper(this->Makefile->GetSafeDefinition(
"CMAKE_" + language +
(this->IsDeviceLink() ? "_DEVICE_LINKER_WRAPPER_FLAG"
@@ -4966,11 +4962,11 @@ cmGeneratorTarget::Names cmGeneratorTarget::GetLibraryNames(
// The library's soname.
this->ComputeVersionedName(targetNames.SharedObject, prefix,
targetNames.Base, suffix, targetNames.Output,
- cmToCStr(soversion));
+ soversion);
// The library's real name on disk.
this->ComputeVersionedName(targetNames.Real, prefix, targetNames.Base,
- suffix, targetNames.Output, cmToCStr(version));
+ suffix, targetNames.Output, version);
}
// The import library name.
@@ -5003,10 +4999,10 @@ 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 = nullptr;
+ cmProp version;
#else
// Check for executable version properties.
- const char* version = cmToCStr(this->GetProperty("VERSION"));
+ cmProp version = this->GetProperty("VERSION");
if (this->GetType() != cmStateEnums::EXECUTABLE ||
this->Makefile->IsOn("XCODE")) {
version = nullptr;
@@ -5030,7 +5026,7 @@ cmGeneratorTarget::Names cmGeneratorTarget::GetExecutableNames(
#endif
if (version) {
targetNames.Real += "-";
- targetNames.Real += version;
+ targetNames.Real += *version;
}
#if defined(__CYGWIN__)
targetNames.Real += suffix;
@@ -5119,13 +5115,13 @@ void cmGeneratorTarget::GetFullNameInternal(
if (this->IsFrameworkOnApple()) {
fw_prefix =
cmStrCat(this->GetFrameworkDirectory(config, ContentLevel), '/');
- targetPrefix = &fw_prefix;
+ targetPrefix = cmProp(fw_prefix);
targetSuffix = nullptr;
}
if (this->IsCFBundleOnApple()) {
fw_prefix = cmStrCat(this->GetCFBundleDirectory(config, FullLevel), '/');
- targetPrefix = &fw_prefix;
+ targetPrefix = cmProp(fw_prefix);
targetSuffix = nullptr;
}
@@ -5141,7 +5137,7 @@ void cmGeneratorTarget::GetFullNameInternal(
// EXECUTABLE_SUFFIX attribute.
if (this->IsFrameworkOnApple() &&
this->GetGlobalGenerator()->GetName() == "Xcode") {
- targetSuffix = &configPostfix;
+ targetSuffix = cmProp(configPostfix);
} else {
outBase += configPostfix;
}
@@ -5672,6 +5668,11 @@ std::string valueAsString<std::string>(std::string value)
return value;
}
template <>
+std::string valueAsString<cmProp>(cmProp value)
+{
+ return value ? value : std::string("(unset)");
+}
+template <>
std::string valueAsString<std::nullptr_t>(std::nullptr_t /*unused*/)
{
return "(unset)";
@@ -5747,7 +5748,7 @@ std::string getTypedProperty<std::string>(
cmProp value = tgt->GetProperty(prop);
if (genexInterpreter == nullptr) {
- return valueAsString(cmToCStr(value));
+ return valueAsString(value);
}
return genexInterpreter->Evaluate(value ? *value : "", prop);
@@ -6175,6 +6176,14 @@ std::string cmGeneratorTarget::GetFortranModuleDirectory(
return this->FortranModuleDirectory;
}
+bool cmGeneratorTarget::IsFortranBuildingInstrinsicModules() const
+{
+ if (cmProp prop = this->GetProperty("Fortran_BUILDING_INSTRINSIC_MODULES")) {
+ return cmIsOn(*prop);
+ }
+ return false;
+}
+
std::string cmGeneratorTarget::CreateFortranModuleDirectory(
std::string const& working_dir) const
{
@@ -6281,17 +6290,14 @@ std::string cmGeneratorTarget::GetFrameworkVersion() const
return "A";
}
-void cmGeneratorTarget::ComputeVersionedName(std::string& vName,
- std::string const& prefix,
- std::string const& base,
- std::string const& suffix,
- std::string const& name,
- const char* version) const
+void cmGeneratorTarget::ComputeVersionedName(
+ std::string& vName, std::string const& prefix, std::string const& base,
+ std::string const& suffix, std::string const& name, cmProp version) const
{
vName = this->Makefile->IsOn("APPLE") ? (prefix + base) : name;
if (version) {
vName += ".";
- vName += version;
+ vName += *version;
}
vName += this->Makefile->IsOn("APPLE") ? suffix : std::string();
}
@@ -6362,12 +6368,12 @@ cm::optional<cmLinkItem> cmGeneratorTarget::LookupLinkItem(
return maybeItem;
}
-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, std::vector<cmLinkItem>& objects,
- bool& hadHeadSensitiveCondition, bool& hadContextSensitiveCondition,
- bool& hadLinkLanguageSensitiveCondition) const
+void cmGeneratorTarget::ExpandLinkItems(std::string const& prop,
+ std::string const& value,
+ std::string const& config,
+ cmGeneratorTarget const* headTarget,
+ bool usage_requirements_only,
+ cmLinkInterface& iface) const
{
// Keep this logic in sync with ComputeLinkImplementationLibraries.
cmGeneratorExpression ge;
@@ -6389,24 +6395,27 @@ void cmGeneratorTarget::ExpandLinkItems(
for (std::string const& lib : libs) {
if (cm::optional<cmLinkItem> maybeItem =
this->LookupLinkItem(lib, cge->GetBacktrace(), &scope)) {
- if (!maybeItem->Target) {
+ cmLinkItem item = std::move(*maybeItem);
+
+ if (!item.Target) {
// Report explicitly linked object files separately.
- std::string const& maybeObj = maybeItem->AsStr();
+ std::string const& maybeObj = item.AsStr();
if (cmSystemTools::FileIsFullPath(maybeObj)) {
cmSourceFile const* sf =
mf->GetSource(maybeObj, cmSourceFileLocationKind::Known);
if (sf && sf->GetPropertyAsBool("EXTERNAL_OBJECT")) {
- objects.emplace_back(std::move(*maybeItem));
+ iface.Objects.emplace_back(std::move(item));
continue;
}
}
}
- items.emplace_back(std::move(*maybeItem));
+
+ iface.Libraries.emplace_back(std::move(item));
}
}
- hadHeadSensitiveCondition = cge->GetHadHeadSensitiveCondition();
- hadContextSensitiveCondition = cge->GetHadContextSensitiveCondition();
- hadLinkLanguageSensitiveCondition =
+ iface.HadHeadSensitiveCondition = cge->GetHadHeadSensitiveCondition();
+ iface.HadContextSensitiveCondition = cge->GetHadContextSensitiveCondition();
+ iface.HadLinkLanguageSensitiveCondition =
cge->GetHadLinkLanguageSensitiveCondition();
}
@@ -6903,23 +6912,20 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
return;
}
iface.Exists = true;
+
+ // If CMP0022 is NEW then the plain tll signature sets the
+ // INTERFACE_LINK_LIBRARIES property. Even if the project
+ // clears it, the link interface is still explicit.
iface.Explicit = cmp0022NEW || explicitLibraries;
if (explicitLibraries) {
// The interface libraries have been explicitly set.
this->ExpandLinkItems(linkIfaceProp, *explicitLibraries, config,
- headTarget, usage_requirements_only, iface.Libraries,
- iface.Objects, iface.HadHeadSensitiveCondition,
- iface.HadContextSensitiveCondition,
- iface.HadLinkLanguageSensitiveCondition);
- return;
+ headTarget, usage_requirements_only, iface);
}
- // If CMP0022 is NEW then the plain tll signature sets the
- // INTERFACE_LINK_LIBRARIES, so if we get here then the project
- // cleared the property explicitly and we should not fall back
- // to the link implementation.
- if (cmp0022NEW) {
+ // If the link interface is explicit, do not fall back to the link impl.
+ if (iface.Explicit) {
return;
}
@@ -6932,22 +6938,15 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
!this->PolicyWarnedCMP0022 && !usage_requirements_only) {
// Compare the link implementation fallback link interface to the
// preferred new link interface property and warn if different.
- std::vector<cmLinkItem> ifaceLibs;
- std::vector<cmLinkItem> ifaceObjects;
+ cmLinkInterface ifaceNew;
static const std::string newProp = "INTERFACE_LINK_LIBRARIES";
if (cmProp newExplicitLibraries = this->GetProperty(newProp)) {
- bool hadHeadSensitiveConditionDummy = false;
- bool hadContextSensitiveConditionDummy = false;
- bool hadLinkLanguageSensitiveConditionDummy = false;
this->ExpandLinkItems(newProp, *newExplicitLibraries, config,
- headTarget, usage_requirements_only, ifaceLibs,
- ifaceObjects, hadHeadSensitiveConditionDummy,
- hadContextSensitiveConditionDummy,
- hadLinkLanguageSensitiveConditionDummy);
+ headTarget, usage_requirements_only, ifaceNew);
}
- if (ifaceLibs != iface.Libraries) {
+ if (ifaceNew.Libraries != iface.Libraries) {
std::string oldLibraries = cmJoin(impl->Libraries, ";");
- std::string newLibraries = cmJoin(ifaceLibs, ";");
+ std::string newLibraries = cmJoin(ifaceNew.Libraries, ";");
if (oldLibraries.empty()) {
oldLibraries = "(empty)";
}
@@ -7085,10 +7084,7 @@ const cmLinkInterface* cmGeneratorTarget::GetImportLinkInterface(
iface.Multiplicity = info->Multiplicity;
cmExpandList(info->Languages, iface.Languages);
this->ExpandLinkItems(info->LibrariesProp, info->Libraries, config,
- headTarget, usage_requirements_only, iface.Libraries,
- iface.Objects, iface.HadHeadSensitiveCondition,
- iface.HadContextSensitiveCondition,
- iface.HadLinkLanguageSensitiveCondition);
+ headTarget, usage_requirements_only, iface);
std::vector<std::string> deps = cmExpandedList(info->SharedDeps);
LookupLinkItemScope scope{ this->LocalGenerator };
for (std::string const& dep : deps) {
@@ -7628,6 +7624,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
std::string const& evaluated =
cge->Evaluate(this->LocalGenerator, config, head, &dagChecker, nullptr,
this->LinkerLanguage);
+ bool const fromGenex = evaluated != *le;
cmExpandList(evaluated, llibs);
if (cge->GetHadHeadSensitiveCondition()) {
impl.HadHeadSensitiveCondition = true;
@@ -7699,7 +7696,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
}
}
- impl.Libraries.emplace_back(std::move(item), evaluated != *le);
+ impl.Libraries.emplace_back(std::move(item), fromGenex);
}
std::set<std::string> const& seenProps = cge->GetSeenTargetProperties();
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 6d2aa85..bb46211 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -498,6 +498,9 @@ public:
std::vector<BT<std::string>> GetLinkOptions(
std::string const& config, std::string const& language) const;
+ std::vector<BT<std::string>>& ResolveLinkerWrapper(
+ std::vector<BT<std::string>>& result, const std::string& language) const;
+
void GetStaticLibraryLinkOptions(std::vector<std::string>& result,
const std::string& config,
const std::string& language) const;
@@ -832,8 +835,9 @@ public:
std::string const& config) const;
std::string GetFortranModuleDirectory(std::string const& working_dir) const;
+ bool IsFortranBuildingInstrinsicModules() const;
- const std::string& GetSourcesProperty() const;
+ cmProp GetSourcesProperty() const;
void AddISPCGeneratedHeader(std::string const& header,
std::string const& config);
@@ -901,8 +905,7 @@ private:
void ComputeVersionedName(std::string& vName, std::string const& prefix,
std::string const& base, std::string const& suffix,
- std::string const& name,
- const char* version) const;
+ std::string const& name, cmProp version) const;
struct CompatibleInterfacesBase
{
@@ -1037,11 +1040,8 @@ private:
std::string const& config,
const cmGeneratorTarget* headTarget,
bool usage_requirements_only,
- std::vector<cmLinkItem>& items,
- std::vector<cmLinkItem>& objects,
- bool& hadHeadSensitiveCondition,
- bool& hadContextSensitiveCondition,
- bool& hadLinkLanguageSensitiveCondition) const;
+ cmLinkInterface& iface) const;
+
struct LookupLinkItemScope
{
cmLocalGenerator const* LG;
diff --git a/Source/cmGetDirectoryPropertyCommand.cxx b/Source/cmGetDirectoryPropertyCommand.cxx
index 7fbd479..d98f95c 100644
--- a/Source/cmGetDirectoryPropertyCommand.cxx
+++ b/Source/cmGetDirectoryPropertyCommand.cxx
@@ -13,6 +13,8 @@
namespace {
void StoreResult(cmMakefile& makefile, std::string const& variable,
const char* prop);
+void StoreResult(cmMakefile& makefile, std::string const& variable,
+ cmProp prop);
}
// cmGetDirectoryPropertyCommand
@@ -76,7 +78,6 @@ bool cmGetDirectoryPropertyCommand(std::vector<std::string> const& args,
return false;
}
- const char* prop = nullptr;
if (*i == "DEFINITIONS") {
switch (status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0059)) {
case cmPolicies::WARN:
@@ -94,8 +95,7 @@ bool cmGetDirectoryPropertyCommand(std::vector<std::string> const& args,
break;
}
}
- prop = cmToCStr(dir->GetProperty(*i));
- StoreResult(status.GetMakefile(), variable, prop);
+ StoreResult(status.GetMakefile(), variable, dir->GetProperty(*i));
return true;
}
@@ -105,4 +105,9 @@ void StoreResult(cmMakefile& makefile, std::string const& variable,
{
makefile.AddDefinition(variable, prop ? prop : "");
}
+void StoreResult(cmMakefile& makefile, std::string const& variable,
+ cmProp prop)
+{
+ makefile.AddDefinition(variable, prop);
+}
}
diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx
index cb657f9..4b380c0 100644
--- a/Source/cmGetPropertyCommand.cxx
+++ b/Source/cmGetPropertyCommand.cxx
@@ -268,6 +268,11 @@ bool StoreResult(OutType infoType, cmMakefile& makefile,
}
return true;
}
+bool StoreResult(OutType infoType, cmMakefile& makefile,
+ const std::string& variable, cmProp value)
+{
+ return StoreResult(infoType, makefile, variable, value.GetCStr());
+}
bool HandleGlobalMode(cmExecutionStatus& status, const std::string& name,
OutType infoType, const std::string& variable,
@@ -280,9 +285,8 @@ bool HandleGlobalMode(cmExecutionStatus& status, const std::string& name,
// Get the property.
cmake* cm = status.GetMakefile().GetCMakeInstance();
- return StoreResult(
- infoType, status.GetMakefile(), variable,
- cmToCStr(cm->GetState()->GetGlobalProperty(propertyName)));
+ return StoreResult(infoType, status.GetMakefile(), variable,
+ cm->GetState()->GetGlobalProperty(propertyName));
}
bool HandleDirectoryMode(cmExecutionStatus& status, const std::string& name,
@@ -329,7 +333,7 @@ bool HandleDirectoryMode(cmExecutionStatus& status, const std::string& name,
// Get the property.
return StoreResult(infoType, status.GetMakefile(), variable,
- cmToCStr(mf->GetProperty(propertyName)));
+ mf->GetProperty(propertyName));
}
bool HandleTargetMode(cmExecutionStatus& status, const std::string& name,
@@ -365,8 +369,7 @@ bool HandleTargetMode(cmExecutionStatus& status, const std::string& name,
if (!prop) {
prop = target->GetProperty(propertyName);
}
- return StoreResult(infoType, status.GetMakefile(), variable,
- cmToCStr(prop));
+ return StoreResult(infoType, status.GetMakefile(), variable, prop);
}
status.SetError(cmStrCat("could not find TARGET ", name,
". Perhaps it has not yet been created."));
@@ -391,7 +394,7 @@ bool HandleSourceMode(cmExecutionStatus& status, const std::string& name,
if (cmSourceFile* sf =
directory_makefile.GetOrCreateSource(source_file_absolute_path)) {
return StoreResult(infoType, status.GetMakefile(), variable,
- cmToCStr(sf->GetPropertyForUser(propertyName)));
+ sf->GetPropertyForUser(propertyName));
}
status.SetError(
cmStrCat("given SOURCE name that could not be found or created: ",
@@ -428,9 +431,8 @@ bool HandleVariableMode(cmExecutionStatus& status, const std::string& name,
return false;
}
- return StoreResult(
- infoType, status.GetMakefile(), variable,
- cmToCStr(status.GetMakefile().GetDefinition(propertyName)));
+ return StoreResult(infoType, status.GetMakefile(), variable,
+ status.GetMakefile().GetDefinition(propertyName));
}
bool HandleCacheMode(cmExecutionStatus& status, const std::string& name,
@@ -447,7 +449,7 @@ bool HandleCacheMode(cmExecutionStatus& status, const std::string& name,
value = status.GetMakefile().GetState()->GetCacheEntryProperty(
name, propertyName);
}
- StoreResult(infoType, status.GetMakefile(), variable, cmToCStr(value));
+ StoreResult(infoType, status.GetMakefile(), variable, value);
return true;
}
diff --git a/Source/cmGetTestPropertyCommand.cxx b/Source/cmGetTestPropertyCommand.cxx
index cf8c1d5..077353e 100644
--- a/Source/cmGetTestPropertyCommand.cxx
+++ b/Source/cmGetTestPropertyCommand.cxx
@@ -4,6 +4,7 @@
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
+#include "cmProperty.h"
#include "cmTest.h"
bool cmGetTestPropertyCommand(std::vector<std::string> const& args,
@@ -19,12 +20,12 @@ bool cmGetTestPropertyCommand(std::vector<std::string> const& args,
cmMakefile& mf = status.GetMakefile();
cmTest* test = mf.GetTest(testName);
if (test) {
- const char* prop = nullptr;
+ cmProp prop;
if (!args[1].empty()) {
prop = test->GetProperty(args[1]);
}
if (prop) {
- mf.AddDefinition(var, prop);
+ mf.AddDefinition(var, prop->c_str());
return true;
}
}
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
index 32238e4..12fd9c4 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -376,7 +376,7 @@ void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper(
#ifdef _WIN32
std::string check_error = "if %errorlevel% neq 0 exit /b %errorlevel%";
#else
- std::string check_error = "if [[ $? -ne 0 ]]; then exit 1; fi";
+ std::string check_error = "if [ $? -ne 0 ]; then exit 1; fi";
#endif
#ifdef _WIN32
diff --git a/Source/cmGlobalCommonGenerator.cxx b/Source/cmGlobalCommonGenerator.cxx
index 9e5bbca..a8e0f23 100644
--- a/Source/cmGlobalCommonGenerator.cxx
+++ b/Source/cmGlobalCommonGenerator.cxx
@@ -16,8 +16,8 @@
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
-
-class cmake;
+#include "cmSystemTools.h"
+#include "cmake.h"
cmGlobalCommonGenerator::cmGlobalCommonGenerator(cmake* cm)
: cmGlobalGenerator(cm)
@@ -95,3 +95,33 @@ bool cmGlobalCommonGenerator::IsExcludedFromAllInConfig(
}
return !t.ExcludedFromAllInConfigs.empty();
}
+
+std::string cmGlobalCommonGenerator::GetEditCacheCommand() const
+{
+ // If generating for an extra IDE, the edit_cache target cannot
+ // launch a terminal-interactive tool, so always use cmake-gui.
+ if (!this->GetExtraGeneratorName().empty()) {
+ return cmSystemTools::GetCMakeGUICommand();
+ }
+
+ // Use an internal cache entry to track the latest dialog used
+ // to edit the cache, and use that for the edit_cache target.
+ cmake* cm = this->GetCMakeInstance();
+ std::string editCacheCommand = cm->GetCMakeEditCommand();
+ if (!cm->GetCacheDefinition("CMAKE_EDIT_COMMAND") ||
+ !editCacheCommand.empty()) {
+ if (this->SupportsDirectConsole() && editCacheCommand.empty()) {
+ editCacheCommand = cmSystemTools::GetCMakeCursesCommand();
+ }
+ if (editCacheCommand.empty()) {
+ editCacheCommand = cmSystemTools::GetCMakeGUICommand();
+ }
+ if (!editCacheCommand.empty()) {
+ cm->AddCacheEntry("CMAKE_EDIT_COMMAND", editCacheCommand.c_str(),
+ "Path to cache edit program executable.",
+ cmStateEnums::INTERNAL);
+ }
+ }
+ cmProp edit_cmd = cm->GetCacheDefinition("CMAKE_EDIT_COMMAND");
+ return edit_cmd ? *edit_cmd : std::string();
+}
diff --git a/Source/cmGlobalCommonGenerator.h b/Source/cmGlobalCommonGenerator.h
index 2aa9d27..fed9ce8 100644
--- a/Source/cmGlobalCommonGenerator.h
+++ b/Source/cmGlobalCommonGenerator.h
@@ -42,4 +42,9 @@ public:
std::map<std::string, DirectoryTarget> ComputeDirectoryTargets() const;
bool IsExcludedFromAllInConfig(const DirectoryTarget::Target& t,
const std::string& config);
+
+protected:
+ virtual bool SupportsDirectConsole() const { return true; }
+ const char* GetEditCacheTargetName() const override { return "edit_cache"; }
+ std::string GetEditCacheCommand() const override;
};
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 9193778..3561deb 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -242,7 +242,7 @@ void cmGlobalGenerator::ResolveLanguageCompiler(const std::string& lang,
std::vector<std::string> cnameArgVec;
if (cname && !cname->empty()) {
cmExpandList(*cname, cnameArgVec);
- cname = &cnameArgVec.front();
+ cname = cmProp(cnameArgVec.front());
}
std::string changeVars;
@@ -498,6 +498,18 @@ bool cmGlobalGenerator::CheckLanguages(
void cmGlobalGenerator::EnableLanguage(
std::vector<std::string> const& languages, cmMakefile* mf, bool optional)
{
+ if (!this->IsMultiConfig()) {
+ std::string envBuildType;
+ if (!mf->GetDefinition("CMAKE_BUILD_TYPE") &&
+ cmSystemTools::GetEnv("CMAKE_BUILD_TYPE", envBuildType)) {
+ mf->AddCacheDefinition(
+ "CMAKE_BUILD_TYPE", envBuildType,
+ "Choose the type of build. Options include: empty, "
+ "Debug, Release, RelWithDebInfo, MinSizeRel.",
+ cmStateEnums::STRING);
+ }
+ }
+
if (languages.empty()) {
cmSystemTools::Error("EnableLanguage must have a lang specified!");
cmSystemTools::SetFatalErrorOccured();
@@ -1167,10 +1179,10 @@ void cmGlobalGenerator::FillExtensionToLanguageMap(const std::string& l,
}
}
-const char* cmGlobalGenerator::GetGlobalSetting(std::string const& name) const
+cmProp cmGlobalGenerator::GetGlobalSetting(std::string const& name) const
{
assert(!this->Makefiles.empty());
- return cmToCStr(this->Makefiles[0]->GetDefinition(name));
+ return this->Makefiles[0]->GetDefinition(name);
}
bool cmGlobalGenerator::GlobalSettingIsOn(std::string const& name) const
@@ -1183,7 +1195,7 @@ std::string cmGlobalGenerator::GetSafeGlobalSetting(
std::string const& name) const
{
assert(!this->Makefiles.empty());
- return this->Makefiles[0]->GetSafeDefinition(name);
+ return this->Makefiles[0]->GetDefinition(name);
}
bool cmGlobalGenerator::IgnoreFile(const char* ext) const
@@ -1251,10 +1263,8 @@ void cmGlobalGenerator::Configure()
this->CreateDefaultGlobalTargets(globalTargets);
for (const auto& mf : this->Makefiles) {
- auto& targets = mf->GetTargets();
for (GlobalTargetInfo const& globalTarget : globalTargets) {
- targets.emplace(globalTarget.Name,
- this->CreateGlobalTarget(globalTarget, mf.get()));
+ this->CreateGlobalTarget(globalTarget, mf.get());
}
}
}
@@ -1771,9 +1781,8 @@ void cmGlobalGenerator::CreateGeneratorTargets(
std::map<cmTarget*, cmGeneratorTarget*> const& importedMap)
{
if (targetTypes == AllTargets) {
- for (auto& target : mf->GetTargets()) {
- cmTarget* t = &target.second;
- lg->AddGeneratorTarget(cm::make_unique<cmGeneratorTarget>(t, lg));
+ for (cmTarget* target : mf->GetOrderedTargets()) {
+ lg->AddGeneratorTarget(cm::make_unique<cmGeneratorTarget>(target, lg));
}
}
@@ -2740,7 +2749,7 @@ void cmGlobalGenerator::AddGlobalTarget_Install(
singleLine.push_back(cfgArg);
cfgArg = "-DEFFECTIVE_PLATFORM_NAME=$(EFFECTIVE_PLATFORM_NAME)";
} else {
- cfgArg += cmToCStr(mf->GetDefinition("CMAKE_CFG_INTDIR"));
+ cfgArg += *mf->GetDefinition("CMAKE_CFG_INTDIR");
}
singleLine.push_back(cfgArg);
}
@@ -2812,12 +2821,19 @@ bool cmGlobalGenerator::UseFolderProperty() const
return false;
}
-cmTarget cmGlobalGenerator::CreateGlobalTarget(GlobalTargetInfo const& gti,
- cmMakefile* mf)
+void cmGlobalGenerator::CreateGlobalTarget(GlobalTargetInfo const& gti,
+ cmMakefile* mf)
{
// Package
- cmTarget target(gti.Name, cmStateEnums::GLOBAL_TARGET,
- cmTarget::VisibilityNormal, mf, gti.PerConfig);
+ auto tb =
+ mf->CreateNewTarget(gti.Name, cmStateEnums::GLOBAL_TARGET, gti.PerConfig);
+
+ // Do nothing if gti.Name is already used
+ if (!tb.second) {
+ return;
+ }
+
+ cmTarget& target = tb.first;
target.SetProperty("EXCLUDE_FROM_ALL", "TRUE");
std::vector<std::string> no_outputs;
@@ -2841,8 +2857,6 @@ cmTarget cmGlobalGenerator::CreateGlobalTarget(GlobalTargetInfo const& gti,
if (this->UseFolderProperty()) {
target.SetProperty("FOLDER", this->GetPredefinedTargetsFolder());
}
-
- return target;
}
std::string cmGlobalGenerator::GenerateRuleFile(
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 147146e..34646d9 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -23,6 +23,7 @@
#include "cmCustomCommandLines.h"
#include "cmDuration.h"
#include "cmExportSet.h"
+#include "cmProperty.h"
#include "cmStateSnapshot.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -308,7 +309,7 @@ public:
cmExportSetMap& GetExportSets() { return this->ExportSets; }
- const char* GetGlobalSetting(std::string const& name) const;
+ cmProp GetGlobalSetting(std::string const& name) const;
bool GlobalSettingIsOn(std::string const& name) const;
std::string GetSafeGlobalSetting(std::string const& name) const;
@@ -596,7 +597,7 @@ protected:
void AddGlobalTarget_RebuildCache(
std::vector<GlobalTargetInfo>& targets) const;
void AddGlobalTarget_Install(std::vector<GlobalTargetInfo>& targets);
- cmTarget CreateGlobalTarget(GlobalTargetInfo const& gti, cmMakefile* mf);
+ void CreateGlobalTarget(GlobalTargetInfo const& gti, cmMakefile* mf);
std::string FindMakeProgramFile;
std::string ConfiguredFilesPath;
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
index 7cf3e93..b81f82e 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -186,8 +186,7 @@ void cmGlobalGhsMultiGenerator::EnableLanguage(
mf->AddDefinition("GHSMULTI", "1"); // identifier for user CMake files
- const char* tgtPlatform =
- cmToCStrSafe(mf->GetDefinition("GHS_TARGET_PLATFORM"));
+ const char* tgtPlatform = mf->GetDefinition("GHS_TARGET_PLATFORM")->c_str();
if (!tgtPlatform) {
cmSystemTools::Message("Green Hills MULTI: GHS_TARGET_PLATFORM not "
"specified; defaulting to \"integrity\"");
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 963118f..47a931d 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -382,7 +382,7 @@ void cmGlobalNinjaGenerator::WriteCustomCommandBuild(
if (restat) {
vars["restat"] = "1";
}
- if (uses_terminal && this->SupportsConsolePool()) {
+ if (uses_terminal && this->SupportsDirectConsole()) {
vars["pool"] = "console";
} else if (!job_pool.empty()) {
vars["pool"] = job_pool;
@@ -920,14 +920,7 @@ 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);
- }
+ mf->InitCMAKE_CONFIGURATION_TYPES("Debug;Release;RelWithDebInfo");
}
this->cmGlobalGenerator::EnableLanguage(langs, mf, optional);
@@ -1019,13 +1012,6 @@ bool cmGlobalNinjaGenerator::HasRule(const std::string& name)
// Private virtual overrides
-std::string cmGlobalNinjaGenerator::GetEditCacheCommand() const
-{
- // Ninja by design does not run interactive tools in the terminal,
- // so our only choice is cmake-gui.
- return cmSystemTools::GetCMakeGUICommand();
-}
-
void cmGlobalNinjaGenerator::ComputeTargetObjectDirectory(
cmGeneratorTarget* gt) const
{
@@ -1847,7 +1833,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
// Use 'console' pool to get non buffered output of the CMake re-run call
// Available since Ninja 1.5
- if (this->SupportsConsolePool()) {
+ if (this->SupportsDirectConsole()) {
reBuild.Variables["pool"] = "console";
}
@@ -1941,7 +1927,7 @@ std::string cmGlobalNinjaGenerator::NinjaCmd() const
return "ninja";
}
-bool cmGlobalNinjaGenerator::SupportsConsolePool() const
+bool cmGlobalNinjaGenerator::SupportsDirectConsole() const
{
return this->NinjaSupportsConsolePool;
}
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index bb4ce2b..ec73475 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -220,7 +220,6 @@ public:
{
return "package_source";
}
- const char* GetEditCacheTargetName() const override { return "edit_cache"; }
const char* GetRebuildCacheTargetName() const override
{
return "rebuild_cache";
@@ -406,7 +405,7 @@ public:
return "1.10.2";
}
static std::string RequiredNinjaVersionForCodePage() { return "1.11"; }
- bool SupportsConsolePool() const;
+ bool SupportsDirectConsole() const override;
bool SupportsImplicitOuts() const;
bool SupportsManifestRestat() const;
bool SupportsMultilineDepfile() const;
@@ -489,7 +488,6 @@ protected:
std::string DefaultFileConfig;
private:
- std::string GetEditCacheCommand() const override;
bool FindMakeProgram(cmMakefile* mf) override;
void CheckNinjaFeatures();
void CheckNinjaCodePage();
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index 9c3de1e..d9f94a1 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -78,36 +78,6 @@ void cmGlobalUnixMakefileGenerator3::GetDocumentation(
entry.Brief = "Generates standard UNIX makefiles.";
}
-std::string cmGlobalUnixMakefileGenerator3::GetEditCacheCommand() const
-{
- // If generating for an extra IDE, the edit_cache target cannot
- // launch a terminal-interactive tool, so always use cmake-gui.
- if (!this->GetExtraGeneratorName().empty()) {
- return cmSystemTools::GetCMakeGUICommand();
- }
-
- // Use an internal cache entry to track the latest dialog used
- // to edit the cache, and use that for the edit_cache target.
- cmake* cm = this->GetCMakeInstance();
- std::string editCacheCommand = cm->GetCMakeEditCommand();
- if (!cm->GetCacheDefinition("CMAKE_EDIT_COMMAND") ||
- !editCacheCommand.empty()) {
- if (editCacheCommand.empty()) {
- editCacheCommand = cmSystemTools::GetCMakeCursesCommand();
- }
- if (editCacheCommand.empty()) {
- editCacheCommand = cmSystemTools::GetCMakeGUICommand();
- }
- if (!editCacheCommand.empty()) {
- cm->AddCacheEntry("CMAKE_EDIT_COMMAND", editCacheCommand.c_str(),
- "Path to cache edit program executable.",
- cmStateEnums::INTERNAL);
- }
- }
- cmProp edit_cmd = cm->GetCacheDefinition("CMAKE_EDIT_COMMAND");
- return edit_cmd ? *edit_cmd : std::string();
-}
-
void cmGlobalUnixMakefileGenerator3::ComputeTargetObjectDirectory(
cmGeneratorTarget* gt) const
{
diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h
index 7c950cc..94ee476 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.h
+++ b/Source/cmGlobalUnixMakefileGenerator3.h
@@ -228,7 +228,6 @@ protected:
{
return "package_source";
}
- const char* GetEditCacheTargetName() const override { return "edit_cache"; }
const char* GetRebuildCacheTargetName() const override
{
return "rebuild_cache";
@@ -278,7 +277,6 @@ protected:
private:
const char* GetBuildIgnoreErrorsFlag() const override { return "-i"; }
- std::string GetEditCacheCommand() const override;
std::map<cmStateSnapshot, std::set<cmGeneratorTarget const*>,
cmStateSnapshot::StrictWeakOrder>
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index fdb7155..488ff2e 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -88,7 +88,7 @@ public:
void GetDocumentation(cmDocumentationEntry& entry) const override
{
entry.Name = std::string(vs10generatorName) + " [arch]";
- entry.Brief = "Generates Visual Studio 2010 project files. "
+ entry.Brief = "Deprecated. Generates Visual Studio 2010 project files. "
"Optional [arch] can be \"Win64\" or \"IA64\".";
}
diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx
index 0083c40..21ea7e6 100644
--- a/Source/cmGlobalVisualStudio71Generator.cxx
+++ b/Source/cmGlobalVisualStudio71Generator.cxx
@@ -157,11 +157,11 @@ void cmGlobalVisualStudio71Generator::WriteProjectDepends(
// executables to the libraries it uses are also done here
void cmGlobalVisualStudio71Generator::WriteExternalProject(
std::ostream& fout, const std::string& name, const std::string& location,
- const char* typeGuid,
- const std::set<BT<std::pair<std::string, bool>>>& depends)
+ cmProp typeGuid, const std::set<BT<std::pair<std::string, bool>>>& depends)
{
fout << "Project(\"{"
- << (typeGuid ? typeGuid : this->ExternalProjectType(location))
+ << (typeGuid ? typeGuid
+ : std::string(this->ExternalProjectType(location)))
<< "}\") = \"" << name << "\", \""
<< this->ConvertToSolutionPath(location) << "\", \"{"
<< this->GetGUID(name) << "}\"\n";
diff --git a/Source/cmGlobalVisualStudio71Generator.h b/Source/cmGlobalVisualStudio71Generator.h
index 7d38199..30ebf08 100644
--- a/Source/cmGlobalVisualStudio71Generator.h
+++ b/Source/cmGlobalVisualStudio71Generator.h
@@ -33,7 +33,7 @@ protected:
const std::string& platformMapping = "") override;
void WriteExternalProject(
std::ostream& fout, const std::string& name, const std::string& path,
- const char* typeGuid,
+ cmProp typeGuid,
const std::set<BT<std::pair<std::string, bool>>>& depends) override;
// Folders are not supported by VS 7.1.
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index 0c85a044..2a142ae 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -107,14 +107,7 @@ void cmGlobalVisualStudio7Generator::EnableLanguage(
{
mf->AddDefinition("CMAKE_GENERATOR_RC", "rc");
mf->AddDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV", "1");
- if (!mf->GetDefinition("CMAKE_CONFIGURATION_TYPES")) {
- mf->AddCacheDefinition(
- "CMAKE_CONFIGURATION_TYPES", "Debug;Release;MinSizeRel;RelWithDebInfo",
- "Semicolon separated list of supported configuration types, "
- "only supports Debug, Release, MinSizeRel, and RelWithDebInfo, "
- "anything else will be ignored.",
- cmStateEnums::STRING);
- }
+ mf->InitCMAKE_CONFIGURATION_TYPES("Debug;Release;MinSizeRel;RelWithDebInfo");
// Create list of configurations requested by user's cache, if any.
this->cmGlobalVisualStudioGenerator::EnableLanguage(lang, mf, optional);
@@ -303,6 +296,25 @@ void cmGlobalVisualStudio7Generator::Generate()
this->CallVisualStudioMacro(MacroReload,
GetSLNFile(this->LocalGenerators[0].get()));
}
+
+ if (this->Version == VS10 && !this->CMakeInstance->GetIsInTryCompile()) {
+ std::string cmakeWarnVS10;
+ if (cmProp cached = this->CMakeInstance->GetState()->GetCacheEntryValue(
+ "CMAKE_WARN_VS10")) {
+ this->CMakeInstance->MarkCliAsUsed("CMAKE_WARN_VS10");
+ cmakeWarnVS10 = *cached;
+ } else {
+ cmSystemTools::GetEnv("CMAKE_WARN_VS10", cmakeWarnVS10);
+ }
+ if (cmakeWarnVS10.empty() || !cmIsOff(cmakeWarnVS10)) {
+ this->CMakeInstance->IssueMessage(
+ MessageType::WARNING,
+ "The \"Visual Studio 10 2010\" generator is deprecated "
+ "and will be removed in a future version of CMake."
+ "\n"
+ "Add CMAKE_WARN_VS10=OFF to the cache to disable this warning.");
+ }
+ }
}
void cmGlobalVisualStudio7Generator::OutputSLNFile(
@@ -379,10 +391,9 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
std::string project = target->GetName();
std::string location = *expath;
- this->WriteExternalProject(
- fout, project, location,
- cmToCStr(target->GetProperty("VS_PROJECT_TYPE")),
- target->GetUtilities());
+ this->WriteExternalProject(fout, project, location,
+ target->GetProperty("VS_PROJECT_TYPE"),
+ target->GetUtilities());
written = true;
} else {
cmProp vcprojName = target->GetProperty("GENERATOR_FILE_NAME");
diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h
index 148762e..1e34792 100644
--- a/Source/cmGlobalVisualStudio7Generator.h
+++ b/Source/cmGlobalVisualStudio7Generator.h
@@ -6,6 +6,7 @@
#include "cmGlobalGeneratorFactory.h"
#include "cmGlobalVisualStudioGenerator.h"
+#include "cmProperty.h"
class cmTarget;
struct cmIDEFlagTable;
@@ -142,7 +143,7 @@ protected:
virtual void WriteExternalProject(
std::ostream& fout, const std::string& name, const std::string& path,
- const char* typeGuid,
+ cmProp typeGuid,
const std::set<BT<std::pair<std::string, bool>>>& dependencies) = 0;
std::string ConvertToSolutionPath(const std::string& path);
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 77403b0..763f12a 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -431,14 +431,7 @@ void cmGlobalXCodeGenerator::EnableLanguage(
{
mf->AddDefinition("XCODE", "1");
mf->AddDefinition("XCODE_VERSION", this->VersionString);
- if (!mf->GetDefinition("CMAKE_CONFIGURATION_TYPES")) {
- mf->AddCacheDefinition(
- "CMAKE_CONFIGURATION_TYPES", "Debug;Release;MinSizeRel;RelWithDebInfo",
- "Semicolon separated list of supported configuration types, "
- "only supports Debug, Release, MinSizeRel, and RelWithDebInfo, "
- "anything else will be ignored.",
- cmStateEnums::STRING);
- }
+ mf->InitCMAKE_CONFIGURATION_TYPES("Debug;Release;MinSizeRel;RelWithDebInfo");
mf->AddDefinition("CMAKE_GENERATOR_NO_COMPILER_ENV", "1");
this->cmGlobalGenerator::EnableLanguage(lang, mf, optional);
this->ComputeArchitectures(mf);
@@ -1674,7 +1667,7 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmGeneratorTarget* gtgt)
fout << "\n";
}
if (cmSourceFile* sf = mf->GetOrCreateSource(fname)) {
- sf->SetProperty("LANGUAGE", llang.c_str());
+ sf->SetProperty("LANGUAGE", llang);
gtgt->AddSource(fname);
}
}
diff --git a/Source/cmIncludeGuardCommand.cxx b/Source/cmIncludeGuardCommand.cxx
index aefd098..d48c823 100644
--- a/Source/cmIncludeGuardCommand.cxx
+++ b/Source/cmIncludeGuardCommand.cxx
@@ -4,6 +4,7 @@
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
+#include "cmProperty.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmSystemTools.h"
diff --git a/Source/cmIncludeRegularExpressionCommand.cxx b/Source/cmIncludeRegularExpressionCommand.cxx
index 655ebd6..cdcc7df 100644
--- a/Source/cmIncludeRegularExpressionCommand.cxx
+++ b/Source/cmIncludeRegularExpressionCommand.cxx
@@ -14,7 +14,7 @@ bool cmIncludeRegularExpressionCommand(std::vector<std::string> const& args,
}
cmMakefile& mf = status.GetMakefile();
- mf.SetIncludeRegularExpression(args[0].c_str());
+ mf.SetIncludeRegularExpression(args[0]);
if (args.size() > 1) {
mf.SetComplainRegularExpression(args[1]);
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index 79109b5..687741b 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -36,6 +36,7 @@
#include "cmMessageType.h"
#include "cmPolicies.h"
#include "cmProperty.h"
+#include "cmRange.h"
#include "cmRuntimeDependencyArchive.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
@@ -681,8 +682,8 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
te->LibraryGenerator = libraryGenerator.get();
te->RuntimeGenerator = runtimeGenerator.get();
te->ObjectsGenerator = objectGenerator.get();
- te->InterfaceIncludeDirectories =
- cmJoin(includesArgs.GetIncludeDirs(), ";");
+ target.AddInstallIncludeDirectories(
+ cmMakeRange(includesArgs.GetIncludeDirs()));
te->NamelinkOnly = namelinkOnly;
helper.Makefile->GetGlobalGenerator()
->GetExportSets()[exports]
diff --git a/Source/cmInstallMode.h b/Source/cmInstallMode.h
new file mode 100644
index 0000000..5343d34
--- /dev/null
+++ b/Source/cmInstallMode.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. */
+#pragma once
+
+/**
+ * Enumerate types known to file(INSTALL).
+ */
+enum class cmInstallMode
+{
+ COPY,
+ ABS_SYMLINK,
+ ABS_SYMLINK_OR_COPY,
+ REL_SYMLINK,
+ REL_SYMLINK_OR_COPY,
+ SYMLINK,
+ SYMLINK_OR_COPY
+};
diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx
index 4f7c959..2e444f2 100644
--- a/Source/cmListFileCache.cxx
+++ b/Source/cmListFileCache.cxx
@@ -548,7 +548,7 @@ void cmListFileBacktrace::PrintTitle(std::ostream& out) const
}
cmListFileContext lfc = this->TopEntry->Context;
cmStateSnapshot bottom = this->GetBottom();
- if (!bottom.GetState()->GetIsInTryCompile()) {
+ if (bottom.GetState()->GetProjectKind() == cmState::ProjectKind::Normal) {
lfc.FilePath = cmSystemTools::RelativeIfUnder(
bottom.GetState()->GetSourceDirectory(), lfc.FilePath);
}
@@ -579,7 +579,7 @@ void cmListFileBacktrace::PrintCallStack(std::ostream& out) const
out << "Call Stack (most recent call first):\n";
}
cmListFileContext lfc = cur->Context;
- if (!bottom.GetState()->GetIsInTryCompile()) {
+ if (bottom.GetState()->GetProjectKind() == cmState::ProjectKind::Normal) {
lfc.FilePath = cmSystemTools::RelativeIfUnder(
bottom.GetState()->GetSourceDirectory(), lfc.FilePath);
}
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 3b282de..5fe5c75 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -107,10 +107,9 @@ cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile)
{
std::vector<std::string> cpath;
cmSystemTools::GetPath(cpath, "CPATH");
- for (std::string& cp : cpath) {
+ for (std::string const& cp : cpath) {
if (cmSystemTools::FileIsFullPath(cp)) {
- cp = cmSystemTools::CollapseFullPath(cp);
- this->EnvCPATH.emplace(std::move(cp));
+ this->EnvCPATH.emplace_back(cmSystemTools::CollapseFullPath(cp));
}
}
}
@@ -426,27 +425,25 @@ void cmLocalGenerator::ProcessEvaluationFiles(
void cmLocalGenerator::GenerateInstallRules()
{
// Compute the install prefix.
- const char* prefix =
- cmToCStr(this->Makefile->GetDefinition("CMAKE_INSTALL_PREFIX"));
+ cmProp installPrefix = this->Makefile->GetDefinition("CMAKE_INSTALL_PREFIX");
+ std::string prefix = installPrefix;
#if defined(_WIN32) && !defined(__CYGWIN__)
- std::string prefix_win32;
- if (!prefix) {
- if (!cmSystemTools::GetEnv("SystemDrive", prefix_win32)) {
- prefix_win32 = "C:";
+ if (!installPrefix) {
+ if (!cmSystemTools::GetEnv("SystemDrive", prefix)) {
+ prefix = "C:";
}
cmProp project_name = this->Makefile->GetDefinition("PROJECT_NAME");
if (cmNonempty(project_name)) {
- prefix_win32 += "/Program Files/";
- prefix_win32 += *project_name;
+ prefix += "/Program Files/";
+ prefix += *project_name;
} else {
- prefix_win32 += "/InstalledCMakeProject";
+ prefix += "/InstalledCMakeProject";
}
- prefix = prefix_win32.c_str();
}
#elif defined(__HAIKU__)
char dir[B_PATH_NAME_LENGTH];
- if (!prefix) {
+ if (!installPrefix) {
if (find_directory(B_SYSTEM_DIRECTORY, -1, false, dir, sizeof(dir)) ==
B_OK) {
prefix = dir;
@@ -455,13 +452,13 @@ void cmLocalGenerator::GenerateInstallRules()
}
}
#else
- if (!prefix) {
+ if (!installPrefix) {
prefix = "/usr/local";
}
#endif
if (cmProp stagingPrefix =
this->Makefile->GetDefinition("CMAKE_STAGING_PREFIX")) {
- prefix = stagingPrefix->c_str();
+ prefix = *stagingPrefix;
}
// Compute the set of configurations.
@@ -878,9 +875,12 @@ std::string cmLocalGenerator::GetIncludeFlags(
// Support special system include flag if it is available and the
// normal flag is repeated for each directory.
cmProp sysIncludeFlag = nullptr;
+ cmProp sysIncludeFlagWarning = nullptr;
if (repeatFlag) {
sysIncludeFlag = this->Makefile->GetDefinition(
cmStrCat("CMAKE_INCLUDE_SYSTEM_FLAG_", lang));
+ sysIncludeFlagWarning = this->Makefile->GetDefinition(
+ cmStrCat("_CMAKE_INCLUDE_SYSTEM_FLAG_", lang, "_WARNING"));
}
cmProp fwSearchFlag = this->Makefile->GetDefinition(
@@ -889,6 +889,7 @@ std::string cmLocalGenerator::GetIncludeFlags(
cmStrCat("CMAKE_", lang, "_SYSTEM_FRAMEWORK_SEARCH_FLAG"));
bool flagUsed = false;
+ bool sysIncludeFlagUsed = false;
std::set<std::string> emitted;
#ifdef __APPLE__
emitted.insert("/System/Library/Frameworks");
@@ -915,6 +916,7 @@ std::string cmLocalGenerator::GetIncludeFlags(
if (sysIncludeFlag && target &&
target->IsSystemIncludeDirectory(i, config, lang)) {
includeFlags << *sysIncludeFlag;
+ sysIncludeFlagUsed = true;
} else {
includeFlags << includeFlag;
}
@@ -931,6 +933,9 @@ std::string cmLocalGenerator::GetIncludeFlags(
}
includeFlags << sep;
}
+ if (sysIncludeFlagUsed && sysIncludeFlagWarning) {
+ includeFlags << *sysIncludeFlagWarning;
+ }
std::string flags = includeFlags.str();
// remove trailing separators
if ((sep[0] != ' ') && !flags.empty() && flags.back() == sep[0]) {
@@ -1239,19 +1244,31 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit(
}
}
+ bool const isCorCxx = (lang == "C" || lang == "CXX");
+
+ // Resolve symlinks in CPATH for comparison with resolved include paths.
+ // We do this here instead of when EnvCPATH is populated in case symlinks
+ // on disk have changed in the meantime.
+ std::set<std::string> resolvedEnvCPATH;
+ if (isCorCxx) {
+ for (std::string const& i : this->EnvCPATH) {
+ resolvedEnvCPATH.emplace(this->GlobalGenerator->GetRealPath(i));
+ }
+ }
+
// Checks if this is not an excluded (implicit) include directory.
- auto notExcluded = [this, &implicitSet, &implicitExclude,
- &lang](std::string const& dir) {
- return (
- // Do not exclude directories that are not in an excluded set.
- ((!cm::contains(implicitSet, this->GlobalGenerator->GetRealPath(dir))) &&
- (!cm::contains(implicitExclude, dir)))
+ auto notExcluded = [this, &implicitSet, &implicitExclude, &resolvedEnvCPATH,
+ isCorCxx](std::string const& dir) -> bool {
+ std::string const& real_dir = this->GlobalGenerator->GetRealPath(dir);
+ return
+ // Do not exclude directories that are not in any excluded set.
+ !(cm::contains(implicitSet, real_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") && cm::contains(this->EnvCPATH, dir)));
+ || (isCorCxx && cm::contains(resolvedEnvCPATH, real_dir));
};
// Get the target-specific include directories.
@@ -1850,17 +1867,17 @@ std::string cmLocalGenerator::GetLinkLibsCMP0065(
}
bool cmLocalGenerator::AllAppleArchSysrootsAreTheSame(
- const std::vector<std::string>& archs, const char* sysroot)
+ const std::vector<std::string>& archs, cmProp sysroot)
{
if (!sysroot) {
return false;
}
return std::all_of(archs.begin(), archs.end(),
- [this, &sysroot](std::string const& arch) -> bool {
+ [this, sysroot](std::string const& arch) -> bool {
std::string const& archSysroot =
this->AppleArchSysroots[arch];
- return cmIsOff(archSysroot) || archSysroot == sysroot;
+ return cmIsOff(archSysroot) || sysroot == archSysroot;
});
}
@@ -1893,7 +1910,7 @@ void cmLocalGenerator::AddArchitectureFlags(std::string& flags,
cmProp sysrootFlag = this->Makefile->GetDefinition(sysrootFlagVar);
if (cmNonempty(sysrootFlag)) {
if (!this->AppleArchSysroots.empty() &&
- !this->AllAppleArchSysrootsAreTheSame(archs, cmToCStr(sysroot))) {
+ !this->AllAppleArchSysrootsAreTheSame(archs, sysroot)) {
for (std::string const& arch : archs) {
std::string const& archSysroot = this->AppleArchSysroots[arch];
if (cmIsOff(archSysroot)) {
@@ -2536,10 +2553,10 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
continue;
}
- const std::string pchExtension =
- this->Makefile->GetSafeDefinition("CMAKE_PCH_EXTENSION");
+ cmProp pchExtension =
+ this->Makefile->GetDefinition("CMAKE_PCH_EXTENSION");
- if (pchExtension.empty()) {
+ if (pchExtension.IsEmpty()) {
continue;
}
@@ -2630,7 +2647,7 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
}
}
} else {
- pch_sf->SetProperty("PCH_EXTENSION", pchExtension.c_str());
+ pch_sf->SetProperty("PCH_EXTENSION", pchExtension);
}
// Add pchHeader to source files, which will
@@ -2771,7 +2788,7 @@ inline void RegisterUnitySources(cmGeneratorTarget* target, cmSourceFile* sf,
std::string const& filename)
{
target->AddSourceFileToUnityBatch(sf->ResolveFullPath());
- sf->SetProperty("UNITY_SOURCE_FILE", filename.c_str());
+ sf->SetProperty("UNITY_SOURCE_FILE", filename);
}
}
@@ -2969,7 +2986,7 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target)
auto* unity = this->GetMakefile()->GetOrCreateSource(file);
target->AddSource(file, true);
unity->SetProperty("SKIP_UNITY_BUILD_INCLUSION", "ON");
- unity->SetProperty("UNITY_SOURCE_FILE", file.c_str());
+ unity->SetProperty("UNITY_SOURCE_FILE", file);
}
}
}
@@ -3039,6 +3056,30 @@ void cmLocalGenerator::AppendPositionIndependentLinkerFlags(
}
}
+bool cmLocalGenerator::AppendLWYUFlags(std::string& flags,
+ const cmGeneratorTarget* target,
+ const std::string& lang)
+{
+ auto useLWYU = target->GetPropertyAsBool("LINK_WHAT_YOU_USE") &&
+ (target->GetType() == cmStateEnums::TargetType::EXECUTABLE ||
+ target->GetType() == cmStateEnums::TargetType::SHARED_LIBRARY ||
+ target->GetType() == cmStateEnums::TargetType::MODULE_LIBRARY);
+
+ if (useLWYU) {
+ const auto& lwyuFlag = this->GetMakefile()->GetSafeDefinition(
+ cmStrCat("CMAKE_", lang, "_LINK_WHAT_YOU_USE_FLAG"));
+ useLWYU = !lwyuFlag.empty();
+
+ if (useLWYU) {
+ std::vector<BT<std::string>> lwyuOpts;
+ lwyuOpts.emplace_back(lwyuFlag);
+ this->AppendFlags(flags, target->ResolveLinkerWrapper(lwyuOpts, lang));
+ }
+ }
+
+ return useLWYU;
+}
+
void cmLocalGenerator::AppendCompileOptions(std::string& options,
std::string const& options_list,
const char* regex) const
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 993280a..678ef8c 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -171,6 +171,8 @@ public:
cmGeneratorTarget* target,
const std::string& config,
const std::string& lang);
+ bool AppendLWYUFlags(std::string& flags, const cmGeneratorTarget* target,
+ const std::string& lang);
enum class IncludePathStyle
{
@@ -587,7 +589,7 @@ protected:
std::string::size_type ObjectPathMax;
std::set<std::string> ObjectMaxPathViolations;
- std::set<std::string> EnvCPATH;
+ std::vector<std::string> EnvCPATH;
using GeneratorTargetMap =
std::unordered_map<std::string, cmGeneratorTarget*>;
@@ -649,7 +651,7 @@ private:
void ComputeObjectMaxPath();
bool AllAppleArchSysrootsAreTheSame(const std::vector<std::string>& archs,
- const char* sysroot);
+ cmProp sysroot);
void CopyPchCompilePdb(const std::string& config, cmGeneratorTarget* target,
const std::string& ReuseFrom,
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index 7f7b1e7..9f8e7ed 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -279,7 +279,7 @@ void cmLocalNinjaGenerator::WriteNinjaRequiredVersion(std::ostream& os)
std::string requiredVersion = cmGlobalNinjaGenerator::RequiredNinjaVersion();
// Ninja generator uses the 'console' pool if available (>= 1.5)
- if (this->GetGlobalNinjaGenerator()->SupportsConsolePool()) {
+ if (this->GetGlobalNinjaGenerator()->SupportsDirectConsole()) {
requiredVersion =
cmGlobalNinjaGenerator::RequiredNinjaVersionForConsolePool();
}
diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx
index 002f484..46f9d31 100644
--- a/Source/cmLocalVisualStudioGenerator.cxx
+++ b/Source/cmLocalVisualStudioGenerator.cxx
@@ -171,7 +171,7 @@ std::string cmLocalVisualStudioGenerator::ConstructScript(
// for visual studio IDE add extra stuff to the PATH
// if CMAKE_MSVCIDE_RUN_PATH is set.
- if (this->Makefile->GetDefinition("MSVC_IDE")) {
+ if (this->GetGlobalGenerator()->IsVisualStudio()) {
cmProp extraPath = this->Makefile->GetDefinition("CMAKE_MSVCIDE_RUN_PATH");
if (extraPath) {
script += newline;
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index c970abe..7abbd31 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -1444,7 +1444,7 @@ bool cmMakefile::ParseDefineFlag(std::string const& def, bool remove)
std::string ndefs = cmJoin(cmMakeRange(defBegin, defEnd), ";");
// Store the new list.
- this->SetProperty("COMPILE_DEFINITIONS", ndefs.c_str());
+ this->SetProperty("COMPILE_DEFINITIONS", ndefs);
}
} else {
// Append the definition to the directory property.
@@ -1465,30 +1465,29 @@ void cmMakefile::InitializeFromParent(cmMakefile* parent)
// Include transform property. There is no per-config version.
{
const char* prop = "IMPLICIT_DEPENDS_INCLUDE_TRANSFORM";
- this->SetProperty(prop, cmToCStr(parent->GetProperty(prop)));
+ this->SetProperty(prop, parent->GetProperty(prop));
}
// 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",
- cmToCStr(parent->GetProperty("COMPILE_DEFINITIONS")));
+ parent->GetProperty("COMPILE_DEFINITIONS"));
std::vector<std::string> configs =
this->GetGeneratorConfigs(cmMakefile::ExcludeEmptyConfig);
for (std::string const& config : configs) {
std::string defPropName =
cmStrCat("COMPILE_DEFINITIONS_", cmSystemTools::UpperCase(config));
cmProp prop = parent->GetProperty(defPropName);
- this->SetProperty(defPropName, cmToCStr(prop));
+ this->SetProperty(defPropName, prop);
}
}
// labels
- this->SetProperty("LABELS", cmToCStr(parent->GetProperty("LABELS")));
+ this->SetProperty("LABELS", parent->GetProperty("LABELS"));
// link libraries
- this->SetProperty("LINK_LIBRARIES",
- cmToCStr(parent->GetProperty("LINK_LIBRARIES")));
+ this->SetProperty("LINK_LIBRARIES", parent->GetProperty("LINK_LIBRARIES"));
// the initial project name
this->StateSnapshot.SetProjectName(parent->StateSnapshot.GetProjectName());
@@ -2118,15 +2117,23 @@ cmTarget* cmMakefile::AddExecutable(const std::string& exeName,
cmTarget* cmMakefile::AddNewTarget(cmStateEnums::TargetType type,
const std::string& name)
{
- auto it = this->Targets
- .emplace(name,
- cmTarget(name, type, cmTarget::VisibilityNormal, this,
- cmTarget::PerConfig::Yes))
- .first;
+ return &this->CreateNewTarget(name, type).first;
+}
+
+std::pair<cmTarget&, bool> cmMakefile::CreateNewTarget(
+ const std::string& name, cmStateEnums::TargetType type,
+ cmTarget::PerConfig perConfig)
+{
+ auto ib = this->Targets.emplace(
+ name, cmTarget(name, type, cmTarget::VisibilityNormal, this, perConfig));
+ auto it = ib.first;
+ if (!ib.second) {
+ return std::make_pair(std::ref(it->second), false);
+ }
this->OrderedTargets.push_back(&it->second);
this->GetGlobalGenerator()->IndexTarget(&it->second);
this->GetStateSnapshot().GetDirectory().AddNormalTargetName(name);
- return &it->second;
+ return std::make_pair(std::ref(it->second), true);
}
cmTarget* cmMakefile::AddNewUtilityTarget(const std::string& utilityName,
@@ -2300,7 +2307,7 @@ void cmMakefile::ExpandVariablesCMP0019()
<< " " << dirs << "\n";
/* clang-format on */
}
- this->SetProperty("INCLUDE_DIRECTORIES", dirs.c_str());
+ this->SetProperty("INCLUDE_DIRECTORIES", dirs);
}
// Also for each target's INCLUDE_DIRECTORIES property:
@@ -2571,12 +2578,7 @@ cmProp cmMakefile::GetDefinition(const std::string& name) const
const std::string& cmMakefile::GetSafeDefinition(const std::string& name) const
{
- static std::string const empty;
- cmProp def = this->GetDefinition(name);
- if (!def) {
- return empty;
- }
- return *def;
+ return this->GetDefinition(name);
}
bool cmMakefile::GetDefExpandList(const std::string& name,
@@ -2959,7 +2961,7 @@ MessageType cmMakefile::ExpandVariablesInStringNew(
break;
case ENVIRONMENT:
if (cmSystemTools::GetEnv(lookup, svalue)) {
- value = &svalue;
+ value = cmProp(svalue);
}
break;
case CACHE:
@@ -3182,6 +3184,23 @@ void cmMakefile::RemoveVariablesInString(std::string& source,
}
}
+void cmMakefile::InitCMAKE_CONFIGURATION_TYPES(std::string const& genDefault)
+{
+ if (this->GetDefinition("CMAKE_CONFIGURATION_TYPES")) {
+ return;
+ }
+ std::string initConfigs;
+ if (!cmSystemTools::GetEnv("CMAKE_CONFIGURATION_TYPES", initConfigs)) {
+ initConfigs = genDefault;
+ }
+ this->AddCacheDefinition(
+ "CMAKE_CONFIGURATION_TYPES", initConfigs,
+ "Semicolon separated list of supported configuration types, "
+ "only supports Debug, Release, MinSizeRel, and RelWithDebInfo, "
+ "anything else will be ignored.",
+ cmStateEnums::STRING);
+}
+
std::string cmMakefile::GetDefaultConfiguration() const
{
if (this->GetGlobalGenerator()->IsMultiConfig()) {
@@ -3542,8 +3561,8 @@ int cmMakefile::TryCompile(const std::string& srcdir,
// make sure the same generator is used
// use this program as the cmake to be run, it should not
// be run that way but the cmake object requires a vailid path
- cmake cm(cmake::RoleProject, cmState::Project);
- cm.SetIsInTryCompile(true);
+ cmake cm(cmake::RoleProject, cmState::Project,
+ cmState::ProjectKind::TryCompile);
auto gg = cm.CreateGlobalGenerator(this->GetGlobalGenerator()->GetName());
if (!gg) {
this->IssueMessage(MessageType::INTERNAL_ERROR,
@@ -3966,6 +3985,10 @@ void cmMakefile::SetProperty(const std::string& prop, const char* value)
{
this->StateSnapshot.GetDirectory().SetProperty(prop, value, this->Backtrace);
}
+void cmMakefile::SetProperty(const std::string& prop, cmProp value)
+{
+ this->StateSnapshot.GetDirectory().SetProperty(prop, value, this->Backtrace);
+}
void cmMakefile::AppendProperty(const std::string& prop,
const std::string& value, bool asString)
@@ -3987,7 +4010,7 @@ cmProp cmMakefile::GetProperty(const std::string& prop) const
return pair.first;
});
output = cmJoin(keys, ";");
- return &output;
+ return cmProp(output);
}
return this->StateSnapshot.GetDirectory().GetProperty(prop);
@@ -4426,13 +4449,12 @@ bool cmMakefile::SetPolicy(cmPolicies::PolicyID id,
return false;
}
- // Deprecate old policies, especially those that require a lot
- // of code to maintain the old behavior.
- if (status == cmPolicies::OLD && id <= cmPolicies::CMP0081 &&
+ // Deprecate old policies.
+ if (status == cmPolicies::OLD && id <= cmPolicies::CMP0088 &&
!(this->GetCMakeInstance()->GetIsInTryCompile() &&
(
// Policies set by cmCoreTryCompile::TryCompileCode.
- id == cmPolicies::CMP0065))) {
+ id == cmPolicies::CMP0065 || id == cmPolicies::CMP0083))) {
this->IssueMessage(MessageType::DEPRECATION_WARNING,
cmPolicies::GetPolicyDeprecatedWarning(id));
}
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 77e9c74..fd9a679 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -13,6 +13,7 @@
#include <stack>
#include <string>
#include <unordered_map>
+#include <utility>
#include <vector>
#include <cm/optional>
@@ -230,6 +231,10 @@ public:
cmTarget* AddImportedTarget(const std::string& name,
cmStateEnums::TargetType type, bool global);
+ std::pair<cmTarget&, bool> CreateNewTarget(
+ const std::string& name, cmStateEnums::TargetType type,
+ cmTarget::PerConfig perConfig = cmTarget::PerConfig::Yes);
+
cmTarget* AddNewTarget(cmStateEnums::TargetType type,
const std::string& name);
@@ -310,6 +315,8 @@ public:
*/
void SetProjectName(std::string const& name);
+ void InitCMAKE_CONFIGURATION_TYPES(std::string const& genDefault);
+
/* Get the default configuration */
std::string GetDefaultConfiguration() const;
@@ -392,13 +399,13 @@ public:
* Set a regular expression that include files must match
* in order to be considered as part of the depend information.
*/
- void SetIncludeRegularExpression(const char* regex)
+ void SetIncludeRegularExpression(const std::string& regex)
{
- this->SetProperty("INCLUDE_REGULAR_EXPRESSION", regex);
+ this->SetProperty("INCLUDE_REGULAR_EXPRESSION", regex.c_str());
}
- const char* GetIncludeRegularExpression() const
+ const std::string& GetIncludeRegularExpression() const
{
- return cmToCStr(this->GetProperty("INCLUDE_REGULAR_EXPRESSION"));
+ return this->GetProperty("INCLUDE_REGULAR_EXPRESSION");
}
/**
@@ -762,6 +769,11 @@ public:
//! Set/Get a property of this directory
void SetProperty(const std::string& prop, const char* value);
+ void SetProperty(const std::string& prop, cmProp value);
+ void SetProperty(const std::string& prop, const std::string& value)
+ {
+ this->SetProperty(prop, cmProp(value));
+ }
void AppendProperty(const std::string& prop, const std::string& value,
bool asString = false);
cmProp GetProperty(const std::string& prop) const;
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 3a2744e..306b38f 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -397,9 +397,8 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
this->LocalGenerator->GetLinkLibsCMP0065(
linkLanguage, *this->GeneratorTarget));
- if (this->GeneratorTarget->GetPropertyAsBool("LINK_WHAT_YOU_USE")) {
- this->LocalGenerator->AppendFlags(linkFlags, " -Wl,--no-as-needed");
- }
+ this->UseLWYU = this->LocalGenerator->AppendLWYUFlags(
+ linkFlags, this->GeneratorTarget, linkLanguage);
// Add language feature flags.
this->LocalGenerator->AddLanguageFlagsForLinking(
@@ -577,12 +576,18 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
vars.Launcher = linkerLauncher.c_str();
}
- if (this->GeneratorTarget->GetPropertyAsBool("LINK_WHAT_YOU_USE")) {
- std::string cmakeCommand =
- cmStrCat(this->LocalGenerator->ConvertToOutputFormat(
- cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL),
- " -E __run_co_compile --lwyu=", targetOutPathReal);
- real_link_commands.push_back(std::move(cmakeCommand));
+ if (this->UseLWYU) {
+ cmProp lwyuCheck =
+ this->Makefile->GetDefinition("CMAKE_LINK_WHAT_YOU_USE_CHECK");
+ if (lwyuCheck) {
+ std::string cmakeCommand = cmStrCat(
+ this->LocalGenerator->ConvertToOutputFormat(
+ cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL),
+ " -E __run_co_compile --lwyu=");
+ cmakeCommand += this->LocalGenerator->EscapeForShell(*lwyuCheck);
+ cmakeCommand += cmStrCat(" --source=", targetOutPathReal);
+ real_link_commands.push_back(std::move(cmakeCommand));
+ }
}
std::string launcher;
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index d0e3837..64992f2 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -178,9 +178,9 @@ void cmMakefileLibraryTargetGenerator::WriteSharedLibraryRules(bool relink)
this->AddModuleDefinitionFlag(linkLineComputer.get(), extraFlags,
this->GetConfigName());
- if (this->GeneratorTarget->GetPropertyAsBool("LINK_WHAT_YOU_USE")) {
- this->LocalGenerator->AppendFlags(extraFlags, " -Wl,--no-as-needed");
- }
+ this->UseLWYU = this->LocalGenerator->AppendLWYUFlags(
+ extraFlags, this->GeneratorTarget, linkLanguage);
+
this->WriteLibraryRules(linkRuleVar, extraFlags, relink);
}
@@ -871,13 +871,18 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
// Get the set of commands.
std::string linkRule = this->GetLinkRule(linkRuleVar);
cmExpandList(linkRule, real_link_commands);
- if (this->GeneratorTarget->GetPropertyAsBool("LINK_WHAT_YOU_USE") &&
- (this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY)) {
- std::string cmakeCommand = cmStrCat(
- this->LocalGenerator->ConvertToOutputFormat(
- cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL),
- " -E __run_co_compile --lwyu=", targetOutPathReal);
- real_link_commands.push_back(std::move(cmakeCommand));
+ if (this->UseLWYU) {
+ cmProp lwyuCheck =
+ this->Makefile->GetDefinition("CMAKE_LINK_WHAT_YOU_USE_CHECK");
+ if (lwyuCheck) {
+ std::string cmakeCommand = cmStrCat(
+ this->LocalGenerator->ConvertToOutputFormat(
+ cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL),
+ " -E __run_co_compile --lwyu=");
+ cmakeCommand += this->LocalGenerator->EscapeForShell(*lwyuCheck);
+ cmakeCommand += cmStrCat(" --source=", targetOutPathReal);
+ real_link_commands.push_back(std::move(cmakeCommand));
+ }
}
// Expand placeholders.
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index a3e5553..c83a7ab 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -293,8 +293,7 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
this->GetConfigName());
for (cmSourceFile const* sf : externalObjects) {
auto const& objectFileName = sf->GetFullPath();
- if (!cmSystemTools::StringEndsWith(objectFileName,
- cmToCStr(pchExtension))) {
+ if (!cmHasSuffix(objectFileName, pchExtension)) {
this->ExternalObjects.push_back(objectFileName);
}
}
@@ -1398,6 +1397,13 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
<< "set(CMAKE_Fortran_TARGET_MODULE_DIR \""
<< this->GeneratorTarget->GetFortranModuleDirectory(working_dir)
<< "\")\n";
+
+ if (this->GeneratorTarget->IsFortranBuildingInstrinsicModules()) {
+ *this->InfoFileStream
+ << "\n"
+ << "# Fortran compiler is building intrinsic modules.\n"
+ << "set(CMAKE_Fortran_TARGET_BUILDING_INSTRINSIC_MODULES ON) \n";
+ }
/* clang-format on */
// and now write the rule to use it
@@ -1725,7 +1731,7 @@ void cmMakefileTargetGenerator::WriteObjectsVariable(
cmProp pchExtension = this->Makefile->GetDefinition("CMAKE_PCH_EXTENSION");
for (std::string const& obj : this->Objects) {
- if (cmSystemTools::StringEndsWith(obj, cmToCStr(pchExtension))) {
+ if (cmHasSuffix(obj, pchExtension)) {
continue;
}
*this->BuildFileStream << " " << lineContinue;
@@ -1815,7 +1821,7 @@ void cmMakefileTargetGenerator::WriteObjectsStrings(
objStrings, this->LocalGenerator,
this->LocalGenerator->GetStateSnapshot().GetDirectory(), limit);
for (std::string const& obj : this->Objects) {
- if (cmSystemTools::StringEndsWith(obj, cmToCStr(pchExtension))) {
+ if (cmHasSuffix(obj, pchExtension)) {
continue;
}
helper.Feed(obj);
diff --git a/Source/cmMarkAsAdvancedCommand.cxx b/Source/cmMarkAsAdvancedCommand.cxx
index 45043fa..5908f74 100644
--- a/Source/cmMarkAsAdvancedCommand.cxx
+++ b/Source/cmMarkAsAdvancedCommand.cxx
@@ -6,6 +6,7 @@
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
+#include "cmProperty.h"
#include "cmState.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 5c21d1b..96e9142 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -581,17 +581,23 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd(
}
}
cmExpandList(linkCmdStr, linkCmds);
- if (this->GetGeneratorTarget()->GetPropertyAsBool("LINK_WHAT_YOU_USE")) {
- std::string cmakeCommand = cmStrCat(
- this->GetLocalGenerator()->ConvertToOutputFormat(
- cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL),
- " -E __run_co_compile --lwyu=");
- cmGeneratorTarget& gt = *this->GetGeneratorTarget();
- std::string targetOutputReal = this->ConvertToNinjaPath(
- gt.GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact,
- /*realname=*/true));
- cmakeCommand += targetOutputReal;
- linkCmds.push_back(std::move(cmakeCommand));
+ if (this->UseLWYU) {
+ cmProp lwyuCheck = mf->GetDefinition("CMAKE_LINK_WHAT_YOU_USE_CHECK");
+ if (lwyuCheck) {
+ std::string cmakeCommand = cmStrCat(
+ this->GetLocalGenerator()->ConvertToOutputFormat(
+ cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL),
+ " -E __run_co_compile --lwyu=");
+ cmakeCommand +=
+ this->GetLocalGenerator()->EscapeForShell(*lwyuCheck);
+
+ std::string targetOutputReal =
+ this->ConvertToNinjaPath(this->GetGeneratorTarget()->GetFullPath(
+ config, cmStateEnums::RuntimeBinaryArtifact,
+ /*realname=*/true));
+ cmakeCommand += cmStrCat(" --source=", targetOutputReal);
+ linkCmds.push_back(std::move(cmakeCommand));
+ }
}
return linkCmds;
}
@@ -1156,12 +1162,11 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
this->AddModuleDefinitionFlag(linkLineComputer.get(), vars["LINK_FLAGS"],
config);
- if (gt->GetPropertyAsBool("LINK_WHAT_YOU_USE") &&
- (gt->GetType() == cmStateEnums::TargetType::EXECUTABLE ||
- gt->GetType() == cmStateEnums::TargetType::SHARED_LIBRARY ||
- gt->GetType() == cmStateEnums::TargetType::MODULE_LIBRARY)) {
- vars["LINK_FLAGS"] += " -Wl,--no-as-needed";
- }
+
+ this->UseLWYU = this->GetLocalGenerator()->AppendLWYUFlags(
+ vars["LINK_FLAGS"], this->GetGeneratorTarget(),
+ this->TargetLinkLanguage(config));
+
vars["LINK_FLAGS"] = globalGen->EncodeLiteral(vars["LINK_FLAGS"]);
vars["MANIFESTS"] = this->GetManifests(config);
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 609848b..1b6b834 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -994,8 +994,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
for (cmSourceFile const* sf : externalObjects) {
auto objectFileName = this->GetGlobalGenerator()->ExpandCFGIntDir(
this->ConvertToNinjaPath(sf->GetFullPath()), config);
- if (!cmSystemTools::StringEndsWith(objectFileName,
- cmToCStr(pchExtension))) {
+ if (!cmHasSuffix(objectFileName, pchExtension)) {
this->Configs[config].Objects.push_back(objectFileName);
}
}
@@ -1260,8 +1259,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
if (firstForConfig) {
cmProp pchExtension =
this->GetMakefile()->GetDefinition("CMAKE_PCH_EXTENSION");
- if (!cmSystemTools::StringEndsWith(objectFileName,
- cmToCStr(pchExtension))) {
+ if (!cmHasSuffix(objectFileName, pchExtension)) {
// Add this object to the list of object files.
this->Configs[config].Objects.push_back(objectFileName);
}
diff --git a/Source/cmOptionCommand.cxx b/Source/cmOptionCommand.cxx
index bae67e0..014da4d 100644
--- a/Source/cmOptionCommand.cxx
+++ b/Source/cmOptionCommand.cxx
@@ -29,7 +29,7 @@ bool cmOptionCommand(std::vector<std::string> const& args,
{
auto policyStatus =
status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0077);
- const auto* existsBeforeSet =
+ const auto& existsBeforeSet =
status.GetMakefile().GetStateSnapshot().GetDefinition(args[0]);
switch (policyStatus) {
case cmPolicies::WARN:
@@ -77,7 +77,7 @@ bool cmOptionCommand(std::vector<std::string> const& args,
}
if (checkAndWarn) {
- const auto* existsAfterSet =
+ const auto& existsAfterSet =
status.GetMakefile().GetStateSnapshot().GetDefinition(args[0]);
if (!existsAfterSet) {
status.GetMakefile().IssueMessage(
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index 01e8c04..fc839c5 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -10,6 +10,7 @@
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmProperty.h"
#include "cmState.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
diff --git a/Source/cmProperty.cxx b/Source/cmProperty.cxx
new file mode 100644
index 0000000..d012630
--- /dev/null
+++ b/Source/cmProperty.cxx
@@ -0,0 +1,113 @@
+
+#include "cmProperty.h"
+
+#include <string>
+
+#include <cmext/string_view>
+
+#include "cmStringAlgorithms.h"
+
+std::string cmProp::Empty;
+
+bool cmProp::IsOn(cm::string_view value) noexcept
+{
+ switch (value.size()) {
+ case 1:
+ return value[0] == '1' || value[0] == 'Y' || value[0] == 'y';
+ case 2:
+ return //
+ (value[0] == 'O' || value[0] == 'o') && //
+ (value[1] == 'N' || value[1] == 'n');
+ case 3:
+ return //
+ (value[0] == 'Y' || value[0] == 'y') && //
+ (value[1] == 'E' || value[1] == 'e') && //
+ (value[2] == 'S' || value[2] == 's');
+ case 4:
+ return //
+ (value[0] == 'T' || value[0] == 't') && //
+ (value[1] == 'R' || value[1] == 'r') && //
+ (value[2] == 'U' || value[2] == 'u') && //
+ (value[3] == 'E' || value[3] == 'e');
+ default:
+ break;
+ }
+
+ return false;
+}
+
+bool cmProp::IsOff(cm::string_view value) noexcept
+{
+ switch (value.size()) {
+ case 0:
+ return true;
+ case 1:
+ return value[0] == '0' || value[0] == 'N' || value[0] == 'n';
+ case 2:
+ return //
+ (value[0] == 'N' || value[0] == 'n') && //
+ (value[1] == 'O' || value[1] == 'o');
+ case 3:
+ return //
+ (value[0] == 'O' || value[0] == 'o') && //
+ (value[1] == 'F' || value[1] == 'f') && //
+ (value[2] == 'F' || value[2] == 'f');
+ case 5:
+ return //
+ (value[0] == 'F' || value[0] == 'f') && //
+ (value[1] == 'A' || value[1] == 'a') && //
+ (value[2] == 'L' || value[2] == 'l') && //
+ (value[3] == 'S' || value[3] == 's') && //
+ (value[4] == 'E' || value[4] == 'e');
+ case 6:
+ return //
+ (value[0] == 'I' || value[0] == 'i') && //
+ (value[1] == 'G' || value[1] == 'g') && //
+ (value[2] == 'N' || value[2] == 'n') && //
+ (value[3] == 'O' || value[3] == 'o') && //
+ (value[4] == 'R' || value[4] == 'r') && //
+ (value[5] == 'E' || value[5] == 'e');
+ default:
+ break;
+ }
+
+ return IsNOTFOUND(value);
+}
+bool cmProp::IsNOTFOUND(cm::string_view value) noexcept
+{
+ return (value == "NOTFOUND"_s) || cmHasSuffix(value, "-NOTFOUND"_s);
+}
+
+int cmProp::Compare(cmProp value) const noexcept
+{
+ if (this->Value == nullptr && !value) {
+ return 0;
+ }
+ if (this->Value == nullptr) {
+ return -1;
+ }
+ if (!value) {
+ return 1;
+ }
+ return this->Value->compare(*value);
+}
+
+int cmProp::Compare(cm::string_view value) const noexcept
+{
+ if (this->Value == nullptr && value.data() == nullptr) {
+ return 0;
+ }
+ if (this->Value == nullptr) {
+ return -1;
+ }
+ if (value.data() == nullptr) {
+ return 1;
+ }
+ return cm::string_view(*this->Value).compare(value);
+}
+
+std::ostream& operator<<(std::ostream& o, cmProp v)
+{
+ o << *v;
+ return o;
+}
diff --git a/Source/cmProperty.h b/Source/cmProperty.h
index 1e03c3f..3a0a5be 100644
--- a/Source/cmProperty.h
+++ b/Source/cmProperty.h
@@ -4,8 +4,12 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <cstddef>
+#include <iosfwd>
#include <string>
+#include <cm/string_view>
+
class cmProperty
{
public:
@@ -23,14 +27,210 @@ public:
};
};
-using cmProp = const std::string*;
+class cmProp
+{
+public:
+ cmProp() noexcept = default;
+ cmProp(std::nullptr_t) noexcept {}
+ explicit cmProp(const std::string* value) noexcept
+ : Value(value)
+ {
+ }
+ explicit cmProp(const std::string& value) noexcept
+ : Value(&value)
+ {
+ }
+ cmProp(const cmProp& other) noexcept = default;
-inline const char* cmToCStr(cmProp p)
+ cmProp& operator=(const cmProp& other) noexcept = default;
+ cmProp& operator=(std::nullptr_t) noexcept
+ {
+ this->Value = nullptr;
+ return *this;
+ }
+
+ const std::string* Get() const noexcept { return this->Value; }
+ const char* GetCStr() const noexcept
+ {
+ return this->Value == nullptr ? nullptr : this->Value->c_str();
+ }
+
+ const std::string* operator->() const noexcept
+ {
+ return this->Value == nullptr ? &cmProp::Empty : this->Value;
+ }
+ const std::string& operator*() const noexcept
+ {
+ return this->Value == nullptr ? cmProp::Empty : *this->Value;
+ }
+
+ explicit operator bool() const noexcept { return this->Value != nullptr; }
+ operator const std::string&() const noexcept { return this->operator*(); }
+ operator cm::string_view() const noexcept { return this->operator*(); }
+
+ /**
+ * Does the value indicate a true or ON value?
+ */
+ bool IsOn() const noexcept
+ {
+ return this->Value != nullptr &&
+ cmProp::IsOn(cm::string_view(*this->Value));
+ }
+ /**
+ * Does the value indicate a false or off value ? Note that this is
+ * not the same as !IsOn(...) because there are a number of
+ * ambiguous values such as "/usr/local/bin" a path will result in
+ * IsOn and IsOff both returning false. Note that the special path
+ * NOTFOUND, *-NOTFOUND or IGNORE will cause IsOff to return true.
+ */
+ bool IsOff() const noexcept
+ {
+ return this->Value == nullptr ||
+ cmProp::IsOff(cm::string_view(*this->Value));
+ }
+ /** Return true if value is NOTFOUND or ends in -NOTFOUND. */
+ bool IsNOTFOUND() const noexcept
+ {
+ return this->Value != nullptr &&
+ cmProp::IsNOTFOUND(cm::string_view(*this->Value));
+ }
+ bool IsEmpty() const noexcept
+ {
+ return this->Value == nullptr || this->Value->empty();
+ }
+
+ bool IsSet() const noexcept
+ {
+ return !this->IsEmpty() && !this->IsNOTFOUND();
+ }
+
+ /**
+ * Does a string indicate a true or ON value?
+ */
+ static bool IsOn(const char* value) noexcept
+ {
+ return value != nullptr && IsOn(cm::string_view(value));
+ }
+ static bool IsOn(cm::string_view) noexcept;
+
+ /**
+ * Compare method has same semantic as std::optional::compare
+ */
+ int Compare(cmProp value) const noexcept;
+ int Compare(cm::string_view value) const noexcept;
+
+ /**
+ * Does a string indicate a false or off value ? Note that this is
+ * not the same as !IsOn(...) because there are a number of
+ * ambiguous values such as "/usr/local/bin" a path will result in
+ * IsOn and IsOff both returning false. Note that the special path
+ * NOTFOUND, *-NOTFOUND or IGNORE will cause IsOff to return true.
+ */
+ static bool IsOff(const char* value) noexcept
+ {
+ return value == nullptr || IsOff(cm::string_view(value));
+ }
+ static bool IsOff(cm::string_view) noexcept;
+
+ /** Return true if value is NOTFOUND or ends in -NOTFOUND. */
+ static bool IsNOTFOUND(const char* value) noexcept
+ {
+ return value == nullptr || IsNOTFOUND(cm::string_view(value));
+ }
+ static bool IsNOTFOUND(cm::string_view) noexcept;
+
+ static bool IsEmpty(const char* value) noexcept
+ {
+ return value == nullptr || *value == '\0';
+ }
+ static bool IsEmpty(cm::string_view value) noexcept { return value.empty(); }
+
+private:
+ static std::string Empty;
+ const std::string* Value = nullptr;
+};
+
+std::ostream& operator<<(std::ostream& o, cmProp v);
+
+inline bool operator==(cmProp l, cmProp r) noexcept
+{
+ return l.Compare(r) == 0;
+}
+inline bool operator!=(cmProp l, cmProp r) noexcept
{
- return p ? p->c_str() : nullptr;
+ return l.Compare(r) != 0;
+}
+inline bool operator<(cmProp l, cmProp r) noexcept
+{
+ return l.Compare(r) < 0;
+}
+inline bool operator<=(cmProp l, cmProp r) noexcept
+{
+ return l.Compare(r) <= 0;
+}
+inline bool operator>(cmProp l, cmProp r) noexcept
+{
+ return l.Compare(r) > 0;
+}
+inline bool operator>=(cmProp l, cmProp r) noexcept
+{
+ return l.Compare(r) >= 0;
}
-inline const char* cmToCStrSafe(cmProp p)
+inline bool operator==(cmProp l, cm::string_view r) noexcept
+{
+ return l.Compare(r) == 0;
+}
+inline bool operator!=(cmProp l, cm::string_view r) noexcept
+{
+ return l.Compare(r) != 0;
+}
+inline bool operator<(cmProp l, cm::string_view r) noexcept
+{
+ return l.Compare(r) < 0;
+}
+inline bool operator<=(cmProp l, cm::string_view r) noexcept
+{
+ return l.Compare(r) <= 0;
+}
+inline bool operator>(cmProp l, cm::string_view r) noexcept
+{
+ return l.Compare(r) > 0;
+}
+inline bool operator>=(cmProp l, cm::string_view r) noexcept
+{
+ return l.Compare(r) >= 0;
+}
+
+inline bool operator==(cmProp l, std::nullptr_t) noexcept
+{
+ return l.Compare(cmProp{}) == 0;
+}
+inline bool operator!=(cmProp l, std::nullptr_t) noexcept
+{
+ return l.Compare(cmProp{}) != 0;
+}
+inline bool operator<(cmProp l, std::nullptr_t) noexcept
+{
+ return l.Compare(cmProp{}) < 0;
+}
+inline bool operator<=(cmProp l, std::nullptr_t) noexcept
+{
+ return l.Compare(cmProp{}) <= 0;
+}
+inline bool operator>(cmProp l, std::nullptr_t) noexcept
+{
+ return l.Compare(cmProp{}) > 0;
+}
+inline bool operator>=(cmProp l, std::nullptr_t) noexcept
+{
+ return l.Compare(cmProp{}) >= 0;
+}
+
+/**
+ * Temporary wrapper
+ */
+inline const char* cmToCStr(cmProp p)
{
- return p ? p->c_str() : "";
+ return p.GetCStr();
}
diff --git a/Source/cmPropertyMap.cxx b/Source/cmPropertyMap.cxx
index 06e151a..8ad3c6f 100644
--- a/Source/cmPropertyMap.cxx
+++ b/Source/cmPropertyMap.cxx
@@ -19,6 +19,15 @@ void cmPropertyMap::SetProperty(const std::string& name, const char* value)
this->Map_[name] = value;
}
+void cmPropertyMap::SetProperty(const std::string& name, cmProp value)
+{
+ if (!value) {
+ this->Map_.erase(name);
+ return;
+ }
+
+ this->Map_[name] = *value;
+}
void cmPropertyMap::AppendProperty(const std::string& name,
const std::string& value, bool asString)
@@ -46,7 +55,7 @@ cmProp cmPropertyMap::GetPropertyValue(const std::string& name) const
{
auto it = this->Map_.find(name);
if (it != this->Map_.end()) {
- return &it->second;
+ return cmProp(it->second);
}
return nullptr;
}
diff --git a/Source/cmPropertyMap.h b/Source/cmPropertyMap.h
index cda585a..b28d3c9 100644
--- a/Source/cmPropertyMap.h
+++ b/Source/cmPropertyMap.h
@@ -26,6 +26,11 @@ public:
//! Set the property value
void SetProperty(const std::string& name, const char* value);
+ void SetProperty(const std::string& name, cmProp value);
+ void SetProperty(const std::string& name, const std::string& value)
+ {
+ this->SetProperty(name, cmProp(value));
+ }
//! Append to the property value
void AppendProperty(const std::string& name, const std::string& value,
diff --git a/Source/cmQTWrapCPPCommand.cxx b/Source/cmQTWrapCPPCommand.cxx
index e9670f9..ca0b259 100644
--- a/Source/cmQTWrapCPPCommand.cxx
+++ b/Source/cmQTWrapCPPCommand.cxx
@@ -6,7 +6,6 @@
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmPolicies.h"
-#include "cmProperty.h"
#include "cmRange.h"
#include "cmSourceFile.h"
#include "cmStringAlgorithms.h"
@@ -41,7 +40,7 @@ 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", cmToCStr(curr->GetProperty("ABSTRACT")));
+ sf->SetProperty("ABSTRACT", curr->GetProperty("ABSTRACT"));
}
// Compute the name of the header from which to generate the file.
diff --git a/Source/cmQtAutoGenGlobalInitializer.cxx b/Source/cmQtAutoGenGlobalInitializer.cxx
index 77fe87e..f3ad565 100644
--- a/Source/cmQtAutoGenGlobalInitializer.cxx
+++ b/Source/cmQtAutoGenGlobalInitializer.cxx
@@ -186,7 +186,7 @@ void cmQtAutoGenGlobalInitializer::GetOrCreateGlobalTarget(
cmProp folder =
makefile->GetState()->GetGlobalProperty("AUTOGEN_TARGETS_FOLDER");
if (folder) {
- target->SetProperty("FOLDER", *folder);
+ target->SetProperty("FOLDER", folder);
}
}
}
diff --git a/Source/cmSetDirectoryPropertiesCommand.cxx b/Source/cmSetDirectoryPropertiesCommand.cxx
index 07ad246..9adf537 100644
--- a/Source/cmSetDirectoryPropertiesCommand.cxx
+++ b/Source/cmSetDirectoryPropertiesCommand.cxx
@@ -32,7 +32,7 @@ bool cmSetDirectoryPropertiesCommand(std::vector<std::string> const& args,
"Commands and macros cannot be set using SET_CMAKE_PROPERTIES");
return false;
}
- status.GetMakefile().SetProperty(prop, (iter + 1)->c_str());
+ status.GetMakefile().SetProperty(prop, *(iter + 1));
}
return true;
diff --git a/Source/cmSetPropertyCommand.cxx b/Source/cmSetPropertyCommand.cxx
index c899053..59b4402 100644
--- a/Source/cmSetPropertyCommand.cxx
+++ b/Source/cmSetPropertyCommand.cxx
@@ -294,7 +294,7 @@ bool HandleAndValidateSourceFilePropertyGENERATED(
sf->SetProperty("GENERATED", nullptr);
break;
case PropertyOp::Set:
- sf->SetProperty("GENERATED", propertyValue.c_str());
+ sf->SetProperty("GENERATED", propertyValue);
break;
}
} else {
@@ -474,7 +474,7 @@ bool HandleGlobalMode(cmExecutionStatus& status,
if (remove) {
cm->SetProperty(propertyName, nullptr);
} else {
- cm->SetProperty(propertyName, propertyValue.c_str());
+ cm->SetProperty(propertyName, propertyValue);
}
}
@@ -520,7 +520,7 @@ bool HandleDirectoryMode(cmExecutionStatus& status,
if (remove) {
mf->SetProperty(propertyName, nullptr);
} else {
- mf->SetProperty(propertyName, propertyValue.c_str());
+ mf->SetProperty(propertyName, propertyValue);
}
}
@@ -631,7 +631,7 @@ bool HandleSource(cmSourceFile* sf, const std::string& propertyName,
if (remove) {
sf->SetProperty(propertyName, nullptr);
} else {
- sf->SetProperty(propertyName, propertyValue.c_str());
+ sf->SetProperty(propertyName, propertyValue);
}
}
return true;
@@ -681,7 +681,7 @@ bool HandleTest(cmTest* test, const std::string& propertyName,
if (remove) {
test->SetProperty(propertyName, nullptr);
} else {
- test->SetProperty(propertyName, propertyValue.c_str());
+ test->SetProperty(propertyName, propertyValue);
}
}
diff --git a/Source/cmSetSourceFilesPropertiesCommand.cxx b/Source/cmSetSourceFilesPropertiesCommand.cxx
index 237b67f..ab93ddb 100644
--- a/Source/cmSetSourceFilesPropertiesCommand.cxx
+++ b/Source/cmSetSourceFilesPropertiesCommand.cxx
@@ -173,7 +173,7 @@ static bool RunCommandForScope(
SetPropertyCommand::HandleAndValidateSourceFilePropertyGENERATED(
sf, *(k + 1));
} else {
- sf->SetProperty(*k, (k + 1)->c_str());
+ sf->SetProperty(*k, *(k + 1));
}
}
}
diff --git a/Source/cmSetTestsPropertiesCommand.cxx b/Source/cmSetTestsPropertiesCommand.cxx
index c4bff76..a17c964 100644
--- a/Source/cmSetTestsPropertiesCommand.cxx
+++ b/Source/cmSetTestsPropertiesCommand.cxx
@@ -37,7 +37,7 @@ bool cmSetTestsPropertiesCommand(std::vector<std::string> const& args,
// 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());
+ test->SetProperty(*k, *(k + 1));
}
}
} else {
diff --git a/Source/cmSourceFile.cxx b/Source/cmSourceFile.cxx
index 3f3c8d5..6caae3a 100644
--- a/Source/cmSourceFile.cxx
+++ b/Source/cmSourceFile.cxx
@@ -269,7 +269,8 @@ bool cmSourceFile::Matches(cmSourceFileLocation const& loc)
return this->Location.Matches(loc);
}
-void cmSourceFile::SetProperty(const std::string& prop, const char* value)
+template <typename ValueType>
+void cmSourceFile::StoreProperty(const std::string& prop, ValueType value)
{
if (prop == propINCLUDE_DIRECTORIES) {
this->IncludeDirectories.clear();
@@ -294,6 +295,15 @@ void cmSourceFile::SetProperty(const std::string& prop, const char* value)
}
}
+void cmSourceFile::SetProperty(const std::string& prop, const char* value)
+{
+ this->StoreProperty(prop, value);
+}
+void cmSourceFile::SetProperty(const std::string& prop, cmProp value)
+{
+ this->StoreProperty(prop, value);
+}
+
void cmSourceFile::AppendProperty(const std::string& prop,
const std::string& value, bool asString)
{
@@ -342,7 +352,7 @@ cmProp cmSourceFile::GetPropertyForUser(const std::string& prop)
// if it is requested by the user.
if (prop == propLANGUAGE) {
// The pointer is valid until `this->Language` is modified.
- return &this->GetOrDetermineLanguage();
+ return cmProp(this->GetOrDetermineLanguage());
}
// Special handling for GENERATED property.
@@ -355,9 +365,9 @@ cmProp cmSourceFile::GetPropertyForUser(const std::string& prop)
(policyStatus == cmPolicies::WARN || policyStatus == cmPolicies::OLD)
? CheckScope::GlobalAndLocal
: CheckScope::Global)) {
- return &propTRUE;
+ return cmProp(propTRUE);
}
- return &propFALSE;
+ return cmProp(propFALSE);
}
// Perform the normal property lookup.
@@ -371,7 +381,7 @@ cmProp cmSourceFile::GetProperty(const std::string& prop) const
if (this->FullPath.empty()) {
return nullptr;
}
- return &this->FullPath;
+ return cmProp(this->FullPath);
}
// Check for the properties with backtraces.
@@ -382,7 +392,7 @@ cmProp cmSourceFile::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(this->IncludeDirectories, ";");
- return &output;
+ return cmProp(output);
}
if (prop == propCOMPILE_OPTIONS) {
@@ -392,7 +402,7 @@ cmProp cmSourceFile::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(this->CompileOptions, ";");
- return &output;
+ return cmProp(output);
}
if (prop == propCOMPILE_DEFINITIONS) {
@@ -402,7 +412,7 @@ cmProp cmSourceFile::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(this->CompileDefinitions, ";");
- return &output;
+ return cmProp(output);
}
cmProp retVal = this->Properties.GetPropertyValue(prop);
diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h
index 32ed687..78e0d27 100644
--- a/Source/cmSourceFile.h
+++ b/Source/cmSourceFile.h
@@ -42,6 +42,11 @@ public:
//! Set/Get a property of this source file
void SetProperty(const std::string& prop, const char* value);
+ void SetProperty(const std::string& prop, cmProp value);
+ void SetProperty(const std::string& prop, const std::string& value)
+ {
+ this->SetProperty(prop, cmProp(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
@@ -145,6 +150,9 @@ public:
std::string GetObjectLibrary() const;
private:
+ template <typename ValueType>
+ void StoreProperty(const std::string& prop, ValueType value);
+
cmSourceFileLocation Location;
cmPropertyMap Properties;
std::unique_ptr<cmCustomCommand> CustomCommand;
diff --git a/Source/cmStandardLevelResolver.cxx b/Source/cmStandardLevelResolver.cxx
index 37ed4c1..499317d 100644
--- a/Source/cmStandardLevelResolver.cxx
+++ b/Source/cmStandardLevelResolver.cxx
@@ -57,10 +57,10 @@ int ParseStd(std::string const& level)
return -1;
}
-struct StanardLevelComputer
+struct StandardLevelComputer
{
- explicit StanardLevelComputer(std::string lang, std::vector<int> levels,
- std::vector<std::string> levelsStr)
+ explicit StandardLevelComputer(std::string lang, std::vector<int> levels,
+ std::vector<std::string> levelsStr)
: Language(std::move(lang))
, Levels(std::move(levels))
, LevelsAsStrings(std::move(levelsStr))
@@ -308,31 +308,33 @@ struct StanardLevelComputer
std::vector<std::string> LevelsAsStrings;
};
-std::unordered_map<std::string, StanardLevelComputer> StandardComputerMapping =
- { { "C",
- StanardLevelComputer{
+std::unordered_map<std::string, StandardLevelComputer>
+ StandardComputerMapping = {
+ { "C",
+ StandardLevelComputer{
"C", std::vector<int>{ 90, 99, 11, 17, 23 },
std::vector<std::string>{ "90", "99", "11", "17", "23" } } },
{ "CXX",
- StanardLevelComputer{
+ StandardLevelComputer{
"CXX", std::vector<int>{ 98, 11, 14, 17, 20, 23 },
std::vector<std::string>{ "98", "11", "14", "17", "20", "23" } } },
{ "CUDA",
- StanardLevelComputer{
+ StandardLevelComputer{
"CUDA", std::vector<int>{ 03, 11, 14, 17, 20, 23 },
std::vector<std::string>{ "03", "11", "14", "17", "20", "23" } } },
{ "OBJC",
- StanardLevelComputer{
+ StandardLevelComputer{
"OBJC", std::vector<int>{ 90, 99, 11, 17, 23 },
std::vector<std::string>{ "90", "99", "11", "17", "23" } } },
{ "OBJCXX",
- StanardLevelComputer{
+ StandardLevelComputer{
"OBJCXX", std::vector<int>{ 98, 11, 14, 17, 20, 23 },
std::vector<std::string>{ "98", "11", "14", "17", "20", "23" } } },
{ "HIP",
- StanardLevelComputer{
+ StandardLevelComputer{
"HIP", std::vector<int>{ 98, 11, 14, 17, 20, 23 },
- std::vector<std::string>{ "98", "11", "14", "17", "20", "23" } } } };
+ std::vector<std::string>{ "98", "11", "14", "17", "20", "23" } } }
+ };
}
std::string cmStandardLevelResolver::GetCompileOptionDef(
@@ -387,7 +389,11 @@ bool cmStandardLevelResolver::CheckCompileFeaturesAvailable(
return false;
}
- const char* features = this->CompileFeaturesAvailable(lang, error);
+ if (!this->Makefile->GetGlobalGenerator()->GetLanguageEnabled(lang)) {
+ return true;
+ }
+
+ cmProp features = this->CompileFeaturesAvailable(lang, error);
if (!features) {
return false;
}
@@ -465,7 +471,7 @@ bool cmStandardLevelResolver::CompileFeatureKnown(
return false;
}
-const char* cmStandardLevelResolver::CompileFeaturesAvailable(
+cmProp cmStandardLevelResolver::CompileFeaturesAvailable(
const std::string& lang, std::string* error) const
{
if (!this->Makefile->GetGlobalGenerator()->GetLanguageEnabled(lang)) {
@@ -507,7 +513,7 @@ const char* cmStandardLevelResolver::CompileFeaturesAvailable(
}
return nullptr;
}
- return cmToCStr(featuresKnown);
+ return featuresKnown;
}
bool cmStandardLevelResolver::GetNewRequiredStandard(
diff --git a/Source/cmStandardLevelResolver.h b/Source/cmStandardLevelResolver.h
index d84fbcb..c01a3b1 100644
--- a/Source/cmStandardLevelResolver.h
+++ b/Source/cmStandardLevelResolver.h
@@ -30,8 +30,8 @@ public:
const std::string& feature, std::string& lang,
std::string* error) const;
- const char* CompileFeaturesAvailable(const std::string& lang,
- std::string* error) const;
+ cmProp CompileFeaturesAvailable(const std::string& lang,
+ std::string* error) const;
bool GetNewRequiredStandard(const std::string& targetName,
const std::string& feature,
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index ce6eb31..a045545 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -26,7 +26,9 @@
#include "cmSystemTools.h"
#include "cmake.h"
-cmState::cmState()
+cmState::cmState(Mode mode, ProjectKind projectKind)
+ : StateMode(mode)
+ , StateProjectKind(projectKind)
{
this->CacheManager = cm::make_unique<cmCacheManager>();
this->GlobVerificationManager = cm::make_unique<cmGlobVerificationManager>();
@@ -381,16 +383,6 @@ void cmState::ClearEnabledLanguages()
this->EnabledLanguages.clear();
}
-bool cmState::GetIsInTryCompile() const
-{
- return this->IsInTryCompile;
-}
-
-void cmState::SetIsInTryCompile(bool b)
-{
- this->IsInTryCompile = b;
-}
-
bool cmState::GetIsGeneratorMultiConfig() const
{
return this->IsGeneratorMultiConfig;
@@ -577,6 +569,10 @@ void cmState::SetGlobalProperty(const std::string& prop, const char* value)
{
this->GlobalProperties.SetProperty(prop, value);
}
+void cmState::SetGlobalProperty(const std::string& prop, cmProp value)
+{
+ this->GlobalProperties.SetProperty(prop, value);
+}
void cmState::AppendGlobalProperty(const std::string& prop,
const std::string& value, bool asString)
@@ -593,8 +589,9 @@ cmProp cmState::GetGlobalProperty(const std::string& prop)
std::vector<std::string> commands = this->GetCommandNames();
this->SetGlobalProperty("COMMANDS", cmJoin(commands, ";").c_str());
} else if (prop == "IN_TRY_COMPILE") {
- this->SetGlobalProperty("IN_TRY_COMPILE",
- this->IsInTryCompile ? "1" : "0");
+ this->SetGlobalProperty(
+ "IN_TRY_COMPILE",
+ this->StateProjectKind == ProjectKind::TryCompile ? "1" : "0");
} else if (prop == "GENERATOR_IS_MULTI_CONFIG") {
this->SetGlobalProperty("GENERATOR_IS_MULTI_CONFIG",
this->IsGeneratorMultiConfig ? "1" : "0");
@@ -610,47 +607,47 @@ cmProp cmState::GetGlobalProperty(const std::string& prop)
if (prop == "CMAKE_C_KNOWN_FEATURES") {
static const std::string s_out(
&FOR_EACH_C_FEATURE(STRING_LIST_ELEMENT)[1]);
- return &s_out;
+ return cmProp(s_out);
}
if (prop == "CMAKE_C90_KNOWN_FEATURES") {
static const std::string s_out(
&FOR_EACH_C90_FEATURE(STRING_LIST_ELEMENT)[1]);
- return &s_out;
+ return cmProp(s_out);
}
if (prop == "CMAKE_C99_KNOWN_FEATURES") {
static const std::string s_out(
&FOR_EACH_C99_FEATURE(STRING_LIST_ELEMENT)[1]);
- return &s_out;
+ return cmProp(s_out);
}
if (prop == "CMAKE_C11_KNOWN_FEATURES") {
static const std::string s_out(
&FOR_EACH_C11_FEATURE(STRING_LIST_ELEMENT)[1]);
- return &s_out;
+ return cmProp(s_out);
}
if (prop == "CMAKE_CXX_KNOWN_FEATURES") {
static const std::string s_out(
&FOR_EACH_CXX_FEATURE(STRING_LIST_ELEMENT)[1]);
- return &s_out;
+ return cmProp(s_out);
}
if (prop == "CMAKE_CXX98_KNOWN_FEATURES") {
static const std::string s_out(
&FOR_EACH_CXX98_FEATURE(STRING_LIST_ELEMENT)[1]);
- return &s_out;
+ return cmProp(s_out);
}
if (prop == "CMAKE_CXX11_KNOWN_FEATURES") {
static const std::string s_out(
&FOR_EACH_CXX11_FEATURE(STRING_LIST_ELEMENT)[1]);
- return &s_out;
+ return cmProp(s_out);
}
if (prop == "CMAKE_CXX14_KNOWN_FEATURES") {
static const std::string s_out(
&FOR_EACH_CXX14_FEATURE(STRING_LIST_ELEMENT)[1]);
- return &s_out;
+ return cmProp(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;
+ return cmProp(s_out);
}
#undef STRING_LIST_ELEMENT
@@ -771,17 +768,12 @@ unsigned int cmState::GetCacheMinorVersion() const
cmState::Mode cmState::GetMode() const
{
- return this->CurrentMode;
+ return this->StateMode;
}
std::string cmState::GetModeString() const
{
- return ModeToString(this->CurrentMode);
-}
-
-void cmState::SetMode(cmState::Mode mode)
-{
- this->CurrentMode = mode;
+ return ModeToString(this->StateMode);
}
std::string cmState::ModeToString(cmState::Mode mode)
@@ -803,6 +795,11 @@ std::string cmState::ModeToString(cmState::Mode mode)
return "UNKNOWN";
}
+cmState::ProjectKind cmState::GetProjectKind() const
+{
+ return this->StateProjectKind;
+}
+
std::string const& cmState::GetBinaryDirectory() const
{
return this->BinaryDirectory;
diff --git a/Source/cmState.h b/Source/cmState.h
index 9951b9a..0fd28d0 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -35,12 +35,6 @@ class cmState
friend class cmStateSnapshot;
public:
- cmState();
- ~cmState();
-
- cmState(const cmState&) = delete;
- cmState& operator=(const cmState&) = delete;
-
enum Mode
{
Unknown,
@@ -51,6 +45,18 @@ public:
CPack,
};
+ enum class ProjectKind
+ {
+ Normal,
+ TryCompile,
+ };
+
+ cmState(Mode mode, ProjectKind projectKind = ProjectKind::Normal);
+ ~cmState();
+
+ cmState(const cmState&) = delete;
+ cmState& operator=(const cmState&) = delete;
+
static const std::string& GetTargetTypeName(
cmStateEnums::TargetType targetType);
@@ -141,9 +147,6 @@ public:
void SetEnabledLanguages(std::vector<std::string> const& langs);
void ClearEnabledLanguages();
- bool GetIsInTryCompile() const;
- void SetIsInTryCompile(bool b);
-
bool GetIsGeneratorMultiConfig() const;
void SetIsGeneratorMultiConfig(bool b);
@@ -175,6 +178,7 @@ public:
std::vector<std::string> GetCommandNames() const;
void SetGlobalProperty(const std::string& prop, const char* value);
+ void SetGlobalProperty(const std::string& prop, cmProp value);
void AppendGlobalProperty(const std::string& prop, const std::string& value,
bool asString = false);
cmProp GetGlobalProperty(const std::string& prop);
@@ -207,10 +211,11 @@ public:
Mode GetMode() const;
std::string GetModeString() const;
- void SetMode(Mode mode);
static std::string ModeToString(Mode mode);
+ ProjectKind GetProjectKind() const;
+
private:
friend class cmake;
void AddCacheEntry(const std::string& key, const char* value,
@@ -248,7 +253,6 @@ private:
std::string SourceDirectory;
std::string BinaryDirectory;
- bool IsInTryCompile = false;
bool IsGeneratorMultiConfig = false;
bool WindowsShell = false;
bool WindowsVSIDE = false;
@@ -258,5 +262,6 @@ private:
bool NMake = false;
bool MSYSShell = false;
bool NinjaMulti = false;
- Mode CurrentMode = Unknown;
+ Mode StateMode = Unknown;
+ ProjectKind StateProjectKind = ProjectKind::Normal;
};
diff --git a/Source/cmStateDirectory.cxx b/Source/cmStateDirectory.cxx
index c898dd4..ed5b5d8 100644
--- a/Source/cmStateDirectory.cxx
+++ b/Source/cmStateDirectory.cxx
@@ -361,8 +361,9 @@ void cmStateDirectory::ClearLinkDirectories()
this->Snapshot_.Position->LinkDirectoriesPosition);
}
-void cmStateDirectory::SetProperty(const std::string& prop, const char* value,
- cmListFileBacktrace const& lfbt)
+template <typename ValueType>
+void cmStateDirectory::StoreProperty(const std::string& prop, ValueType value,
+ cmListFileBacktrace const& lfbt)
{
if (prop == "INCLUDE_DIRECTORIES") {
if (!value) {
@@ -408,6 +409,17 @@ void cmStateDirectory::SetProperty(const std::string& prop, const char* value,
this->DirectoryState->Properties.SetProperty(prop, value);
}
+void cmStateDirectory::SetProperty(const std::string& prop, const char* value,
+ cmListFileBacktrace const& lfbt)
+{
+ this->StoreProperty(prop, value, lfbt);
+}
+void cmStateDirectory::SetProperty(const std::string& prop, cmProp value,
+ cmListFileBacktrace const& lfbt)
+{
+ this->StoreProperty(prop, value, lfbt);
+}
+
void cmStateDirectory::AppendProperty(const std::string& prop,
const std::string& value, bool asString,
cmListFileBacktrace const& lfbt)
@@ -450,17 +462,17 @@ cmProp cmStateDirectory::GetProperty(const std::string& prop, bool chain) const
if (prop == "PARENT_DIRECTORY") {
cmStateSnapshot parent = this->Snapshot_.GetBuildsystemDirectoryParent();
if (parent.IsValid()) {
- return &parent.GetDirectory().GetCurrentSource();
+ return cmProp(parent.GetDirectory().GetCurrentSource());
}
- return &output;
+ return cmProp(output);
}
if (prop == kBINARY_DIR) {
output = this->GetCurrentBinary();
- return &output;
+ return cmProp(output);
}
if (prop == kSOURCE_DIR) {
output = this->GetCurrentSource();
- return &output;
+ return cmProp(output);
}
if (prop == kSUBDIRECTORIES) {
std::vector<std::string> child_dirs;
@@ -471,15 +483,15 @@ cmProp cmStateDirectory::GetProperty(const std::string& prop, bool chain) const
child_dirs.push_back(ci.GetDirectory().GetCurrentSource());
}
output = cmJoin(child_dirs, ";");
- return &output;
+ return cmProp(output);
}
if (prop == kBUILDSYSTEM_TARGETS) {
output = cmJoin(this->DirectoryState->NormalTargetNames, ";");
- return &output;
+ return cmProp(output);
}
if (prop == "IMPORTED_TARGETS"_s) {
output = cmJoin(this->DirectoryState->ImportedTargetNames, ";");
- return &output;
+ return cmProp(output);
}
if (prop == "LISTFILE_STACK") {
@@ -491,38 +503,38 @@ cmProp cmStateDirectory::GetProperty(const std::string& prop, bool chain) const
}
std::reverse(listFiles.begin(), listFiles.end());
output = cmJoin(listFiles, ";");
- return &output;
+ return cmProp(output);
}
if (prop == "CACHE_VARIABLES") {
output = cmJoin(this->Snapshot_.State->GetCacheEntryKeys(), ";");
- return &output;
+ return cmProp(output);
}
if (prop == "VARIABLES") {
std::vector<std::string> res = this->Snapshot_.ClosureKeys();
cm::append(res, this->Snapshot_.State->GetCacheEntryKeys());
std::sort(res.begin(), res.end());
output = cmJoin(res, ";");
- return &output;
+ return cmProp(output);
}
if (prop == "INCLUDE_DIRECTORIES") {
output = cmJoin(this->GetIncludeDirectoriesEntries(), ";");
- return &output;
+ return cmProp(output);
}
if (prop == "COMPILE_OPTIONS") {
output = cmJoin(this->GetCompileOptionsEntries(), ";");
- return &output;
+ return cmProp(output);
}
if (prop == "COMPILE_DEFINITIONS") {
output = cmJoin(this->GetCompileDefinitionsEntries(), ";");
- return &output;
+ return cmProp(output);
}
if (prop == "LINK_OPTIONS") {
output = cmJoin(this->GetLinkOptionsEntries(), ";");
- return &output;
+ return cmProp(output);
}
if (prop == "LINK_DIRECTORIES") {
output = cmJoin(this->GetLinkDirectoriesEntries(), ";");
- return &output;
+ return cmProp(output);
}
cmProp retVal = this->DirectoryState->Properties.GetPropertyValue(prop);
diff --git a/Source/cmStateDirectory.h b/Source/cmStateDirectory.h
index b8abccb..65e2f30 100644
--- a/Source/cmStateDirectory.h
+++ b/Source/cmStateDirectory.h
@@ -73,6 +73,8 @@ public:
void SetProperty(const std::string& prop, const char* value,
cmListFileBacktrace const& lfbt);
+ void SetProperty(const std::string& prop, cmProp value,
+ cmListFileBacktrace const& lfbt);
void AppendProperty(const std::string& prop, const std::string& value,
bool asString, cmListFileBacktrace const& lfbt);
cmProp GetProperty(const std::string& prop) const;
@@ -84,6 +86,10 @@ public:
void AddImportedTargetName(std::string const& name);
private:
+ template <typename ValueType>
+ void StoreProperty(const std::string& prop, ValueType value,
+ cmListFileBacktrace const& lfbt);
+
cmLinkedTree<cmStateDetail::BuildsystemDirectoryStateType>::iterator
DirectoryState;
cmStateSnapshot Snapshot_;
diff --git a/Source/cmStateSnapshot.cxx b/Source/cmStateSnapshot.cxx
index fbf47ef..66cbcca 100644
--- a/Source/cmStateSnapshot.cxx
+++ b/Source/cmStateSnapshot.cxx
@@ -201,8 +201,7 @@ bool cmStateSnapshot::HasDefinedPolicyCMP0011()
return !this->Position->Policies->IsEmpty();
}
-std::string const* cmStateSnapshot::GetDefinition(
- std::string const& name) const
+cmProp cmStateSnapshot::GetDefinition(std::string const& name) const
{
assert(this->Position->Vars.IsValid());
return cmDefinitions::Get(name, this->Position->Vars, this->Position->Root);
@@ -396,7 +395,7 @@ void cmStateSnapshot::InitializeFromParent()
parent->BuildSystemDirectory->Properties.GetPropertyValue(
"INCLUDE_REGULAR_EXPRESSION");
this->Position->BuildSystemDirectory->Properties.SetProperty(
- "INCLUDE_REGULAR_EXPRESSION", cmToCStr(include_regex));
+ "INCLUDE_REGULAR_EXPRESSION", include_regex);
}
cmState* cmStateSnapshot::GetState() const
diff --git a/Source/cmStateSnapshot.h b/Source/cmStateSnapshot.h
index d06cba3..a5fe7e2 100644
--- a/Source/cmStateSnapshot.h
+++ b/Source/cmStateSnapshot.h
@@ -12,6 +12,7 @@
#include "cmLinkedTree.h"
#include "cmPolicies.h"
+#include "cmProperty.h"
#include "cmStateTypes.h"
class cmState;
@@ -23,7 +24,7 @@ public:
cmStateSnapshot(cmState* state = nullptr);
cmStateSnapshot(cmState* state, cmStateDetail::PositionType position);
- std::string const* GetDefinition(std::string const& name) const;
+ cmProp GetDefinition(std::string const& name) const;
bool IsInitialized(std::string const& name) const;
void SetDefinition(std::string const& name, cm::string_view value);
void RemoveDefinition(std::string const& name);
diff --git a/Source/cmStringAlgorithms.cxx b/Source/cmStringAlgorithms.cxx
index 5bb6e7b..acb5e5b 100644
--- a/Source/cmStringAlgorithms.cxx
+++ b/Source/cmStringAlgorithms.cxx
@@ -227,76 +227,6 @@ bool cmIsInternallyOn(cm::string_view val)
(val[3] == 'N' || val[3] == 'n');
}
-bool cmIsNOTFOUND(cm::string_view val)
-{
- return (val == "NOTFOUND") || cmHasLiteralSuffix(val, "-NOTFOUND");
-}
-
-bool cmIsOn(cm::string_view val)
-{
- switch (val.size()) {
- case 1:
- return val[0] == '1' || val[0] == 'Y' || val[0] == 'y';
- case 2:
- return //
- (val[0] == 'O' || val[0] == 'o') && //
- (val[1] == 'N' || val[1] == 'n');
- case 3:
- return //
- (val[0] == 'Y' || val[0] == 'y') && //
- (val[1] == 'E' || val[1] == 'e') && //
- (val[2] == 'S' || val[2] == 's');
- case 4:
- return //
- (val[0] == 'T' || val[0] == 't') && //
- (val[1] == 'R' || val[1] == 'r') && //
- (val[2] == 'U' || val[2] == 'u') && //
- (val[3] == 'E' || val[3] == 'e');
- default:
- break;
- }
-
- return false;
-}
-
-bool cmIsOff(cm::string_view val)
-{
- switch (val.size()) {
- case 0:
- return true;
- case 1:
- return val[0] == '0' || val[0] == 'N' || val[0] == 'n';
- case 2:
- return //
- (val[0] == 'N' || val[0] == 'n') && //
- (val[1] == 'O' || val[1] == 'o');
- case 3:
- return //
- (val[0] == 'O' || val[0] == 'o') && //
- (val[1] == 'F' || val[1] == 'f') && //
- (val[2] == 'F' || val[2] == 'f');
- case 5:
- return //
- (val[0] == 'F' || val[0] == 'f') && //
- (val[1] == 'A' || val[1] == 'a') && //
- (val[2] == 'L' || val[2] == 'l') && //
- (val[3] == 'S' || val[3] == 's') && //
- (val[4] == 'E' || val[4] == 'e');
- case 6:
- return //
- (val[0] == 'I' || val[0] == 'i') && //
- (val[1] == 'G' || val[1] == 'g') && //
- (val[2] == 'N' || val[2] == 'n') && //
- (val[3] == 'O' || val[3] == 'o') && //
- (val[4] == 'R' || val[4] == 'r') && //
- (val[5] == 'E' || val[5] == 'e');
- default:
- break;
- }
-
- return cmIsNOTFOUND(val);
-}
-
bool cmStrToLong(const char* str, long* value)
{
errno = 0;
diff --git a/Source/cmStringAlgorithms.h b/Source/cmStringAlgorithms.h
index 6b458ec..20061e9 100644
--- a/Source/cmStringAlgorithms.h
+++ b/Source/cmStringAlgorithms.h
@@ -14,25 +14,12 @@
#include <cm/string_view>
+#include "cmProperty.h"
#include "cmRange.h"
/** String range type. */
using cmStringRange = cmRange<std::vector<std::string>::const_iterator>;
-/** Check for non-empty string. */
-inline bool cmNonempty(const char* str)
-{
- return str && *str;
-}
-inline bool cmNonempty(cm::string_view str)
-{
- return !str.empty();
-}
-inline bool cmNonempty(std::string const* str)
-{
- return str && !str->empty();
-}
-
/** Returns length of a literal string. */
template <size_t N>
constexpr size_t cmStrLen(const char (&/*str*/)[N])
@@ -175,6 +162,10 @@ public:
cmAlphaNum(unsigned long long int val);
cmAlphaNum(float val);
cmAlphaNum(double val);
+ cmAlphaNum(cmProp value)
+ : View_(*value)
+ {
+ }
cm::string_view View() const { return this->View_; }
@@ -227,20 +218,44 @@ inline bool cmIsInternallyOn(const char* val)
return cmIsInternallyOn(cm::string_view(val));
}
+/** Check for non-empty Property/Variable value. */
+inline bool cmNonempty(cm::string_view val)
+{
+ return !cmProp::IsEmpty(val);
+}
+inline bool cmNonempty(const char* val)
+{
+ return !cmProp::IsEmpty(val);
+}
+inline bool cmNonempty(cmProp val)
+{
+ return !val.IsEmpty();
+}
+
/** Return true if value is NOTFOUND or ends in -NOTFOUND. */
-bool cmIsNOTFOUND(cm::string_view val);
+inline bool cmIsNOTFOUND(cm::string_view val)
+{
+ return cmProp::IsNOTFOUND(val);
+}
+inline bool cmIsNOTFOUND(cmProp val)
+{
+ return val.IsNOTFOUND();
+}
/**
* Does a string indicate a true or ON value? This is not the same as ifdef.
*/
-bool cmIsOn(cm::string_view val);
+inline bool cmIsOn(cm::string_view val)
+{
+ return cmProp::IsOn(val);
+}
inline bool cmIsOn(const char* val)
{
- return val && cmIsOn(cm::string_view(val));
+ return cmProp::IsOn(val);
}
-inline bool cmIsOn(std::string const* val)
+inline bool cmIsOn(cmProp val)
{
- return val && cmIsOn(*val);
+ return val.IsOn();
}
/**
@@ -250,14 +265,17 @@ inline bool cmIsOn(std::string const* val)
* IsON and IsOff both returning false. Note that the special path
* NOTFOUND, *-NOTFOUND or IGNORE will cause IsOff to return true.
*/
-bool cmIsOff(cm::string_view val);
+inline bool cmIsOff(cm::string_view val)
+{
+ return cmProp::IsOff(val);
+}
inline bool cmIsOff(const char* val)
{
- return !val || cmIsOff(cm::string_view(val));
+ return cmProp::IsOff(val);
}
-inline bool cmIsOff(std::string const* val)
+inline bool cmIsOff(cmProp val)
{
- return !val || cmIsOff(*val);
+ return val.IsOff();
}
/** Returns true if string @a str starts with the character @a prefix. */
@@ -273,6 +291,16 @@ inline bool cmHasPrefix(cm::string_view str, cm::string_view prefix)
}
/** Returns true if string @a str starts with string @a prefix. */
+inline bool cmHasPrefix(cm::string_view str, cmProp prefix)
+{
+ if (!prefix) {
+ return false;
+ }
+
+ return str.compare(0, prefix->size(), prefix) == 0;
+}
+
+/** Returns true if string @a str starts with string @a prefix. */
template <size_t N>
inline bool cmHasLiteralPrefix(cm::string_view str, const char (&prefix)[N])
{
@@ -293,6 +321,17 @@ inline bool cmHasSuffix(cm::string_view str, cm::string_view suffix)
}
/** Returns true if string @a str ends with string @a suffix. */
+inline bool cmHasSuffix(cm::string_view str, cmProp suffix)
+{
+ if (!suffix) {
+ return false;
+ }
+
+ return str.size() >= suffix->size() &&
+ str.compare(str.size() - suffix->size(), suffix->size(), suffix) == 0;
+}
+
+/** Returns true if string @a str ends with string @a suffix. */
template <size_t N>
inline bool cmHasLiteralSuffix(cm::string_view str, const char (&suffix)[N])
{
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 10d2e50..54fe7a1 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -20,6 +20,7 @@
#include <cm3p/uv.h>
#include "cmDuration.h"
+#include "cmELF.h"
#include "cmMessageMetadata.h"
#include "cmProcessOutput.h"
#include "cmRange.h"
@@ -46,10 +47,6 @@
# include "cmCryptoHash.h"
#endif
-#if defined(CMake_USE_ELF_PARSER)
-# include "cmELF.h"
-#endif
-
#if defined(CMake_USE_MACH_PARSER)
# include "cmMachO.h"
#endif
@@ -1632,7 +1629,10 @@ bool cmSystemTools::CreateTar(const std::string& outFileName,
cmArchiveWrite a(fout, compress, format.empty() ? "paxr" : format,
compressionLevel);
- a.Open();
+ if (!a.Open()) {
+ cmSystemTools::Error(a.GetError());
+ return false;
+ }
a.SetMTime(mtime);
a.SetVerbose(verbose);
bool tarCreatedSuccessfully = true;
@@ -2446,14 +2446,12 @@ void cmSystemTools::MakefileColorEcho(int color, const char* message,
bool cmSystemTools::GuessLibrarySOName(std::string const& fullPath,
std::string& soname)
{
-// For ELF shared libraries use a real parser to get the correct
-// soname.
-#if defined(CMake_USE_ELF_PARSER)
+ // For ELF shared libraries use a real parser to get the correct
+ // soname.
cmELF elf(fullPath.c_str());
if (elf) {
return elf.GetSOName(soname);
}
-#endif
// If the file is not a symlink we have no guess for its soname.
if (!cmSystemTools::FileIsSymlink(fullPath)) {
@@ -2491,7 +2489,6 @@ bool cmSystemTools::GuessLibraryInstallName(std::string const& fullPath,
return false;
}
-#if defined(CMake_USE_ELF_PARSER) || defined(CMake_USE_XCOFF_PARSER)
std::string::size_type cmSystemToolsFindRPath(cm::string_view const& have,
cm::string_view const& want)
{
@@ -2523,9 +2520,7 @@ std::string::size_type cmSystemToolsFindRPath(cm::string_view const& have,
// The desired rpath was not found.
return std::string::npos;
}
-#endif
-#if defined(CMake_USE_ELF_PARSER)
namespace {
struct cmSystemToolsRPathInfo
{
@@ -2539,10 +2534,10 @@ using EmptyCallback = std::function<bool(std::string*, const cmELF&)>;
using AdjustCallback = std::function<bool(
cm::optional<std::string>&, const std::string&, const char*, std::string*)>;
-// FIXME: Dispatch if multiple formats are supported.
-bool AdjustRPath(std::string const& file, const EmptyCallback& emptyCallback,
- const AdjustCallback& adjustCallback, std::string* emsg,
- bool* changed)
+cm::optional<bool> AdjustRPathELF(std::string const& file,
+ const EmptyCallback& emptyCallback,
+ const AdjustCallback& adjustCallback,
+ std::string* emsg, bool* changed)
{
if (changed) {
*changed = false;
@@ -2553,6 +2548,9 @@ bool AdjustRPath(std::string const& file, const EmptyCallback& emptyCallback,
{
// Parse the ELF binary.
cmELF elf(file.c_str());
+ if (!elf) {
+ return cm::nullopt; // Not a valid ELF file.
+ }
// Get the RPATH and RUNPATH entries from it.
int se_count = 0;
@@ -2686,14 +2684,14 @@ std::function<bool(std::string*, const cmELF&)> MakeEmptyCallback(
}
return false;
};
-};
+}
}
-bool cmSystemTools::ChangeRPath(std::string const& file,
- std::string const& oldRPath,
- std::string const& newRPath,
- bool removeEnvironmentRPath, std::string* emsg,
- bool* changed)
+cm::optional<bool> ChangeRPathELF(std::string const& file,
+ std::string const& oldRPath,
+ std::string const& newRPath,
+ bool removeEnvironmentRPath,
+ std::string* emsg, bool* changed)
{
auto adjustCallback = [oldRPath, newRPath, removeEnvironmentRPath](
cm::optional<std::string>& outRPath,
@@ -2741,13 +2739,13 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
return true;
};
- return AdjustRPath(file, MakeEmptyCallback(newRPath), adjustCallback, emsg,
- changed);
+ return AdjustRPathELF(file, MakeEmptyCallback(newRPath), adjustCallback,
+ emsg, changed);
}
-bool cmSystemTools::SetRPath(std::string const& file,
- std::string const& newRPath, std::string* emsg,
- bool* changed)
+static cm::optional<bool> SetRPathELF(std::string const& file,
+ std::string const& newRPath,
+ std::string* emsg, bool* changed)
{
auto adjustCallback = [newRPath](cm::optional<std::string>& outRPath,
const std::string& inRPath,
@@ -2759,22 +2757,31 @@ bool cmSystemTools::SetRPath(std::string const& file,
return true;
};
- return AdjustRPath(file, MakeEmptyCallback(newRPath), adjustCallback, emsg,
- changed);
+ return AdjustRPathELF(file, MakeEmptyCallback(newRPath), adjustCallback,
+ emsg, changed);
}
-#elif defined(CMake_USE_XCOFF_PARSER)
-bool cmSystemTools::ChangeRPath(std::string const& file,
- std::string const& oldRPath,
- std::string const& newRPath,
- bool removeEnvironmentRPath, std::string* emsg,
- bool* changed)
+static cm::optional<bool> ChangeRPathXCOFF(std::string const& file,
+ std::string const& oldRPath,
+ std::string const& newRPath,
+ bool removeEnvironmentRPath,
+ std::string* emsg, bool* changed)
{
if (changed) {
*changed = false;
}
-
+#if !defined(CMake_USE_XCOFF_PARSER)
+ (void)file;
+ (void)oldRPath;
+ (void)newRPath;
+ (void)removeEnvironmentRPath;
+ (void)emsg;
+ return cm::nullopt;
+#else
bool chg = false;
cmXCOFF xcoff(file.c_str(), cmXCOFF::Mode::ReadWrite);
+ if (!xcoff) {
+ return cm::nullopt; // Not a valid XCOFF file
+ }
if (cm::optional<cm::string_view> maybeLibPath = xcoff.GetLibPath()) {
cm::string_view libPath = *maybeLibPath;
// Make sure the current rpath contains the old rpath.
@@ -2830,31 +2837,47 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
*changed = chg;
}
return true;
+#endif
}
-bool cmSystemTools::SetRPath(std::string const& /*file*/,
- std::string const& /*newRPath*/,
- std::string* /*emsg*/, bool* /*changed*/)
+static cm::optional<bool> SetRPathXCOFF(std::string const& /*file*/,
+ std::string const& /*newRPath*/,
+ std::string* /*emsg*/,
+ bool* /*changed*/)
{
- return false;
+ return cm::nullopt; // Not implemented.
}
-#else
-bool cmSystemTools::ChangeRPath(std::string const& /*file*/,
- std::string const& /*oldRPath*/,
- std::string const& /*newRPath*/,
- bool /*removeEnvironmentRPath*/,
- std::string* /*emsg*/, bool* /*changed*/)
+
+bool cmSystemTools::ChangeRPath(std::string const& file,
+ std::string const& oldRPath,
+ std::string const& newRPath,
+ bool removeEnvironmentRPath, std::string* emsg,
+ bool* changed)
{
+ if (cm::optional<bool> result = ChangeRPathELF(
+ file, oldRPath, newRPath, removeEnvironmentRPath, emsg, changed)) {
+ return result.value();
+ }
+ if (cm::optional<bool> result = ChangeRPathXCOFF(
+ file, oldRPath, newRPath, removeEnvironmentRPath, emsg, changed)) {
+ return result.value();
+ }
return false;
}
-bool cmSystemTools::SetRPath(std::string const& /*file*/,
- std::string const& /*newRPath*/,
- std::string* /*emsg*/, bool* /*changed*/)
+bool cmSystemTools::SetRPath(std::string const& file,
+ std::string const& newRPath, std::string* emsg,
+ bool* changed)
{
+ if (cm::optional<bool> result = SetRPathELF(file, newRPath, emsg, changed)) {
+ return result.value();
+ }
+ if (cm::optional<bool> result =
+ SetRPathXCOFF(file, newRPath, emsg, changed)) {
+ return result.value();
+ }
return false;
}
-#endif
bool cmSystemTools::VersionCompare(cmSystemTools::CompareOp op,
const char* lhss, const char* rhss)
@@ -2989,10 +3012,8 @@ int cmSystemTools::strverscmp(std::string const& lhs, std::string const& rhs)
return cm_strverscmp(lhs.c_str(), rhs.c_str());
}
-// FIXME: Dispatch if multiple formats are supported.
-#if defined(CMake_USE_ELF_PARSER)
-bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
- bool* removed)
+static cm::optional<bool> RemoveRPathELF(std::string const& file,
+ std::string* emsg, bool* removed)
{
if (removed) {
*removed = false;
@@ -3005,6 +3026,9 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
{
// Parse the ELF binary.
cmELF elf(file.c_str());
+ if (!elf) {
+ return cm::nullopt; // Not a valid ELF file.
+ }
// Get the RPATH and RUNPATH entries from it and sort them by index
// in the dynamic section header.
@@ -3054,8 +3078,7 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
entriesErased++;
continue;
}
- if (cmELF::TagMipsRldMapRel != 0 &&
- it->first == cmELF::TagMipsRldMapRel) {
+ if (it->first == cmELF::TagMipsRldMapRel && elf.IsMIPS()) {
// Background: debuggers need to know the "linker map" which contains
// the addresses each dynamic object is loaded at. Most arches use
// the DT_DEBUG tag which the dynamic linker writes to (directly) and
@@ -3131,15 +3154,22 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
}
return true;
}
-#elif defined(CMake_USE_XCOFF_PARSER)
-bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
- bool* removed)
+
+static cm::optional<bool> RemoveRPathXCOFF(std::string const& file,
+ std::string* emsg, bool* removed)
{
if (removed) {
*removed = false;
}
-
+#if !defined(CMake_USE_XCOFF_PARSER)
+ (void)file;
+ (void)emsg;
+ return cm::nullopt; // Cannot handle XCOFF files.
+#else
cmXCOFF xcoff(file.c_str(), cmXCOFF::Mode::ReadWrite);
+ if (!xcoff) {
+ return cm::nullopt; // Not a valid XCOFF file.
+ }
bool rm = xcoff.RemoveLibPath();
if (!xcoff) {
if (emsg) {
@@ -3152,55 +3182,60 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
*removed = rm;
}
return true;
+#endif
}
-#else
-bool cmSystemTools::RemoveRPath(std::string const& /*file*/,
- std::string* /*emsg*/, bool* /*removed*/)
+bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
+ bool* removed)
{
+ if (cm::optional<bool> result = RemoveRPathELF(file, emsg, removed)) {
+ return result.value();
+ }
+ if (cm::optional<bool> result = RemoveRPathXCOFF(file, emsg, removed)) {
+ return result.value();
+ }
return false;
}
-#endif
-// FIXME: Dispatch if multiple formats are supported.
bool cmSystemTools::CheckRPath(std::string const& file,
std::string const& newRPath)
{
-#if defined(CMake_USE_ELF_PARSER)
// Parse the ELF binary.
cmELF elf(file.c_str());
-
- // Get the RPATH or RUNPATH entry from it.
- cmELF::StringEntry const* se = elf.GetRPath();
- if (!se) {
- se = elf.GetRunPath();
- }
-
- // Make sure the current rpath contains the new rpath.
- if (newRPath.empty()) {
+ if (elf) {
+ // Get the RPATH or RUNPATH entry from it.
+ cmELF::StringEntry const* se = elf.GetRPath();
if (!se) {
- return true;
+ se = elf.GetRunPath();
}
- } else {
- if (se &&
- cmSystemToolsFindRPath(se->Value, newRPath) != std::string::npos) {
- return true;
+
+ // Make sure the current rpath contains the new rpath.
+ if (newRPath.empty()) {
+ if (!se) {
+ return true;
+ }
+ } else {
+ if (se &&
+ cmSystemToolsFindRPath(se->Value, newRPath) != std::string::npos) {
+ return true;
+ }
}
+ return false;
}
- return false;
-#elif defined(CMake_USE_XCOFF_PARSER)
+#if defined(CMake_USE_XCOFF_PARSER)
// Parse the XCOFF binary.
cmXCOFF xcoff(file.c_str());
- if (cm::optional<cm::string_view> libPath = xcoff.GetLibPath()) {
- if (cmSystemToolsFindRPath(*libPath, newRPath) != std::string::npos) {
- return true;
+ if (xcoff) {
+ if (cm::optional<cm::string_view> libPath = xcoff.GetLibPath()) {
+ if (cmSystemToolsFindRPath(*libPath, newRPath) != std::string::npos) {
+ return true;
+ }
}
+ return false;
}
- return false;
-#else
+#endif
(void)file;
(void)newRPath;
return false;
-#endif
}
bool cmSystemTools::RepeatedRemoveDirectory(const std::string& dir)
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 7622700..4f446d8 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -157,7 +157,7 @@ cmProp cmTargetPropertyComputer::GetSources<cmTarget>(
}
static std::string srcs;
srcs = ss.str();
- return &srcs;
+ return cmProp(srcs);
}
class cmTargetInternals
@@ -189,6 +189,7 @@ public:
std::map<std::string, BTs<std::string>> LanguageStandardProperties;
std::vector<std::string> IncludeDirectoriesEntries;
std::vector<cmListFileBacktrace> IncludeDirectoriesBacktraces;
+ std::vector<std::string> InstallIncludeDirectoriesEntries;
std::vector<std::string> CompileOptionsEntries;
std::vector<cmListFileBacktrace> CompileOptionsBacktraces;
std::vector<std::string> CompileFeaturesEntries;
@@ -266,7 +267,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
// Replace everything after "CMAKE_"
defKey.replace(defKey.begin() + 6, defKey.end(), property);
if (cmProp value = mf->GetDefinition(defKey)) {
- this->SetProperty(property, *value);
+ this->SetProperty(property, value);
}
};
auto initPropValue = [this, mf, &defKey](const std::string& property,
@@ -274,7 +275,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
// Replace everything after "CMAKE_"
defKey.replace(defKey.begin() + 6, defKey.end(), property);
if (cmProp value = mf->GetDefinition(defKey)) {
- this->SetProperty(property, *value);
+ this->SetProperty(property, value);
} else if (default_value) {
this->SetProperty(property, default_value);
}
@@ -1075,6 +1076,17 @@ std::set<std::string> const& cmTarget::GetSystemIncludeDirectories() const
return this->impl->SystemIncludeDirectories;
}
+void cmTarget::AddInstallIncludeDirectories(cmStringRange const& incs)
+{
+ std::copy(incs.begin(), incs.end(),
+ std::back_inserter(this->impl->InstallIncludeDirectoriesEntries));
+}
+
+cmStringRange cmTarget::GetInstallIncludeDirectoriesEntries() const
+{
+ return cmMakeRange(this->impl->InstallIncludeDirectoriesEntries);
+}
+
cmStringRange cmTarget::GetIncludeDirectoriesEntries() const
{
return cmMakeRange(this->impl->IncludeDirectoriesEntries);
@@ -1165,32 +1177,59 @@ cmBacktraceRange cmTarget::GetLinkImplementationBacktraces() const
return cmMakeRange(this->impl->LinkImplementationPropertyBacktraces);
}
-void cmTarget::SetProperty(const std::string& prop, const char* value)
+namespace {
+#define MAKE_PROP(PROP) const std::string prop##PROP = #PROP
+MAKE_PROP(C_STANDARD);
+MAKE_PROP(CXX_STANDARD);
+MAKE_PROP(CUDA_STANDARD);
+MAKE_PROP(HIP_STANDARD);
+MAKE_PROP(OBJC_STANDARD);
+MAKE_PROP(OBJCXX_STANDARD);
+MAKE_PROP(COMPILE_DEFINITIONS);
+MAKE_PROP(COMPILE_FEATURES);
+MAKE_PROP(COMPILE_OPTIONS);
+MAKE_PROP(PRECOMPILE_HEADERS);
+MAKE_PROP(PRECOMPILE_HEADERS_REUSE_FROM);
+MAKE_PROP(CUDA_PTX_COMPILATION);
+MAKE_PROP(EXPORT_NAME);
+MAKE_PROP(IMPORTED);
+MAKE_PROP(IMPORTED_GLOBAL);
+MAKE_PROP(INCLUDE_DIRECTORIES);
+MAKE_PROP(LINK_OPTIONS);
+MAKE_PROP(LINK_DIRECTORIES);
+MAKE_PROP(LINK_LIBRARIES);
+MAKE_PROP(MANUALLY_ADDED_DEPENDENCIES);
+MAKE_PROP(NAME);
+MAKE_PROP(SOURCES);
+MAKE_PROP(TYPE);
+MAKE_PROP(BINARY_DIR);
+MAKE_PROP(SOURCE_DIR);
+MAKE_PROP(FALSE);
+MAKE_PROP(TRUE);
+#undef MAKE_PROP
+}
+
+namespace {
+// to workaround bug on GCC/AIX
+// Define a template to force conversion to std::string
+template <typename ValueType>
+std::string ConvertToString(ValueType value);
+
+template <>
+std::string ConvertToString<const char*>(const char* value)
+{
+ return std::string(value);
+}
+template <>
+std::string ConvertToString<cmProp>(cmProp value)
+{
+ return std::string(*value);
+}
+}
+
+template <typename ValueType>
+void cmTarget::StoreProperty(const std::string& prop, ValueType value)
{
-#define MAKE_STATIC_PROP(PROP) static const std::string prop##PROP = #PROP
- MAKE_STATIC_PROP(C_STANDARD);
- MAKE_STATIC_PROP(CXX_STANDARD);
- MAKE_STATIC_PROP(CUDA_STANDARD);
- MAKE_STATIC_PROP(HIP_STANDARD);
- MAKE_STATIC_PROP(OBJC_STANDARD);
- MAKE_STATIC_PROP(OBJCXX_STANDARD);
- MAKE_STATIC_PROP(COMPILE_DEFINITIONS);
- MAKE_STATIC_PROP(COMPILE_FEATURES);
- MAKE_STATIC_PROP(COMPILE_OPTIONS);
- MAKE_STATIC_PROP(PRECOMPILE_HEADERS);
- MAKE_STATIC_PROP(PRECOMPILE_HEADERS_REUSE_FROM);
- MAKE_STATIC_PROP(CUDA_PTX_COMPILATION);
- MAKE_STATIC_PROP(EXPORT_NAME);
- MAKE_STATIC_PROP(IMPORTED_GLOBAL);
- MAKE_STATIC_PROP(INCLUDE_DIRECTORIES);
- MAKE_STATIC_PROP(LINK_OPTIONS);
- MAKE_STATIC_PROP(LINK_DIRECTORIES);
- MAKE_STATIC_PROP(LINK_LIBRARIES);
- MAKE_STATIC_PROP(MANUALLY_ADDED_DEPENDENCIES);
- MAKE_STATIC_PROP(NAME);
- MAKE_STATIC_PROP(SOURCES);
- MAKE_STATIC_PROP(TYPE);
-#undef MAKE_STATIC_PROP
if (prop == propMANUALLY_ADDED_DEPENDENCIES) {
this->impl->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
@@ -1315,7 +1354,8 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
this->GetGlobalGenerator()->IndexTarget(this);
}
} else if (cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME") &&
- !this->impl->CheckImportedLibName(prop, value ? value : "")) {
+ !this->impl->CheckImportedLibName(
+ prop, value ? value : std::string{})) {
/* error was reported by check method */
} else if (prop == propCUDA_PTX_COMPILATION &&
this->GetType() != cmStateEnums::OBJECT_LIBRARY) {
@@ -1345,17 +1385,17 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
std::string reusedFrom = reusedTarget->GetSafeProperty(prop);
if (reusedFrom.empty()) {
- reusedFrom = value;
+ reusedFrom = ConvertToString(value);
}
- this->impl->Properties.SetProperty(prop, reusedFrom.c_str());
+ this->impl->Properties.SetProperty(prop, reusedFrom);
reusedTarget->SetProperty("COMPILE_PDB_NAME", reusedFrom);
reusedTarget->SetProperty("COMPILE_PDB_OUTPUT_DIRECTORY",
cmStrCat(reusedFrom, ".dir/"));
cmProp tmp = reusedTarget->GetProperty("COMPILE_PDB_NAME");
- this->SetProperty("COMPILE_PDB_NAME", cmToCStr(tmp));
+ this->SetProperty("COMPILE_PDB_NAME", tmp);
this->AddUtility(reusedFrom, false, this->impl->Makefile);
} else if (prop == propC_STANDARD || prop == propCXX_STANDARD ||
prop == propCUDA_STANDARD || prop == propHIP_STANDARD ||
@@ -1474,6 +1514,15 @@ void cmTarget::AppendProperty(const std::string& prop,
}
}
+void cmTarget::SetProperty(const std::string& prop, const char* value)
+{
+ this->StoreProperty(prop, value);
+}
+void cmTarget::SetProperty(const std::string& prop, cmProp value)
+{
+ this->StoreProperty(prop, value);
+}
+
void cmTarget::AppendBuildInterfaceIncludes()
{
if (this->GetType() != cmStateEnums::SHARED_LIBRARY &&
@@ -1681,31 +1730,6 @@ cmProp cmTarget::GetComputedProperty(const std::string& prop,
cmProp cmTarget::GetProperty(const std::string& prop) const
{
-#define MAKE_STATIC_PROP(PROP) static const std::string prop##PROP = #PROP
- MAKE_STATIC_PROP(C_STANDARD);
- MAKE_STATIC_PROP(CXX_STANDARD);
- MAKE_STATIC_PROP(CUDA_STANDARD);
- MAKE_STATIC_PROP(OBJC_STANDARD);
- MAKE_STATIC_PROP(OBJCXX_STANDARD);
- MAKE_STATIC_PROP(LINK_LIBRARIES);
- MAKE_STATIC_PROP(TYPE);
- MAKE_STATIC_PROP(INCLUDE_DIRECTORIES);
- MAKE_STATIC_PROP(COMPILE_FEATURES);
- MAKE_STATIC_PROP(COMPILE_OPTIONS);
- MAKE_STATIC_PROP(COMPILE_DEFINITIONS);
- MAKE_STATIC_PROP(LINK_OPTIONS);
- MAKE_STATIC_PROP(LINK_DIRECTORIES);
- MAKE_STATIC_PROP(PRECOMPILE_HEADERS);
- MAKE_STATIC_PROP(IMPORTED);
- MAKE_STATIC_PROP(IMPORTED_GLOBAL);
- MAKE_STATIC_PROP(MANUALLY_ADDED_DEPENDENCIES);
- MAKE_STATIC_PROP(NAME);
- 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{
propC_STANDARD,
propCXX_STANDARD,
@@ -1737,7 +1761,7 @@ cmProp cmTarget::GetProperty(const std::string& prop) const
if (propertyIter == this->impl->LanguageStandardProperties.end()) {
return nullptr;
}
- return &(propertyIter->second.Value);
+ return cmProp(propertyIter->second.Value);
}
if (prop == propLINK_LIBRARIES) {
if (this->impl->LinkImplementationPropertyEntries.empty()) {
@@ -1746,11 +1770,11 @@ cmProp cmTarget::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(this->impl->LinkImplementationPropertyEntries, ";");
- return &output;
+ return cmProp(output);
}
// the type property returns what type the target is
if (prop == propTYPE) {
- return &cmState::GetTargetTypeName(this->GetType());
+ return cmProp(cmState::GetTargetTypeName(this->GetType()));
}
if (prop == propINCLUDE_DIRECTORIES) {
if (this->impl->IncludeDirectoriesEntries.empty()) {
@@ -1759,7 +1783,7 @@ cmProp cmTarget::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(this->impl->IncludeDirectoriesEntries, ";");
- return &output;
+ return cmProp(output);
}
if (prop == propCOMPILE_FEATURES) {
if (this->impl->CompileFeaturesEntries.empty()) {
@@ -1768,7 +1792,7 @@ cmProp cmTarget::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(this->impl->CompileFeaturesEntries, ";");
- return &output;
+ return cmProp(output);
}
if (prop == propCOMPILE_OPTIONS) {
if (this->impl->CompileOptionsEntries.empty()) {
@@ -1777,7 +1801,7 @@ cmProp cmTarget::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(this->impl->CompileOptionsEntries, ";");
- return &output;
+ return cmProp(output);
}
if (prop == propCOMPILE_DEFINITIONS) {
if (this->impl->CompileDefinitionsEntries.empty()) {
@@ -1786,7 +1810,7 @@ cmProp cmTarget::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(this->impl->CompileDefinitionsEntries, ";");
- return &output;
+ return cmProp(output);
}
if (prop == propLINK_OPTIONS) {
if (this->impl->LinkOptionsEntries.empty()) {
@@ -1795,7 +1819,7 @@ cmProp cmTarget::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(this->impl->LinkOptionsEntries, ";");
- return &output;
+ return cmProp(output);
}
if (prop == propLINK_DIRECTORIES) {
if (this->impl->LinkDirectoriesEntries.empty()) {
@@ -1805,7 +1829,7 @@ cmProp cmTarget::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(this->impl->LinkDirectoriesEntries, ";");
- return &output;
+ return cmProp(output);
}
if (prop == propMANUALLY_ADDED_DEPENDENCIES) {
if (this->impl->Utilities.empty()) {
@@ -1822,7 +1846,7 @@ cmProp cmTarget::GetProperty(const std::string& prop) const
return item.Value.first;
});
output = cmJoin(utilities, ";");
- return &output;
+ return cmProp(output);
}
if (prop == propPRECOMPILE_HEADERS) {
if (this->impl->PrecompileHeadersEntries.empty()) {
@@ -1831,26 +1855,27 @@ cmProp cmTarget::GetProperty(const std::string& prop) const
static std::string output;
output = cmJoin(this->impl->PrecompileHeadersEntries, ";");
- return &output;
+ return cmProp(output);
}
if (prop == propIMPORTED) {
- return this->IsImported() ? &propTRUE : &propFALSE;
+ return this->IsImported() ? cmProp(propTRUE) : cmProp(propFALSE);
}
if (prop == propIMPORTED_GLOBAL) {
- return this->IsImportedGloballyVisible() ? &propTRUE : &propFALSE;
+ return this->IsImportedGloballyVisible() ? cmProp(propTRUE)
+ : cmProp(propFALSE);
}
if (prop == propNAME) {
- return &this->GetName();
+ return cmProp(this->GetName());
}
if (prop == propBINARY_DIR) {
- return &this->impl->Makefile->GetStateSnapshot()
- .GetDirectory()
- .GetCurrentBinary();
+ return cmProp(this->impl->Makefile->GetStateSnapshot()
+ .GetDirectory()
+ .GetCurrentBinary());
}
if (prop == propSOURCE_DIR) {
- return &this->impl->Makefile->GetStateSnapshot()
- .GetDirectory()
- .GetCurrentSource();
+ return cmProp(this->impl->Makefile->GetStateSnapshot()
+ .GetDirectory()
+ .GetCurrentSource());
}
}
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 30d9f5d..de0c4e3 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -170,9 +170,10 @@ public:
//! Set/Get a property of this target file
void SetProperty(const std::string& prop, const char* value);
+ void SetProperty(const std::string& prop, cmProp value);
void SetProperty(const std::string& prop, const std::string& value)
{
- this->SetProperty(prop, value.c_str());
+ this->SetProperty(prop, cmProp(value));
}
void AppendProperty(const std::string& prop, const std::string& value,
bool asString = false);
@@ -237,6 +238,9 @@ public:
void AddSystemIncludeDirectories(std::set<std::string> const& incs);
std::set<std::string> const& GetSystemIncludeDirectories() const;
+ void AddInstallIncludeDirectories(cmStringRange const& incs);
+ cmStringRange GetInstallIncludeDirectoriesEntries() const;
+
BTs<std::string> const* GetLanguageStandardProperty(
const std::string& propertyName) const;
@@ -280,6 +284,9 @@ public:
};
private:
+ template <typename ValueType>
+ void StoreProperty(const std::string& prop, ValueType value);
+
// Internal representation details.
friend class cmGeneratorTarget;
diff --git a/Source/cmTargetExport.h b/Source/cmTargetExport.h
index 1e38d84..19fc931 100644
--- a/Source/cmTargetExport.h
+++ b/Source/cmTargetExport.h
@@ -29,7 +29,6 @@ public:
cmInstallTargetGenerator* FrameworkGenerator;
cmInstallTargetGenerator* BundleGenerator;
cmInstallFilesGenerator* HeaderGenerator;
- std::string InterfaceIncludeDirectories;
///@}
bool NamelinkOnly = false;
diff --git a/Source/cmTargetPropertyComputer.h b/Source/cmTargetPropertyComputer.h
index f2be318..a749b53 100644
--- a/Source/cmTargetPropertyComputer.h
+++ b/Source/cmTargetPropertyComputer.h
@@ -65,7 +65,7 @@ private:
context)) {
return nullptr;
}
- return &ComputeLocationForBuild(tgt);
+ return cmProp(ComputeLocationForBuild(tgt));
}
// Support "LOCATION_<CONFIG>".
@@ -76,7 +76,7 @@ private:
return nullptr;
}
std::string configName = prop.substr(9);
- return &ComputeLocation(tgt, configName);
+ return cmProp(ComputeLocation(tgt, configName));
}
// Support "<CONFIG>_LOCATION".
@@ -89,7 +89,7 @@ private:
context)) {
return nullptr;
}
- return &ComputeLocation(tgt, configName);
+ return cmProp(ComputeLocation(tgt, configName));
}
}
}
diff --git a/Source/cmTest.cxx b/Source/cmTest.cxx
index a26bef3..9d25ce9 100644
--- a/Source/cmTest.cxx
+++ b/Source/cmTest.cxx
@@ -32,7 +32,7 @@ void cmTest::SetCommand(std::vector<std::string> const& command)
this->Command = command;
}
-const char* cmTest::GetProperty(const std::string& prop) const
+cmProp cmTest::GetProperty(const std::string& prop) const
{
cmProp retVal = this->Properties.GetPropertyValue(prop);
if (!retVal) {
@@ -40,12 +40,12 @@ const char* cmTest::GetProperty(const std::string& prop) const
this->Makefile->GetState()->IsPropertyChained(prop, cmProperty::TEST);
if (chain) {
if (cmProp p = this->Makefile->GetProperty(prop, chain)) {
- return p->c_str();
+ return p;
}
}
return nullptr;
}
- return retVal->c_str();
+ return retVal;
}
bool cmTest::GetPropertyAsBool(const std::string& prop) const
@@ -57,6 +57,10 @@ void cmTest::SetProperty(const std::string& prop, const char* value)
{
this->Properties.SetProperty(prop, value);
}
+void cmTest::SetProperty(const std::string& prop, cmProp value)
+{
+ this->Properties.SetProperty(prop, value);
+}
void cmTest::AppendProperty(const std::string& prop, const std::string& value,
bool asString)
diff --git a/Source/cmTest.h b/Source/cmTest.h
index f33b7e2..a790501 100644
--- a/Source/cmTest.h
+++ b/Source/cmTest.h
@@ -8,6 +8,7 @@
#include <vector>
#include "cmListFileCache.h"
+#include "cmProperty.h"
#include "cmPropertyMap.h"
class cmMakefile;
@@ -34,9 +35,14 @@ public:
//! Set/Get a property of this source file
void SetProperty(const std::string& prop, const char* value);
+ void SetProperty(const std::string& prop, cmProp value);
+ void SetProperty(const std::string& prop, const std::string& value)
+ {
+ this->SetProperty(prop, cmProp(value));
+ }
void AppendProperty(const std::string& prop, const std::string& value,
bool asString = false);
- const char* GetProperty(const std::string& prop) const;
+ cmProp GetProperty(const std::string& prop) const;
bool GetPropertyAsBool(const std::string& prop) const;
cmPropertyMap& GetProperties() { return this->Properties; }
diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx
index 056696d..cfea4cf 100644
--- a/Source/cmTimestamp.cxx
+++ b/Source/cmTimestamp.cxx
@@ -18,6 +18,10 @@
#include <cstring>
#include <sstream>
+#ifdef __MINGW32__
+# include <libloaderapi.h>
+#endif
+
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -159,6 +163,7 @@ std::string cmTimestamp::AddTimestampComponent(char flag,
case 'M':
case 'S':
case 'U':
+ case 'V':
case 'w':
case 'y':
case 'Y':
@@ -187,6 +192,24 @@ std::string cmTimestamp::AddTimestampComponent(char flag,
}
}
+#ifdef __MINGW32__
+ /* See a bug in MinGW: https://sourceforge.net/p/mingw-w64/bugs/793/. A work
+ * around is to try to use strftime() from ucrtbase.dll. */
+ using T = size_t(WINAPI*)(char*, size_t, const char*, const struct tm*);
+ auto loadStrftime = [] {
+ auto handle =
+ LoadLibraryExA("ucrtbase.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
+ if (handle) {
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wcast-function-type"
+ return reinterpret_cast<T>(GetProcAddress(handle, "strftime"));
+# pragma GCC diagnostic pop
+ }
+ return strftime;
+ };
+ static T strftime = loadStrftime();
+#endif
+
char buffer[16];
size_t size =
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index bda2f91..9407228 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -490,10 +490,7 @@ void cmVisualStudio10TargetGenerator::Generate()
e1.Element("Platform", this->Platform);
cmProp projLabel = this->GeneratorTarget->GetProperty("PROJECT_LABEL");
- if (!projLabel) {
- projLabel = &this->Name;
- }
- e1.Element("ProjectName", *projLabel);
+ e1.Element("ProjectName", projLabel ? projLabel : this->Name);
{
cmProp targetFramework =
this->GeneratorTarget->GetProperty("DOTNET_TARGET_FRAMEWORK");
@@ -511,15 +508,15 @@ void cmVisualStudio10TargetGenerator::Generate()
p = this->GeneratorTarget->GetProperty(
"DOTNET_TARGET_FRAMEWORK_VERSION");
}
- const char* targetFrameworkVersion = cmToCStr(p);
- if (!targetFrameworkVersion && this->ProjectType == csproj &&
+ std::string targetFrameworkVersion = p;
+ if (targetFrameworkVersion.empty() && this->ProjectType == csproj &&
this->GlobalGenerator->TargetsWindowsCE() &&
this->GlobalGenerator->GetVersion() ==
cmGlobalVisualStudioGenerator::VS12) {
// VS12 .NETCF default to .NET framework 3.9
targetFrameworkVersion = "v3.9";
}
- if (targetFrameworkVersion) {
+ if (!targetFrameworkVersion.empty()) {
e1.Element("TargetFrameworkVersion", targetFrameworkVersion);
}
}
@@ -3543,8 +3540,6 @@ void cmVisualStudio10TargetGenerator::WriteNasmOptions(
}
Elem e2(e1, "NASM");
- std::vector<std::string> includes =
- this->GetIncludes(configName, "ASM_NASM");
OptionsHelper nasmOptions(*(this->NasmOptions[configName]), e2);
nasmOptions.OutputAdditionalIncludeDirectories("ASM_NASM");
nasmOptions.OutputFlagMap();
diff --git a/Source/cmWhileCommand.cxx b/Source/cmWhileCommand.cxx
index 327c1c7..b8297ce 100644
--- a/Source/cmWhileCommand.cxx
+++ b/Source/cmWhileCommand.cxx
@@ -16,13 +16,14 @@
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmOutputConverter.h"
#include "cmSystemTools.h"
#include "cmake.h"
class cmWhileFunctionBlocker : public cmFunctionBlocker
{
public:
- cmWhileFunctionBlocker(cmMakefile* mf);
+ cmWhileFunctionBlocker(cmMakefile* mf, std::vector<cmListFileArgument> args);
~cmWhileFunctionBlocker() override;
cm::string_view StartCommandName() const override { return "while"_s; }
@@ -34,14 +35,15 @@ public:
bool Replay(std::vector<cmListFileFunction> functions,
cmExecutionStatus& inStatus) override;
- std::vector<cmListFileArgument> Args;
-
private:
cmMakefile* Makefile;
+ std::vector<cmListFileArgument> Args;
};
-cmWhileFunctionBlocker::cmWhileFunctionBlocker(cmMakefile* mf)
- : Makefile(mf)
+cmWhileFunctionBlocker::cmWhileFunctionBlocker(
+ cmMakefile* const mf, std::vector<cmListFileArgument> args)
+ : Makefile{ mf }
+ , Args{ std::move(args) }
{
this->Makefile->PushLoopBlock();
}
@@ -60,39 +62,29 @@ bool cmWhileFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff,
bool cmWhileFunctionBlocker::Replay(std::vector<cmListFileFunction> functions,
cmExecutionStatus& inStatus)
{
- cmMakefile& mf = inStatus.GetMakefile();
- std::string errorString;
-
- std::vector<cmExpandedCommandArgument> expandedArguments;
- mf.ExpandArguments(this->Args, expandedArguments);
- MessageType messageType;
+ auto& mf = inStatus.GetMakefile();
cmListFileBacktrace whileBT =
mf.GetBacktrace().Push(this->GetStartingContext());
- cmConditionEvaluator conditionEvaluator(mf, whileBT);
-
- bool isTrue =
- conditionEvaluator.IsTrue(expandedArguments, errorString, messageType);
-
- while (isTrue) {
- if (!errorString.empty()) {
- std::string err = "had incorrect arguments: ";
- for (cmListFileArgument const& arg : this->Args) {
- err += (arg.Delim ? "\"" : "");
- err += arg.Value;
- err += (arg.Delim ? "\"" : "");
- err += " ";
- }
- err += "(";
- err += errorString;
- err += ").";
- mf.GetCMakeInstance()->IssueMessage(messageType, err, whileBT);
- if (messageType == MessageType::FATAL_ERROR) {
- cmSystemTools::SetFatalErrorOccured();
- return true;
- }
- }
+ std::vector<cmExpandedCommandArgument> expandedArguments;
+ // At least same size expected for `expandedArguments` as `Args`
+ expandedArguments.reserve(this->Args.size());
+
+ auto expandArgs = [&mf](std::vector<cmListFileArgument> const& args,
+ std::vector<cmExpandedCommandArgument>& out)
+ -> std::vector<cmExpandedCommandArgument>& {
+ out.clear();
+ mf.ExpandArguments(args, out);
+ return out;
+ };
+
+ std::string errorString;
+ MessageType messageType;
+
+ for (cmConditionEvaluator conditionEvaluator(mf, whileBT);
+ conditionEvaluator.IsTrue(expandArgs(this->Args, expandedArguments),
+ errorString, messageType);) {
// Invoke all the functions that were collected in the block.
for (cmListFileFunction const& fn : functions) {
cmExecutionStatus status(mf);
@@ -111,11 +103,22 @@ bool cmWhileFunctionBlocker::Replay(std::vector<cmListFileFunction> functions,
return true;
}
}
- expandedArguments.clear();
- mf.ExpandArguments(this->Args, expandedArguments);
- isTrue =
- conditionEvaluator.IsTrue(expandedArguments, errorString, messageType);
}
+
+ if (!errorString.empty()) {
+ std::string err = "had incorrect arguments:\n ";
+ for (auto const& i : expandedArguments) {
+ err += " ";
+ err += cmOutputConverter::EscapeForCMake(i.GetValue());
+ }
+ err += "\n";
+ err += errorString;
+ mf.GetCMakeInstance()->IssueMessage(messageType, err, whileBT);
+ if (messageType == MessageType::FATAL_ERROR) {
+ cmSystemTools::SetFatalErrorOccured();
+ }
+ }
+
return true;
}
@@ -128,11 +131,9 @@ bool cmWhileCommand(std::vector<cmListFileArgument> const& args,
}
// create a function blocker
- {
- cmMakefile& makefile = status.GetMakefile();
- auto fb = cm::make_unique<cmWhileFunctionBlocker>(&makefile);
- fb->Args = args;
- makefile.AddFunctionBlocker(std::move(fb));
- }
+ auto& makefile = status.GetMakefile();
+ makefile.AddFunctionBlocker(
+ cm::make_unique<cmWhileFunctionBlocker>(&makefile, args));
+
return true;
}
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 73f5ad5..beb5d16 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -114,7 +114,9 @@
# include "cmExtraSublimeTextGenerator.h"
#endif
-#if defined(__linux__) || defined(_WIN32)
+// NOTE: the __linux__ macro is predefined on Android host too, but
+// main CMakeLists.txt filters out this generator by host name.
+#if (defined(__linux__) && !defined(__ANDROID__)) || defined(_WIN32)
# include "cmGlobalGhsMultiGenerator.h"
#endif
@@ -156,17 +158,16 @@ static void cmWarnUnusedCliWarning(const std::string& variable, int /*unused*/,
}
#endif
-cmake::cmake(Role role, cmState::Mode mode)
+cmake::cmake(Role role, cmState::Mode mode, cmState::ProjectKind projectKind)
: CMakeWorkingDirectory(cmSystemTools::GetCurrentWorkingDirectory())
, FileTimeCache(cm::make_unique<cmFileTimeCache>())
#ifndef CMAKE_BOOTSTRAP
, VariableWatch(cm::make_unique<cmVariableWatch>())
#endif
- , State(cm::make_unique<cmState>())
+ , State(cm::make_unique<cmState>(mode, projectKind))
, Messenger(cm::make_unique<cmMessenger>())
{
this->TraceFile.close();
- this->State->SetMode(mode);
this->CurrentSnapshot = this->State->CreateBaseSnapshot();
#ifdef __APPLE__
@@ -1843,7 +1844,7 @@ int cmake::HandleDeleteCacheVariables(const std::string& var)
std::vector<std::string> argsSplit = cmExpandedList(var, true);
// erase the property to avoid infinite recursion
this->State->SetGlobalProperty("__CMAKE_DELETE_CACHE_CHANGE_VARS_", "");
- if (this->State->GetIsInTryCompile()) {
+ if (this->GetIsInTryCompile()) {
return 0;
}
std::vector<SaveCacheEntry> saved;
@@ -2111,7 +2112,7 @@ int cmake::ActualConfigure()
// reset any system configuration information, except for when we are
// InTryCompile. With TryCompile the system info is taken from the parent's
// info to save time
- if (!this->State->GetIsInTryCompile()) {
+ if (!this->GetIsInTryCompile()) {
this->GlobalGenerator->ClearEnabledLanguages();
this->TruncateOutputLog("CMakeOutput.log");
@@ -2529,7 +2530,7 @@ void cmake::AddDefaultGenerators()
this->Generators.push_back(cmGlobalMinGWMakefileGenerator::NewFactory());
#endif
#if !defined(CMAKE_BOOTSTRAP)
-# if defined(__linux__) || defined(_WIN32)
+# if (defined(__linux__) && !defined(__ANDROID__)) || defined(_WIN32)
this->Generators.push_back(cmGlobalGhsMultiGenerator::NewFactory());
# endif
this->Generators.push_back(cmGlobalUnixMakefileGenerator3::NewFactory());
@@ -2622,19 +2623,14 @@ void cmake::SetProgressCallback(ProgressCallbackType f)
void cmake::UpdateProgress(const std::string& msg, float prog)
{
- if (this->ProgressCallback && !this->State->GetIsInTryCompile()) {
+ if (this->ProgressCallback && !this->GetIsInTryCompile()) {
this->ProgressCallback(msg, prog);
}
}
bool cmake::GetIsInTryCompile() const
{
- return this->State->GetIsInTryCompile();
-}
-
-void cmake::SetIsInTryCompile(bool b)
-{
- this->State->SetIsInTryCompile(b);
+ return this->State->GetProjectKind() == cmState::ProjectKind::TryCompile;
}
void cmake::AppendGlobalGeneratorsDocumentation(
@@ -2923,6 +2919,10 @@ void cmake::SetProperty(const std::string& prop, const char* value)
{
this->State->SetGlobalProperty(prop, value);
}
+void cmake::SetProperty(const std::string& prop, cmProp value)
+{
+ this->State->SetGlobalProperty(prop, value);
+}
void cmake::AppendProperty(const std::string& prop, const std::string& value,
bool asString)
diff --git a/Source/cmake.h b/Source/cmake.h
index 5a2a88f..32c7582 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -168,7 +168,8 @@ public:
static const int DEFAULT_BUILD_PARALLEL_LEVEL = 0;
/// Default constructor
- cmake(Role role, cmState::Mode mode);
+ cmake(Role role, cmState::Mode mode,
+ cmState::ProjectKind projectKind = cmState::ProjectKind::Normal);
/// Destructor
~cmake();
@@ -356,7 +357,6 @@ public:
//! Is this cmake running as a result of a TRY_COMPILE command
bool GetIsInTryCompile() const;
- void SetIsInTryCompile(bool b);
#ifndef CMAKE_BOOTSTRAP
void SetWarningFromPreset(const std::string& name,
@@ -396,6 +396,11 @@ public:
//! Set/Get a property of this target file
void SetProperty(const std::string& prop, const char* value);
+ void SetProperty(const std::string& prop, cmProp value);
+ void SetProperty(const std::string& prop, const std::string& value)
+ {
+ this->SetProperty(prop, cmProp(value));
+ }
void AppendProperty(const std::string& prop, const std::string& value,
bool asString = false);
cmProp GetProperty(const std::string& prop);
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 1f4c0b8..1e0f497 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -385,18 +385,15 @@ int HandleTidy(const std::string& runCmd, const std::string& sourceFile,
return ret;
}
-int HandleLWYU(const std::string& runCmd, const std::string& /* sourceFile */,
+int HandleLWYU(const std::string& runCmd, const std::string& sourceFile,
const std::vector<std::string>&)
{
// Construct the ldd -r -u (link what you use lwyu) command line
// ldd -u -r lwuy target
- std::vector<std::string> lwyu_cmd;
- lwyu_cmd.emplace_back("ldd");
- lwyu_cmd.emplace_back("-u");
- lwyu_cmd.emplace_back("-r");
- lwyu_cmd.push_back(runCmd);
+ std::vector<std::string> lwyu_cmd = cmExpandedList(runCmd, true);
+ lwyu_cmd.push_back(sourceFile);
- // Run the ldd -u -r command line.
+ // Run the lwyu check command line, currently ldd is expected.
// Capture its stdout and hide its stderr.
// Ignore its return code because the tool always returns non-zero
// if there are any warnings, but we just want to warn.
diff --git a/Source/kwsys/Status.hxx.in b/Source/kwsys/Status.hxx.in
index ed46d5c..16efaef 100644
--- a/Source/kwsys/Status.hxx.in
+++ b/Source/kwsys/Status.hxx.in
@@ -55,7 +55,10 @@ public:
#endif
/** Return true on "Success", false otherwise. */
- explicit operator bool() const { return this->Kind_ == Kind::Success; }
+ bool IsSuccess() const { return this->Kind_ == Kind::Success; }
+
+ /** Return true on "Success", false otherwise. */
+ explicit operator bool() const { return this->IsSuccess(); }
/** Return the kind of status. */
Kind GetKind() const { return this->Kind_; }
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx
index 12f9139..f2bf85f 100644
--- a/Source/kwsys/SystemInformation.cxx
+++ b/Source/kwsys/SystemInformation.cxx
@@ -1356,14 +1356,12 @@ std::string SymbolProperties::Demangle(const char* symbol) const
std::string result = safes(symbol);
# if defined(KWSYS_SYSTEMINFORMATION_HAS_CPP_DEMANGLE)
int status = 0;
- size_t bufferLen = 1024;
- char* buffer = (char*)malloc(1024);
char* demangledSymbol =
- abi::__cxa_demangle(symbol, buffer, &bufferLen, &status);
+ abi::__cxa_demangle(symbol, nullptr, nullptr, &status);
if (!status) {
result = demangledSymbol;
}
- free(buffer);
+ free(demangledSymbol);
# else
(void)symbol;
# endif
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index f610a70..930d84c 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -2423,7 +2423,7 @@ Status SystemTools::CopyFileAlways(std::string const& source,
if (SystemTools::FileIsDirectory(source)) {
status = SystemTools::MakeDirectory(destination);
- if (!status) {
+ if (!status.IsSuccess()) {
return status;
}
} else {
@@ -2448,17 +2448,17 @@ Status SystemTools::CopyFileAlways(std::string const& source,
// Create destination directory
if (!destination_dir.empty()) {
status = SystemTools::MakeDirectory(destination_dir);
- if (!status) {
+ if (!status.IsSuccess()) {
return status;
}
}
status = SystemTools::CloneFileContent(source, real_destination);
// if cloning did not succeed, fall back to blockwise copy
- if (!status) {
+ if (!status.IsSuccess()) {
status = SystemTools::CopyFileContentBlockwise(source, real_destination);
}
- if (!status) {
+ if (!status.IsSuccess()) {
return status;
}
}
@@ -2488,11 +2488,11 @@ Status SystemTools::CopyADirectory(std::string const& source,
Status status;
Directory dir;
status = dir.Load(source);
- if (!status) {
+ if (!status.IsSuccess()) {
return status;
}
status = SystemTools::MakeDirectory(destination);
- if (!status) {
+ if (!status.IsSuccess()) {
return status;
}
@@ -2507,12 +2507,12 @@ Status SystemTools::CopyADirectory(std::string const& source,
fullDestPath += "/";
fullDestPath += dir.GetFile(static_cast<unsigned long>(fileNum));
status = SystemTools::CopyADirectory(fullPath, fullDestPath, always);
- if (!status) {
+ if (!status.IsSuccess()) {
return status;
}
} else {
status = SystemTools::CopyAFile(fullPath, destination, always);
- if (!status) {
+ if (!status.IsSuccess()) {
return status;
}
}
@@ -2664,7 +2664,7 @@ Status SystemTools::RemoveADirectory(std::string const& source)
Status status;
Directory dir;
status = dir.Load(source);
- if (!status) {
+ if (!status.IsSuccess()) {
return status;
}
@@ -2678,12 +2678,12 @@ Status SystemTools::RemoveADirectory(std::string const& source)
if (SystemTools::FileIsDirectory(fullPath) &&
!SystemTools::FileIsSymlink(fullPath)) {
status = SystemTools::RemoveADirectory(fullPath);
- if (!status) {
+ if (!status.IsSuccess()) {
return status;
}
} else {
status = SystemTools::RemoveFile(fullPath);
- if (!status) {
+ if (!status.IsSuccess()) {
return status;
}
}
@@ -3147,7 +3147,7 @@ Status SystemTools::ReadSymlink(std::string const& newName,
status = Status::Windows_GetLastError();
}
CloseHandle(hFile);
- if (!status) {
+ if (!status.IsSuccess()) {
return status;
}
PREPARSE_DATA_BUFFER data =
diff --git a/Source/kwsys/testDirectory.cxx b/Source/kwsys/testDirectory.cxx
index 06a22dc..a847462 100644
--- a/Source/kwsys/testDirectory.cxx
+++ b/Source/kwsys/testDirectory.cxx
@@ -122,7 +122,7 @@ int _copyDirectoryTest()
}
const Status copysuccess = SystemTools::CopyADirectory(source, destination);
const bool destinationexists = SystemTools::PathExists(destination);
- if (copysuccess) {
+ if (copysuccess.IsSuccess()) {
std::cerr << "CopyADirectory should have returned false" << std::endl;
SystemTools::RemoveADirectory(destination);
return 3;
diff --git a/Source/kwsys/testStatus.cxx b/Source/kwsys/testStatus.cxx
index f85ef42..0a767a8 100644
--- a/Source/kwsys/testStatus.cxx
+++ b/Source/kwsys/testStatus.cxx
@@ -31,6 +31,10 @@ int testStatus(int, char* [])
std::cerr << "Status Success constructor does not produce Success\n";
res = false;
}
+ if (!status.IsSuccess()) {
+ std::cerr << "Status Success gives false IsSuccess\n";
+ res = false;
+ }
if (!status) {
std::cerr << "Status Success kind is not true\n";
res = false;
@@ -55,6 +59,10 @@ int testStatus(int, char* [])
std::cerr << "Status POSIX constructor does not produce POSIX\n";
res = false;
}
+ if (status.IsSuccess()) {
+ std::cerr << "Status POSIX gives true IsSuccess\n";
+ res = false;
+ }
if (status) {
std::cerr << "Status POSIX kind is not false\n";
res = false;
@@ -87,6 +95,10 @@ int testStatus(int, char* [])
std::cerr << "Status Windows constructor does not produce Windows\n";
res = false;
}
+ if (status.IsSuccess()) {
+ std::cerr << "Status Windows gives true IsSuccess\n";
+ res = false;
+ }
if (status) {
std::cerr << "Status Windows kind is not false\n";
res = false;
diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx
index 39a19cb..6ccc7a7 100644
--- a/Source/kwsys/testSystemTools.cxx
+++ b/Source/kwsys/testSystemTools.cxx
@@ -436,7 +436,7 @@ static bool CheckFileOperations()
if (symlinkStatus.GetWindows() != ERROR_PRIVILEGE_NOT_HELD)
#endif
{
- if (!symlinkStatus) {
+ if (!symlinkStatus.IsSuccess()) {
std::cerr << "CreateSymlink for: " << testBadSymlink << " -> "
<< testBadSymlinkTgt
<< " failed: " << symlinkStatus.GetString() << std::endl;
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 341aba6..76c6c05 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -39,6 +39,13 @@ set(ENV{HOME} \"${TEST_HOME}\")
")
endif()
+# Suppress generator deprecation warnings in test suite.
+if(CMAKE_GENERATOR MATCHES "^Visual Studio 10 2010")
+ set(TEST_WARN_VS10_CODE "set(ENV{CMAKE_WARN_VS10} OFF)")
+else()
+ set(TEST_WARN_VS10_CODE "")
+endif()
+
# 3.9 or later provides a definitive answer to whether we are multi-config
# through a global property. Prior to 3.9, CMAKE_CONFIGURATION_TYPES being set
# is assumed to mean multi-config, but developers might modify it so it is
@@ -1442,6 +1449,7 @@ if(BUILD_TESTING)
GIF
Git
GLEW
+ GLUT
GnuTLS
GSL
GTK2
@@ -1640,6 +1648,53 @@ if(BUILD_TESTING)
WORKING_DIRECTORY ${CMake_SOURCE_DIR}/Tests/ExternalProjectUpdate
DEPENDS ExternalProjectUpdateSetup )
+ execute_process(
+ COMMAND ${CMAKE_COMMAND}
+ "-E" create_symlink
+ "${CMake_SOURCE_DIR}/Tests/CMakeLists.txt" # random source file that exists
+ "${CMake_BINARY_DIR}/Tests/try_to_create_symlink" # random target file in existing directory
+ RESULT_VARIABLE _symlink_result
+ )
+ if(_symlink_result EQUAL 0)
+ file(REMOVE "${CMake_BINARY_DIR}/Tests/try_to_create_symlink")
+ function(add_installmode_test _mode)
+ set(ENV{CMAKE_INSTALL_MODE} _mode)
+ set(_maybe_InstallMode_CTEST_OPTIONS)
+ set(_maybe_BUILD_OPTIONS)
+ if(_isMultiConfig)
+ set(_maybe_CTEST_OPTIONS -C $<CONFIGURATION>)
+ else()
+ set(_maybe_BUILD_OPTIONS "-DCMAKE_BUILD_TYPE=$<CONFIGURATION>")
+ endif()
+ add_test(
+ NAME "InstallMode-${_mode}"
+ COMMAND
+ ${CMAKE_CTEST_COMMAND} -V ${_maybe_CTEST_OPTIONS}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/InstallMode"
+ "${CMake_BINARY_DIR}/Tests/InstallMode-${_mode}"
+ ${build_generator_args}
+ --build-project superpro
+ --build-exe-dir "${CMake_BINARY_DIR}/Tests/InstallMode-${_mode}"
+ --force-new-ctest-process
+ --build-options
+ ${_maybe_BUILD_OPTIONS}
+ "-DCMAKE_INSTALL_PREFIX:PATH=${CMake_BINARY_DIR}/Tests/InstallMode-${_mode}/install"
+ )
+ list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/InstallMode-${_mode}")
+ unset(ENV{CMAKE_INSTALL_MODE})
+ endfunction()
+
+ add_installmode_test(COPY)
+ add_installmode_test(REL_SYMLINK)
+ add_installmode_test(REL_SYMLINK_OR_COPY)
+ add_installmode_test(ABS_SYMLINK)
+ add_installmode_test(ABS_SYMLINK_OR_COPY)
+ add_installmode_test(SYMLINK)
+ add_installmode_test(SYMLINK_OR_COPY)
+ endif()
+
+
# do each of the tutorial steps
function(add_tutorial_test step_name use_mymath tutorial_arg pass_regex)
set(tutorial_test_name Tutorial${step_name})
diff --git a/Tests/CMakeTests/CMakeLists.txt b/Tests/CMakeTests/CMakeLists.txt
index 52959e6..9e0b891 100644
--- a/Tests/CMakeTests/CMakeLists.txt
+++ b/Tests/CMakeTests/CMakeLists.txt
@@ -31,7 +31,6 @@ AddCMakeTest(CompilerIdVendor "")
AddCMakeTest(ProcessorCount "-DKWSYS_TEST_EXE=$<TARGET_FILE:cmsysTestsCxx>")
AddCMakeTest(PushCheckState "")
AddCMakeTest(While "")
-AddCMakeTest(CMakeHostSystemInformation "")
AddCMakeTest(FileDownload "")
set_tests_properties(CMake.FileDownload PROPERTIES
diff --git a/Tests/CPackNSISGenerator/CMakeLists.txt b/Tests/CPackNSISGenerator/CMakeLists.txt
index 64a8ef6..5d6320b 100644
--- a/Tests/CPackNSISGenerator/CMakeLists.txt
+++ b/Tests/CPackNSISGenerator/CMakeLists.txt
@@ -19,5 +19,6 @@ set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON)
set(CPACK_NSIS_MANIFEST_DPI_AWARE ON)
set(CPACK_NSIS_BRANDING_TEXT "CMake branding text")
set(CPACK_NSIS_BRANDING_TEXT_TRIM_POSITION "RIGHT")
+set(CPACK_NSIS_IGNORE_LICENSE_PAGE ON)
include(CPack)
diff --git a/Tests/CPackNSISGenerator/RunCPackVerifyResult.cmake b/Tests/CPackNSISGenerator/RunCPackVerifyResult.cmake
index 8bfcf26..31a2560 100644
--- a/Tests/CPackNSISGenerator/RunCPackVerifyResult.cmake
+++ b/Tests/CPackNSISGenerator/RunCPackVerifyResult.cmake
@@ -60,3 +60,12 @@ if("${output_index}" EQUAL "-1")
else()
message(STATUS "Found BrandingText")
endif()
+
+# license page should not be present
+file(STRINGS "${project_file}" line REGEX "!insertmacro MUI_PAGE_LICENSE")
+string(FIND "${line}" "MUI_PAGE_LICENSE" output_index)
+if("${output_index}" EQUAL "-1")
+ message(STATUS "License not found in the project")
+else()
+ message(FATAL_ERROR "License found in the project")
+endif()
diff --git a/Tests/CTestTestSerialInDepends/test.ctest b/Tests/CTestTestSerialInDepends/test.ctest
index 28ee094..cf0d314 100644
--- a/Tests/CTestTestSerialInDepends/test.ctest
+++ b/Tests/CTestTestSerialInDepends/test.ctest
@@ -2,6 +2,9 @@ set(CTEST_RUN_CURRENT_SCRIPT 0)
set(LOCK_FILE "${TEST_NAME}.lock")
+# Delete the old lock file in case it's lingering from a previous failed test run
+file(REMOVE "${LOCK_FILE}")
+
if("${TEST_NAME}" STREQUAL "i_want_to_be_alone")
file(GLOB LOCK_FILES *.lock)
if(LOCK_FILES)
diff --git a/Tests/Cuda/CMakeLists.txt b/Tests/Cuda/CMakeLists.txt
index be5ccac..669c412 100644
--- a/Tests/Cuda/CMakeLists.txt
+++ b/Tests/Cuda/CMakeLists.txt
@@ -4,7 +4,6 @@ macro (add_cuda_test_macro name)
PROPERTY LABELS "CUDA")
endmacro ()
-add_cuda_test_macro(Cuda.ConsumeCompileFeatures CudaConsumeCompileFeatures)
add_cuda_test_macro(Cuda.CXXStandardSetTwice CXXStandardSetTwice)
add_cuda_test_macro(Cuda.ObjectLibrary CudaObjectLibrary)
add_cuda_test_macro(Cuda.MixedStandardLevels1 MixedStandardLevels1)
diff --git a/Tests/Cuda/ConsumeCompileFeatures/CMakeLists.txt b/Tests/Cuda/ConsumeCompileFeatures/CMakeLists.txt
deleted file mode 100644
index b01b9d7..0000000
--- a/Tests/Cuda/ConsumeCompileFeatures/CMakeLists.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-cmake_minimum_required(VERSION 3.18)
-project(ConsumeCompileFeatures CXX CUDA)
-#Goal for this example:
-
-#build a c++11 library that express a c++11 public compile feature
-#link a cuda library and verify it builds with c++11 enabled
-
-#build a standalone c++/cuda mixed executable where we express a c++11
-#compile feature.
-
-
-add_library(CudaConsumeLib STATIC static.cpp static.cu)
-target_compile_features(CudaConsumeLib PUBLIC cxx_nullptr)
-
-add_executable(CudaConsumeCompileFeatures main.cu)
-target_link_libraries(CudaConsumeCompileFeatures PRIVATE CudaConsumeLib)
diff --git a/Tests/Cuda/ConsumeCompileFeatures/main.cu b/Tests/Cuda/ConsumeCompileFeatures/main.cu
deleted file mode 100644
index bc32450..0000000
--- a/Tests/Cuda/ConsumeCompileFeatures/main.cu
+++ /dev/null
@@ -1,20 +0,0 @@
-
-#include <iostream>
-
-int static_cxx11_func(int);
-
-void test_functions()
-{
- auto x = static_cxx11_func(int(42));
- std::cout << x << std::endl;
-}
-
-int main(int argc, char** argv)
-{
- test_functions();
- std::cout
- << "this executable doesn't use cuda code, just call methods defined"
- << std::endl;
- std::cout << "in libraries that have cuda code" << std::endl;
- return 0;
-}
diff --git a/Tests/Cuda/ConsumeCompileFeatures/static.cpp b/Tests/Cuda/ConsumeCompileFeatures/static.cpp
deleted file mode 100644
index 565d52e..0000000
--- a/Tests/Cuda/ConsumeCompileFeatures/static.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-#include <type_traits>
-
-int static_cuda11_func(int);
-
-int static_cxx11_func(int x)
-{
- return static_cuda11_func(x) + std::integral_constant<int, 32>::value;
-}
diff --git a/Tests/Cuda/ConsumeCompileFeatures/static.cu b/Tests/Cuda/ConsumeCompileFeatures/static.cu
deleted file mode 100644
index 73e43a8..0000000
--- a/Tests/Cuda/ConsumeCompileFeatures/static.cu
+++ /dev/null
@@ -1,9 +0,0 @@
-
-#include <type_traits>
-
-using tt = std::true_type;
-using ft = std::false_type;
-int __host__ static_cuda11_func(int x)
-{
- return x * x + std::integral_constant<int, 17>::value;
-}
diff --git a/Tests/EnforceConfig.cmake.in b/Tests/EnforceConfig.cmake.in
index 7781ded..7c6f76a 100644
--- a/Tests/EnforceConfig.cmake.in
+++ b/Tests/EnforceConfig.cmake.in
@@ -36,3 +36,4 @@ unset(ENV{CMAKE_GENERATOR_TOOLSET})
unset(ENV{CMAKE_EXPORT_COMPILE_COMMANDS})
@TEST_HOME_ENV_CODE@
+@TEST_WARN_VS10_CODE@
diff --git a/Tests/Environment/CMakeLists.txt b/Tests/Environment/CMakeLists.txt
index 2b18d24..17009bd 100644
--- a/Tests/Environment/CMakeLists.txt
+++ b/Tests/Environment/CMakeLists.txt
@@ -9,6 +9,7 @@ add_test(Environment1 Environment)
add_test(Environment2 Environment)
add_test(EchoEnvironment1 ${CMAKE_COMMAND} -E environment)
add_test(EchoEnvironment2 ${CMAKE_COMMAND} -E environment)
+add_test(EchoEnvironment3 ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_SOURCE_DIR}/check_mod.cmake")
# Make sure "CMAKE_ENV.*Happy Thanksgiving" is in the output of
# the "1" tests:
@@ -24,3 +25,37 @@ set_tests_properties(Environment1 EchoEnvironment1 PROPERTIES
set_tests_properties(Environment2 EchoEnvironment2 PROPERTIES
FAIL_REGULAR_EXPRESSION "CMAKE_ENV.*Happy Thanksgiving"
)
+
+set_property(TEST EchoEnvironment3
+ PROPERTY ENVIRONMENT_MODIFICATION
+ # Variables expected to be unset.
+ "UNSET_EXPLICIT=set:value"
+ "UNSET_EXPLICIT=unset:"
+ "UNSET_VIA_RESET=set:value"
+ "UNSET_VIA_RESET=reset:"
+
+ # Direct settings.
+ "DIRECT=set:old"
+ "DIRECT=set:new"
+
+ # String manipulation.
+ "STRING_MANIP=set:-core-"
+ "STRING_MANIP=string_append:post-"
+ "STRING_MANIP=string_prepend:-pre"
+ "STRING_MANIP=string_append:suffix"
+ "STRING_MANIP=string_prepend:prefix"
+
+ # Path manipulation.
+ "PATH_MANIP=set:core"
+ "PATH_MANIP=path_list_append:post"
+ "PATH_MANIP=path_list_prepend:pre"
+ "PATH_MANIP=path_list_append:suffix"
+ "PATH_MANIP=path_list_prepend:prefix"
+
+ # CMake list manipulation.
+ "CMAKE_LIST_MANIP=set:core"
+ "CMAKE_LIST_MANIP=cmake_list_append:post"
+ "CMAKE_LIST_MANIP=cmake_list_prepend:pre"
+ "CMAKE_LIST_MANIP=cmake_list_append:suffix"
+ "CMAKE_LIST_MANIP=cmake_list_prepend:prefix"
+)
diff --git a/Tests/Environment/check_mod.cmake b/Tests/Environment/check_mod.cmake
new file mode 100644
index 0000000..16d02f2
--- /dev/null
+++ b/Tests/Environment/check_mod.cmake
@@ -0,0 +1,55 @@
+execute_process(
+ COMMAND ${CMAKE_COMMAND} -E environment
+ OUTPUT_VARIABLE out
+ ERROR_VARIABLE err
+ RESULT_VARIABLE res)
+
+if (res)
+ message(FATAL_ERROR "Failed with exit code ${res}: ${err}")
+endif ()
+
+if (CMAKE_HOST_WIN32)
+ set(path_sep ";")
+else ()
+ set(path_sep ":")
+endif ()
+
+set(unexpect_UNSET_EXPLICIT "")
+set(unexpect_UNSET_VIA_RESET "")
+set(expect_DIRECT "new")
+set(expect_STRING_MANIP "prefix-pre-core-post-suffix")
+set(expect_PATH_MANIP "prefix${path_sep}pre${path_sep}core${path_sep}post${path_sep}suffix")
+set(expect_CMAKE_LIST_MANIP "prefix;pre;core;post;suffix")
+
+set(expected_vars
+ DIRECT
+ STRING_MANIP
+ PATH_MANIP
+ CMAKE_LIST_MANIP)
+
+while (out)
+ string(FIND "${out}" "\n" nl_pos)
+ string(SUBSTRING "${out}" 0 "${nl_pos}" line)
+ math(EXPR line_next "${nl_pos} + 1")
+ string(SUBSTRING "${out}" "${line_next}" -1 out)
+
+ string(FIND "${line}" "=" eq_pos)
+ string(SUBSTRING "${line}" 0 "${eq_pos}" name)
+ math(EXPR value_start "${eq_pos} + 1")
+ string(SUBSTRING "${line}" "${value_start}" -1 value)
+
+ if (DEFINED "unexpect_${name}")
+ message(SEND_ERROR "Found `${name}=${value}` when it should have been unset")
+ elseif (DEFINED "expect_${name}")
+ list(REMOVE_ITEM expected_vars "${name}")
+ if (expect_${name} STREQUAL value)
+ message(STATUS "Found `${name}=${value}` as expected")
+ else ()
+ message(SEND_ERROR "Found `${name}=${value}` when it should have been ${expect_${name}}")
+ endif ()
+ endif ()
+endwhile ()
+
+if (expected_vars)
+ message(SEND_ERROR "Did not test expected variables: ${expected_vars}")
+endif ()
diff --git a/Tests/FindGLUT/CMakeLists.txt b/Tests/FindGLUT/CMakeLists.txt
new file mode 100644
index 0000000..e75ec40
--- /dev/null
+++ b/Tests/FindGLUT/CMakeLists.txt
@@ -0,0 +1,9 @@
+add_test(NAME FindGLUT.Test COMMAND ${CMAKE_CTEST_COMMAND}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindGLUT/Test"
+ "${CMake_BINARY_DIR}/Tests/FindGLUT/Test"
+ ${build_generator_args}
+ --build-project TestFindGLUT
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V
+ )
diff --git a/Tests/FindGLUT/Test/CMakeLists.txt b/Tests/FindGLUT/Test/CMakeLists.txt
new file mode 100644
index 0000000..0f4e536
--- /dev/null
+++ b/Tests/FindGLUT/Test/CMakeLists.txt
@@ -0,0 +1,17 @@
+cmake_minimum_required(VERSION 3.21)
+project(TestFindGLUT C)
+include(CTest)
+
+find_package(GLUT REQUIRED)
+
+add_executable(testglut_tgt main.c)
+target_link_libraries(testglut_tgt GLUT::GLUT)
+add_test(NAME testglut_tgt COMMAND testglut_tgt)
+
+add_executable(testglut_var main.c)
+target_include_directories(testglut_var PRIVATE ${GLUT_INCLUDE_DIRS})
+target_link_libraries(testglut_var PRIVATE ${GLUT_LIBRARIES})
+add_test(NAME testglut_var COMMAND testglut_var)
+
+set_tests_properties(testglut_tgt testglut_var
+ PROPERTIES WILL_FAIL true)
diff --git a/Tests/FindGLUT/Test/main.c b/Tests/FindGLUT/Test/main.c
new file mode 100644
index 0000000..1c8569c
--- /dev/null
+++ b/Tests/FindGLUT/Test/main.c
@@ -0,0 +1,11 @@
+#include <GL/glut.h>
+#include <stdio.h>
+
+int main()
+{
+ /* The following should call exit(1) and print
+ freeglut ERROR: Function <glutCreateWindow> called
+ without first calling 'glutInit'.
+ to stderr */
+ glutCreateWindow("gluttest");
+}
diff --git a/Tests/IncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/CMakeLists.txt
index d4c19c7..4c488e6 100644
--- a/Tests/IncludeDirectories/CMakeLists.txt
+++ b/Tests/IncludeDirectories/CMakeLists.txt
@@ -2,17 +2,25 @@ cmake_minimum_required (VERSION 2.6)
project(IncludeDirectories)
if (((CMAKE_C_COMPILER_ID STREQUAL GNU AND CMAKE_C_COMPILER_VERSION VERSION_GREATER 4.4)
- OR (CMAKE_C_COMPILER_ID STREQUAL Clang AND NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC") OR CMAKE_C_COMPILER_ID STREQUAL AppleClang)
+ OR (CMAKE_C_COMPILER_ID STREQUAL Clang AND NOT "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
+ OR CMAKE_C_COMPILER_ID STREQUAL AppleClang
+ OR ("x${CMAKE_C_COMPILER_ID}" STREQUAL "xMSVC" AND
+ CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "19.29.30036.3" AND
+ NOT CMAKE_GENERATOR MATCHES "Visual Studio")) # No support for VS generators yet.
AND (CMAKE_GENERATOR STREQUAL "Unix Makefiles"
OR CMAKE_GENERATOR STREQUAL "Ninja"
OR (CMAKE_GENERATOR STREQUAL "Xcode" AND NOT XCODE_VERSION VERSION_LESS 6.0)))
- include(CheckCXXCompilerFlag)
- check_cxx_compiler_flag(-Wunused-variable run_sys_includes_test)
- if(run_sys_includes_test)
- # The Bullseye wrapper appears to break the -isystem effect.
- execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version OUTPUT_VARIABLE out ERROR_VARIABLE out)
- if("x${out}" MATCHES "Bullseye")
- set(run_sys_includes_test 0)
+ if ("x${CMAKE_C_COMPILER_ID}" STREQUAL "xMSVC")
+ set(run_sys_includes_test 1)
+ else ()
+ include(CheckCXXCompilerFlag)
+ check_cxx_compiler_flag(-Wunused-variable run_sys_includes_test)
+ if(run_sys_includes_test)
+ # The Bullseye wrapper appears to break the -isystem effect.
+ execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version OUTPUT_VARIABLE out ERROR_VARIABLE out)
+ if("x${out}" MATCHES "Bullseye")
+ set(run_sys_includes_test 0)
+ endif()
endif()
endif()
if (run_sys_includes_test)
diff --git a/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt
index dee39c8..a746a68 100644
--- a/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt
+++ b/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt
@@ -6,9 +6,17 @@ project(SystemIncludeDirectories)
add_library(systemlib systemlib.cpp)
target_include_directories(systemlib PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/systemlib")
+function (apply_error_flags target)
+ if (MSVC)
+ target_compile_options(${target} PRIVATE /we4101)
+ else ()
+ target_compile_options(${target} PRIVATE -Werror=unused-variable)
+ endif ()
+endfunction ()
+
add_library(upstream upstream.cpp)
target_link_libraries(upstream LINK_PUBLIC systemlib)
-target_compile_options(upstream PRIVATE -Werror=unused-variable)
+apply_error_flags(upstream)
target_include_directories(upstream SYSTEM PUBLIC
$<TARGET_PROPERTY:systemlib,INTERFACE_INCLUDE_DIRECTORIES>
@@ -29,7 +37,7 @@ endif()
add_library(consumer consumer.cpp)
target_link_libraries(consumer upstream config_specific)
-target_compile_options(consumer PRIVATE -Werror=unused-variable)
+apply_error_flags(consumer)
add_library(iface IMPORTED INTERFACE)
set_property(TARGET iface PROPERTY INTERFACE_INCLUDE_DIRECTORIES
@@ -38,21 +46,21 @@ set_property(TARGET iface PROPERTY INTERFACE_INCLUDE_DIRECTORIES
add_library(imported_consumer imported_consumer.cpp)
target_link_libraries(imported_consumer iface)
-target_compile_options(imported_consumer PRIVATE -Werror=unused-variable)
+apply_error_flags(imported_consumer)
add_library(imported_consumer2 imported_consumer.cpp)
target_link_libraries(imported_consumer2 imported_consumer)
-target_compile_options(imported_consumer2 PRIVATE -Werror=unused-variable)
+apply_error_flags(imported_consumer2)
# add a target which has a relative system include
add_library(somelib imported_consumer.cpp)
target_include_directories(somelib SYSTEM PUBLIC "systemlib_header_only")
-target_compile_options(somelib PRIVATE -Werror=unused-variable)
+apply_error_flags(somelib)
# add a target which consumes a relative system include
add_library(otherlib upstream.cpp)
target_link_libraries(otherlib PUBLIC somelib)
-target_compile_options(somelib PRIVATE -Werror=unused-variable)
+apply_error_flags(otherlib)
macro(do_try_compile error_option)
set(TC_ARGS
@@ -61,7 +69,11 @@ macro(do_try_compile error_option)
LINK_LIBRARIES iface
)
if (${error_option} STREQUAL WITH_ERROR)
- list(APPEND TC_ARGS COMPILE_DEFINITIONS -Werror=unused-variable)
+ if (MSVC)
+ list(APPEND TC_ARGS COMPILE_DEFINITIONS /we4101)
+ else ()
+ list(APPEND TC_ARGS COMPILE_DEFINITIONS -Werror=unused-variable)
+ endif ()
endif()
try_compile(${TC_ARGS})
endmacro()
diff --git a/Tests/IncludeDirectories/SystemIncludeDirectories/consumer.cpp b/Tests/IncludeDirectories/SystemIncludeDirectories/consumer.cpp
index a13f08f..3da308d 100644
--- a/Tests/IncludeDirectories/SystemIncludeDirectories/consumer.cpp
+++ b/Tests/IncludeDirectories/SystemIncludeDirectories/consumer.cpp
@@ -1,5 +1,6 @@
-#include "config_iface.h"
+#include <config_iface.h>
+
#include "upstream.h"
int consumer()
diff --git a/Tests/IncludeDirectories/SystemIncludeDirectories/imported_consumer.cpp b/Tests/IncludeDirectories/SystemIncludeDirectories/imported_consumer.cpp
index 1dbe819..53759b1 100644
--- a/Tests/IncludeDirectories/SystemIncludeDirectories/imported_consumer.cpp
+++ b/Tests/IncludeDirectories/SystemIncludeDirectories/imported_consumer.cpp
@@ -1,5 +1,5 @@
-#include "systemlib.h"
+#include <systemlib.h>
int main()
{
diff --git a/Tests/IncludeDirectories/SystemIncludeDirectories/upstream.h b/Tests/IncludeDirectories/SystemIncludeDirectories/upstream.h
index a670c2a..3daf69e 100644
--- a/Tests/IncludeDirectories/SystemIncludeDirectories/upstream.h
+++ b/Tests/IncludeDirectories/SystemIncludeDirectories/upstream.h
@@ -2,7 +2,7 @@
#ifndef UPSTREAM_H
#define UPSTREAM_H
-#include "systemlib.h"
+#include <systemlib.h>
#ifdef _WIN32
__declspec(dllexport)
diff --git a/Tests/IncludeDirectories/SystemIncludeDirectoriesPerLang/CMakeLists.txt b/Tests/IncludeDirectories/SystemIncludeDirectoriesPerLang/CMakeLists.txt
index 70dfa01..5d58633 100644
--- a/Tests/IncludeDirectories/SystemIncludeDirectoriesPerLang/CMakeLists.txt
+++ b/Tests/IncludeDirectories/SystemIncludeDirectoriesPerLang/CMakeLists.txt
@@ -7,14 +7,14 @@ set_target_properties(c_interface PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "$<$<COMPILE_LANGUAGE:C>:${CMAKE_CURRENT_SOURCE_DIR}>"
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "$<$<COMPILE_LANGUAGE:C>:${CMAKE_CURRENT_SOURCE_DIR}>"
)
-target_compile_options(c_interface INTERFACE "$<$<COMPILE_LANG_AND_ID:C,GNU,Clang>:-Werror=unused-variable>")
+target_compile_options(c_interface INTERFACE "$<$<COMPILE_LANG_AND_ID:C,GNU,Clang>:-Werror=unused-variable>;$<$<COMPILE_LANG_AND_ID:C,MSVC>:/we4101>")
add_library(cxx_interface INTERFACE)
set_target_properties(cxx_interface PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "$<$<COMPILE_LANGUAGE:CXX>:${CMAKE_CURRENT_SOURCE_DIR}/cxx_system_include>"
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "$<$<COMPILE_LANGUAGE:CXX>:${CMAKE_CURRENT_SOURCE_DIR}/cxx_system_include>"
)
-target_compile_options(cxx_interface INTERFACE "$<$<COMPILE_LANG_AND_ID:CXX,GNU,Clang>:-Werror=unused-variable>")
+target_compile_options(cxx_interface INTERFACE "$<$<COMPILE_LANG_AND_ID:CXX,GNU,Clang>:-Werror=unused-variable>;$<$<COMPILE_LANG_AND_ID:C,MSVC>:/we4101>")
# The C header must come before the C++ header for this test to smoke out the
# failure. The order of sources is how CMake determines the include cache
diff --git a/Tests/InstallMode/CMakeLists.txt b/Tests/InstallMode/CMakeLists.txt
new file mode 100644
index 0000000..96c83a0
--- /dev/null
+++ b/Tests/InstallMode/CMakeLists.txt
@@ -0,0 +1,124 @@
+cmake_minimum_required(VERSION 3.20.0)
+
+project(superpro LANGUAGES NONE)
+
+add_subdirectory(superpro)
+
+include(Subproject.cmake)
+add_subproject(static_lib DIR subpro_a_static_lib)
+add_subproject(shared_lib DIR subpro_b_shared_lib)
+add_subproject(nested_lib DIR subpro_c_nested_lib NO_INSTALL)
+add_subproject(executable DIR subpro_d_executable
+ DEPENDS
+ static_lib
+ shared_lib
+ nested_lib
+)
+
+include(CTest)
+if(BUILD_TESTING)
+ enable_language(CXX) # required by GNUInstallDirs
+ include(GNUInstallDirs)
+
+ macro(testme _name _path _symlink)
+ add_test(
+ NAME "${_name}"
+ WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
+ COMMAND
+ "${CMAKE_COMMAND}"
+ "-DFILE_PATH=${CMAKE_INSTALL_PREFIX}/${_path}"
+ "-DEXPECT_SYMLINK:BOOL=${_symlink}"
+ "-DEXPECT_ABSOLUTE:BOOL=${ARGN}"
+ "-P" "${CMAKE_SOURCE_DIR}/Test.cmake"
+ )
+ endmacro()
+
+ set(_mode $ENV{CMAKE_INSTALL_MODE})
+ if(NOT "${_mode}" OR "${_mode}" STREQUAL "COPY")
+ set(expect_symlink NO)
+ elseif("${_mode}" MATCHES "(REL_)?SYMLINK(_OR_COPY)?")
+ set(expect_symlink YES)
+ set(expect_absolute NO)
+ elseif("${_mode}" MATCHES "ABS_SYMLINK(_OR_COPY)?")
+ set(expect_symlink YES)
+ set(expect_absolute YES)
+ endif()
+
+ # toplevel project should respect CMAKE_INSTALL_MODE
+
+ testme(superproj_file_copy
+ "file_copy.txt" NO)
+ testme(superproj_file_copy_file
+ "file_copy_file.txt" NO)
+ testme(superproj_file_install
+ "file_install.txt"
+ ${expect_symlink}
+ ${expect_absolute})
+ testme(superproj_file_create_link_symbolic
+ "file_create_link_symbolic.txt" YES YES)
+
+ # subprojects should receive and respect CMAKE_INSTALL_MODE too
+
+ testme(subpro_a_static_lib_header
+ "${CMAKE_INSTALL_INCLUDEDIR}/static_lib.h"
+ ${expect_symlink}
+ ${expect_absolute}
+ )
+ testme(subpro_a_static_lib_libfile
+ "${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}the_static_lib${CMAKE_STATIC_LIBRARY_SUFFIX}"
+ ${expect_symlink}
+ ${expect_absolute}
+ )
+
+ testme(subpro_b_shared_lib_header
+ "${CMAKE_INSTALL_INCLUDEDIR}/shared_lib.h"
+ ${expect_symlink}
+ ${expect_absolute}
+ )
+
+ if(CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG AND
+ "${CMAKE_CXX_CREATE_SHARED_MODULE}" MATCHES "SONAME_FLAG")
+ # due to semver, this is always a link
+ testme(subpro_b_shared_lib_libfile
+ "${CMAKE_INSTALL_LIBDIR}/${CMAKE_SHARED_LIBRARY_PREFIX}the_shared_lib${CMAKE_SHARED_LIBRARY_SUFFIX}"
+ YES
+ ${expect_absolute}
+ )
+ # this is the actual shared lib, so should follow CMAKE_INSTALL_MODE rules
+ testme(subpro_b_shared_lib_libfile_versuffix
+ "${CMAKE_INSTALL_LIBDIR}/${CMAKE_SHARED_LIBRARY_PREFIX}the_shared_lib${CMAKE_SHARED_LIBRARY_SUFFIX}.2.3.4"
+ ${expect_symlink}
+ ${expect_absolute}
+ )
+ endif()
+
+ testme(subpro_d_executable_exefile
+ "${CMAKE_INSTALL_BINDIR}/the_executable${CMAKE_EXECUTABLE_SUFFIX}"
+ ${expect_symlink}
+ ${expect_absolute}
+ )
+
+ # nested subprojects should receive and respect CMAKE_INSTALL_MODE too
+
+ testme(subsubpro_c1_header
+ "${CMAKE_INSTALL_INCLUDEDIR}/c1_lib.h"
+ ${expect_symlink}
+ ${expect_absolute}
+ )
+ testme(subsubpro_c1_libfile
+ "${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}the_c1_lib${CMAKE_STATIC_LIBRARY_SUFFIX}"
+ ${expect_symlink}
+ ${expect_absolute}
+ )
+
+ testme(subsubpro_c2_header
+ "${CMAKE_INSTALL_INCLUDEDIR}/c2_lib.h"
+ ${expect_symlink}
+ ${expect_absolute}
+ )
+ testme(subsubpro_c2_libfile
+ "${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}the_c2_lib${CMAKE_STATIC_LIBRARY_SUFFIX}"
+ ${expect_symlink}
+ ${expect_absolute}
+ )
+endif()
diff --git a/Tests/InstallMode/README.txt b/Tests/InstallMode/README.txt
new file mode 100644
index 0000000..a4316eb
--- /dev/null
+++ b/Tests/InstallMode/README.txt
@@ -0,0 +1,43 @@
+This is an example superbuild project to demonstrate the use of the
+CMAKE_INSTALL_MODE environment variable on.
+
+The project hierarchy is like (B = Builds / D = Link Dependency):
+
++---------------------------------------------------------------------+
+| Superbuild (Top) |
++---------------------------------------------------------------------+
+ | | | |
+ | | | |
+ (B) (B) (B) (B)
+ | | | |
+ v v v v
++---------------+ +---------------+ +---------------+ +---------------+
+| A: Static Lib | | B: Shared Lib | | C: Nested | | D: Executable |
+| Project | | Project | | Superbuild | | Project |
++---------------+ +---------------+ +---------------+ +---------------+
+ ^ ^ | | | | |
+ | | (B) (B) | | |
+ | | | | | | |
+ | | v | | | |
+ | | +----------------+ | | | |
+ | | | C1: Static Lib | | | | |
+ | | | Project | | (D) (D) (D)
+ | | +----------------+ | | | |
+ | | ^ | | | |
+ | | | v | | |
+ | | (D) +----------------+ | | |
+ | | | | C2: Static Lib |<---+ | |
+ | | +--| Project | | |
+ | | +----------------+ | |
+ | | | |
+ | +------------------------------------+ |
+ | |
+ +--------------------------------------------------------+
+
+The superbuild system is built on top of ExternalProject_Add().
+
+NOTE that the subprojects will configure, build and install
+during the build phase ('make') of the top-level project.
+There is no install target in the top-level project!
+The CMAKE_INSTALL_PREFIX is therefore populated during the build
+phase already.
diff --git a/Tests/InstallMode/Subproject.cmake b/Tests/InstallMode/Subproject.cmake
new file mode 100644
index 0000000..826e61e
--- /dev/null
+++ b/Tests/InstallMode/Subproject.cmake
@@ -0,0 +1,73 @@
+include(ExternalProject)
+
+# add_subproject(<name> [NO_INSTALL] [DIR <dirname>] [DEPENDS [subpro_dep ...]])
+function(add_subproject _name)
+ cmake_parse_arguments(_arg "NO_INSTALL" "DIR" "DEPENDS" ${ARGN})
+
+ if(_arg_UNPARSED_ARGUMENTS)
+ message(FATAL_ERROR "There are unparsed arguments")
+ endif()
+
+ set(_maybe_NO_INSTALL)
+ if(_arg_NO_INSTALL)
+ set(_maybe_NO_INSTALL INSTALL_COMMAND "")
+ endif()
+
+ if(CMAKE_GENERATOR MATCHES "Ninja Multi-Config")
+ # Replace list separator before passing on to ExternalProject_Add
+ string(REPLACE ";" "|" _CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}")
+ string(REPLACE ";" "|" _CROSS_CONFIGS "${CMAKE_CROSS_CONFIGS}")
+ string(REPLACE ";" "|" _DEFAULT_CONFIGS "${CMAKE_DEFAULT_CONFIGS}")
+
+ set(_maybe_NINJA_MULTICONFIG_ARGS
+ "-DCMAKE_CONFIGURATION_TYPES:STRINGS=${_CONFIGURATION_TYPES}"
+ "-DCMAKE_CROSS_CONFIGS:STRINGS=${_CROSS_CONFIGS}"
+ "-DCMAKE_DEFAULT_BUILD_TYPE:STRING=${CMAKE_DEFAULT_BUILD_TYPE}"
+ "-DCMAKE_DEFAULT_CONFIGS:STRINGS=${_DEFAULT_CONFIGS}"
+ )
+ endif()
+
+ ExternalProject_Add("${_name}"
+ DOWNLOAD_COMMAND ""
+ UPDATE_COMMAND ""
+ UPDATE_DISCONNECTED ON
+
+ "${_maybe_NO_INSTALL}"
+
+ BUILD_ALWAYS ON
+
+ LOG_DOWNLOAD OFF
+ LOG_UPDATE OFF
+ LOG_PATCH OFF
+ LOG_CONFIGURE OFF
+ LOG_BUILD OFF
+ LOG_INSTALL OFF
+
+ SOURCE_DIR "${PROJECT_SOURCE_DIR}/${_arg_DIR}"
+
+ # Private build directory per subproject
+ BINARY_DIR "${PROJECT_BINARY_DIR}/subproject/${_arg_DIR}"
+
+ # Common install directory, populated immediately
+ # during build (during build - not install - of superproject)
+ INSTALL_DIR "${CMAKE_INSTALL_PREFIX}"
+
+ DEPENDS
+ ${_arg_DEPENDS}
+
+ LIST_SEPARATOR "|"
+ CMAKE_ARGS
+ "-DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>"
+
+ # We can rely on ExternalProject to pick the right
+ # generator (and architecture/toolset where applicable),
+ # however, we need to explicitly inherit other parent
+ # project's build settings.
+ "-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}"
+ "${_maybe_NINJA_MULTICONFIG_ARGS}"
+
+ # Subproject progress reports clutter up the output, disable
+ "-DCMAKE_TARGET_MESSAGES:BOOL=OFF"
+ "-DCMAKE_RULE_MESSAGES:BOOL=OFF"
+ )
+endfunction()
diff --git a/Tests/InstallMode/Test.cmake b/Tests/InstallMode/Test.cmake
new file mode 100644
index 0000000..46c8fa1
--- /dev/null
+++ b/Tests/InstallMode/Test.cmake
@@ -0,0 +1,38 @@
+message("Testing...")
+message("FILE_PATH = ${FILE_PATH}")
+message("EXPECT_SYMLINK = ${EXPECT_SYMLINK}")
+message("EXPECT_ABSOLUTE = ${EXPECT_ABSOLUTE}")
+
+if(NOT DEFINED FILE_PATH)
+ message(FATAL_ERROR "FILE_PATH variable must be defined")
+endif()
+
+if(NOT EXISTS "${FILE_PATH}")
+ message(FATAL_ERROR "File ${FILE_PATH} does not exist")
+endif()
+
+if(NOT DEFINED EXPECT_SYMLINK)
+ message(FATAL_ERROR "EXPECT_SYMLINK must be defined")
+endif()
+
+if(EXPECT_SYMLINK)
+ if(NOT DEFINED EXPECT_ABSOLUTE)
+ message(FATAL_ERROR "EXPECT_ABSOLUTE variable must be defined")
+ endif()
+
+ if(NOT IS_SYMLINK "${FILE_PATH}")
+ message(FATAL_ERROR "${FILE_PATH} must be a symlink")
+ endif()
+
+ file(READ_SYMLINK "${FILE_PATH}" TARGET_PATH)
+
+ if(EXPECT_ABSOLUTE AND NOT IS_ABSOLUTE "${TARGET_PATH}")
+ message(FATAL_ERROR "${FILE_PATH} must be an absolute symlink")
+ elseif(NOT EXPECT_ABSOLUTE AND IS_ABSOLUTE "${TARGET_PATH}")
+ message(FATAL_ERROR "${FILE_PATH} must be a relative symlink")
+ endif()
+else()
+ if(IS_SYMLINK "${FILE_PATH}")
+ message(FATAL_ERROR "${FILE_PATH} must NOT be a symlink")
+ endif()
+endif()
diff --git a/Tests/InstallMode/subpro_a_static_lib/CMakeLists.txt b/Tests/InstallMode/subpro_a_static_lib/CMakeLists.txt
new file mode 100644
index 0000000..7cd32cc
--- /dev/null
+++ b/Tests/InstallMode/subpro_a_static_lib/CMakeLists.txt
@@ -0,0 +1,60 @@
+# This CMakeLists.txt is part of the subproject A (ExternalProject_Add).
+
+cmake_minimum_required(VERSION 3.20)
+project(static_lib_project VERSION 1.2.3 LANGUAGES CXX)
+
+include(GNUInstallDirs)
+
+add_library(the_static_lib STATIC
+ "include/static_lib.h"
+ "src/static_lib.cpp"
+)
+
+target_include_directories(the_static_lib PUBLIC
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
+ $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
+)
+
+install(
+ DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/"
+ DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
+)
+
+install(
+ TARGETS
+ the_static_lib
+ EXPORT main
+ ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+ LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+)
+
+set(INSTALL_CMAKE_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
+
+include(CMakePackageConfigHelpers)
+
+configure_package_config_file(
+ "cmake/PackageConfig.cmake.in"
+ "${PROJECT_NAME}Config.cmake"
+ INSTALL_DESTINATION "${INSTALL_CMAKE_DIR}"
+ PATH_VARS
+ CMAKE_INSTALL_INCLUDEDIR
+ CMAKE_INSTALL_LIBDIR
+)
+
+write_basic_package_version_file("${PROJECT_NAME}Version.cmake"
+ VERSION "${PROJECT_VERSION}"
+ COMPATIBILITY SameMajorVersion
+)
+
+install(
+ EXPORT main
+ FILE "${PROJECT_NAME}Targets.cmake"
+ DESTINATION "${INSTALL_CMAKE_DIR}"
+)
+
+install(
+ FILES
+ "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
+ "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Version.cmake"
+ DESTINATION "${INSTALL_CMAKE_DIR}"
+)
diff --git a/Tests/InstallMode/subpro_a_static_lib/cmake/PackageConfig.cmake.in b/Tests/InstallMode/subpro_a_static_lib/cmake/PackageConfig.cmake.in
new file mode 100644
index 0000000..0fe72c9
--- /dev/null
+++ b/Tests/InstallMode/subpro_a_static_lib/cmake/PackageConfig.cmake.in
@@ -0,0 +1,8 @@
+set(@PROJECT_NAME@_VERSION @PROJECT_VERSION@)
+
+@PACKAGE_INIT@
+
+include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
+
+set_and_check(@PROJECT_NAME@_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@")
+set_and_check(@PROJECT_NAME@_LIB_DIR "@PACKAGE_CMAKE_INSTALL_LIBDIR@")
diff --git a/Tests/InstallMode/subpro_a_static_lib/include/static_lib.h b/Tests/InstallMode/subpro_a_static_lib/include/static_lib.h
new file mode 100644
index 0000000..bd82d2e
--- /dev/null
+++ b/Tests/InstallMode/subpro_a_static_lib/include/static_lib.h
@@ -0,0 +1,3 @@
+#pragma once
+
+void static_hello();
diff --git a/Tests/InstallMode/subpro_a_static_lib/src/static_lib.cpp b/Tests/InstallMode/subpro_a_static_lib/src/static_lib.cpp
new file mode 100644
index 0000000..fe1cd85
--- /dev/null
+++ b/Tests/InstallMode/subpro_a_static_lib/src/static_lib.cpp
@@ -0,0 +1,10 @@
+#include <iostream>
+
+#include <static_lib.h>
+
+using namespace std;
+
+void static_hello()
+{
+ cout << "Hello from static_lib" << endl;
+}
diff --git a/Tests/InstallMode/subpro_b_shared_lib/CMakeLists.txt b/Tests/InstallMode/subpro_b_shared_lib/CMakeLists.txt
new file mode 100644
index 0000000..b3d9cb2
--- /dev/null
+++ b/Tests/InstallMode/subpro_b_shared_lib/CMakeLists.txt
@@ -0,0 +1,75 @@
+# This CMakeLists.txt is part of the subproject B (ExternalProject_Add).
+
+cmake_minimum_required(VERSION 3.20)
+project(shared_lib_project VERSION 2.3.4 LANGUAGES CXX)
+
+include(GNUInstallDirs)
+include(GenerateExportHeader)
+
+add_library(the_shared_lib SHARED
+ "include/shared_lib.h"
+ "src/shared_lib.cpp"
+)
+
+generate_export_header(the_shared_lib
+ BASE_NAME shared_lib
+ EXPORT_FILE_NAME include/shared_lib_export.h
+)
+
+set_target_properties(the_shared_lib
+ PROPERTIES
+ VERSION "${PROJECT_VERSION}"
+ SOVERSION "${PROJECT_VERSION}"
+)
+
+target_include_directories(the_shared_lib PUBLIC
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>
+ $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
+)
+
+install(
+ DIRECTORY
+ "${CMAKE_CURRENT_SOURCE_DIR}/include/"
+ "${CMAKE_CURRENT_BINARY_DIR}/include/"
+ DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
+)
+
+install(
+ TARGETS
+ the_shared_lib
+ EXPORT main
+ ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+ LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+)
+
+set(INSTALL_CMAKE_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
+
+include(CMakePackageConfigHelpers)
+
+configure_package_config_file(
+ "cmake/PackageConfig.cmake.in"
+ "${PROJECT_NAME}Config.cmake"
+ INSTALL_DESTINATION "${INSTALL_CMAKE_DIR}"
+ PATH_VARS
+ CMAKE_INSTALL_INCLUDEDIR
+ CMAKE_INSTALL_LIBDIR
+)
+
+write_basic_package_version_file("${PROJECT_NAME}Version.cmake"
+ VERSION "${PROJECT_VERSION}"
+ COMPATIBILITY SameMajorVersion
+)
+
+install(
+ EXPORT main
+ FILE "${PROJECT_NAME}Targets.cmake"
+ DESTINATION "${INSTALL_CMAKE_DIR}"
+)
+
+install(
+ FILES
+ "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
+ "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Version.cmake"
+ DESTINATION "${INSTALL_CMAKE_DIR}"
+)
diff --git a/Tests/InstallMode/subpro_b_shared_lib/cmake/PackageConfig.cmake.in b/Tests/InstallMode/subpro_b_shared_lib/cmake/PackageConfig.cmake.in
new file mode 100644
index 0000000..0fe72c9
--- /dev/null
+++ b/Tests/InstallMode/subpro_b_shared_lib/cmake/PackageConfig.cmake.in
@@ -0,0 +1,8 @@
+set(@PROJECT_NAME@_VERSION @PROJECT_VERSION@)
+
+@PACKAGE_INIT@
+
+include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
+
+set_and_check(@PROJECT_NAME@_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@")
+set_and_check(@PROJECT_NAME@_LIB_DIR "@PACKAGE_CMAKE_INSTALL_LIBDIR@")
diff --git a/Tests/InstallMode/subpro_b_shared_lib/include/shared_lib.h b/Tests/InstallMode/subpro_b_shared_lib/include/shared_lib.h
new file mode 100644
index 0000000..550b2b4
--- /dev/null
+++ b/Tests/InstallMode/subpro_b_shared_lib/include/shared_lib.h
@@ -0,0 +1,5 @@
+#pragma once
+
+#include <shared_lib_export.h>
+
+void SHARED_LIB_EXPORT shared_hello();
diff --git a/Tests/InstallMode/subpro_b_shared_lib/src/shared_lib.cpp b/Tests/InstallMode/subpro_b_shared_lib/src/shared_lib.cpp
new file mode 100644
index 0000000..2820d5d
--- /dev/null
+++ b/Tests/InstallMode/subpro_b_shared_lib/src/shared_lib.cpp
@@ -0,0 +1,10 @@
+#include <iostream>
+
+#include <shared_lib.h>
+
+using namespace std;
+
+void shared_hello()
+{
+ cout << "Hello from shared_lib" << endl;
+}
diff --git a/Tests/InstallMode/subpro_c_nested_lib/CMakeLists.txt b/Tests/InstallMode/subpro_c_nested_lib/CMakeLists.txt
new file mode 100644
index 0000000..e397c02
--- /dev/null
+++ b/Tests/InstallMode/subpro_c_nested_lib/CMakeLists.txt
@@ -0,0 +1,10 @@
+cmake_minimum_required(VERSION 3.20.0)
+
+project(subpro_c_nested_lib LANGUAGES NONE)
+
+include(../Subproject.cmake)
+add_subproject(c1_lib DIR subsubpro_c1_lib)
+add_subproject(c2_lib DIR subsubpro_c2_lib
+ DEPENDS
+ c1_lib
+)
diff --git a/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c1_lib/CMakeLists.txt b/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c1_lib/CMakeLists.txt
new file mode 100644
index 0000000..89f3755
--- /dev/null
+++ b/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c1_lib/CMakeLists.txt
@@ -0,0 +1,61 @@
+# This CMakeLists.txt is a nested subproject of the
+# subproject C (ExternalProject_Add).
+
+cmake_minimum_required(VERSION 3.20)
+project(c1_lib_project VERSION 1.2.3 LANGUAGES CXX)
+
+include(GNUInstallDirs)
+
+add_library(the_c1_lib STATIC
+ "include/c1_lib.h"
+ "src/c1_lib.cpp"
+)
+
+target_include_directories(the_c1_lib PUBLIC
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
+ $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
+)
+
+install(
+ DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/"
+ DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
+)
+
+install(
+ TARGETS
+ the_c1_lib
+ EXPORT main
+ ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+ LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+)
+
+set(INSTALL_CMAKE_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
+
+include(CMakePackageConfigHelpers)
+
+configure_package_config_file(
+ "cmake/PackageConfig.cmake.in"
+ "${PROJECT_NAME}Config.cmake"
+ INSTALL_DESTINATION "${INSTALL_CMAKE_DIR}"
+ PATH_VARS
+ CMAKE_INSTALL_INCLUDEDIR
+ CMAKE_INSTALL_LIBDIR
+)
+
+write_basic_package_version_file("${PROJECT_NAME}Version.cmake"
+ VERSION "${PROJECT_VERSION}"
+ COMPATIBILITY SameMajorVersion
+)
+
+install(
+ EXPORT main
+ FILE "${PROJECT_NAME}Targets.cmake"
+ DESTINATION "${INSTALL_CMAKE_DIR}"
+)
+
+install(
+ FILES
+ "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
+ "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Version.cmake"
+ DESTINATION "${INSTALL_CMAKE_DIR}"
+)
diff --git a/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c1_lib/cmake/PackageConfig.cmake.in b/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c1_lib/cmake/PackageConfig.cmake.in
new file mode 100644
index 0000000..0fe72c9
--- /dev/null
+++ b/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c1_lib/cmake/PackageConfig.cmake.in
@@ -0,0 +1,8 @@
+set(@PROJECT_NAME@_VERSION @PROJECT_VERSION@)
+
+@PACKAGE_INIT@
+
+include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
+
+set_and_check(@PROJECT_NAME@_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@")
+set_and_check(@PROJECT_NAME@_LIB_DIR "@PACKAGE_CMAKE_INSTALL_LIBDIR@")
diff --git a/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c1_lib/include/c1_lib.h b/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c1_lib/include/c1_lib.h
new file mode 100644
index 0000000..245f9d4
--- /dev/null
+++ b/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c1_lib/include/c1_lib.h
@@ -0,0 +1,3 @@
+#pragma once
+
+void c1_hello();
diff --git a/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c1_lib/src/c1_lib.cpp b/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c1_lib/src/c1_lib.cpp
new file mode 100644
index 0000000..c405056
--- /dev/null
+++ b/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c1_lib/src/c1_lib.cpp
@@ -0,0 +1,10 @@
+#include <iostream>
+
+#include <c1_lib.h>
+
+using namespace std;
+
+void c1_hello()
+{
+ cout << "Hello from c1_lib" << endl;
+}
diff --git a/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c2_lib/CMakeLists.txt b/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c2_lib/CMakeLists.txt
new file mode 100644
index 0000000..7580c77
--- /dev/null
+++ b/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c2_lib/CMakeLists.txt
@@ -0,0 +1,71 @@
+# This CMakeLists.txt is a nested subproject of the
+# subproject C (ExternalProject_Add).
+
+cmake_minimum_required(VERSION 3.20)
+project(c2_lib_project VERSION 1.2.3 LANGUAGES CXX)
+
+find_package(c1_lib_project REQUIRED)
+
+include(GNUInstallDirs)
+
+add_library(the_c2_lib STATIC
+ "include/c2_lib.h"
+ "src/c2_lib.cpp"
+)
+
+target_link_libraries(the_c2_lib
+ PUBLIC
+ the_c1_lib
+)
+
+# This is to fix an issue on AIX/GCC (see commit 4fc47424)
+set_property(TARGET the_c2_lib PROPERTY NO_SYSTEM_FROM_IMPORTED 1)
+
+target_include_directories(the_c2_lib PUBLIC
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
+ $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
+)
+
+install(
+ DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/"
+ DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
+)
+
+install(
+ TARGETS
+ the_c2_lib
+ EXPORT main
+ ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+ LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+)
+
+set(INSTALL_CMAKE_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
+
+include(CMakePackageConfigHelpers)
+
+configure_package_config_file(
+ "cmake/PackageConfig.cmake.in"
+ "${PROJECT_NAME}Config.cmake"
+ INSTALL_DESTINATION "${INSTALL_CMAKE_DIR}"
+ PATH_VARS
+ CMAKE_INSTALL_INCLUDEDIR
+ CMAKE_INSTALL_LIBDIR
+)
+
+write_basic_package_version_file("${PROJECT_NAME}Version.cmake"
+ VERSION "${PROJECT_VERSION}"
+ COMPATIBILITY SameMajorVersion
+)
+
+install(
+ EXPORT main
+ FILE "${PROJECT_NAME}Targets.cmake"
+ DESTINATION "${INSTALL_CMAKE_DIR}"
+)
+
+install(
+ FILES
+ "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
+ "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Version.cmake"
+ DESTINATION "${INSTALL_CMAKE_DIR}"
+)
diff --git a/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c2_lib/cmake/PackageConfig.cmake.in b/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c2_lib/cmake/PackageConfig.cmake.in
new file mode 100644
index 0000000..45a177a
--- /dev/null
+++ b/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c2_lib/cmake/PackageConfig.cmake.in
@@ -0,0 +1,11 @@
+set(@PROJECT_NAME@_VERSION @PROJECT_VERSION@)
+
+@PACKAGE_INIT@
+
+include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
+
+set_and_check(@PROJECT_NAME@_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@")
+set_and_check(@PROJECT_NAME@_LIB_DIR "@PACKAGE_CMAKE_INSTALL_LIBDIR@")
+
+include(CMakeFindDependencyMacro)
+find_dependency(c1_lib_project REQUIRED)
diff --git a/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c2_lib/include/c2_lib.h b/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c2_lib/include/c2_lib.h
new file mode 100644
index 0000000..5056814
--- /dev/null
+++ b/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c2_lib/include/c2_lib.h
@@ -0,0 +1,3 @@
+#pragma once
+
+void c2_hello();
diff --git a/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c2_lib/src/c2_lib.cpp b/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c2_lib/src/c2_lib.cpp
new file mode 100644
index 0000000..cd2c932
--- /dev/null
+++ b/Tests/InstallMode/subpro_c_nested_lib/subsubpro_c2_lib/src/c2_lib.cpp
@@ -0,0 +1,12 @@
+#include <iostream>
+
+#include <c1_lib.h>
+#include <c2_lib.h>
+
+using namespace std;
+
+void c2_hello()
+{
+ cout << "Hello from c2_lib and also..." << endl;
+ c1_hello();
+}
diff --git a/Tests/InstallMode/subpro_d_executable/CMakeLists.txt b/Tests/InstallMode/subpro_d_executable/CMakeLists.txt
new file mode 100644
index 0000000..60189e2
--- /dev/null
+++ b/Tests/InstallMode/subpro_d_executable/CMakeLists.txt
@@ -0,0 +1,27 @@
+# This CMakeLists.txt is part of the subproject B (ExternalProject_Add).
+
+cmake_minimum_required(VERSION 3.20)
+project(subpro_d_executable LANGUAGES CXX)
+
+find_package(static_lib_project REQUIRED)
+find_package(shared_lib_project REQUIRED)
+find_package(c2_lib_project REQUIRED)
+
+add_executable(the_executable
+ "src/main.cpp"
+)
+
+target_link_libraries(the_executable PRIVATE
+ the_static_lib
+ the_shared_lib
+ the_c2_lib
+)
+
+# This is to fix an issue on AIX/GCC (see commit 4fc47424)
+set_property(TARGET the_executable PROPERTY NO_SYSTEM_FROM_IMPORTED 1)
+
+install(
+ TARGETS
+ the_executable
+ RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
+)
diff --git a/Tests/InstallMode/subpro_d_executable/src/main.cpp b/Tests/InstallMode/subpro_d_executable/src/main.cpp
new file mode 100644
index 0000000..ec12004
--- /dev/null
+++ b/Tests/InstallMode/subpro_d_executable/src/main.cpp
@@ -0,0 +1,13 @@
+#include <cstdlib>
+
+#include <c2_lib.h>
+#include <shared_lib.h>
+#include <static_lib.h>
+
+int main()
+{
+ static_hello();
+ shared_hello();
+ c2_hello();
+ return EXIT_SUCCESS;
+}
diff --git a/Tests/InstallMode/superpro/CMakeLists.txt b/Tests/InstallMode/superpro/CMakeLists.txt
new file mode 100644
index 0000000..ae4d25c
--- /dev/null
+++ b/Tests/InstallMode/superpro/CMakeLists.txt
@@ -0,0 +1,29 @@
+# This CMakeLists.txt is part of the superproject (add_subdirectory).
+
+# Below file transfers are executed at configuration time!
+
+file(
+ COPY
+ "file_copy.txt"
+ DESTINATION
+ "${CMAKE_INSTALL_PREFIX}"
+)
+
+file(COPY_FILE
+ "${CMAKE_CURRENT_SOURCE_DIR}/file_copy_file.txt"
+ "${CMAKE_INSTALL_PREFIX}/file_copy_file.txt"
+)
+
+file(
+ INSTALL
+ "file_install.txt"
+ DESTINATION
+ "${CMAKE_INSTALL_PREFIX}"
+)
+
+file(
+ CREATE_LINK
+ "${CMAKE_CURRENT_SOURCE_DIR}/file_create_link_symbolic.txt"
+ "${CMAKE_INSTALL_PREFIX}/file_create_link_symbolic.txt"
+ SYMBOLIC
+)
diff --git a/Tests/InstallMode/superpro/file_copy.txt b/Tests/InstallMode/superpro/file_copy.txt
new file mode 100644
index 0000000..aacbb96
--- /dev/null
+++ b/Tests/InstallMode/superpro/file_copy.txt
@@ -0,0 +1 @@
+This file should always be copied into CMAKE_INSTALL_PREFIX.
diff --git a/Tests/InstallMode/superpro/file_copy_file.txt b/Tests/InstallMode/superpro/file_copy_file.txt
new file mode 100644
index 0000000..aacbb96
--- /dev/null
+++ b/Tests/InstallMode/superpro/file_copy_file.txt
@@ -0,0 +1 @@
+This file should always be copied into CMAKE_INSTALL_PREFIX.
diff --git a/Tests/InstallMode/superpro/file_create_link_symbolic.txt b/Tests/InstallMode/superpro/file_create_link_symbolic.txt
new file mode 100644
index 0000000..16a481b
--- /dev/null
+++ b/Tests/InstallMode/superpro/file_create_link_symbolic.txt
@@ -0,0 +1,2 @@
+This file should always be installed into CMAKE_INSTALL_PREFIX
+as a symbolic link to the original file.
diff --git a/Tests/InstallMode/superpro/file_install.txt b/Tests/InstallMode/superpro/file_install.txt
new file mode 100644
index 0000000..eac9782
--- /dev/null
+++ b/Tests/InstallMode/superpro/file_install.txt
@@ -0,0 +1,6 @@
+This file should be placed in CMAKE_INSTALL_PREFIX
+as a copy if the CMAKE_INSTALL_MODE environment variable
+is unset or equals "COPY".
+If the variable's value is "SYMLINK" or "SYMLINK_OR_COPY",
+the CMAKE_INSTALL_PREFIX should rather receive a symbolic
+link to this file.
diff --git a/Tests/RunCMake/CMAKE_MSVCIDE_RUN_PATH/CMakeLists.txt b/Tests/RunCMake/CMAKE_MSVCIDE_RUN_PATH/CMakeLists.txt
new file mode 100644
index 0000000..bbc08e6
--- /dev/null
+++ b/Tests/RunCMake/CMAKE_MSVCIDE_RUN_PATH/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.21)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMAKE_MSVCIDE_RUN_PATH/CheckEnvironmentVar-build-stdout.txt b/Tests/RunCMake/CMAKE_MSVCIDE_RUN_PATH/CheckEnvironmentVar-build-stdout.txt
new file mode 100644
index 0000000..f0f2efc
--- /dev/null
+++ b/Tests/RunCMake/CMAKE_MSVCIDE_RUN_PATH/CheckEnvironmentVar-build-stdout.txt
@@ -0,0 +1 @@
+This message is printed by echo_message.bat
diff --git a/Tests/RunCMake/CMAKE_MSVCIDE_RUN_PATH/CheckEnvironmentVar.cmake b/Tests/RunCMake/CMAKE_MSVCIDE_RUN_PATH/CheckEnvironmentVar.cmake
new file mode 100644
index 0000000..63d6068
--- /dev/null
+++ b/Tests/RunCMake/CMAKE_MSVCIDE_RUN_PATH/CheckEnvironmentVar.cmake
@@ -0,0 +1,2 @@
+set(CMAKE_MSVCIDE_RUN_PATH "${CMAKE_SOURCE_DIR}")
+add_custom_target(main COMMAND echo_message)
diff --git a/Tests/RunCMake/CMAKE_MSVCIDE_RUN_PATH/RunCMakeTest.cmake b/Tests/RunCMake/CMAKE_MSVCIDE_RUN_PATH/RunCMakeTest.cmake
new file mode 100644
index 0000000..a424ff2
--- /dev/null
+++ b/Tests/RunCMake/CMAKE_MSVCIDE_RUN_PATH/RunCMakeTest.cmake
@@ -0,0 +1,8 @@
+include(RunCMake)
+
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CheckEnvironmentVar-build)
+run_cmake(CheckEnvironmentVar)
+set(RunCMake_TEST_NO_CLEAN 1)
+run_cmake_command(CheckEnvironmentVar-build ${CMAKE_COMMAND} --build . --config Debug --target main)
+unset(RunCMake_TEST_BINARY_DIR)
+unset(RunCMake_TEST_NO_CLEAN)
diff --git a/Tests/RunCMake/CMAKE_MSVCIDE_RUN_PATH/echo_message.bat b/Tests/RunCMake/CMAKE_MSVCIDE_RUN_PATH/echo_message.bat
new file mode 100755
index 0000000..9037d02
--- /dev/null
+++ b/Tests/RunCMake/CMAKE_MSVCIDE_RUN_PATH/echo_message.bat
@@ -0,0 +1 @@
+echo This message is printed by echo_message.bat
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 86cb849..eb2c2d9 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -349,6 +349,7 @@ if(NOT CMake_TEST_EXTERNAL_CMAKE)
endif()
add_RunCMake_test(execute_process)
add_RunCMake_test(export)
+add_RunCMake_test(cmake_host_system_information)
add_RunCMake_test(cmake_language)
add_RunCMake_test(cmake_minimum_required)
add_RunCMake_test(cmake_parse_arguments)
@@ -374,12 +375,11 @@ add_RunCMake_test(ctest_disabled_test)
add_RunCMake_test(ctest_skipped_test)
add_RunCMake_test(ctest_update)
add_RunCMake_test(ctest_upload)
+add_RunCMake_test(ctest_environment)
add_RunCMake_test(ctest_fixtures)
add_RunCMake_test(file -DMSYS=${MSYS})
add_RunCMake_test(file-CHMOD -DMSYS=${MSYS})
-if(HAVE_ELF_H OR CMAKE_SYSTEM_NAME STREQUAL "AIX")
- add_RunCMake_test(file-RPATH -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME} -DHAVE_ELF_H=${HAVE_ELF_H})
-endif()
+add_RunCMake_test(file-RPATH -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME})
add_RunCMake_test(find_file)
add_RunCMake_test(find_library -DCYGWIN=${CYGWIN} -DMSYS=${MSYS})
add_RunCMake_test(find_package -DMSYS=${MSYS})
@@ -557,6 +557,7 @@ if(CMake_TEST_FindGTK2)
endif()
if("${CMAKE_GENERATOR}" MATCHES "Visual Studio")
+ add_RunCMake_test(CMAKE_MSVCIDE_RUN_PATH)
add_RunCMake_test(include_external_msproject -DVS_PLATFORM_NAME=${CMAKE_VS_PLATFORM_NAME})
if("${CMAKE_GENERATOR}" MATCHES "Visual Studio (9|10)" AND NOT CMAKE_VS_DEVENV_COMMAND)
set(NO_USE_FOLDERS 1)
diff --git a/Tests/RunCMake/CPack/RunCMakeTest.cmake b/Tests/RunCMake/CPack/RunCMakeTest.cmake
index 746ff8b..7997c78 100644
--- a/Tests/RunCMake/CPack/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CPack/RunCMakeTest.cmake
@@ -7,6 +7,7 @@ include("${RunCMake_SOURCE_DIR}/CPackTestHelpers.cmake")
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;DragNDrop" true "COMPONENT")
run_cpack_test(DEBUGINFO "RPM.DEBUGINFO;DEB.DEBUGINFO" true "COMPONENT")
+run_cpack_test(DEBUGINFO "DEB.DEBUGINFO" true "MONOLITHIC")
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")
run_cpack_test(DIST "RPM.DIST" false "MONOLITHIC")
diff --git a/Tests/RunCMake/CPack/tests/DEBUGINFO/ExpectedFiles.cmake b/Tests/RunCMake/CPack/tests/DEBUGINFO/ExpectedFiles.cmake
index cf4aa51..b3e6485 100644
--- a/Tests/RunCMake/CPack/tests/DEBUGINFO/ExpectedFiles.cmake
+++ b/Tests/RunCMake/CPack/tests/DEBUGINFO/ExpectedFiles.cmake
@@ -1,8 +1,5 @@
set(whitespaces_ "[\t\n\r ]*")
-set(EXPECTED_FILES_COUNT "6")
-set(EXPECTED_FILES_NAME_GENERATOR_SPECIFIC_FORMAT TRUE)
-
if(GENERATOR_TYPE STREQUAL "RPM")
set(NAME "Debuginfo")
set(DEBUG_SUFFIX "debuginfo")
@@ -15,30 +12,49 @@ elseif(GENERATOR_TYPE STREQUAL "DEB")
set(DEBUG_PKG "ddeb")
endif()
-set(EXPECTED_FILE_1_NAME "${NAME}")
-set(EXPECTED_FILE_1_COMPONENT "applications")
-set(EXPECTED_FILE_CONTENT_1_LIST "/foo;/foo/test_prog")
+set(EXPECTED_FILES_NAME_GENERATOR_SPECIFIC_FORMAT TRUE)
-set(EXPECTED_FILE_2 "TestDinfo-pkg*-headers.${PKG}")
-set(EXPECTED_FILE_CONTENT_2_LIST "/bar;/bar/CMakeLists.txt")
+if(PACKAGING_TYPE STREQUAL "COMPONENT")
+ set(EXPECTED_FILES_COUNT "6")
-set(EXPECTED_FILE_3 "TestDinfo-pkg*-libs.${PKG}")
-set(EXPECTED_FILE_CONTENT_3_LIST "/bas;/bas/libtest_lib.so")
+ set(EXPECTED_FILE_1_NAME "${NAME}")
+ set(EXPECTED_FILE_1_COMPONENT "applications")
+ set(EXPECTED_FILE_CONTENT_1_LIST "/foo;/foo/test_prog")
-set(EXPECTED_FILE_4 "${NAME}-applications-${DEBUG_SUFFIX}*.${DEBUG_PKG}")
-if(GENERATOR_TYPE STREQUAL "RPM")
- set(EXPECTED_FILE_CONTENT_4 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/main.cpp.*\.debug.*")
-elseif(GENERATOR_TYPE STREQUAL "DEB")
- set(EXPECTED_FILE_CONTENT_4 ".*/usr/lib/debug/.build-id/.*\.debug.*")
-endif()
+ set(EXPECTED_FILE_2 "TestDinfo-pkg*-headers.${PKG}")
+ set(EXPECTED_FILE_CONTENT_2_LIST "/bar;/bar/CMakeLists.txt")
-if(GENERATOR_TYPE STREQUAL "RPM")
- set(EXPECTED_FILE_5 "libs-DebugInfoPackage.rpm")
- set(EXPECTED_FILE_CONTENT_5 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/test_lib.cpp.*\.debug.*")
-elseif(GENERATOR_TYPE STREQUAL "DEB")
- set(EXPECTED_FILE_5 "TestDinfo-pkg-libs-dbgsym.ddeb")
- set(EXPECTED_FILE_CONTENT_5 ".*/usr/lib/debug/.build-id/.*\.debug.*")
-endif()
+ set(EXPECTED_FILE_3 "TestDinfo-pkg*-libs.${PKG}")
+ set(EXPECTED_FILE_CONTENT_3_LIST "/bas;/bas/libtest_lib.so")
+
+ set(EXPECTED_FILE_4 "${NAME}-applications-${DEBUG_SUFFIX}*.${DEBUG_PKG}")
+ if(GENERATOR_TYPE STREQUAL "RPM")
+ set(EXPECTED_FILE_CONTENT_4 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/main.cpp.*\.debug.*")
+ elseif(GENERATOR_TYPE STREQUAL "DEB")
+ set(EXPECTED_FILE_CONTENT_4 ".*/usr/lib/debug/.build-id/.*\.debug.*")
+ endif()
+
+ if(GENERATOR_TYPE STREQUAL "RPM")
+ set(EXPECTED_FILE_5 "libs-DebugInfoPackage.rpm")
+ set(EXPECTED_FILE_CONTENT_5 ".*/src${whitespaces_}/src/src_1${whitespaces_}/src/src_1/test_lib.cpp.*\.debug.*")
+ elseif(GENERATOR_TYPE STREQUAL "DEB")
+ set(EXPECTED_FILE_5 "TestDinfo-pkg-libs-dbgsym.ddeb")
+ set(EXPECTED_FILE_CONTENT_5 ".*/usr/lib/debug/.build-id/.*\.debug.*")
+ endif()
+
+ set(EXPECTED_FILE_6 "TestDinfo-pkg*-appheaders.${PKG}")
+ set(EXPECTED_FILE_CONTENT_6_LIST "/include;/include/test_lib.hpp")
-set(EXPECTED_FILE_6 "TestDinfo-pkg*-appheaders.${PKG}")
-set(EXPECTED_FILE_CONTENT_6_LIST "/include;/include/test_lib.hpp")
+elseif(PACKAGING_TYPE STREQUAL "MONOLITHIC" AND GENERATOR_TYPE STREQUAL "DEB")
+ set(EXPECTED_FILES_COUNT "2")
+
+ set(EXPECTED_FILE_1 "TestDinfo-pkg.deb")
+ set(
+ EXPECTED_FILE_CONTENT_1_LIST
+ "/bar;/bar/CMakeLists.txt;/bas;/bas/libtest_lib.so;/foo;/foo/test_prog;/include;/include/test_lib.hpp"
+ )
+
+ set(EXPECTED_FILE_2 "TestDinfo-pkg-dbgsym.ddeb")
+ set(EXPECTED_FILE_CONTENT_2 ".*/usr/lib/debug/.build-id/.*\.debug.*")
+
+endif()
diff --git a/Tests/RunCMake/CPack/tests/DEBUGINFO/test.cmake b/Tests/RunCMake/CPack/tests/DEBUGINFO/test.cmake
index 9ff1f8a..e9cebbf 100644
--- a/Tests/RunCMake/CPack/tests/DEBUGINFO/test.cmake
+++ b/Tests/RunCMake/CPack/tests/DEBUGINFO/test.cmake
@@ -28,6 +28,8 @@ install(TARGETS test_prog DESTINATION foo COMPONENT applications)
install(FILES CMakeLists.txt DESTINATION bar COMPONENT headers)
install(TARGETS test_lib DESTINATION bas COMPONENT libs)
+set(CPACK_DEBIAN_DEBUGINFO_PACKAGE ON)
+
set(CPACK_RPM_APPLICATIONS_FILE_NAME "RPM-DEFAULT")
set(CPACK_RPM_APPLICATIONS_DEBUGINFO_PACKAGE ON)
set(CPACK_DEBIAN_APPLICATIONS_FILE_NAME "DEB-DEFAULT")
diff --git a/Tests/RunCMake/CPack/tests/MD5SUMS/ExpectedFiles.cmake b/Tests/RunCMake/CPack/tests/MD5SUMS/ExpectedFiles.cmake
index d1a3a5f..f859215 100644
--- a/Tests/RunCMake/CPack/tests/MD5SUMS/ExpectedFiles.cmake
+++ b/Tests/RunCMake/CPack/tests/MD5SUMS/ExpectedFiles.cmake
@@ -1,2 +1,2 @@
set(EXPECTED_FILES_COUNT "1")
-set(EXPECTED_FILE_CONTENT_1_LIST "/foo;/foo/CMakeLists.txt")
+set(EXPECTED_FILE_CONTENT_1_LIST "/bar;/bar/CMakeLists.txt;/baz;/baz/CMakeLists.txt;/foo;/foo/CMakeLists.txt")
diff --git a/Tests/RunCMake/CPack/tests/MD5SUMS/VerifyResult.cmake b/Tests/RunCMake/CPack/tests/MD5SUMS/VerifyResult.cmake
index fbdda9c..13af097 100644
--- a/Tests/RunCMake/CPack/tests/MD5SUMS/VerifyResult.cmake
+++ b/Tests/RunCMake/CPack/tests/MD5SUMS/VerifyResult.cmake
@@ -1,3 +1,4 @@
set(whitespaces_ "[\t\n\r ]*")
-set(md5sums_md5sums "^.* usr/foo/CMakeLists\.txt${whitespaces_}$")
+set(hashsyms_ "[a-f0-9]+")
+set(md5sums_md5sums "^${hashsyms_} usr/bar/CMakeLists\.txt${whitespaces_}${hashsyms_} usr/baz/CMakeLists\.txt${whitespaces_}${hashsyms_} usr/foo/CMakeLists\.txt${whitespaces_}$")
verifyDebControl("${FOUND_FILE_1}" "md5sums" "md5sums")
diff --git a/Tests/RunCMake/CPack/tests/MD5SUMS/test.cmake b/Tests/RunCMake/CPack/tests/MD5SUMS/test.cmake
index 15c5892..3c922d2 100644
--- a/Tests/RunCMake/CPack/tests/MD5SUMS/test.cmake
+++ b/Tests/RunCMake/CPack/tests/MD5SUMS/test.cmake
@@ -1,4 +1,6 @@
install(FILES CMakeLists.txt DESTINATION foo COMPONENT test)
+install(FILES CMakeLists.txt DESTINATION bar COMPONENT test)
+install(FILES CMakeLists.txt DESTINATION baz COMPONENT test)
if(PACKAGING_TYPE STREQUAL "COMPONENT")
set(CPACK_COMPONENTS_ALL test)
diff --git a/Tests/RunCMake/CommandLine/DeprecateVS10-WARN-OFF.cmake b/Tests/RunCMake/CommandLine/DeprecateVS10-WARN-OFF.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/DeprecateVS10-WARN-OFF.cmake
diff --git a/Tests/RunCMake/CommandLine/DeprecateVS10-WARN-ON-stderr.txt b/Tests/RunCMake/CommandLine/DeprecateVS10-WARN-ON-stderr.txt
new file mode 100644
index 0000000..202ef80
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/DeprecateVS10-WARN-ON-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Warning:
+ The "Visual Studio 10 2010" generator is deprecated and will be removed in
+ a future version of CMake.
+
+ Add CMAKE_WARN_VS10=OFF to the cache to disable this warning.$
diff --git a/Tests/RunCMake/CommandLine/DeprecateVS10-WARN-ON.cmake b/Tests/RunCMake/CommandLine/DeprecateVS10-WARN-ON.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/DeprecateVS10-WARN-ON.cmake
diff --git a/Tests/RunCMake/CommandLine/EnvBuildType-stdout.txt b/Tests/RunCMake/CommandLine/EnvBuildType-stdout.txt
new file mode 100644
index 0000000..03b92a7
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/EnvBuildType-stdout.txt
@@ -0,0 +1,2 @@
+-- ENV{CMAKE_BUILD_TYPE}='BuildTypeEnv'
+-- CMAKE_BUILD_TYPE='BuildTypeEnv'
diff --git a/Tests/RunCMake/CommandLine/EnvBuildType.cmake b/Tests/RunCMake/CommandLine/EnvBuildType.cmake
new file mode 100644
index 0000000..e5e6d04
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/EnvBuildType.cmake
@@ -0,0 +1,2 @@
+message(STATUS "ENV{CMAKE_BUILD_TYPE}='$ENV{CMAKE_BUILD_TYPE}'")
+message(STATUS "CMAKE_BUILD_TYPE='${CMAKE_BUILD_TYPE}'")
diff --git a/Tests/RunCMake/CommandLine/EnvBuildTypeIgnore-stdout.txt b/Tests/RunCMake/CommandLine/EnvBuildTypeIgnore-stdout.txt
new file mode 100644
index 0000000..4a26732
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/EnvBuildTypeIgnore-stdout.txt
@@ -0,0 +1,2 @@
+-- ENV{CMAKE_BUILD_TYPE}='BuildTypeEnv'
+-- CMAKE_BUILD_TYPE='BuildTypeOpt'
diff --git a/Tests/RunCMake/CommandLine/EnvBuildTypeIgnore.cmake b/Tests/RunCMake/CommandLine/EnvBuildTypeIgnore.cmake
new file mode 100644
index 0000000..f21666f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/EnvBuildTypeIgnore.cmake
@@ -0,0 +1 @@
+include(EnvBuildType.cmake)
diff --git a/Tests/RunCMake/CommandLine/EnvConfigTypes-stdout.txt b/Tests/RunCMake/CommandLine/EnvConfigTypes-stdout.txt
new file mode 100644
index 0000000..bfec18f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/EnvConfigTypes-stdout.txt
@@ -0,0 +1,2 @@
+-- ENV{CMAKE_CONFIGURATION_TYPES}='ConfigTypesEnv'
+-- CMAKE_CONFIGURATION_TYPES='ConfigTypesEnv'
diff --git a/Tests/RunCMake/CommandLine/EnvConfigTypes.cmake b/Tests/RunCMake/CommandLine/EnvConfigTypes.cmake
new file mode 100644
index 0000000..8c9b63a
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/EnvConfigTypes.cmake
@@ -0,0 +1,2 @@
+message(STATUS "ENV{CMAKE_CONFIGURATION_TYPES}='$ENV{CMAKE_CONFIGURATION_TYPES}'")
+message(STATUS "CMAKE_CONFIGURATION_TYPES='${CMAKE_CONFIGURATION_TYPES}'")
diff --git a/Tests/RunCMake/CommandLine/EnvConfigTypesIgnore-stdout.txt b/Tests/RunCMake/CommandLine/EnvConfigTypesIgnore-stdout.txt
new file mode 100644
index 0000000..7800a4f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/EnvConfigTypesIgnore-stdout.txt
@@ -0,0 +1,2 @@
+-- ENV{CMAKE_CONFIGURATION_TYPES}='ConfigTypesEnv'
+-- CMAKE_CONFIGURATION_TYPES='ConfigTypesOpt'
diff --git a/Tests/RunCMake/CommandLine/EnvConfigTypesIgnore.cmake b/Tests/RunCMake/CommandLine/EnvConfigTypesIgnore.cmake
new file mode 100644
index 0000000..fcbbaea
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/EnvConfigTypesIgnore.cmake
@@ -0,0 +1 @@
+include(EnvConfigTypes.cmake)
diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
index c58b1d0..cea5b1b 100644
--- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -344,6 +344,26 @@ if(RunCMake_GENERATOR MATCHES "Unix Makefiles" OR RunCMake_GENERATOR MATCHES "Ni
run_EnvironmentExportCompileCommands()
endif()
+function(run_EnvironmentBuildType)
+ set(ENV{CMAKE_BUILD_TYPE} "BuildTypeEnv")
+ run_cmake(EnvBuildType)
+ run_cmake_with_options(EnvBuildTypeIgnore -DCMAKE_BUILD_TYPE=BuildTypeOpt)
+ unset(ENV{CMAKE_BUILD_TYPE})
+endfunction()
+
+function(run_EnvironmentConfigTypes)
+ set(ENV{CMAKE_CONFIGURATION_TYPES} "ConfigTypesEnv")
+ run_cmake(EnvConfigTypes)
+ run_cmake_with_options(EnvConfigTypesIgnore -DCMAKE_CONFIGURATION_TYPES=ConfigTypesOpt)
+ unset(ENV{CMAKE_CONFIGURATION_TYPES})
+endfunction()
+
+if(RunCMake_GENERATOR MATCHES "Make|^Ninja$")
+ run_EnvironmentBuildType()
+elseif(RunCMake_GENERATOR MATCHES "Ninja Multi-Config|Visual Studio|Xcode")
+ run_EnvironmentConfigTypes()
+endif()
+
function(run_EnvironmentToolchain)
set(ENV{CMAKE_TOOLCHAIN_FILE} "${RunCMake_SOURCE_DIR}/EnvToolchain-toolchain.cmake")
run_cmake(EnvToolchainAbsolute)
@@ -898,3 +918,10 @@ 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)
+
+if(RunCMake_GENERATOR MATCHES "^Visual Studio 10 2010")
+ run_cmake_with_options(DeprecateVS10-WARN-ON -DCMAKE_WARN_VS10=ON)
+ unset(ENV{CMAKE_WARN_VS10})
+ run_cmake(DeprecateVS10-WARN-ON)
+ run_cmake_with_options(DeprecateVS10-WARN-OFF -DCMAKE_WARN_VS10=OFF)
+endif()
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_MATCHING_ARGN.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_MATCHING_ARGN.cmake
new file mode 100644
index 0000000..e49ff22
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_GET_MATCHING_ARGN.cmake
@@ -0,0 +1,17 @@
+if(WIN32)
+ set(ENV{PKG_CONFIG} "\"${CMAKE_CURRENT_SOURCE_DIR}\\dummy-pkg-config.bat\" --static --print-errors")
+else()
+ set(ENV{PKG_CONFIG} "\"${CMAKE_CURRENT_SOURCE_DIR}/dummy-pkg-config.sh\" --static --print-errors")
+endif()
+
+find_package(PkgConfig REQUIRED)
+
+if(NOT PKG_CONFIG_ARGN STREQUAL "--static;--print-errors")
+ message(SEND_ERROR "PKG_CONFIG_ARGN has wrong value '${PKG_CONFIG_ARGN}'")
+endif()
+
+_pkgconfig_invoke("none" "prefix" "output" "")
+
+if(NOT prefix_output STREQUAL "Received;--static;Received;--print-errors")
+ message(SEND_ERROR "prefix_output has wrong value '${prefix_output}'")
+endif()
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH-stdout.txt b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH-stdout.txt
new file mode 100644
index 0000000..6615d80
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH-stdout.txt
@@ -0,0 +1,3 @@
+-- ZOT_LIBRARIES='zot'
+-- ZOT_LINK_LIBRARIES='[^']*/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH-build/zot/lib/prefix-zot-suffix'
+-- ZOT_LDFLAGS='-L[^']*/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH-build/zot/lib;-lzot'
diff --git a/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH.cmake b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH.cmake
new file mode 100644
index 0000000..9f654b5
--- /dev/null
+++ b/Tests/RunCMake/FindPkgConfig/FindPkgConfig_LIBRARY_PATH.cmake
@@ -0,0 +1,29 @@
+find_package(PkgConfig REQUIRED)
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/zot/lib/pkgconfig/zot.pc" "
+prefix=${CMAKE_CURRENT_BINARY_DIR}/zot
+libdir=\${prefix}/lib
+
+Name: Zot
+Description: Dummy packaget to test LIBRARY_DIR support
+Version: 1.0
+Libs: -L\${libdir} -lzot
+")
+
+# Create a "library" file to find in libdir.
+set(CMAKE_FIND_LIBRARY_PREFIXES "prefix-")
+set(CMAKE_FIND_LIBRARY_SUFFIXES "-suffix")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/zot/lib/prefix-zot-suffix")
+
+# 'pkg-config --libs' drops -L flags in PKG_CONFIG_SYSTEM_LIBRARY_PATH by default.
+set(ENV{PKG_CONFIG_SYSTEM_LIBRARY_PATH} "${CMAKE_CURRENT_BINARY_DIR}/zot/lib")
+
+# 'pkgconf --libs' also drops -L flags in LIBRARY_PATH by default.
+set(ENV{LIBRARY_PATH} "${CMAKE_CURRENT_BINARY_DIR}/zot/lib")
+
+set(ENV{PKG_CONFIG_PATH} "${CMAKE_CURRENT_BINARY_DIR}/zot/lib/pkgconfig")
+pkg_check_modules(ZOT REQUIRED zot)
+
+message(STATUS "ZOT_LIBRARIES='${ZOT_LIBRARIES}'")
+message(STATUS "ZOT_LINK_LIBRARIES='${ZOT_LINK_LIBRARIES}'")
+message(STATUS "ZOT_LDFLAGS='${ZOT_LDFLAGS}'")
diff --git a/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake b/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake
index 78ccd96..f36d1eb 100644
--- a/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake
+++ b/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake
@@ -13,6 +13,7 @@ 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)
+run_cmake(FindPkgConfig_GET_MATCHING_ARGN)
if(APPLE)
run_cmake(FindPkgConfig_extract_frameworks_target)
@@ -31,4 +32,8 @@ if (PKG_CONFIG_FOUND)
run_cmake(FindPkgConfig_VERSION_OPERATORS)
run_cmake(FindPkgConfig_GET_MATCHING_MODULE_NAME)
run_cmake(FindPkgConfig_empty_target)
+
+ if(NOT RunCMake_BINARY_DIR MATCHES " ")
+ run_cmake(FindPkgConfig_LIBRARY_PATH)
+ endif()
endif ()
diff --git a/Tests/RunCMake/FindPkgConfig/dummy-pkg-config.bat b/Tests/RunCMake/FindPkgConfig/dummy-pkg-config.bat
index b038370..c91713b 100755
--- a/Tests/RunCMake/FindPkgConfig/dummy-pkg-config.bat
+++ b/Tests/RunCMake/FindPkgConfig/dummy-pkg-config.bat
@@ -1,5 +1,10 @@
@ECHO OFF
+rem variables to get around `--static --version` printing the received
+rem message and then version
+set static=false
+set print_errors=false
+
:LOOP
IF "%1"=="" (
@@ -21,7 +26,19 @@ IF "%1"=="--exists" (
EXIT /B 0
)
)
+IF "%1"=="--static" (
+ set static=true
+)
+IF "%1"=="--print-errors" (
+ set print_errors=true
+)
SHIFT
IF NOT "%~1"=="" GOTO LOOP
+IF "%static%"=="true" ECHO Received --static
+IF "%print_errors%"=="true" ECHO Received --print-errors
+
+IF "%static%"=="true" GOTO :EOF
+IF "%print_errors%"=="true" GOTO :EOF
+
EXIT /B 255
diff --git a/Tests/RunCMake/FindPkgConfig/dummy-pkg-config.sh b/Tests/RunCMake/FindPkgConfig/dummy-pkg-config.sh
index 56bba30..4021bf7 100755
--- a/Tests/RunCMake/FindPkgConfig/dummy-pkg-config.sh
+++ b/Tests/RunCMake/FindPkgConfig/dummy-pkg-config.sh
@@ -4,6 +4,11 @@
# to the --exists argument with the PKG_CONFIG_PATH environment variable
# and returns 1 if they are different.
+# variables to get around `--static --version` printing the received
+# message and then version
+static=false
+print_errors=false
+
while [ $# -gt 0 ]; do
case $1 in
--version)
@@ -17,7 +22,21 @@ while [ $# -gt 0 ]; do
echo "Found: ${PKG_CONFIG_PATH}"
[ "${last}" = "${PKG_CONFIG_PATH}" ] && exit 0 || exit 1
;;
+ --static)
+ static=true
+ ;;
+ --print-errors)
+ print_errors=true
+ ;;
esac
shift
done
+
+$static && echo "Received --static"
+$print_errors && echo "Received --print-errors"
+
+if $static || $print_errors; then
+ exit 0
+fi
+
exit 255
diff --git a/Tests/RunCMake/GeneratorExpression/CMP0085-OLD-stderr.txt b/Tests/RunCMake/GeneratorExpression/CMP0085-OLD-stderr.txt
new file mode 100644
index 0000000..cae3679
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/CMP0085-OLD-stderr.txt
@@ -0,0 +1,8 @@
+^CMake Deprecation Warning at CMakeLists.txt:[0-9]+ \(cmake_minimum_required\):
+ The OLD behavior for policy CMP0085 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.$
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-test3-stdout.txt b/Tests/RunCMake/GoogleTest/GoogleTest-test3-stdout.txt
new file mode 100644
index 0000000..cf08267
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-test3-stdout.txt
@@ -0,0 +1,16 @@
+Test project .*
+ Start 27: TEST:basic\.case_foo!3
+1/4 Test #27: TEST:basic\.case_foo!3 \.+ +Passed +[0-9.]+ sec
+ Start 28: TEST:basic\.case_bar!3
+2/4 Test #28: TEST:basic\.case_bar!3 \.+ +Passed +[0-9.]+ sec
+ Start 29: TEST:basic\.disabled_case!3
+3/4 Test #29: TEST:basic\.disabled_case!3 \.+\*+Not Run \(Disabled\) +[0-9.]+ sec
+ Start 30: TEST:basic\.DISABLEDnot_really_case!3
+4/4 Test #30: TEST:basic\.DISABLEDnot_really_case!3 \.+ +Passed +[0-9.]+ sec
+
+100% tests passed, 0 tests failed out of 3
+
+Total Test time \(real\) = +[0-9.]+ sec
+
+The following tests did not run:
+.*29 - TEST:basic.disabled_case!3 \(Disabled\)
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest-test4-stdout.txt b/Tests/RunCMake/GoogleTest/GoogleTest-test4-stdout.txt
new file mode 100644
index 0000000..4a9d75b
--- /dev/null
+++ b/Tests/RunCMake/GoogleTest/GoogleTest-test4-stdout.txt
@@ -0,0 +1,9 @@
+Test project .*
+ Start 31: TEST:typed/short\.case!4
+1/2 Test #31: TEST:typed/short\.case!4 \.+ +Passed +[0-9.]+ sec
+ Start 32: TEST:typed/float\.case!4
+2/2 Test #32: TEST:typed/float\.case!4 \.+ +Passed +[0-9.]+ sec
+
+100% tests passed, 0 tests failed out of 2
+
+Total Test time \(real\) = +[0-9.]+ sec
diff --git a/Tests/RunCMake/GoogleTest/GoogleTest.cmake b/Tests/RunCMake/GoogleTest/GoogleTest.cmake
index 8efd117..221d6ad 100644
--- a/Tests/RunCMake/GoogleTest/GoogleTest.cmake
+++ b/Tests/RunCMake/GoogleTest/GoogleTest.cmake
@@ -24,6 +24,24 @@ gtest_discover_tests(
PROPERTIES LABELS TEST2
)
+gtest_discover_tests(
+ fake_gtest
+ TEST_PREFIX TEST:
+ TEST_SUFFIX !3
+ TEST_FILTER basic*
+ EXTRA_ARGS how now "\"brown\" cow"
+ PROPERTIES LABELS TEST3
+)
+
+gtest_discover_tests(
+ fake_gtest
+ TEST_PREFIX TEST:
+ TEST_SUFFIX !4
+ TEST_FILTER typed*
+ EXTRA_ARGS how now "\"brown\" cow"
+ PROPERTIES LABELS TEST4
+)
+
add_executable(no_tests_defined no_tests_defined.cpp)
xcode_sign_adhoc(no_tests_defined)
diff --git a/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake b/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake
index 530c8ab..c5c5925 100644
--- a/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GoogleTest/RunCMakeTest.cmake
@@ -40,6 +40,20 @@ function(run_GoogleTest DISCOVERY_MODE)
--no-label-summary
)
+ run_cmake_command(GoogleTest-test3
+ ${CMAKE_CTEST_COMMAND}
+ -C Debug
+ -L TEST3
+ --no-label-summary
+ )
+
+ run_cmake_command(GoogleTest-test4
+ ${CMAKE_CTEST_COMMAND}
+ -C Debug
+ -L TEST4
+ --no-label-summary
+ )
+
run_cmake_command(GoogleTest-test-missing
${CMAKE_CTEST_COMMAND}
-C Debug
diff --git a/Tests/RunCMake/GoogleTest/fake_gtest.cpp b/Tests/RunCMake/GoogleTest/fake_gtest.cpp
index 1956c37..b2a5cb4 100644
--- a/Tests/RunCMake/GoogleTest/fake_gtest.cpp
+++ b/Tests/RunCMake/GoogleTest/fake_gtest.cpp
@@ -7,27 +7,42 @@ int main(int argc, char** argv)
// 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.
+ bool is_filtered =
+ argc > 2 && std::string(argv[2]).find("--gtest_filter=") == 0;
+ bool is_basic_only =
+ is_filtered && std::string(argv[2]).find("basic*") != std::string::npos;
+ bool is_typed_only =
+ is_filtered && std::string(argv[2]).find("typed*") != std::string::npos;
+
if (argc > 1 && std::string(argv[1]) == "--gtest_list_tests") {
- std::cout << "basic." << std::endl;
- std::cout << " case_foo" << std::endl;
- std::cout << " case_bar" << std::endl;
- std::cout << " DISABLED_disabled_case" << std::endl;
- std::cout << " DISABLEDnot_really_case" << std::endl;
- std::cout << "DISABLED_disabled." << std::endl;
- std::cout << " case" << std::endl;
- std::cout << "DISABLEDnotreally." << std::endl;
- std::cout << " case" << std::endl;
- std::cout << "typed/0. # TypeParam = short" << std::endl;
- std::cout << " case" << std::endl;
- std::cout << "typed/1. # TypeParam = float" << std::endl;
- std::cout << " case" << std::endl;
- 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;
+ if (!is_typed_only) {
+ std::cout << "basic." << std::endl;
+ std::cout << " case_foo" << std::endl;
+ std::cout << " case_bar" << std::endl;
+ std::cout << " DISABLED_disabled_case" << std::endl;
+ std::cout << " DISABLEDnot_really_case" << std::endl;
+ }
+ if (!is_basic_only && !is_typed_only) {
+ std::cout << "DISABLED_disabled." << std::endl;
+ std::cout << " case" << std::endl;
+ std::cout << "DISABLEDnotreally." << std::endl;
+ std::cout << " case" << std::endl;
+ }
+ if (!is_basic_only) {
+ std::cout << "typed/0. # TypeParam = short" << std::endl;
+ std::cout << " case" << std::endl;
+ std::cout << "typed/1. # TypeParam = float" << std::endl;
+ std::cout << " case" << std::endl;
+ }
+ if (!is_basic_only && !is_typed_only) {
+ 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/UseSWIG/CMP0086-OLD-stderr.txt b/Tests/RunCMake/UseSWIG/CMP0086-OLD-stderr.txt
new file mode 100644
index 0000000..fca7a73
--- /dev/null
+++ b/Tests/RunCMake/UseSWIG/CMP0086-OLD-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at CMP0086-OLD.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0086 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/VS10Project/VsDpiAwareBadParam-stderr.txt b/Tests/RunCMake/VS10Project/VsDpiAwareBadParam-stderr.txt
index 95fc5ca..39415af 100644
--- a/Tests/RunCMake/VS10Project/VsDpiAwareBadParam-stderr.txt
+++ b/Tests/RunCMake/VS10Project/VsDpiAwareBadParam-stderr.txt
@@ -1,3 +1,3 @@
-CMake Error: Bad parameter for VS_DPI_AWARE: Bar
CMake Error: Bad parameter for VS_DPI_AWARE: Foo
+CMake Error: Bad parameter for VS_DPI_AWARE: Bar
CMake Generate step failed. Build files cannot be regenerated correctly.
diff --git a/Tests/RunCMake/add_subdirectory/CMP0082-OLD-stderr.txt b/Tests/RunCMake/add_subdirectory/CMP0082-OLD-stderr.txt
new file mode 100644
index 0000000..50838c3
--- /dev/null
+++ b/Tests/RunCMake/add_subdirectory/CMP0082-OLD-stderr.txt
@@ -0,0 +1,8 @@
+^CMake Deprecation Warning at CMakeLists.txt:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0082 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.$
diff --git a/Tests/RunCMake/cmake_host_system_information/000-FirstFallbackScript.cmake b/Tests/RunCMake/cmake_host_system_information/000-FirstFallbackScript.cmake
new file mode 100644
index 0000000..ad873eb
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/000-FirstFallbackScript.cmake
@@ -0,0 +1 @@
+message(WARNING "The warning text to match just to make sure the script get executed")
diff --git a/Tests/RunCMake/cmake_host_system_information/999-LastFallbackScript.cmake b/Tests/RunCMake/cmake_host_system_information/999-LastFallbackScript.cmake
new file mode 100644
index 0000000..08d8da8
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/999-LastFallbackScript.cmake
@@ -0,0 +1,21 @@
+if(DEFINED CMAKE_GET_OS_RELEASE_FALLBACK_RESULT)
+ message(FATAL_ERROR "The `CMAKE_GET_OS_RELEASE_FALLBACK_RESULT` expected to be unset at this moment")
+endif()
+
+set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_NAME UnitTest)
+set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_PRETTY_NAME "Just a Unit Test")
+set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_ID unittest)
+set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_ID_LIKE nothing)
+set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION 0.0.1)
+set(CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION_ID 0.0.1)
+
+list(
+ APPEND CMAKE_GET_OS_RELEASE_FALLBACK_RESULT
+ CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_NAME
+ CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_PRETTY_NAME
+ IGNORED_VARIABLE_NAME_WHICH_IS_NOT_STARTED_WITH_EXPECTED_PREFIX
+ CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_ID
+ CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_ID_LIKE
+ CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION
+ CMAKE_GET_OS_RELEASE_FALLBACK_RESULT_VERSION_ID
+ )
diff --git a/Tests/RunCMake/cmake_host_system_information/BadArg1-result.txt b/Tests/RunCMake/cmake_host_system_information/BadArg1-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/BadArg1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/cmake_host_system_information/BadArg1-stderr.txt b/Tests/RunCMake/cmake_host_system_information/BadArg1-stderr.txt
new file mode 100644
index 0000000..ed995e6
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/BadArg1-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at BadArg1\.cmake:1 \(cmake_host_system_information\):
+ cmake_host_system_information missing RESULT specification.
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:7 \(include\)
diff --git a/Tests/CMakeTests/CMakeHostSystemInformation-BadArg1.cmake b/Tests/RunCMake/cmake_host_system_information/BadArg1.cmake
index 1655eb4..1655eb4 100644
--- a/Tests/CMakeTests/CMakeHostSystemInformation-BadArg1.cmake
+++ b/Tests/RunCMake/cmake_host_system_information/BadArg1.cmake
diff --git a/Tests/RunCMake/cmake_host_system_information/BadArg2-result.txt b/Tests/RunCMake/cmake_host_system_information/BadArg2-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/BadArg2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/cmake_host_system_information/BadArg2-stderr.txt b/Tests/RunCMake/cmake_host_system_information/BadArg2-stderr.txt
new file mode 100644
index 0000000..b78c927
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/BadArg2-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at BadArg2\.cmake:1 \(cmake_host_system_information\):
+ cmake_host_system_information missing QUERY specification
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:7 \(include\)
diff --git a/Tests/CMakeTests/CMakeHostSystemInformation-BadArg2.cmake b/Tests/RunCMake/cmake_host_system_information/BadArg2.cmake
index 1f056d5..1f056d5 100644
--- a/Tests/CMakeTests/CMakeHostSystemInformation-BadArg2.cmake
+++ b/Tests/RunCMake/cmake_host_system_information/BadArg2.cmake
diff --git a/Tests/RunCMake/cmake_host_system_information/BadArg3-result.txt b/Tests/RunCMake/cmake_host_system_information/BadArg3-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/BadArg3-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/cmake_host_system_information/BadArg3-stderr.txt b/Tests/RunCMake/cmake_host_system_information/BadArg3-stderr.txt
new file mode 100644
index 0000000..c3f1314
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/BadArg3-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at BadArg3\.cmake:1 \(cmake_host_system_information\):
+ cmake_host_system_information does not recognize <key> FOOBAR
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:7 \(include\)
diff --git a/Tests/CMakeTests/CMakeHostSystemInformation-BadArg3.cmake b/Tests/RunCMake/cmake_host_system_information/BadArg3.cmake
index 9c5a558..9c5a558 100644
--- a/Tests/CMakeTests/CMakeHostSystemInformation-BadArg3.cmake
+++ b/Tests/RunCMake/cmake_host_system_information/BadArg3.cmake
diff --git a/Tests/RunCMake/cmake_host_system_information/CMakeLists.txt b/Tests/RunCMake/cmake_host_system_information/CMakeLists.txt
new file mode 100644
index 0000000..0198f9b
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 3.21)
+
+project(${RunCMake_TEST} NONE)
+
+set(CMAKE_SYSROOT ${PROJECT_SOURCE_DIR}/${RunCMake_TEST})
+
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/cmake_host_system_information/CentOS6-stdout.txt b/Tests/RunCMake/cmake_host_system_information/CentOS6-stdout.txt
new file mode 100644
index 0000000..50dbb08
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/CentOS6-stdout.txt
@@ -0,0 +1,7 @@
+-- CENTOS6_ID=`centos`
+-- CENTOS6_ID_LIKE=`rhel`
+-- CENTOS6_NAME=`CentOS`
+-- CENTOS6_PRETTY_NAME=`CentOS release 6\.10 \(Final\)`
+-- CENTOS6_USED_FALLBACK_SCRIPT=`.*/Modules/Internal/OSRelease/010-TryOldCentOS.cmake`
+-- CENTOS6_VERSION=`6\.10`
+-- CENTOS6_VERSION_ID=`6\.10`
diff --git a/Tests/RunCMake/cmake_host_system_information/CentOS6.cmake b/Tests/RunCMake/cmake_host_system_information/CentOS6.cmake
new file mode 100644
index 0000000..3bc632b
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/CentOS6.cmake
@@ -0,0 +1,5 @@
+cmake_host_system_information(RESULT CENTOS6 QUERY DISTRIB_INFO)
+
+foreach(VAR IN LISTS CENTOS6)
+ message(STATUS "${VAR}=`${${VAR}}`")
+endforeach()
diff --git a/Tests/RunCMake/cmake_host_system_information/CentOS6/etc/centos-release b/Tests/RunCMake/cmake_host_system_information/CentOS6/etc/centos-release
new file mode 100644
index 0000000..294ccc9
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/CentOS6/etc/centos-release
@@ -0,0 +1 @@
+CentOS release 6.10 (Final)
diff --git a/Tests/RunCMake/cmake_host_system_information/Debian6-stdout.txt b/Tests/RunCMake/cmake_host_system_information/Debian6-stdout.txt
new file mode 100644
index 0000000..4193d6f
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/Debian6-stdout.txt
@@ -0,0 +1,5 @@
+-- DEBIAN6_ID=`debian`
+-- DEBIAN6_NAME=`Debian`
+-- DEBIAN6_USED_FALLBACK_SCRIPT=`.*/Modules/Internal/OSRelease/020-TryDebianVersion.cmake`
+-- DEBIAN6_VERSION=`6\.0\.10`
+-- DEBIAN6_VERSION_ID=`6\.0\.10`
diff --git a/Tests/RunCMake/cmake_host_system_information/Debian6.cmake b/Tests/RunCMake/cmake_host_system_information/Debian6.cmake
new file mode 100644
index 0000000..cbf83a9
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/Debian6.cmake
@@ -0,0 +1,5 @@
+cmake_host_system_information(RESULT DEBIAN6 QUERY DISTRIB_INFO)
+
+foreach(VAR IN LISTS DEBIAN6)
+ message(STATUS "${VAR}=`${${VAR}}`")
+endforeach()
diff --git a/Tests/RunCMake/cmake_host_system_information/Debian6/etc/debian_version b/Tests/RunCMake/cmake_host_system_information/Debian6/etc/debian_version
new file mode 100644
index 0000000..c7d48f0
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/Debian6/etc/debian_version
@@ -0,0 +1 @@
+6.0.10
diff --git a/Tests/RunCMake/cmake_host_system_information/Exherbo-stdout.txt b/Tests/RunCMake/cmake_host_system_information/Exherbo-stdout.txt
new file mode 100644
index 0000000..11ae71f
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/Exherbo-stdout.txt
@@ -0,0 +1,9 @@
+-- TEST1_ANSI_COLOR=`0;32`
+-- TEST1_BUG_REPORT_URL=`https://bugs.exherbo.org/`
+-- TEST1_HOME_URL=`https://www.exherbo.org/`
+-- TEST1_ID=`exherbo`
+-- TEST1_NAME=`Exherbo`
+-- TEST1_PRETTY_NAME=`Exherbo Linux`
+-- TEST1_SUPPORT_URL=`irc://irc.freenode.net/#exherbo`
+-- TEST2_ID=`exherbo`
+-- TEST2_VERSION=``
diff --git a/Tests/RunCMake/cmake_host_system_information/Exherbo.cmake b/Tests/RunCMake/cmake_host_system_information/Exherbo.cmake
new file mode 100644
index 0000000..7fc26d8
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/Exherbo.cmake
@@ -0,0 +1,11 @@
+cmake_host_system_information(RESULT TEST1 QUERY DISTRIB_INFO)
+
+foreach(VAR IN LISTS TEST1)
+ message(STATUS "${VAR}=`${${VAR}}`")
+endforeach()
+
+# Query individual variables
+cmake_host_system_information(RESULT TEST2 QUERY DISTRIB_ID DISTRIB_VERSION)
+list(POP_FRONT TEST2 TEST2_ID TEST2_VERSION)
+message(STATUS "TEST2_ID=`${TEST2_ID}`")
+message(STATUS "TEST2_VERSION=`${TEST2_VERSION}`")
diff --git a/Tests/RunCMake/cmake_host_system_information/Exherbo/etc/os-release b/Tests/RunCMake/cmake_host_system_information/Exherbo/etc/os-release
new file mode 100644
index 0000000..944c9b4
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/Exherbo/etc/os-release
@@ -0,0 +1,7 @@
+NAME="Exherbo"
+PRETTY_NAME="Exherbo Linux"
+ID="exherbo"
+ANSI_COLOR="0;32"
+HOME_URL="https://www.exherbo.org/"
+SUPPORT_URL="irc://irc.freenode.net/#exherbo"
+BUG_REPORT_URL="https://bugs.exherbo.org/"
diff --git a/Tests/RunCMake/cmake_host_system_information/QueryKeys-stdout.txt b/Tests/RunCMake/cmake_host_system_information/QueryKeys-stdout.txt
new file mode 100644
index 0000000..f583deb
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/QueryKeys-stdout.txt
@@ -0,0 +1,27 @@
+-- NUMBER_OF_LOGICAL_CORES=`[0-9]+`
+-- NUMBER_OF_PHYSICAL_CORES=`[0-9]+`
+-- HOSTNAME=`.*`
+-- FQDN=`.*`
+-- TOTAL_VIRTUAL_MEMORY=`[0-9]+`
+-- AVAILABLE_VIRTUAL_MEMORY=`[0-9]+`
+-- TOTAL_PHYSICAL_MEMORY=`[0-9]+`
+-- AVAILABLE_PHYSICAL_MEMORY=`[0-9]+`
+-- IS_64BIT=`[01]`
+-- HAS_FPU=`[01]`
+-- HAS_MMX=`[01]`
+-- HAS_MMX_PLUS=`[01]`
+-- HAS_SSE=`[01]`
+-- HAS_SSE2=`[01]`
+-- HAS_SSE_FP=`[01]`
+-- HAS_SSE_MMX=`[01]`
+-- HAS_AMD_3DNOW=`[01]`
+-- HAS_AMD_3DNOW_PLUS=`[01]`
+-- HAS_IA64=`[01]`
+-- HAS_SERIAL_NUMBER=`[01]`
+-- PROCESSOR_SERIAL_NUMBER=`.*`
+-- PROCESSOR_NAME=`.*`
+-- PROCESSOR_DESCRIPTION=`.*`
+-- OS_NAME=`.*`
+-- OS_RELEASE=`.*`
+-- OS_VERSION=`.*`
+-- OS_PLATFORM=`.*`
diff --git a/Tests/CMakeTests/CMakeHostSystemInformationTest.cmake.in b/Tests/RunCMake/cmake_host_system_information/QueryKeys.cmake
index a3c2b05..f22a0ae 100644
--- a/Tests/CMakeTests/CMakeHostSystemInformationTest.cmake.in
+++ b/Tests/RunCMake/cmake_host_system_information/QueryKeys.cmake
@@ -1,19 +1,8 @@
-set(BadArg1-RESULT 1)
-set(BadArg1-STDERR "missing RESULT specification")
-set(BadArg2-RESULT 1)
-set(BadArg2-STDERR "missing QUERY specification")
-set(BadArg3-RESULT 1)
-set(BadArg3-STDERR "does not recognize <key> FOOBAR")
-set(QueryList-RESULT 0)
-set(QueryList-STDERR "\\[[0-9]+;[0-9]+\\]")
-
function(try_and_print key)
- cmake_host_system_information(RESULT RESULT QUERY ${key})
- message(STATUS "[${key}] [${RESULT}]")
+ cmake_host_system_information(RESULT RESULT QUERY ${key})
+ message(STATUS "${key}=`${RESULT}`")
endfunction()
-message("CTEST_FULL_OUTPUT (Avoid ctest truncation of output)")
-
try_and_print(NUMBER_OF_LOGICAL_CORES)
try_and_print(NUMBER_OF_PHYSICAL_CORES)
try_and_print(HOSTNAME)
@@ -41,12 +30,3 @@ try_and_print(OS_NAME)
try_and_print(OS_RELEASE)
try_and_print(OS_VERSION)
try_and_print(OS_PLATFORM)
-
-include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake")
-
-check_cmake_test(CMakeHostSystemInformation
- BadArg1
- BadArg2
- BadArg3
- QueryList
-)
diff --git a/Tests/RunCMake/cmake_host_system_information/QueryList-stdout.txt b/Tests/RunCMake/cmake_host_system_information/QueryList-stdout.txt
new file mode 100644
index 0000000..eebe0d4
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/QueryList-stdout.txt
@@ -0,0 +1 @@
+-- \[[0-9]+;[0-9]+\]
diff --git a/Tests/CMakeTests/CMakeHostSystemInformation-QueryList.cmake b/Tests/RunCMake/cmake_host_system_information/QueryList.cmake
index 1c3156d..f24aa2b 100644
--- a/Tests/CMakeTests/CMakeHostSystemInformation-QueryList.cmake
+++ b/Tests/RunCMake/cmake_host_system_information/QueryList.cmake
@@ -2,4 +2,4 @@ cmake_host_system_information(RESULT RESULT
QUERY NUMBER_OF_LOGICAL_CORES NUMBER_OF_PHYSICAL_CORES
)
-message("[${RESULT}]")
+message(STATUS "[${RESULT}]")
diff --git a/Tests/RunCMake/cmake_host_system_information/RunCMakeTest.cmake b/Tests/RunCMake/cmake_host_system_information/RunCMakeTest.cmake
new file mode 100644
index 0000000..189013f
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/RunCMakeTest.cmake
@@ -0,0 +1,17 @@
+include(RunCMake)
+
+run_cmake(BadArg1)
+run_cmake(BadArg2)
+run_cmake(BadArg3)
+
+run_cmake(QueryList)
+run_cmake(QueryKeys)
+
+run_cmake(UnitTest)
+run_cmake(Exherbo)
+run_cmake(Ubuntu)
+
+run_cmake(CentOS6)
+run_cmake(Debian6)
+
+run_cmake(UserFallbackScript)
diff --git a/Tests/RunCMake/cmake_host_system_information/Ubuntu-stdout.txt b/Tests/RunCMake/cmake_host_system_information/Ubuntu-stdout.txt
new file mode 100644
index 0000000..d1a18da
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/Ubuntu-stdout.txt
@@ -0,0 +1,14 @@
+-- TEST1_BUG_REPORT_URL=`https://bugs\.launchpad\.net/ubuntu/`
+-- TEST1_HOME_URL=`https://www\.ubuntu\.com/`
+-- TEST1_ID=`ubuntu`
+-- TEST1_ID_LIKE=`debian`
+-- TEST1_NAME=`Ubuntu`
+-- TEST1_PRETTY_NAME=`Ubuntu 20\.04\.2 LTS`
+-- TEST1_PRIVACY_POLICY_URL=`https://www\.ubuntu\.com/legal/terms-and-policies/privacy-policy`
+-- TEST1_SUPPORT_URL=`https://help\.ubuntu\.com/`
+-- TEST1_UBUNTU_CODENAME=`focal`
+-- TEST1_VERSION=`20\.04\.2 LTS \(Focal Fossa\)`
+-- TEST1_VERSION_CODENAME=`focal`
+-- TEST1_VERSION_ID=`20\.04`
+-- TEST2_ID=`ubuntu`
+-- TEST2_VERSION=`20\.04\.2 LTS \(Focal Fossa\)`
diff --git a/Tests/RunCMake/cmake_host_system_information/Ubuntu.cmake b/Tests/RunCMake/cmake_host_system_information/Ubuntu.cmake
new file mode 100644
index 0000000..7fc26d8
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/Ubuntu.cmake
@@ -0,0 +1,11 @@
+cmake_host_system_information(RESULT TEST1 QUERY DISTRIB_INFO)
+
+foreach(VAR IN LISTS TEST1)
+ message(STATUS "${VAR}=`${${VAR}}`")
+endforeach()
+
+# Query individual variables
+cmake_host_system_information(RESULT TEST2 QUERY DISTRIB_ID DISTRIB_VERSION)
+list(POP_FRONT TEST2 TEST2_ID TEST2_VERSION)
+message(STATUS "TEST2_ID=`${TEST2_ID}`")
+message(STATUS "TEST2_VERSION=`${TEST2_VERSION}`")
diff --git a/Tests/RunCMake/cmake_host_system_information/Ubuntu/etc/os-release b/Tests/RunCMake/cmake_host_system_information/Ubuntu/etc/os-release
new file mode 100644
index 0000000..f228f22
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/Ubuntu/etc/os-release
@@ -0,0 +1,12 @@
+NAME="Ubuntu"
+VERSION="20.04.2 LTS (Focal Fossa)"
+ID=ubuntu
+ID_LIKE=debian
+PRETTY_NAME="Ubuntu 20.04.2 LTS"
+VERSION_ID="20.04"
+HOME_URL="https://www.ubuntu.com/"
+SUPPORT_URL="https://help.ubuntu.com/"
+BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
+PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
+VERSION_CODENAME=focal
+UBUNTU_CODENAME=focal
diff --git a/Tests/RunCMake/cmake_host_system_information/UnitTest-stdout.txt b/Tests/RunCMake/cmake_host_system_information/UnitTest-stdout.txt
new file mode 100644
index 0000000..db6f487
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/UnitTest-stdout.txt
@@ -0,0 +1,7 @@
+-- UNIT_TEST_A_LIST_LIKE_VARIABLE=`satu;dua;tiga`
+-- UNIT_TEST_DBL_QUOTED_VALUE=`"The" value in double "quotes"`
+-- UNIT_TEST_DBL_QUOTED_VALUE_STIPPED_COMMENT=`Blah blah blah`
+-- UNIT_TEST_NON_SPACE_VALUE=`Blah-blah-blah`
+-- UNIT_TEST_QUOTED_VALUE=`'The' value in single 'quotes'`
+-- UNIT_TEST_QUOTED_VALUE_STIPPED_COMMENT=`The value in single quotes`
+-- UNIT_TEST_THE_URL_WITH_ANCHOR_TEST=`https://blah.blah/resource#anchor`
diff --git a/Tests/RunCMake/cmake_host_system_information/UnitTest.cmake b/Tests/RunCMake/cmake_host_system_information/UnitTest.cmake
new file mode 100644
index 0000000..d9a0aca
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/UnitTest.cmake
@@ -0,0 +1,5 @@
+cmake_host_system_information(RESULT UNIT_TEST QUERY DISTRIB_INFO)
+
+foreach(VAR IN LISTS UNIT_TEST)
+ message(STATUS "${VAR}=`${${VAR}}`")
+endforeach()
diff --git a/Tests/RunCMake/cmake_host_system_information/UnitTest/etc/os-release b/Tests/RunCMake/cmake_host_system_information/UnitTest/etc/os-release
new file mode 100644
index 0000000..66c33b5
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/UnitTest/etc/os-release
@@ -0,0 +1,9 @@
+# Comment string gonna be ignored
+NON_SPACE_VALUE=Blah-blah-blah
+QUOTED_VALUE='\'The\' value in single \'quotes\''
+QUOTED_VALUE_STIPPED_COMMENT='The value in single quotes'# The comment right after `'`
+DBL_QUOTED_VALUE="\"The\" value in double \"quotes\""
+DBL_QUOTED_VALUE_STIPPED_COMMENT="Blah blah blah"# The comment right after `'`
+THE_URL_WITH_ANCHOR_TEST="https://blah.blah/resource#anchor" # And a comment after
+A_LIST_LIKE_VARIABLE='satu;dua;tiga'
+INCORRECT_ESCAPE_IGNORED=\'This line gonna be ignored'
diff --git a/Tests/RunCMake/cmake_host_system_information/UserFallbackScript-stderr.txt b/Tests/RunCMake/cmake_host_system_information/UserFallbackScript-stderr.txt
new file mode 100644
index 0000000..78acea2
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/UserFallbackScript-stderr.txt
@@ -0,0 +1,5 @@
+CMake Warning at 000-FirstFallbackScript\.cmake:[0-9]+ \(message\):
+ The warning text to match just to make sure the script get executed
+Call Stack \(most recent call first\):
+ UserFallbackScript\.cmake:[0-9]+ \(cmake_host_system_information\)
+ CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/cmake_host_system_information/UserFallbackScript-stdout.txt b/Tests/RunCMake/cmake_host_system_information/UserFallbackScript-stdout.txt
new file mode 100644
index 0000000..acaf47e
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/UserFallbackScript-stdout.txt
@@ -0,0 +1,7 @@
+-- UFS_ID=`unittest`
+-- UFS_ID_LIKE=`nothing`
+-- UFS_NAME=`UnitTest`
+-- UFS_PRETTY_NAME=`Just a Unit Test`
+-- UFS_USED_FALLBACK_SCRIPT=`.*/999-LastFallbackScript\.cmake`
+-- UFS_VERSION=`0\.0\.1`
+-- UFS_VERSION_ID=`0\.0\.1`
diff --git a/Tests/RunCMake/cmake_host_system_information/UserFallbackScript.cmake b/Tests/RunCMake/cmake_host_system_information/UserFallbackScript.cmake
new file mode 100644
index 0000000..660aa1c
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/UserFallbackScript.cmake
@@ -0,0 +1,12 @@
+list(
+ APPEND CMAKE_GET_OS_RELEASE_FALLBACK_SCRIPTS
+ ${CMAKE_CURRENT_SOURCE_DIR}/000-FirstFallbackScript.cmake
+ ${CMAKE_CURRENT_SOURCE_DIR}/Ignored-Script.cmake
+ ${CMAKE_CURRENT_SOURCE_DIR}/999-LastFallbackScript.cmake
+ )
+
+cmake_host_system_information(RESULT UFS QUERY DISTRIB_INFO)
+
+foreach(VAR IN LISTS UFS)
+ message(STATUS "${VAR}=`${${VAR}}`")
+endforeach()
diff --git a/Tests/RunCMake/ctest_environment/CMakeLists.txt.in b/Tests/RunCMake/ctest_environment/CMakeLists.txt.in
new file mode 100644
index 0000000..c9c4a64
--- /dev/null
+++ b/Tests/RunCMake/ctest_environment/CMakeLists.txt.in
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.21.0)
+project("@CASE_NAME@" NONE)
+include("@CASE_SOURCE_DIR@/@CASE_NAME@.cmake")
diff --git a/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-invalid-op-result.txt b/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-invalid-op-result.txt
new file mode 100644
index 0000000..b57e2de
--- /dev/null
+++ b/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-invalid-op-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-invalid-op-stderr.txt b/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-invalid-op-stderr.txt
new file mode 100644
index 0000000..5b56d6f
--- /dev/null
+++ b/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-invalid-op-stderr.txt
@@ -0,0 +1 @@
+Error: Unrecognized environment manipulation argument: unknown
diff --git a/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-invalid-op.cmake b/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-invalid-op.cmake
new file mode 100644
index 0000000..d6ca4b2
--- /dev/null
+++ b/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-invalid-op.cmake
@@ -0,0 +1,6 @@
+include(CTest)
+add_test(NAME cmake_version COMMAND "${CMAKE_COMMAND}" --version)
+
+set_property(TEST cmake_version
+ PROPERTY ENVIRONMENT_MODIFICATION
+ INVALID_OP=unknown:)
diff --git a/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-no-colon-result.txt b/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-no-colon-result.txt
new file mode 100644
index 0000000..b57e2de
--- /dev/null
+++ b/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-no-colon-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-no-colon-stderr.txt b/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-no-colon-stderr.txt
new file mode 100644
index 0000000..3ba6ba7
--- /dev/null
+++ b/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-no-colon-stderr.txt
@@ -0,0 +1 @@
+Error: Missing `:` after the operation in: MISSING_COLON=unset
diff --git a/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-no-colon.cmake b/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-no-colon.cmake
new file mode 100644
index 0000000..601dd8b
--- /dev/null
+++ b/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-no-colon.cmake
@@ -0,0 +1,6 @@
+include(CTest)
+
+add_test(NAME cmake_version COMMAND "${CMAKE_COMMAND}" --version)
+set_property(TEST cmake_version
+ PROPERTY ENVIRONMENT_MODIFICATION
+ MISSING_COLON=unset)
diff --git a/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-no-equals-result.txt b/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-no-equals-result.txt
new file mode 100644
index 0000000..b57e2de
--- /dev/null
+++ b/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-no-equals-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-no-equals-stderr.txt b/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-no-equals-stderr.txt
new file mode 100644
index 0000000..20bc9a5
--- /dev/null
+++ b/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-no-equals-stderr.txt
@@ -0,0 +1 @@
+Error: Missing `=` after the variable name in: MISSING_EQUAL
diff --git a/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-no-equals.cmake b/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-no-equals.cmake
new file mode 100644
index 0000000..18448cf
--- /dev/null
+++ b/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-no-equals.cmake
@@ -0,0 +1,6 @@
+include(CTest)
+
+add_test(NAME cmake_version COMMAND "${CMAKE_COMMAND}" --version)
+set_property(TEST cmake_version
+ PROPERTY ENVIRONMENT_MODIFICATION
+ MISSING_EQUAL)
diff --git a/Tests/RunCMake/ctest_environment/RunCMakeTest.cmake b/Tests/RunCMake/ctest_environment/RunCMakeTest.cmake
new file mode 100644
index 0000000..3447779
--- /dev/null
+++ b/Tests/RunCMake/ctest_environment/RunCMakeTest.cmake
@@ -0,0 +1,12 @@
+include(RunCTest)
+
+# Isolate our ctest runs from external environment.
+unset(ENV{CTEST_PARALLEL_LEVEL})
+unset(ENV{CTEST_OUTPUT_ON_FAILURE})
+
+set(CASE_SOURCE_DIR "${RunCMake_SOURCE_DIR}")
+set(RunCTest_VERBOSE_FLAG "-VV")
+
+run_ctest(ENVIRONMENT_MODIFICATION-invalid-op)
+run_ctest(ENVIRONMENT_MODIFICATION-no-colon)
+run_ctest(ENVIRONMENT_MODIFICATION-no-equals)
diff --git a/Tests/RunCMake/ctest_environment/test.cmake.in b/Tests/RunCMake/ctest_environment/test.cmake.in
new file mode 100644
index 0000000..ca23c83
--- /dev/null
+++ b/Tests/RunCMake/ctest_environment/test.cmake.in
@@ -0,0 +1,16 @@
+cmake_minimum_required(VERSION 3.7)
+
+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}")
+
+set(ctest_test_args "@CASE_CTEST_TEST_ARGS@")
+ctest_start(Experimental)
+ctest_configure()
+ctest_build()
+ctest_test(${ctest_test_args})
diff --git a/Tests/RunCMake/ctest_test/RunCMakeTest.cmake b/Tests/RunCMake/ctest_test/RunCMakeTest.cmake
index 5f9b32d..de81049 100644
--- a/Tests/RunCMake/ctest_test/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ctest_test/RunCMakeTest.cmake
@@ -158,13 +158,25 @@ add_test(
COMMAND ${CMAKE_COMMAND} -E
echo <DartMeasurement type="numeric/double" name="my_custom_value">1.4847</DartMeasurement>)
add_test(
+ NAME double_measurement2
+ COMMAND ${CMAKE_COMMAND} -E
+ echo <CTestMeasurement type="numeric/double" name="another_custom_value">1.8474</CTestMeasurement>)
+add_test(
NAME img_measurement
COMMAND ${CMAKE_COMMAND} -E
echo <DartMeasurementFile name="TestImage" type="image/png">]] ${IMAGE_DIR}/cmake-logo-16.png [[</DartMeasurementFile>)
add_test(
+ NAME img_measurement2
+ COMMAND ${CMAKE_COMMAND} -E
+ echo <CTestMeasurementFile name="TestImage2" type="image/png">]] ${IMAGE_DIR}/cmake-logo-16.png [[</CTestMeasurementFile>)
+add_test(
NAME file_measurement
COMMAND ${CMAKE_COMMAND} -E
echo <DartMeasurementFile name="my_test_input_data" type="file">]] ${IMAGE_DIR}/cmake-logo-16.png [[</DartMeasurementFile>)
+add_test(
+ NAME file_measurement2
+ COMMAND ${CMAKE_COMMAND} -E
+ echo <CTestMeasurementFile name="another_test_input_data" type="file">]] ${IMAGE_DIR}/cmake-logo-16.png [[</CTestMeasurementFile>)
]])
run_ctest(TestMeasurements)
endfunction()
@@ -194,3 +206,16 @@ set_property(TEST b PROPERTY LABELS b)
run_ctest(TestChangingLabels)
endfunction()
run_changing_labels()
+
+# Verify that test output can add additional labels
+function(run_extra_labels)
+ set(CASE_CMAKELISTS_SUFFIX_CODE [[
+add_test(
+ NAME custom_labels
+ COMMAND ${CMAKE_COMMAND} -E
+ echo before\n<CTestLabel>label2</CTestLabel>\n<CTestLabel>label1</CTestLabel>\n<CTestLabel>label3</CTestLabel>\n<CTestLabel>label2</CTestLabel>\nafter)
+set_tests_properties(custom_labels PROPERTIES LABELS "label1")
+ ]])
+ run_ctest(TestExtraLabels)
+endfunction()
+run_extra_labels()
diff --git a/Tests/RunCMake/ctest_test/TestExtraLabels-check.cmake b/Tests/RunCMake/ctest_test/TestExtraLabels-check.cmake
new file mode 100644
index 0000000..eaa50d1
--- /dev/null
+++ b/Tests/RunCMake/ctest_test/TestExtraLabels-check.cmake
@@ -0,0 +1,25 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/Testing/TAG" _tag)
+string(REGEX REPLACE "^([^\n]*)\n.*$" "\\1" _date "${_tag}")
+file(READ "${RunCMake_TEST_BINARY_DIR}/Testing/${_date}/Test.xml" _test_contents)
+
+# Check labels.
+STRING(REGEX MATCHALL [[<Label>label1</Label>]] matches "${_test_contents}")
+list(LENGTH matches n_matches)
+if(NOT n_matches EQUAL 1)
+ string(APPEND RunCMake_TEST_FAILED "expected 1 match for label1, found ${n_matches}")
+endif()
+STRING(REGEX MATCHALL [[<Label>label2</Label>]] matches "${_test_contents}")
+list(LENGTH matches n_matches)
+if(NOT n_matches EQUAL 1)
+ string(APPEND RunCMake_TEST_FAILED "expected 1 match for label2, found ${n_matches}")
+endif()
+STRING(REGEX MATCHALL [[<Label>label3</Label>]] matches "${_test_contents}")
+list(LENGTH matches n_matches)
+if(NOT n_matches EQUAL 1)
+ string(APPEND RunCMake_TEST_FAILED "expected 1 match for label3, found ${n_matches}")
+endif()
+
+# Check test output.
+if(NOT _test_contents MATCHES "<Value>before\nafter\n</Value>")
+ string(APPEND RunCMake_TEST_FAILED "Could not find expected output in Test.xml")
+endif()
diff --git a/Tests/RunCMake/ctest_test/TestMeasurements-check.cmake b/Tests/RunCMake/ctest_test/TestMeasurements-check.cmake
index 0095db0..7e0928d 100644
--- a/Tests/RunCMake/ctest_test/TestMeasurements-check.cmake
+++ b/Tests/RunCMake/ctest_test/TestMeasurements-check.cmake
@@ -10,13 +10,31 @@ endif()
if(NOT _test_contents MATCHES "<Value>1.4847</Value>")
string(APPEND RunCMake_TEST_FAILED "Could not find expected measurement value in Test.xml")
endif()
+# Check the other double measurement.
+if(NOT _test_contents MATCHES [[NamedMeasurement type="numeric/double" name="another_custom_value"]])
+ string(APPEND RunCMake_TEST_FAILED
+ "Could not find expected <NamedMeasurement> tag(2) for type='numeric/double' in Test.xml")
+endif()
+if(NOT _test_contents MATCHES "<Value>1.8474</Value>")
+ string(APPEND RunCMake_TEST_FAILED "Could not find expected measurement value(2) in Test.xml")
+endif()
# Check img measurement.
if(NOT _test_contents MATCHES [[NamedMeasurement name="TestImage" type="image/png" encoding="base64"]])
string(APPEND RunCMake_TEST_FAILED
"Could not find expected <NamedMeasurement> tag for type='image/png' in Test.xml")
endif()
+# Check img measurement 2.
+if(NOT _test_contents MATCHES [[NamedMeasurement name="TestImage2" type="image/png" encoding="base64"]])
+ string(APPEND RunCMake_TEST_FAILED
+ "Could not find expected <NamedMeasurement> tag(2) for type='image/png' in Test.xml")
+endif()
# Check file measurement.
if(NOT _test_contents MATCHES [[NamedMeasurement name="my_test_input_data" encoding="base64" compression="tar/gzip" filename="cmake-logo-16.png" type="file"]])
string(APPEND RunCMake_TEST_FAILED
"Could not find expected <NamedMeasurement> tag for type='file' in Test.xml")
endif()
+# Check file measurement 2.
+if(NOT _test_contents MATCHES [[NamedMeasurement name="another_test_input_data" encoding="base64" compression="tar/gzip" filename="cmake-logo-16.png" type="file"]])
+ string(APPEND RunCMake_TEST_FAILED
+ "Could not find expected <NamedMeasurement> tag(2) for type='file' in Test.xml")
+endif()
diff --git a/Tests/RunCMake/file-RPATH/RunCMakeTest.cmake b/Tests/RunCMake/file-RPATH/RunCMakeTest.cmake
index eb7b497..1ca2e75 100644
--- a/Tests/RunCMake/file-RPATH/RunCMakeTest.cmake
+++ b/Tests/RunCMake/file-RPATH/RunCMakeTest.cmake
@@ -1,8 +1,6 @@
include(RunCMake)
-if(HAVE_ELF_H)
- run_cmake_command(ELF ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/ELF.cmake)
-endif()
+run_cmake_command(ELF ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/ELF.cmake)
if(CMAKE_SYSTEM_NAME STREQUAL "AIX")
run_cmake_command(XCOFF ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/XCOFF.cmake)
diff --git a/Tests/RunCMake/find_library/FromScriptMode-stderr-darwin.txt b/Tests/RunCMake/find_library/FromScriptMode-stderr-darwin.txt
new file mode 100644
index 0000000..185720b
--- /dev/null
+++ b/Tests/RunCMake/find_library/FromScriptMode-stderr-darwin.txt
@@ -0,0 +1,4 @@
+.*find_library considered the following locations.*
+.*\(lib\)library_no_exist\(\\.tbd\|\\.dylib\|\\.so\|\\.a\).*
+.*The item was found at.*
+.*lib/libcreated.a.*
diff --git a/Tests/RunCMake/find_library/FromScriptMode-stderr-windows.txt b/Tests/RunCMake/find_library/FromScriptMode-stderr-windows.txt
new file mode 100644
index 0000000..501ec0f
--- /dev/null
+++ b/Tests/RunCMake/find_library/FromScriptMode-stderr-windows.txt
@@ -0,0 +1,4 @@
+.*find_library considered the following locations.*
+.*\(\|lib\)library_no_exist\(\\.lib\|\\.dll\\.a\|\\.a\).*
+.*The item was found at.*
+.*lib/libcreated.a.*
diff --git a/Tests/RunCMake/find_library/FromScriptMode-stderr.txt b/Tests/RunCMake/find_library/FromScriptMode-stderr.txt
new file mode 100644
index 0000000..046f680
--- /dev/null
+++ b/Tests/RunCMake/find_library/FromScriptMode-stderr.txt
@@ -0,0 +1,4 @@
+.*find_library considered the following locations.*
+.*\(lib\)library_no_exist\(\\.so\|\\.a\).*
+.*The item was found at.*
+.*lib/libcreated.a.*
diff --git a/Tests/RunCMake/find_library/FromScriptMode.cmake b/Tests/RunCMake/find_library/FromScriptMode.cmake
new file mode 100644
index 0000000..4d3c699
--- /dev/null
+++ b/Tests/RunCMake/find_library/FromScriptMode.cmake
@@ -0,0 +1,15 @@
+
+if(TEMP_DIR)
+ file(REMOVE_RECURSE "${TEMP_DIR}")
+ file(MAKE_DIRECTORY "${TEMP_DIR}")
+ file(MAKE_DIRECTORY "${TEMP_DIR}/lib")
+ file(WRITE "${TEMP_DIR}/lib/libcreated.a" "created")
+endif()
+
+set(CMAKE_FIND_DEBUG_MODE 1)
+find_library(CREATED_LIBRARY NAMES library_no_exist)
+
+set(CMAKE_PREFIX_PATH "${TEMP_DIR}")
+find_library(CREATED_LIBRARY NAMES created)
+message(STATUS "CREATED_LIBRARY='${CREATED_LIBRARY}'")
+set(CMAKE_FIND_DEBUG_MODE 0)
diff --git a/Tests/RunCMake/find_library/RunCMakeTest.cmake b/Tests/RunCMake/find_library/RunCMakeTest.cmake
index e297173..ad02c82 100644
--- a/Tests/RunCMake/find_library/RunCMakeTest.cmake
+++ b/Tests/RunCMake/find_library/RunCMakeTest.cmake
@@ -10,3 +10,5 @@ endif()
run_cmake(PrefixInPATH)
run_cmake(Required)
run_cmake(NO_CACHE)
+
+run_cmake_script(FromScriptMode "-DTEMP_DIR=${RunCMake_BINARY_DIR}/FromScriptMode-temp")
diff --git a/Tests/RunCMake/find_package/CMP0084-OLD-stderr.txt b/Tests/RunCMake/find_package/CMP0084-OLD-stderr.txt
new file mode 100644
index 0000000..0db83aa
--- /dev/null
+++ b/Tests/RunCMake/find_package/CMP0084-OLD-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at CMP0084-OLD.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0084 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/find_package/MissingNormalForceRequired-result.txt b/Tests/RunCMake/find_package/MissingNormalForceRequired-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/find_package/MissingNormalForceRequired-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/find_package/MissingNormalForceRequired-stderr.txt b/Tests/RunCMake/find_package/MissingNormalForceRequired-stderr.txt
new file mode 100644
index 0000000..f6c0b44
--- /dev/null
+++ b/Tests/RunCMake/find_package/MissingNormalForceRequired-stderr.txt
@@ -0,0 +1,20 @@
+CMake Error at MissingNormalForceRequired.cmake:2 \(find_package\):
+ No "FindNotHere.cmake" found in CMAKE_MODULE_PATH\.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Warning \(dev\) at MissingNormalForceRequired.cmake:2 \(find_package\):
+ FindNotHere.cmake must either be part of this project itself, in this case
+ adjust CMAKE_MODULE_PATH so that it points to the correct location inside
+ its source tree\.
+
+ Or it must be installed by a package which has already been found via
+ find_package\(\)\. In this case make sure that package has indeed been found
+ and adjust CMAKE_MODULE_PATH to contain the location where that package has
+ installed FindNotHere\.cmake\. This must be a location provided by that
+ package. This error in general means that the buildsystem of this project
+ is relying on a Find-module without ensuring that it is actually available\.
+
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it\.
diff --git a/Tests/RunCMake/find_package/MissingNormalForceRequired.cmake b/Tests/RunCMake/find_package/MissingNormalForceRequired.cmake
new file mode 100644
index 0000000..5935316
--- /dev/null
+++ b/Tests/RunCMake/find_package/MissingNormalForceRequired.cmake
@@ -0,0 +1,3 @@
+set(CMAKE_REQUIRE_FIND_PACKAGE_NotHere ON)
+find_package(NotHere MODULE)
+message(FATAL_ERROR "This error must not be reachable.")
diff --git a/Tests/RunCMake/find_package/RequiredOptionValuesClash-result.txt b/Tests/RunCMake/find_package/RequiredOptionValuesClash-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/find_package/RequiredOptionValuesClash-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/find_package/RequiredOptionValuesClash-stderr.txt b/Tests/RunCMake/find_package/RequiredOptionValuesClash-stderr.txt
new file mode 100644
index 0000000..b4fdd98
--- /dev/null
+++ b/Tests/RunCMake/find_package/RequiredOptionValuesClash-stderr.txt
@@ -0,0 +1,11 @@
+CMake Error at RequiredOptionValuesClash.cmake:4 \(find_package\):
+ find_package for module Foo was made REQUIRED with
+ CMAKE_REQUIRE_FIND_PACKAGE_Foo but CMAKE_DISABLE_FIND_PACKAGE_Foo is
+ enabled. A REQUIRED package cannot be disabled.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
++
+CMake Error at RequiredOptionValuesClash.cmake:5 \(message\):
+ This error must not be reachable\.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/find_package/RequiredOptionValuesClash.cmake b/Tests/RunCMake/find_package/RequiredOptionValuesClash.cmake
new file mode 100644
index 0000000..04fece7
--- /dev/null
+++ b/Tests/RunCMake/find_package/RequiredOptionValuesClash.cmake
@@ -0,0 +1,5 @@
+set(CMAKE_DISABLE_FIND_PACKAGE_Foo ON)
+set(CMAKE_REQUIRE_FIND_PACKAGE_Foo ON)
+
+find_package(Foo)
+message(FATAL_ERROR "This error must not be reachable.")
diff --git a/Tests/RunCMake/find_package/RunCMakeTest.cmake b/Tests/RunCMake/find_package/RunCMakeTest.cmake
index 3ba04c8..b20a889 100644
--- a/Tests/RunCMake/find_package/RunCMakeTest.cmake
+++ b/Tests/RunCMake/find_package/RunCMakeTest.cmake
@@ -6,6 +6,7 @@ run_cmake(ComponentRequiredAndOptional)
run_cmake(FromPATHEnv)
run_cmake(FromPrefixPath)
run_cmake(MissingNormal)
+run_cmake(MissingNormalForceRequired)
run_cmake(MissingNormalRequired)
run_cmake(MissingNormalVersion)
run_cmake(MissingNormalWarnNoModuleOld)
@@ -23,6 +24,7 @@ run_cmake(PackageRootNestedConfig)
run_cmake(PackageRootNestedModule)
run_cmake(PolicyPush)
run_cmake(PolicyPop)
+run_cmake(RequiredOptionValuesClash)
run_cmake(SetFoundFALSE)
run_cmake(WrongVersion)
run_cmake(WrongVersionConfig)
diff --git a/Tests/RunCMake/if/IncompleteMatches-stdout.txt b/Tests/RunCMake/if/IncompleteMatches-stdout.txt
new file mode 100644
index 0000000..634d988
--- /dev/null
+++ b/Tests/RunCMake/if/IncompleteMatches-stdout.txt
@@ -0,0 +1,6 @@
+-- Test #1 passed
+-- Test #2 passed
+-- Test #3 passed
+-- Test #4 passed
+-- Test #5 passed
+-- Test #6 passed
diff --git a/Tests/RunCMake/if/IncompleteMatches.cmake b/Tests/RunCMake/if/IncompleteMatches.cmake
new file mode 100644
index 0000000..7142cfc
--- /dev/null
+++ b/Tests/RunCMake/if/IncompleteMatches.cmake
@@ -0,0 +1,36 @@
+if(MATCHES)
+ message(SEND_ERROR "Test #1 failed")
+else()
+ message(STATUS "Test #1 passed")
+endif()
+
+if("" MATCHES "")
+ message(STATUS "Test #2 passed")
+else()
+ message(SEND_ERROR "Test #2 failed")
+endif()
+
+if(MATCHES RHS)
+ message(SEND_ERROR "Test #3 failed")
+else()
+ message(STATUS "Test #3 passed")
+endif()
+
+set(RHS "")
+if(MATCHES RHS)
+ message(SEND_ERROR "Test #4 failed")
+else()
+ message(STATUS "Test #4 passed")
+endif()
+
+if(MATCHES "^$")
+ message(SEND_ERROR "Test #5 failed")
+else()
+ message(STATUS "Test #5 passed")
+endif()
+
+if("" MATCHES "^$")
+ message(STATUS "Test #6 passed")
+else()
+ message(SEND_ERROR "Test #6 failed")
+endif()
diff --git a/Tests/RunCMake/if/IncompleteMatchesFail-result.txt b/Tests/RunCMake/if/IncompleteMatchesFail-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/if/IncompleteMatchesFail-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/if/IncompleteMatchesFail-stderr.txt b/Tests/RunCMake/if/IncompleteMatchesFail-stderr.txt
new file mode 100644
index 0000000..6e8ac80
--- /dev/null
+++ b/Tests/RunCMake/if/IncompleteMatchesFail-stderr.txt
@@ -0,0 +1,6 @@
+CMake Error at IncompleteMatchesFail\.cmake:1 \(if\):
+ if given arguments:
+
+ "LHS" "MATCHES"
+
+ Unknown arguments specified
diff --git a/Tests/RunCMake/if/IncompleteMatchesFail.cmake b/Tests/RunCMake/if/IncompleteMatchesFail.cmake
new file mode 100644
index 0000000..a3ef2b8
--- /dev/null
+++ b/Tests/RunCMake/if/IncompleteMatchesFail.cmake
@@ -0,0 +1,2 @@
+if(LHS MATCHES)
+endif()
diff --git a/Tests/RunCMake/if/RunCMakeTest.cmake b/Tests/RunCMake/if/RunCMakeTest.cmake
index f54edf7..6baa840 100644
--- a/Tests/RunCMake/if/RunCMakeTest.cmake
+++ b/Tests/RunCMake/if/RunCMakeTest.cmake
@@ -9,7 +9,11 @@ run_cmake(duplicate-else-after-elseif)
run_cmake(elseif-message)
run_cmake(misplaced-elseif)
+run_cmake(unbalanced-parenthesis)
+
run_cmake(MatchesSelf)
+run_cmake(IncompleteMatches)
+run_cmake(IncompleteMatchesFail)
run_cmake(TestNameThatExists)
run_cmake(TestNameThatDoesNotExist)
diff --git a/Tests/RunCMake/if/unbalanced-parenthesis-result.txt b/Tests/RunCMake/if/unbalanced-parenthesis-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/if/unbalanced-parenthesis-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/if/unbalanced-parenthesis-stderr.txt b/Tests/RunCMake/if/unbalanced-parenthesis-stderr.txt
new file mode 100644
index 0000000..770ccb8f
--- /dev/null
+++ b/Tests/RunCMake/if/unbalanced-parenthesis-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at unbalanced-parenthesis\.cmake:[0-9]+ \(if\):
+ if given arguments:
+
+ "NOT" "\(" "IN_LIST" "some_list"
+
+ mismatched parenthesis in condition
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/if/unbalanced-parenthesis.cmake b/Tests/RunCMake/if/unbalanced-parenthesis.cmake
new file mode 100644
index 0000000..c51c755
--- /dev/null
+++ b/Tests/RunCMake/if/unbalanced-parenthesis.cmake
@@ -0,0 +1,8 @@
+set(var_with_paren "(")
+set(some_list "")
+
+if(NOT ${var_with_paren} IN_LIST some_list)
+ message(STATUS "Never prints")
+else()
+ message(STATUS "Never prints")
+endif()
diff --git a/Tests/RunCMake/install/CMP0087-OLD-stderr.txt b/Tests/RunCMake/install/CMP0087-OLD-stderr.txt
new file mode 100644
index 0000000..5233ebc
--- /dev/null
+++ b/Tests/RunCMake/install/CMP0087-OLD-stderr.txt
@@ -0,0 +1,8 @@
+^CMake Deprecation Warning at CMP0087-OLD/CMakeLists.txt:5 \(cmake_policy\):
+ The OLD behavior for policy CMP0087 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.$
diff --git a/Tests/RunCMake/string/Timestamp-stderr.txt b/Tests/RunCMake/string/Timestamp-stderr.txt
index cd4dcb3..d54777b 100644
--- a/Tests/RunCMake/string/Timestamp-stderr.txt
+++ b/Tests/RunCMake/string/Timestamp-stderr.txt
@@ -1 +1 @@
-RESULT=2005-08-07 23:19:49 Sunday=Sun August=Aug 05 day=219 wd=0 week=32 %I=11 epoch=1123456789
+RESULT=2005-08-07 23:19:49 Sunday=Sun August=Aug 05 day=219 wd=0 week=32 w_iso=31 %I=11 epoch=1123456789
diff --git a/Tests/RunCMake/string/Timestamp.cmake b/Tests/RunCMake/string/Timestamp.cmake
index cba258d..7fd6d72 100644
--- a/Tests/RunCMake/string/Timestamp.cmake
+++ b/Tests/RunCMake/string/Timestamp.cmake
@@ -1,3 +1,3 @@
set(ENV{SOURCE_DATE_EPOCH} "1123456789")
-string(TIMESTAMP RESULT "%Y-%m-%d %H:%M:%S %A=%a %B=%b %y day=%j wd=%w week=%U %%I=%I epoch=%s" UTC)
+string(TIMESTAMP RESULT "%Y-%m-%d %H:%M:%S %A=%a %B=%b %y day=%j wd=%w week=%U w_iso=%V %%I=%I epoch=%s" UTC)
message("RESULT=${RESULT}")
diff --git a/Tests/RunCMake/target_compile_features/cxx_not_enabled-stderr.txt b/Tests/RunCMake/target_compile_features/cxx_not_enabled-stderr.txt
index 5b4761c..cf4c540 100644
--- a/Tests/RunCMake/target_compile_features/cxx_not_enabled-stderr.txt
+++ b/Tests/RunCMake/target_compile_features/cxx_not_enabled-stderr.txt
@@ -1,4 +1,2 @@
-^CMake Error at cxx_not_enabled.cmake:[0-9]+ \(target_compile_features\):
- target_compile_features cannot use features from non-enabled language CXX
-Call Stack \(most recent call first\):
- CMakeLists\.txt:[0-9]+ \(include\)$
+^CMake Error:.*CMake can not determine linker language for target: main.*
+CMake Generate step failed. Build files cannot be regenerated correctly.$
diff --git a/Tests/RunCMake/while/RunCMakeTest.cmake b/Tests/RunCMake/while/RunCMakeTest.cmake
index 7da80ac..bb9b991 100644
--- a/Tests/RunCMake/while/RunCMakeTest.cmake
+++ b/Tests/RunCMake/while/RunCMakeTest.cmake
@@ -5,3 +5,5 @@ run_cmake(EndMissing)
run_cmake(EndMismatch)
run_cmake(EndAlone)
run_cmake(EndAloneArgs)
+
+run_cmake(unbalanced-parenthesis)
diff --git a/Tests/RunCMake/while/unbalanced-parenthesis-result.txt b/Tests/RunCMake/while/unbalanced-parenthesis-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/while/unbalanced-parenthesis-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/while/unbalanced-parenthesis-stderr.txt b/Tests/RunCMake/while/unbalanced-parenthesis-stderr.txt
new file mode 100644
index 0000000..9d4132c
--- /dev/null
+++ b/Tests/RunCMake/while/unbalanced-parenthesis-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at unbalanced-parenthesis.cmake:[0-9]+ \(while\):
+ had incorrect arguments:
+
+ "NOT" "\(" "IN_LIST" "some_list"
+
+ mismatched parenthesis in condition
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/while/unbalanced-parenthesis.cmake b/Tests/RunCMake/while/unbalanced-parenthesis.cmake
new file mode 100644
index 0000000..7a12701
--- /dev/null
+++ b/Tests/RunCMake/while/unbalanced-parenthesis.cmake
@@ -0,0 +1,8 @@
+set(var_with_paren "(")
+set(some_list "")
+
+while(NOT ${var_with_paren} IN_LIST some_list)
+ message(STATUS "Never prints")
+endwhile()
+
+message(STATUS "Never prints")
diff --git a/Tests/UseSWIG/CMakeLists.txt b/Tests/UseSWIG/CMakeLists.txt
index f1b2f32..c3f9e03 100644
--- a/Tests/UseSWIG/CMakeLists.txt
+++ b/Tests/UseSWIG/CMakeLists.txt
@@ -67,7 +67,7 @@ add_test(NAME UseSWIG.BasicPerl COMMAND
--test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
)
if(SWIG_FOUND AND NOT SWIG_VERSION VERSION_LESS "4.0.2"
- AND CMAKE_GENERATOR MATCHES "Make|Ninja|Xcode")
+ AND CMAKE_GENERATOR MATCHES "Make|Ninja|Xcode|Visual Studio (1[1-9]|[2-9][0-9])")
add_test(NAME UseSWIG.Depfile.BasicPython COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
diff --git a/Utilities/Doxygen/CMakeLists.txt b/Utilities/Doxygen/CMakeLists.txt
index 0ccb721..69b4e2f 100644
--- a/Utilities/Doxygen/CMakeLists.txt
+++ b/Utilities/Doxygen/CMakeLists.txt
@@ -3,7 +3,7 @@
if(NOT CMake_SOURCE_DIR)
set(CMakeDeveloperReference_STANDALONE 1)
- cmake_minimum_required(VERSION 3.1...3.19 FATAL_ERROR)
+ cmake_minimum_required(VERSION 3.1...3.20 FATAL_ERROR)
get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH)
get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH)
include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake)
diff --git a/Utilities/KWIML/include/kwiml/int.h b/Utilities/KWIML/include/kwiml/int.h
index b2e14d5..25a063a 100644
--- a/Utilities/KWIML/include/kwiml/int.h
+++ b/Utilities/KWIML/include/kwiml/int.h
@@ -162,7 +162,11 @@ An includer may test the following macros after inclusion:
#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
# define KWIML_INT_HAVE_INTTYPES_H 1
#elif defined(_MSC_VER) /* MSVC */
-# define KWIML_INT_NO_INTTYPES_H 1
+# if _MSC_VER >= 1800
+# define KWIML_INT_HAVE_INTTYPES_H 1
+# else
+# define KWIML_INT_NO_INTTYPES_H 1
+# endif
#elif defined(__BORLANDC__) /* Borland */
# define KWIML_INT_NO_INTTYPES_H 1
#elif defined(__WATCOMC__) /* Watcom */
@@ -272,6 +276,15 @@ An includer may test the following macros after inclusion:
# define KWIML_INT_BROKEN_PRIXPTR 1
#endif
+#if defined(_MSC_VER) && _MSC_VER < 1900
+ /* MSVC scanf seems broken on 8-bit sizes until 19.00 */
+# define KWIML_INT_BROKEN_SCNd8 1
+# define KWIML_INT_BROKEN_SCNi8 1
+# define KWIML_INT_BROKEN_SCNo8 1
+# define KWIML_INT_BROKEN_SCNu8 1
+# define KWIML_INT_BROKEN_SCNx8 1
+#endif
+
#if (defined(__SUNPRO_C)||defined(__SUNPRO_CC)) && defined(_CHAR_IS_UNSIGNED)
# define KWIML_INT_BROKEN_INT8_T 1 /* system type defined incorrectly */
#elif defined(__BORLANDC__) && defined(_CHAR_UNSIGNED)
@@ -303,7 +316,7 @@ An includer may test the following macros after inclusion:
#elif defined(__BORLANDC__)
# define KWIML_INT_private_NO_SCN8
# define KWIML_INT_private_NO_SCN64
-#elif defined(_MSC_VER)
+#elif defined(_MSC_VER) && _MSC_VER < 1900
# define KWIML_INT_private_NO_SCN8
#elif defined(__WATCOMC__)
# define KWIML_INT_private_NO_SCN8
diff --git a/Utilities/Scripts/update-elf.bash b/Utilities/Scripts/update-elf.bash
new file mode 100755
index 0000000..1a065ba
--- /dev/null
+++ b/Utilities/Scripts/update-elf.bash
@@ -0,0 +1,28 @@
+#!/usr/bin/env bash
+
+set -e
+set -x
+shopt -s dotglob
+
+readonly name="elf"
+readonly ownership="FreeBSD Upstream <kwrobot@kitware.com>"
+readonly subtree="Utilities/cmelf"
+readonly repo="https://github.com/freebsd/freebsd-src.git"
+readonly tag="main"
+readonly shortlog=false
+readonly paths="
+ sys/sys/elf32.h
+ sys/sys/elf64.h
+ sys/sys/elf_common.h
+"
+
+extract_source () {
+ git_archive
+ pushd "${extractdir}/${name}-reduced"
+ echo "* -whitespace" > .gitattributes
+ mv sys/sys/* .
+ sed -i -e 's/<sys\/elf_common.h>/"elf_common.h"/g' -e 's/u_int32_t/uint32_t/g' *.h
+ popd
+}
+
+. "${BASH_SOURCE%/*}/update-third-party.bash"
diff --git a/Utilities/Scripts/update-libarchive.bash b/Utilities/Scripts/update-libarchive.bash
index 3db89ff..3a24e2b 100755
--- a/Utilities/Scripts/update-libarchive.bash
+++ b/Utilities/Scripts/update-libarchive.bash
@@ -8,7 +8,7 @@ readonly name="LibArchive"
readonly ownership="LibArchive Upstream <libarchive-discuss@googlegroups.com>"
readonly subtree="Utilities/cmlibarchive"
readonly repo="https://github.com/libarchive/libarchive.git"
-readonly tag="v3.4.2"
+readonly tag="v3.5.1"
readonly shortlog=false
readonly paths="
CMakeLists.txt
diff --git a/Utilities/Sphinx/CMakeLists.txt b/Utilities/Sphinx/CMakeLists.txt
index 32efd48..a71dfcd 100644
--- a/Utilities/Sphinx/CMakeLists.txt
+++ b/Utilities/Sphinx/CMakeLists.txt
@@ -3,7 +3,7 @@
if(NOT CMake_SOURCE_DIR)
set(CMakeHelp_STANDALONE 1)
- cmake_minimum_required(VERSION 3.1...3.19 FATAL_ERROR)
+ cmake_minimum_required(VERSION 3.1...3.20 FATAL_ERROR)
get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH)
get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH)
include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake)
diff --git a/Utilities/cmThirdPartyChecks.cmake b/Utilities/cmThirdPartyChecks.cmake
index bab3046..7e38df9 100644
--- a/Utilities/cmThirdPartyChecks.cmake
+++ b/Utilities/cmThirdPartyChecks.cmake
@@ -180,6 +180,7 @@ if(WIN32)
set(HAVE_STRERROR_R 0)
set(HAVE_STRNCMPI 0)
set(HAVE_STRNCPY_S 1)
+ set(HAVE_STRNLEN 1)
set(HAVE_STROPTS_H 0)
set(HAVE__STRTOI64 1)
set(HAVE_STRTOLL 1)
diff --git a/Utilities/cmelf/.gitattributes b/Utilities/cmelf/.gitattributes
new file mode 100644
index 0000000..562b12e
--- /dev/null
+++ b/Utilities/cmelf/.gitattributes
@@ -0,0 +1 @@
+* -whitespace
diff --git a/Utilities/cmelf/elf32.h b/Utilities/cmelf/elf32.h
new file mode 100644
index 0000000..20d2ec2
--- /dev/null
+++ b/Utilities/cmelf/elf32.h
@@ -0,0 +1,265 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 1996-1998 John D. Polstra.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_ELF32_H_
+#define _SYS_ELF32_H_ 1
+
+#include "elf_common.h"
+
+/*
+ * ELF definitions common to all 32-bit architectures.
+ */
+
+typedef uint32_t Elf32_Addr;
+typedef uint16_t Elf32_Half;
+typedef uint32_t Elf32_Off;
+typedef int32_t Elf32_Sword;
+typedef uint32_t Elf32_Word;
+typedef uint64_t Elf32_Lword;
+
+typedef Elf32_Word Elf32_Hashelt;
+
+/* Non-standard class-dependent datatype used for abstraction. */
+typedef Elf32_Word Elf32_Size;
+typedef Elf32_Sword Elf32_Ssize;
+
+/*
+ * ELF header.
+ */
+
+typedef struct {
+ unsigned char e_ident[EI_NIDENT]; /* File identification. */
+ Elf32_Half e_type; /* File type. */
+ Elf32_Half e_machine; /* Machine architecture. */
+ Elf32_Word e_version; /* ELF format version. */
+ Elf32_Addr e_entry; /* Entry point. */
+ Elf32_Off e_phoff; /* Program header file offset. */
+ Elf32_Off e_shoff; /* Section header file offset. */
+ Elf32_Word e_flags; /* Architecture-specific flags. */
+ Elf32_Half e_ehsize; /* Size of ELF header in bytes. */
+ Elf32_Half e_phentsize; /* Size of program header entry. */
+ Elf32_Half e_phnum; /* Number of program header entries. */
+ Elf32_Half e_shentsize; /* Size of section header entry. */
+ Elf32_Half e_shnum; /* Number of section header entries. */
+ Elf32_Half e_shstrndx; /* Section name strings section. */
+} Elf32_Ehdr;
+
+/*
+ * Shared object information, found in SHT_MIPS_LIBLIST.
+ */
+
+typedef struct {
+ Elf32_Word l_name; /* The name of a shared object. */
+ Elf32_Word l_time_stamp; /* 32-bit timestamp. */
+ Elf32_Word l_checksum; /* Checksum of visible symbols, sizes. */
+ Elf32_Word l_version; /* Interface version string index. */
+ Elf32_Word l_flags; /* Flags (LL_*). */
+} Elf32_Lib;
+
+/*
+ * Section header.
+ */
+
+typedef struct {
+ Elf32_Word sh_name; /* Section name (index into the
+ section header string table). */
+ Elf32_Word sh_type; /* Section type. */
+ Elf32_Word sh_flags; /* Section flags. */
+ Elf32_Addr sh_addr; /* Address in memory image. */
+ Elf32_Off sh_offset; /* Offset in file. */
+ Elf32_Word sh_size; /* Size in bytes. */
+ Elf32_Word sh_link; /* Index of a related section. */
+ Elf32_Word sh_info; /* Depends on section type. */
+ Elf32_Word sh_addralign; /* Alignment in bytes. */
+ Elf32_Word sh_entsize; /* Size of each entry in section. */
+} Elf32_Shdr;
+
+/*
+ * Program header.
+ */
+
+typedef struct {
+ Elf32_Word p_type; /* Entry type. */
+ Elf32_Off p_offset; /* File offset of contents. */
+ Elf32_Addr p_vaddr; /* Virtual address in memory image. */
+ Elf32_Addr p_paddr; /* Physical address (not used). */
+ Elf32_Word p_filesz; /* Size of contents in file. */
+ Elf32_Word p_memsz; /* Size of contents in memory. */
+ Elf32_Word p_flags; /* Access permission flags. */
+ Elf32_Word p_align; /* Alignment in memory and file. */
+} Elf32_Phdr;
+
+/*
+ * Dynamic structure. The ".dynamic" section contains an array of them.
+ */
+
+typedef struct {
+ Elf32_Sword d_tag; /* Entry type. */
+ union {
+ Elf32_Word d_val; /* Integer value. */
+ Elf32_Addr d_ptr; /* Address value. */
+ } d_un;
+} Elf32_Dyn;
+
+/*
+ * Relocation entries.
+ */
+
+/* Relocations that don't need an addend field. */
+typedef struct {
+ Elf32_Addr r_offset; /* Location to be relocated. */
+ Elf32_Word r_info; /* Relocation type and symbol index. */
+} Elf32_Rel;
+
+/* Relocations that need an addend field. */
+typedef struct {
+ Elf32_Addr r_offset; /* Location to be relocated. */
+ Elf32_Word r_info; /* Relocation type and symbol index. */
+ Elf32_Sword r_addend; /* Addend. */
+} Elf32_Rela;
+
+/* Macros for accessing the fields of r_info. */
+#define ELF32_R_SYM(info) ((info) >> 8)
+#define ELF32_R_TYPE(info) ((unsigned char)(info))
+
+/* Macro for constructing r_info from field values. */
+#define ELF32_R_INFO(sym, type) (((sym) << 8) + (unsigned char)(type))
+
+/*
+ * Note entry header
+ */
+typedef Elf_Note Elf32_Nhdr;
+
+/*
+ * Move entry
+ */
+typedef struct {
+ Elf32_Lword m_value; /* symbol value */
+ Elf32_Word m_info; /* size + index */
+ Elf32_Word m_poffset; /* symbol offset */
+ Elf32_Half m_repeat; /* repeat count */
+ Elf32_Half m_stride; /* stride info */
+} Elf32_Move;
+
+/*
+ * The macros compose and decompose values for Move.r_info
+ *
+ * sym = ELF32_M_SYM(M.m_info)
+ * size = ELF32_M_SIZE(M.m_info)
+ * M.m_info = ELF32_M_INFO(sym, size)
+ */
+#define ELF32_M_SYM(info) ((info)>>8)
+#define ELF32_M_SIZE(info) ((unsigned char)(info))
+#define ELF32_M_INFO(sym, size) (((sym)<<8)+(unsigned char)(size))
+
+/*
+ * Hardware/Software capabilities entry
+ */
+typedef struct {
+ Elf32_Word c_tag; /* how to interpret value */
+ union {
+ Elf32_Word c_val;
+ Elf32_Addr c_ptr;
+ } c_un;
+} Elf32_Cap;
+
+/*
+ * Symbol table entries.
+ */
+
+typedef struct {
+ Elf32_Word st_name; /* String table index of name. */
+ Elf32_Addr st_value; /* Symbol value. */
+ Elf32_Word st_size; /* Size of associated object. */
+ unsigned char st_info; /* Type and binding information. */
+ unsigned char st_other; /* Reserved (not used). */
+ Elf32_Half st_shndx; /* Section index of symbol. */
+} Elf32_Sym;
+
+/* Macros for accessing the fields of st_info. */
+#define ELF32_ST_BIND(info) ((info) >> 4)
+#define ELF32_ST_TYPE(info) ((info) & 0xf)
+
+/* Macro for constructing st_info from field values. */
+#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
+
+/* Macro for accessing the fields of st_other. */
+#define ELF32_ST_VISIBILITY(oth) ((oth) & 0x3)
+
+/* Structures used by Sun & GNU symbol versioning. */
+typedef struct
+{
+ Elf32_Half vd_version;
+ Elf32_Half vd_flags;
+ Elf32_Half vd_ndx;
+ Elf32_Half vd_cnt;
+ Elf32_Word vd_hash;
+ Elf32_Word vd_aux;
+ Elf32_Word vd_next;
+} Elf32_Verdef;
+
+typedef struct
+{
+ Elf32_Word vda_name;
+ Elf32_Word vda_next;
+} Elf32_Verdaux;
+
+typedef struct
+{
+ Elf32_Half vn_version;
+ Elf32_Half vn_cnt;
+ Elf32_Word vn_file;
+ Elf32_Word vn_aux;
+ Elf32_Word vn_next;
+} Elf32_Verneed;
+
+typedef struct
+{
+ Elf32_Word vna_hash;
+ Elf32_Half vna_flags;
+ Elf32_Half vna_other;
+ Elf32_Word vna_name;
+ Elf32_Word vna_next;
+} Elf32_Vernaux;
+
+typedef Elf32_Half Elf32_Versym;
+
+typedef struct {
+ Elf32_Half si_boundto; /* direct bindings - symbol bound to */
+ Elf32_Half si_flags; /* per symbol flags */
+} Elf32_Syminfo;
+
+typedef struct {
+ Elf32_Word ch_type;
+ Elf32_Word ch_size;
+ Elf32_Word ch_addralign;
+} Elf32_Chdr;
+
+#endif /* !_SYS_ELF32_H_ */
diff --git a/Utilities/cmelf/elf64.h b/Utilities/cmelf/elf64.h
new file mode 100644
index 0000000..6efe147
--- /dev/null
+++ b/Utilities/cmelf/elf64.h
@@ -0,0 +1,269 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 1996-1998 John D. Polstra.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_ELF64_H_
+#define _SYS_ELF64_H_ 1
+
+#include "elf_common.h"
+
+/*
+ * ELF definitions common to all 64-bit architectures.
+ */
+
+typedef uint64_t Elf64_Addr;
+typedef uint16_t Elf64_Half;
+typedef uint64_t Elf64_Off;
+typedef int32_t Elf64_Sword;
+typedef int64_t Elf64_Sxword;
+typedef uint32_t Elf64_Word;
+typedef uint64_t Elf64_Lword;
+typedef uint64_t Elf64_Xword;
+
+/*
+ * Types of dynamic symbol hash table bucket and chain elements.
+ *
+ * This is inconsistent among 64 bit architectures, so a machine dependent
+ * typedef is required.
+ */
+
+typedef Elf64_Word Elf64_Hashelt;
+
+/* Non-standard class-dependent datatype used for abstraction. */
+typedef Elf64_Xword Elf64_Size;
+typedef Elf64_Sxword Elf64_Ssize;
+
+/*
+ * ELF header.
+ */
+
+typedef struct {
+ unsigned char e_ident[EI_NIDENT]; /* File identification. */
+ Elf64_Half e_type; /* File type. */
+ Elf64_Half e_machine; /* Machine architecture. */
+ Elf64_Word e_version; /* ELF format version. */
+ Elf64_Addr e_entry; /* Entry point. */
+ Elf64_Off e_phoff; /* Program header file offset. */
+ Elf64_Off e_shoff; /* Section header file offset. */
+ Elf64_Word e_flags; /* Architecture-specific flags. */
+ Elf64_Half e_ehsize; /* Size of ELF header in bytes. */
+ Elf64_Half e_phentsize; /* Size of program header entry. */
+ Elf64_Half e_phnum; /* Number of program header entries. */
+ Elf64_Half e_shentsize; /* Size of section header entry. */
+ Elf64_Half e_shnum; /* Number of section header entries. */
+ Elf64_Half e_shstrndx; /* Section name strings section. */
+} Elf64_Ehdr;
+
+/*
+ * Shared object information, found in SHT_MIPS_LIBLIST.
+ */
+
+typedef struct {
+ Elf64_Word l_name; /* The name of a shared object. */
+ Elf64_Word l_time_stamp; /* 64-bit timestamp. */
+ Elf64_Word l_checksum; /* Checksum of visible symbols, sizes. */
+ Elf64_Word l_version; /* Interface version string index. */
+ Elf64_Word l_flags; /* Flags (LL_*). */
+} Elf64_Lib;
+
+/*
+ * Section header.
+ */
+
+typedef struct {
+ Elf64_Word sh_name; /* Section name (index into the
+ section header string table). */
+ Elf64_Word sh_type; /* Section type. */
+ Elf64_Xword sh_flags; /* Section flags. */
+ Elf64_Addr sh_addr; /* Address in memory image. */
+ Elf64_Off sh_offset; /* Offset in file. */
+ Elf64_Xword sh_size; /* Size in bytes. */
+ Elf64_Word sh_link; /* Index of a related section. */
+ Elf64_Word sh_info; /* Depends on section type. */
+ Elf64_Xword sh_addralign; /* Alignment in bytes. */
+ Elf64_Xword sh_entsize; /* Size of each entry in section. */
+} Elf64_Shdr;
+
+/*
+ * Program header.
+ */
+
+typedef struct {
+ Elf64_Word p_type; /* Entry type. */
+ Elf64_Word p_flags; /* Access permission flags. */
+ Elf64_Off p_offset; /* File offset of contents. */
+ Elf64_Addr p_vaddr; /* Virtual address in memory image. */
+ Elf64_Addr p_paddr; /* Physical address (not used). */
+ Elf64_Xword p_filesz; /* Size of contents in file. */
+ Elf64_Xword p_memsz; /* Size of contents in memory. */
+ Elf64_Xword p_align; /* Alignment in memory and file. */
+} Elf64_Phdr;
+
+/*
+ * Dynamic structure. The ".dynamic" section contains an array of them.
+ */
+
+typedef struct {
+ Elf64_Sxword d_tag; /* Entry type. */
+ union {
+ Elf64_Xword d_val; /* Integer value. */
+ Elf64_Addr d_ptr; /* Address value. */
+ } d_un;
+} Elf64_Dyn;
+
+/*
+ * Relocation entries.
+ */
+
+/* Relocations that don't need an addend field. */
+typedef struct {
+ Elf64_Addr r_offset; /* Location to be relocated. */
+ Elf64_Xword r_info; /* Relocation type and symbol index. */
+} Elf64_Rel;
+
+/* Relocations that need an addend field. */
+typedef struct {
+ Elf64_Addr r_offset; /* Location to be relocated. */
+ Elf64_Xword r_info; /* Relocation type and symbol index. */
+ Elf64_Sxword r_addend; /* Addend. */
+} Elf64_Rela;
+
+/* Macros for accessing the fields of r_info. */
+#define ELF64_R_SYM(info) ((info) >> 32)
+#define ELF64_R_TYPE(info) ((info) & 0xffffffffL)
+
+/* Macro for constructing r_info from field values. */
+#define ELF64_R_INFO(sym, type) (((sym) << 32) + ((type) & 0xffffffffL))
+
+#define ELF64_R_TYPE_DATA(info) (((Elf64_Xword)(info)<<32)>>40)
+#define ELF64_R_TYPE_ID(info) (((Elf64_Xword)(info)<<56)>>56)
+#define ELF64_R_TYPE_INFO(data, type) \
+ (((Elf64_Xword)(data)<<8)+(Elf64_Xword)(type))
+
+/*
+ * Note entry header
+ */
+typedef Elf_Note Elf64_Nhdr;
+
+/*
+ * Move entry
+ */
+typedef struct {
+ Elf64_Lword m_value; /* symbol value */
+ Elf64_Xword m_info; /* size + index */
+ Elf64_Xword m_poffset; /* symbol offset */
+ Elf64_Half m_repeat; /* repeat count */
+ Elf64_Half m_stride; /* stride info */
+} Elf64_Move;
+
+#define ELF64_M_SYM(info) ((info)>>8)
+#define ELF64_M_SIZE(info) ((unsigned char)(info))
+#define ELF64_M_INFO(sym, size) (((sym)<<8)+(unsigned char)(size))
+
+/*
+ * Hardware/Software capabilities entry
+ */
+typedef struct {
+ Elf64_Xword c_tag; /* how to interpret value */
+ union {
+ Elf64_Xword c_val;
+ Elf64_Addr c_ptr;
+ } c_un;
+} Elf64_Cap;
+
+/*
+ * Symbol table entries.
+ */
+
+typedef struct {
+ Elf64_Word st_name; /* String table index of name. */
+ unsigned char st_info; /* Type and binding information. */
+ unsigned char st_other; /* Reserved (not used). */
+ Elf64_Half st_shndx; /* Section index of symbol. */
+ Elf64_Addr st_value; /* Symbol value. */
+ Elf64_Xword st_size; /* Size of associated object. */
+} Elf64_Sym;
+
+/* Macros for accessing the fields of st_info. */
+#define ELF64_ST_BIND(info) ((info) >> 4)
+#define ELF64_ST_TYPE(info) ((info) & 0xf)
+
+/* Macro for constructing st_info from field values. */
+#define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
+
+/* Macro for accessing the fields of st_other. */
+#define ELF64_ST_VISIBILITY(oth) ((oth) & 0x3)
+
+/* Structures used by Sun & GNU-style symbol versioning. */
+typedef struct {
+ Elf64_Half vd_version;
+ Elf64_Half vd_flags;
+ Elf64_Half vd_ndx;
+ Elf64_Half vd_cnt;
+ Elf64_Word vd_hash;
+ Elf64_Word vd_aux;
+ Elf64_Word vd_next;
+} Elf64_Verdef;
+
+typedef struct {
+ Elf64_Word vda_name;
+ Elf64_Word vda_next;
+} Elf64_Verdaux;
+
+typedef struct {
+ Elf64_Half vn_version;
+ Elf64_Half vn_cnt;
+ Elf64_Word vn_file;
+ Elf64_Word vn_aux;
+ Elf64_Word vn_next;
+} Elf64_Verneed;
+
+typedef struct {
+ Elf64_Word vna_hash;
+ Elf64_Half vna_flags;
+ Elf64_Half vna_other;
+ Elf64_Word vna_name;
+ Elf64_Word vna_next;
+} Elf64_Vernaux;
+
+typedef Elf64_Half Elf64_Versym;
+
+typedef struct {
+ Elf64_Half si_boundto; /* direct bindings - symbol bound to */
+ Elf64_Half si_flags; /* per symbol flags */
+} Elf64_Syminfo;
+
+typedef struct {
+ Elf64_Word ch_type;
+ Elf64_Word ch_reserved;
+ Elf64_Xword ch_size;
+ Elf64_Xword ch_addralign;
+} Elf64_Chdr;
+
+#endif /* !_SYS_ELF64_H_ */
diff --git a/Utilities/cmelf/elf_common.h b/Utilities/cmelf/elf_common.h
new file mode 100644
index 0000000..395c45b
--- /dev/null
+++ b/Utilities/cmelf/elf_common.h
@@ -0,0 +1,1492 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2017, 2018 Dell EMC
+ * Copyright (c) 2000, 2001, 2008, 2011, David E. O'Brien
+ * Copyright (c) 1998 John D. Polstra.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_ELF_COMMON_H_
+#define _SYS_ELF_COMMON_H_ 1
+
+/*
+ * ELF definitions that are independent of architecture or word size.
+ */
+
+/*
+ * Note header. The ".note" section contains an array of notes. Each
+ * begins with this header, aligned to a word boundary. Immediately
+ * following the note header is n_namesz bytes of name, padded to the
+ * next word boundary. Then comes n_descsz bytes of descriptor, again
+ * padded to a word boundary. The values of n_namesz and n_descsz do
+ * not include the padding.
+ */
+
+#ifndef LOCORE
+typedef struct {
+ uint32_t n_namesz; /* Length of name. */
+ uint32_t n_descsz; /* Length of descriptor. */
+ uint32_t n_type; /* Type of this note. */
+} Elf_Note;
+typedef Elf_Note Elf_Nhdr;
+#endif
+
+/*
+ * Option kinds.
+ */
+#define ODK_NULL 0 /* undefined */
+#define ODK_REGINFO 1 /* register usage info */
+#define ODK_EXCEPTIONS 2 /* exception processing info */
+#define ODK_PAD 3 /* section padding */
+#define ODK_HWPATCH 4 /* hardware patch applied */
+#define ODK_FILL 5 /* fill value used by the linker */
+#define ODK_TAGS 6 /* reserved space for tools */
+#define ODK_HWAND 7 /* hardware AND patch applied */
+#define ODK_HWOR 8 /* hardware OR patch applied */
+#define ODK_GP_GROUP 9 /* GP group for text/data sections */
+#define ODK_IDENT 10 /* ID information */
+#define ODK_PAGESIZE 11 /* page size information */
+
+/*
+ * ODK_EXCEPTIONS info field masks.
+ */
+#define OEX_FPU_MIN 0x0000001f /* min FPU exception required */
+#define OEX_FPU_MAX 0x00001f00 /* max FPU exception allowed */
+#define OEX_PAGE0 0x00010000 /* page zero must be mapped */
+#define OEX_SMM 0x00020000 /* run in sequential memory mode */
+#define OEX_PRECISEFP 0x00040000 /* run in precise FP exception mode */
+#define OEX_DISMISS 0x00080000 /* dismiss invalid address traps */
+
+/*
+ * ODK_PAD info field masks.
+ */
+#define OPAD_PREFIX 0x0001
+#define OPAD_POSTFIX 0x0002
+#define OPAD_SYMBOL 0x0004
+
+/*
+ * ODK_HWPATCH info field masks.
+ */
+#define OHW_R4KEOP 0x00000001 /* patch for R4000 branch at end-of-page bug */
+#define OHW_R8KPFETCH 0x00000002 /* R8000 prefetch bug may occur */
+#define OHW_R5KEOP 0x00000004 /* patch for R5000 branch at end-of-page bug */
+#define OHW_R5KCVTL 0x00000008 /* R5000 cvt.[ds].l bug: clean == 1 */
+#define OHW_R10KLDL 0x00000010UL /* need patch for R10000 misaligned load */
+
+/*
+ * ODK_HWAND/ODK_HWOR info field and hwp_flags[12] masks.
+ */
+#define OHWA0_R4KEOP_CHECKED 0x00000001 /* object checked for R4000 end-of-page bug */
+#define OHWA0_R4KEOP_CLEAN 0x00000002 /* object verified clean for R4000 end-of-page bug */
+#define OHWO0_FIXADE 0x00000001 /* object requires call to fixade */
+
+/*
+ * ODK_IDENT/ODK_GP_GROUP info field masks.
+ */
+#define OGP_GROUP 0x0000ffff /* GP group number */
+#define OGP_SELF 0x00010000 /* GP group is self-contained */
+
+/*
+ * The header for GNU-style hash sections.
+ */
+
+#ifndef LOCORE
+typedef struct {
+ uint32_t gh_nbuckets; /* Number of hash buckets. */
+ uint32_t gh_symndx; /* First visible symbol in .dynsym. */
+ uint32_t gh_maskwords; /* #maskwords used in bloom filter. */
+ uint32_t gh_shift2; /* Bloom filter shift count. */
+} Elf_GNU_Hash_Header;
+#endif
+
+/* Indexes into the e_ident array. Keep synced with
+ http://www.sco.com/developers/gabi/latest/ch4.eheader.html */
+#define EI_MAG0 0 /* Magic number, byte 0. */
+#define EI_MAG1 1 /* Magic number, byte 1. */
+#define EI_MAG2 2 /* Magic number, byte 2. */
+#define EI_MAG3 3 /* Magic number, byte 3. */
+#define EI_CLASS 4 /* Class of machine. */
+#define EI_DATA 5 /* Data format. */
+#define EI_VERSION 6 /* ELF format version. */
+#define EI_OSABI 7 /* Operating system / ABI identification */
+#define EI_ABIVERSION 8 /* ABI version */
+#define OLD_EI_BRAND 8 /* Start of architecture identification. */
+#define EI_PAD 9 /* Start of padding (per SVR4 ABI). */
+#define EI_NIDENT 16 /* Size of e_ident array. */
+
+/* Values for the magic number bytes. */
+#define ELFMAG0 0x7f
+#define ELFMAG1 'E'
+#define ELFMAG2 'L'
+#define ELFMAG3 'F'
+#define ELFMAG "\177ELF" /* magic string */
+#define SELFMAG 4 /* magic string size */
+
+/* Values for e_ident[EI_VERSION] and e_version. */
+#define EV_NONE 0
+#define EV_CURRENT 1
+
+/* Values for e_ident[EI_CLASS]. */
+#define ELFCLASSNONE 0 /* Unknown class. */
+#define ELFCLASS32 1 /* 32-bit architecture. */
+#define ELFCLASS64 2 /* 64-bit architecture. */
+
+/* Values for e_ident[EI_DATA]. */
+#define ELFDATANONE 0 /* Unknown data format. */
+#define ELFDATA2LSB 1 /* 2's complement little-endian. */
+#define ELFDATA2MSB 2 /* 2's complement big-endian. */
+
+/* Values for e_ident[EI_OSABI]. */
+#define ELFOSABI_NONE 0 /* UNIX System V ABI */
+#define ELFOSABI_HPUX 1 /* HP-UX operating system */
+#define ELFOSABI_NETBSD 2 /* NetBSD */
+#define ELFOSABI_LINUX 3 /* GNU/Linux */
+#define ELFOSABI_HURD 4 /* GNU/Hurd */
+#define ELFOSABI_86OPEN 5 /* 86Open common IA32 ABI */
+#define ELFOSABI_SOLARIS 6 /* Solaris */
+#define ELFOSABI_AIX 7 /* AIX */
+#define ELFOSABI_IRIX 8 /* IRIX */
+#define ELFOSABI_FREEBSD 9 /* FreeBSD */
+#define ELFOSABI_TRU64 10 /* TRU64 UNIX */
+#define ELFOSABI_MODESTO 11 /* Novell Modesto */
+#define ELFOSABI_OPENBSD 12 /* OpenBSD */
+#define ELFOSABI_OPENVMS 13 /* Open VMS */
+#define ELFOSABI_NSK 14 /* HP Non-Stop Kernel */
+#define ELFOSABI_AROS 15 /* Amiga Research OS */
+#define ELFOSABI_FENIXOS 16 /* FenixOS */
+#define ELFOSABI_CLOUDABI 17 /* Nuxi CloudABI */
+#define ELFOSABI_OPENVOS 18 /* Stratus Technologies OpenVOS */
+#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */
+#define ELFOSABI_ARM 97 /* ARM */
+#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
+
+#define ELFOSABI_SYSV ELFOSABI_NONE /* symbol used in old spec */
+#define ELFOSABI_MONTEREY ELFOSABI_AIX /* Monterey */
+#define ELFOSABI_GNU ELFOSABI_LINUX
+
+/* e_ident */
+#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
+ (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
+ (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
+ (ehdr).e_ident[EI_MAG3] == ELFMAG3)
+
+/* Values for e_type. */
+#define ET_NONE 0 /* Unknown type. */
+#define ET_REL 1 /* Relocatable. */
+#define ET_EXEC 2 /* Executable. */
+#define ET_DYN 3 /* Shared object. */
+#define ET_CORE 4 /* Core file. */
+#define ET_LOOS 0xfe00 /* First operating system specific. */
+#define ET_HIOS 0xfeff /* Last operating system-specific. */
+#define ET_LOPROC 0xff00 /* First processor-specific. */
+#define ET_HIPROC 0xffff /* Last processor-specific. */
+
+/* Values for e_machine. */
+#define EM_NONE 0 /* Unknown machine. */
+#define EM_M32 1 /* AT&T WE32100. */
+#define EM_SPARC 2 /* Sun SPARC. */
+#define EM_386 3 /* Intel i386. */
+#define EM_68K 4 /* Motorola 68000. */
+#define EM_88K 5 /* Motorola 88000. */
+#define EM_IAMCU 6 /* Intel MCU. */
+#define EM_860 7 /* Intel i860. */
+#define EM_MIPS 8 /* MIPS R3000 Big-Endian only. */
+#define EM_S370 9 /* IBM System/370. */
+#define EM_MIPS_RS3_LE 10 /* MIPS R3000 Little-Endian. */
+#define EM_PARISC 15 /* HP PA-RISC. */
+#define EM_VPP500 17 /* Fujitsu VPP500. */
+#define EM_SPARC32PLUS 18 /* SPARC v8plus. */
+#define EM_960 19 /* Intel 80960. */
+#define EM_PPC 20 /* PowerPC 32-bit. */
+#define EM_PPC64 21 /* PowerPC 64-bit. */
+#define EM_S390 22 /* IBM System/390. */
+#define EM_V800 36 /* NEC V800. */
+#define EM_FR20 37 /* Fujitsu FR20. */
+#define EM_RH32 38 /* TRW RH-32. */
+#define EM_RCE 39 /* Motorola RCE. */
+#define EM_ARM 40 /* ARM. */
+#define EM_SH 42 /* Hitachi SH. */
+#define EM_SPARCV9 43 /* SPARC v9 64-bit. */
+#define EM_TRICORE 44 /* Siemens TriCore embedded processor. */
+#define EM_ARC 45 /* Argonaut RISC Core. */
+#define EM_H8_300 46 /* Hitachi H8/300. */
+#define EM_H8_300H 47 /* Hitachi H8/300H. */
+#define EM_H8S 48 /* Hitachi H8S. */
+#define EM_H8_500 49 /* Hitachi H8/500. */
+#define EM_IA_64 50 /* Intel IA-64 Processor. */
+#define EM_MIPS_X 51 /* Stanford MIPS-X. */
+#define EM_COLDFIRE 52 /* Motorola ColdFire. */
+#define EM_68HC12 53 /* Motorola M68HC12. */
+#define EM_MMA 54 /* Fujitsu MMA. */
+#define EM_PCP 55 /* Siemens PCP. */
+#define EM_NCPU 56 /* Sony nCPU. */
+#define EM_NDR1 57 /* Denso NDR1 microprocessor. */
+#define EM_STARCORE 58 /* Motorola Star*Core processor. */
+#define EM_ME16 59 /* Toyota ME16 processor. */
+#define EM_ST100 60 /* STMicroelectronics ST100 processor. */
+#define EM_TINYJ 61 /* Advanced Logic Corp. TinyJ processor. */
+#define EM_X86_64 62 /* Advanced Micro Devices x86-64 */
+#define EM_AMD64 EM_X86_64 /* Advanced Micro Devices x86-64 (compat) */
+#define EM_PDSP 63 /* Sony DSP Processor. */
+#define EM_FX66 66 /* Siemens FX66 microcontroller. */
+#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16
+ microcontroller. */
+#define EM_ST7 68 /* STmicroelectronics ST7 8-bit
+ microcontroller. */
+#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller. */
+#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller. */
+#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller. */
+#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller. */
+#define EM_SVX 73 /* Silicon Graphics SVx. */
+#define EM_ST19 74 /* STMicroelectronics ST19 8-bit mc. */
+#define EM_VAX 75 /* Digital VAX. */
+#define EM_CRIS 76 /* Axis Communications 32-bit embedded
+ processor. */
+#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded
+ processor. */
+#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor. */
+#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor. */
+#define EM_MMIX 80 /* Donald Knuth's educational 64-bit proc. */
+#define EM_HUANY 81 /* Harvard University machine-independent
+ object files. */
+#define EM_PRISM 82 /* SiTera Prism. */
+#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller. */
+#define EM_FR30 84 /* Fujitsu FR30. */
+#define EM_D10V 85 /* Mitsubishi D10V. */
+#define EM_D30V 86 /* Mitsubishi D30V. */
+#define EM_V850 87 /* NEC v850. */
+#define EM_M32R 88 /* Mitsubishi M32R. */
+#define EM_MN10300 89 /* Matsushita MN10300. */
+#define EM_MN10200 90 /* Matsushita MN10200. */
+#define EM_PJ 91 /* picoJava. */
+#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor. */
+#define EM_ARC_A5 93 /* ARC Cores Tangent-A5. */
+#define EM_XTENSA 94 /* Tensilica Xtensa Architecture. */
+#define EM_VIDEOCORE 95 /* Alphamosaic VideoCore processor. */
+#define EM_TMM_GPP 96 /* Thompson Multimedia General Purpose
+ Processor. */
+#define EM_NS32K 97 /* National Semiconductor 32000 series. */
+#define EM_TPC 98 /* Tenor Network TPC processor. */
+#define EM_SNP1K 99 /* Trebia SNP 1000 processor. */
+#define EM_ST200 100 /* STMicroelectronics ST200 microcontroller. */
+#define EM_IP2K 101 /* Ubicom IP2xxx microcontroller family. */
+#define EM_MAX 102 /* MAX Processor. */
+#define EM_CR 103 /* National Semiconductor CompactRISC
+ microprocessor. */
+#define EM_F2MC16 104 /* Fujitsu F2MC16. */
+#define EM_MSP430 105 /* Texas Instruments embedded microcontroller
+ msp430. */
+#define EM_BLACKFIN 106 /* Analog Devices Blackfin (DSP) processor. */
+#define EM_SE_C33 107 /* S1C33 Family of Seiko Epson processors. */
+#define EM_SEP 108 /* Sharp embedded microprocessor. */
+#define EM_ARCA 109 /* Arca RISC Microprocessor. */
+#define EM_UNICORE 110 /* Microprocessor series from PKU-Unity Ltd.
+ and MPRC of Peking University */
+#define EM_AARCH64 183 /* AArch64 (64-bit ARM) */
+#define EM_RISCV 243 /* RISC-V */
+
+/* Non-standard or deprecated. */
+#define EM_486 6 /* Intel i486. */
+#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */
+#define EM_ALPHA_STD 41 /* Digital Alpha (standard value). */
+#define EM_ALPHA 0x9026 /* Alpha (written in the absence of an ABI) */
+
+/**
+ * e_flags
+ */
+#define EF_ARM_RELEXEC 0x1
+#define EF_ARM_HASENTRY 0x2
+#define EF_ARM_SYMSARESORTED 0x4
+#define EF_ARM_DYNSYMSUSESEGIDX 0x8
+#define EF_ARM_MAPSYMSFIRST 0x10
+#define EF_ARM_LE8 0x00400000
+#define EF_ARM_BE8 0x00800000
+#define EF_ARM_EABIMASK 0xFF000000
+#define EF_ARM_EABI_UNKNOWN 0x00000000
+#define EF_ARM_EABI_VER1 0x01000000
+#define EF_ARM_EABI_VER2 0x02000000
+#define EF_ARM_EABI_VER3 0x03000000
+#define EF_ARM_EABI_VER4 0x04000000
+#define EF_ARM_EABI_VER5 0x05000000
+#define EF_ARM_INTERWORK 0x00000004
+#define EF_ARM_APCS_26 0x00000008
+#define EF_ARM_APCS_FLOAT 0x00000010
+#define EF_ARM_PIC 0x00000020
+#define EF_ARM_ALIGN8 0x00000040
+#define EF_ARM_NEW_ABI 0x00000080
+#define EF_ARM_OLD_ABI 0x00000100
+#define EF_ARM_ABI_FLOAT_SOFT 0x00000200
+#define EF_ARM_SOFT_FLOAT EF_ARM_ABI_FLOAT_SOFT /* Pre-V5 ABI name */
+#define EF_ARM_ABI_FLOAT_HARD 0x00000400
+#define EF_ARM_VFP_FLOAT EF_ARM_ABI_FLOAT_HARD /* Pre-V5 ABI name */
+#define EF_ARM_MAVERICK_FLOAT 0x00000800
+
+#define EF_MIPS_NOREORDER 0x00000001
+#define EF_MIPS_PIC 0x00000002 /* Contains PIC code */
+#define EF_MIPS_CPIC 0x00000004 /* STD PIC calling sequence */
+#define EF_MIPS_UCODE 0x00000010
+#define EF_MIPS_ABI2 0x00000020 /* N32 */
+#define EF_MIPS_OPTIONS_FIRST 0x00000080
+#define EF_MIPS_ABI 0x0000F000
+#define EF_MIPS_ABI_O32 0x00001000
+#define EF_MIPS_ABI_O64 0x00002000
+#define EF_MIPS_ABI_EABI32 0x00003000
+#define EF_MIPS_ABI_EABI64 0x00004000
+#define EF_MIPS_ARCH_ASE 0x0F000000 /* Architectural extensions */
+#define EF_MIPS_ARCH_ASE_MDMX 0x08000000 /* MDMX multimedia extension */
+#define EF_MIPS_ARCH_ASE_M16 0x04000000 /* MIPS-16 ISA extensions */
+#define EF_MIPS_ARCH 0xF0000000 /* Architecture field */
+#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code */
+#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code */
+#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code */
+#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code */
+#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code */
+#define EF_MIPS_ARCH_32 0x50000000 /* -mips32 code */
+#define EF_MIPS_ARCH_64 0x60000000 /* -mips64 code */
+#define EF_MIPS_ARCH_32R2 0x70000000 /* -mips32r2 code */
+#define EF_MIPS_ARCH_64R2 0x80000000 /* -mips64r2 code */
+
+#define EF_PPC_EMB 0x80000000
+#define EF_PPC_RELOCATABLE 0x00010000
+#define EF_PPC_RELOCATABLE_LIB 0x00008000
+
+#define EF_RISCV_RVC 0x00000001
+#define EF_RISCV_FLOAT_ABI_MASK 0x00000006
+#define EF_RISCV_FLOAT_ABI_SOFT 0x00000000
+#define EF_RISCV_FLOAT_ABI_SINGLE 0x000002
+#define EF_RISCV_FLOAT_ABI_DOUBLE 0x000004
+#define EF_RISCV_FLOAT_ABI_QUAD 0x00000006
+#define EF_RISCV_RVE 0x00000008
+#define EF_RISCV_TSO 0x00000010
+
+#define EF_SPARC_EXT_MASK 0x00ffff00
+#define EF_SPARC_32PLUS 0x00000100
+#define EF_SPARC_SUN_US1 0x00000200
+#define EF_SPARC_HAL_R1 0x00000200
+#define EF_SPARC_SUN_US3 0x00000800
+
+#define EF_SPARCV9_MM 0x00000003
+#define EF_SPARCV9_TSO 0x00000000
+#define EF_SPARCV9_PSO 0x00000001
+#define EF_SPARCV9_RMO 0x00000002
+
+/* Special section indexes. */
+#define SHN_UNDEF 0 /* Undefined, missing, irrelevant. */
+#define SHN_LORESERVE 0xff00 /* First of reserved range. */
+#define SHN_LOPROC 0xff00 /* First processor-specific. */
+#define SHN_HIPROC 0xff1f /* Last processor-specific. */
+#define SHN_LOOS 0xff20 /* First operating system-specific. */
+#define SHN_FBSD_CACHED SHN_LOOS /* Transient, for sys/kern/link_elf_obj
+ linker only: Cached global in local
+ symtab. */
+#define SHN_HIOS 0xff3f /* Last operating system-specific. */
+#define SHN_ABS 0xfff1 /* Absolute values. */
+#define SHN_COMMON 0xfff2 /* Common data. */
+#define SHN_XINDEX 0xffff /* Escape -- index stored elsewhere. */
+#define SHN_HIRESERVE 0xffff /* Last of reserved range. */
+
+/* sh_type */
+#define SHT_NULL 0 /* inactive */
+#define SHT_PROGBITS 1 /* program defined information */
+#define SHT_SYMTAB 2 /* symbol table section */
+#define SHT_STRTAB 3 /* string table section */
+#define SHT_RELA 4 /* relocation section with addends */
+#define SHT_HASH 5 /* symbol hash table section */
+#define SHT_DYNAMIC 6 /* dynamic section */
+#define SHT_NOTE 7 /* note section */
+#define SHT_NOBITS 8 /* no space section */
+#define SHT_REL 9 /* relocation section - no addends */
+#define SHT_SHLIB 10 /* reserved - purpose unknown */
+#define SHT_DYNSYM 11 /* dynamic symbol table section */
+#define SHT_INIT_ARRAY 14 /* Initialization function pointers. */
+#define SHT_FINI_ARRAY 15 /* Termination function pointers. */
+#define SHT_PREINIT_ARRAY 16 /* Pre-initialization function ptrs. */
+#define SHT_GROUP 17 /* Section group. */
+#define SHT_SYMTAB_SHNDX 18 /* Section indexes (see SHN_XINDEX). */
+#define SHT_LOOS 0x60000000 /* First of OS specific semantics */
+#define SHT_LOSUNW 0x6ffffff4
+#define SHT_SUNW_dof 0x6ffffff4
+#define SHT_SUNW_cap 0x6ffffff5
+#define SHT_GNU_ATTRIBUTES 0x6ffffff5
+#define SHT_SUNW_SIGNATURE 0x6ffffff6
+#define SHT_GNU_HASH 0x6ffffff6
+#define SHT_GNU_LIBLIST 0x6ffffff7
+#define SHT_SUNW_ANNOTATE 0x6ffffff7
+#define SHT_SUNW_DEBUGSTR 0x6ffffff8
+#define SHT_SUNW_DEBUG 0x6ffffff9
+#define SHT_SUNW_move 0x6ffffffa
+#define SHT_SUNW_COMDAT 0x6ffffffb
+#define SHT_SUNW_syminfo 0x6ffffffc
+#define SHT_SUNW_verdef 0x6ffffffd
+#define SHT_GNU_verdef 0x6ffffffd /* Symbol versions provided */
+#define SHT_SUNW_verneed 0x6ffffffe
+#define SHT_GNU_verneed 0x6ffffffe /* Symbol versions required */
+#define SHT_SUNW_versym 0x6fffffff
+#define SHT_GNU_versym 0x6fffffff /* Symbol version table */
+#define SHT_HISUNW 0x6fffffff
+#define SHT_HIOS 0x6fffffff /* Last of OS specific semantics */
+#define SHT_LOPROC 0x70000000 /* reserved range for processor */
+#define SHT_X86_64_UNWIND 0x70000001 /* unwind information */
+#define SHT_AMD64_UNWIND SHT_X86_64_UNWIND
+
+#define SHT_ARM_EXIDX 0x70000001 /* Exception index table. */
+#define SHT_ARM_PREEMPTMAP 0x70000002 /* BPABI DLL dynamic linking
+ pre-emption map. */
+#define SHT_ARM_ATTRIBUTES 0x70000003 /* Object file compatibility
+ attributes. */
+#define SHT_ARM_DEBUGOVERLAY 0x70000004 /* See DBGOVL for details. */
+#define SHT_ARM_OVERLAYSECTION 0x70000005 /* See DBGOVL for details. */
+#define SHT_MIPS_LIBLIST 0x70000000
+#define SHT_MIPS_MSYM 0x70000001
+#define SHT_MIPS_CONFLICT 0x70000002
+#define SHT_MIPS_GPTAB 0x70000003
+#define SHT_MIPS_UCODE 0x70000004
+#define SHT_MIPS_DEBUG 0x70000005
+#define SHT_MIPS_REGINFO 0x70000006
+#define SHT_MIPS_PACKAGE 0x70000007
+#define SHT_MIPS_PACKSYM 0x70000008
+#define SHT_MIPS_RELD 0x70000009
+#define SHT_MIPS_IFACE 0x7000000b
+#define SHT_MIPS_CONTENT 0x7000000c
+#define SHT_MIPS_OPTIONS 0x7000000d
+#define SHT_MIPS_DELTASYM 0x7000001b
+#define SHT_MIPS_DELTAINST 0x7000001c
+#define SHT_MIPS_DELTACLASS 0x7000001d
+#define SHT_MIPS_DWARF 0x7000001e /* MIPS gcc uses MIPS_DWARF */
+#define SHT_MIPS_DELTADECL 0x7000001f
+#define SHT_MIPS_SYMBOL_LIB 0x70000020
+#define SHT_MIPS_EVENTS 0x70000021
+#define SHT_MIPS_TRANSLATE 0x70000022
+#define SHT_MIPS_PIXIE 0x70000023
+#define SHT_MIPS_XLATE 0x70000024
+#define SHT_MIPS_XLATE_DEBUG 0x70000025
+#define SHT_MIPS_WHIRL 0x70000026
+#define SHT_MIPS_EH_REGION 0x70000027
+#define SHT_MIPS_XLATE_OLD 0x70000028
+#define SHT_MIPS_PDR_EXCEPTION 0x70000029
+#define SHT_MIPS_ABIFLAGS 0x7000002a
+
+#define SHT_SPARC_GOTDATA 0x70000000
+
+#define SHTORDERED
+#define SHT_HIPROC 0x7fffffff /* specific section header types */
+#define SHT_LOUSER 0x80000000 /* reserved range for application */
+#define SHT_HIUSER 0xffffffff /* specific indexes */
+
+/* Flags for sh_flags. */
+#define SHF_WRITE 0x1 /* Section contains writable data. */
+#define SHF_ALLOC 0x2 /* Section occupies memory. */
+#define SHF_EXECINSTR 0x4 /* Section contains instructions. */
+#define SHF_MERGE 0x10 /* Section may be merged. */
+#define SHF_STRINGS 0x20 /* Section contains strings. */
+#define SHF_INFO_LINK 0x40 /* sh_info holds section index. */
+#define SHF_LINK_ORDER 0x80 /* Special ordering requirements. */
+#define SHF_OS_NONCONFORMING 0x100 /* OS-specific processing required. */
+#define SHF_GROUP 0x200 /* Member of section group. */
+#define SHF_TLS 0x400 /* Section contains TLS data. */
+#define SHF_COMPRESSED 0x800 /* Section contains compressed data. */
+#define SHF_MASKOS 0x0ff00000 /* OS-specific semantics. */
+#define SHF_MASKPROC 0xf0000000 /* Processor-specific semantics. */
+
+/* Flags for section groups. */
+#define GRP_COMDAT 0x1 /* COMDAT semantics. */
+
+/*
+ * Flags / mask for .gnu.versym sections.
+ */
+#define VERSYM_VERSION 0x7fff
+#define VERSYM_HIDDEN 0x8000
+
+/* Values for p_type. */
+#define PT_NULL 0 /* Unused entry. */
+#define PT_LOAD 1 /* Loadable segment. */
+#define PT_DYNAMIC 2 /* Dynamic linking information segment. */
+#define PT_INTERP 3 /* Pathname of interpreter. */
+#define PT_NOTE 4 /* Auxiliary information. */
+#define PT_SHLIB 5 /* Reserved (not used). */
+#define PT_PHDR 6 /* Location of program header itself. */
+#define PT_TLS 7 /* Thread local storage segment */
+#define PT_LOOS 0x60000000 /* First OS-specific. */
+#define PT_SUNW_UNWIND 0x6464e550 /* amd64 UNWIND program header */
+#define PT_GNU_EH_FRAME 0x6474e550
+#define PT_GNU_STACK 0x6474e551
+#define PT_GNU_RELRO 0x6474e552
+#define PT_DUMP_DELTA 0x6fb5d000 /* va->pa map for kernel dumps
+ (currently arm). */
+#define PT_LOSUNW 0x6ffffffa
+#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */
+#define PT_SUNWSTACK 0x6ffffffb /* describes the stack segment */
+#define PT_SUNWDTRACE 0x6ffffffc /* private */
+#define PT_SUNWCAP 0x6ffffffd /* hard/soft capabilities segment */
+#define PT_HISUNW 0x6fffffff
+#define PT_HIOS 0x6fffffff /* Last OS-specific. */
+#define PT_LOPROC 0x70000000 /* First processor-specific type. */
+#define PT_ARM_ARCHEXT 0x70000000 /* ARM arch compat information. */
+#define PT_ARM_EXIDX 0x70000001 /* ARM exception unwind tables. */
+#define PT_MIPS_REGINFO 0x70000000 /* MIPS register usage info */
+#define PT_MIPS_RTPROC 0x70000001 /* MIPS runtime procedure tbl */
+#define PT_MIPS_OPTIONS 0x70000002 /* MIPS e_flags value*/
+#define PT_MIPS_ABIFLAGS 0x70000003 /* MIPS fp mode */
+#define PT_HIPROC 0x7fffffff /* Last processor-specific type. */
+
+#define PT_OPENBSD_RANDOMIZE 0x65A3DBE6 /* OpenBSD random data segment */
+#define PT_OPENBSD_WXNEEDED 0x65A3DBE7 /* OpenBSD EXEC/WRITE pages needed */
+#define PT_OPENBSD_BOOTDATA 0x65A41BE6 /* OpenBSD section for boot args */
+
+/* Values for p_flags. */
+#define PF_X 0x1 /* Executable. */
+#define PF_W 0x2 /* Writable. */
+#define PF_R 0x4 /* Readable. */
+#define PF_MASKOS 0x0ff00000 /* Operating system-specific. */
+#define PF_MASKPROC 0xf0000000 /* Processor-specific. */
+
+/* Extended program header index. */
+#define PN_XNUM 0xffff
+
+/* Values for d_tag. */
+#define DT_NULL 0 /* Terminating entry. */
+#define DT_NEEDED 1 /* String table offset of a needed shared
+ library. */
+#define DT_PLTRELSZ 2 /* Total size in bytes of PLT relocations. */
+#define DT_PLTGOT 3 /* Processor-dependent address. */
+#define DT_HASH 4 /* Address of symbol hash table. */
+#define DT_STRTAB 5 /* Address of string table. */
+#define DT_SYMTAB 6 /* Address of symbol table. */
+#define DT_RELA 7 /* Address of ElfNN_Rela relocations. */
+#define DT_RELASZ 8 /* Total size of ElfNN_Rela relocations. */
+#define DT_RELAENT 9 /* Size of each ElfNN_Rela relocation entry. */
+#define DT_STRSZ 10 /* Size of string table. */
+#define DT_SYMENT 11 /* Size of each symbol table entry. */
+#define DT_INIT 12 /* Address of initialization function. */
+#define DT_FINI 13 /* Address of finalization function. */
+#define DT_SONAME 14 /* String table offset of shared object
+ name. */
+#define DT_RPATH 15 /* String table offset of library path. [sup] */
+#define DT_SYMBOLIC 16 /* Indicates "symbolic" linking. [sup] */
+#define DT_REL 17 /* Address of ElfNN_Rel relocations. */
+#define DT_RELSZ 18 /* Total size of ElfNN_Rel relocations. */
+#define DT_RELENT 19 /* Size of each ElfNN_Rel relocation. */
+#define DT_PLTREL 20 /* Type of relocation used for PLT. */
+#define DT_DEBUG 21 /* Reserved (not used). */
+#define DT_TEXTREL 22 /* Indicates there may be relocations in
+ non-writable segments. [sup] */
+#define DT_JMPREL 23 /* Address of PLT relocations. */
+#define DT_BIND_NOW 24 /* [sup] */
+#define DT_INIT_ARRAY 25 /* Address of the array of pointers to
+ initialization functions */
+#define DT_FINI_ARRAY 26 /* Address of the array of pointers to
+ termination functions */
+#define DT_INIT_ARRAYSZ 27 /* Size in bytes of the array of
+ initialization functions. */
+#define DT_FINI_ARRAYSZ 28 /* Size in bytes of the array of
+ termination functions. */
+#define DT_RUNPATH 29 /* String table offset of a null-terminated
+ library search path string. */
+#define DT_FLAGS 30 /* Object specific flag values. */
+#define DT_ENCODING 32 /* Values greater than or equal to DT_ENCODING
+ and less than DT_LOOS follow the rules for
+ the interpretation of the d_un union
+ as follows: even == 'd_ptr', odd == 'd_val'
+ or none */
+#define DT_PREINIT_ARRAY 32 /* Address of the array of pointers to
+ pre-initialization functions. */
+#define DT_PREINIT_ARRAYSZ 33 /* Size in bytes of the array of
+ pre-initialization functions. */
+#define DT_MAXPOSTAGS 34 /* number of positive tags */
+#define DT_LOOS 0x6000000d /* First OS-specific */
+#define DT_SUNW_AUXILIARY 0x6000000d /* symbol auxiliary name */
+#define DT_SUNW_RTLDINF 0x6000000e /* ld.so.1 info (private) */
+#define DT_SUNW_FILTER 0x6000000f /* symbol filter name */
+#define DT_SUNW_CAP 0x60000010 /* hardware/software */
+#define DT_SUNW_ASLR 0x60000023 /* ASLR control */
+#define DT_HIOS 0x6ffff000 /* Last OS-specific */
+
+/*
+ * DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the
+ * Dyn.d_un.d_val field of the Elf*_Dyn structure.
+ */
+#define DT_VALRNGLO 0x6ffffd00
+#define DT_GNU_PRELINKED 0x6ffffdf5 /* prelinking timestamp */
+#define DT_GNU_CONFLICTSZ 0x6ffffdf6 /* size of conflict section */
+#define DT_GNU_LIBLISTSZ 0x6ffffdf7 /* size of library list */
+#define DT_CHECKSUM 0x6ffffdf8 /* elf checksum */
+#define DT_PLTPADSZ 0x6ffffdf9 /* pltpadding size */
+#define DT_MOVEENT 0x6ffffdfa /* move table entry size */
+#define DT_MOVESZ 0x6ffffdfb /* move table size */
+#define DT_FEATURE 0x6ffffdfc /* feature holder */
+#define DT_FEATURE_1 DT_FEATURE
+#define DT_POSFLAG_1 0x6ffffdfd /* flags for DT_* entries, effecting */
+ /* the following DT_* entry. */
+ /* See DF_P1_* definitions */
+#define DT_SYMINSZ 0x6ffffdfe /* syminfo table size (in bytes) */
+#define DT_SYMINENT 0x6ffffdff /* syminfo entry size (in bytes) */
+#define DT_VALRNGHI 0x6ffffdff
+
+/*
+ * DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the
+ * Dyn.d_un.d_ptr field of the Elf*_Dyn structure.
+ *
+ * If any adjustment is made to the ELF object after it has been
+ * built, these entries will need to be adjusted.
+ */
+#define DT_ADDRRNGLO 0x6ffffe00
+#define DT_GNU_HASH 0x6ffffef5 /* GNU-style hash table */
+#define DT_TLSDESC_PLT 0x6ffffef6 /* loc. of PLT for tlsdesc resolver */
+#define DT_TLSDESC_GOT 0x6ffffef7 /* loc. of GOT for tlsdesc resolver */
+#define DT_GNU_CONFLICT 0x6ffffef8 /* address of conflict section */
+#define DT_GNU_LIBLIST 0x6ffffef9 /* address of library list */
+#define DT_CONFIG 0x6ffffefa /* configuration information */
+#define DT_DEPAUDIT 0x6ffffefb /* dependency auditing */
+#define DT_AUDIT 0x6ffffefc /* object auditing */
+#define DT_PLTPAD 0x6ffffefd /* pltpadding (sparcv9) */
+#define DT_MOVETAB 0x6ffffefe /* move table */
+#define DT_SYMINFO 0x6ffffeff /* syminfo table */
+#define DT_ADDRRNGHI 0x6ffffeff
+
+#define DT_VERSYM 0x6ffffff0 /* Address of versym section. */
+#define DT_RELACOUNT 0x6ffffff9 /* number of RELATIVE relocations */
+#define DT_RELCOUNT 0x6ffffffa /* number of RELATIVE relocations */
+#define DT_FLAGS_1 0x6ffffffb /* state flags - see DF_1_* defs */
+#define DT_VERDEF 0x6ffffffc /* Address of verdef section. */
+#define DT_VERDEFNUM 0x6ffffffd /* Number of elems in verdef section */
+#define DT_VERNEED 0x6ffffffe /* Address of verneed section. */
+#define DT_VERNEEDNUM 0x6fffffff /* Number of elems in verneed section */
+
+#define DT_LOPROC 0x70000000 /* First processor-specific type. */
+
+#define DT_ARM_SYMTABSZ 0x70000001
+#define DT_ARM_PREEMPTMAP 0x70000002
+
+#define DT_SPARC_REGISTER 0x70000001
+#define DT_DEPRECATED_SPARC_REGISTER 0x7000001
+
+#define DT_MIPS_RLD_VERSION 0x70000001
+#define DT_MIPS_TIME_STAMP 0x70000002
+#define DT_MIPS_ICHECKSUM 0x70000003
+#define DT_MIPS_IVERSION 0x70000004
+#define DT_MIPS_FLAGS 0x70000005
+#define DT_MIPS_BASE_ADDRESS 0x70000006
+#define DT_MIPS_CONFLICT 0x70000008
+#define DT_MIPS_LIBLIST 0x70000009
+#define DT_MIPS_LOCAL_GOTNO 0x7000000a
+#define DT_MIPS_CONFLICTNO 0x7000000b
+#define DT_MIPS_LIBLISTNO 0x70000010
+#define DT_MIPS_SYMTABNO 0x70000011
+#define DT_MIPS_UNREFEXTNO 0x70000012
+#define DT_MIPS_GOTSYM 0x70000013
+#define DT_MIPS_HIPAGENO 0x70000014
+#define DT_MIPS_RLD_MAP 0x70000016
+#define DT_MIPS_DELTA_CLASS 0x70000017
+#define DT_MIPS_DELTA_CLASS_NO 0x70000018
+#define DT_MIPS_DELTA_INSTANCE 0x70000019
+#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001A
+#define DT_MIPS_DELTA_RELOC 0x7000001B
+#define DT_MIPS_DELTA_RELOC_NO 0x7000001C
+#define DT_MIPS_DELTA_SYM 0x7000001D
+#define DT_MIPS_DELTA_SYM_NO 0x7000001E
+#define DT_MIPS_DELTA_CLASSSYM 0x70000020
+#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021
+#define DT_MIPS_CXX_FLAGS 0x70000022
+#define DT_MIPS_PIXIE_INIT 0x70000023
+#define DT_MIPS_SYMBOL_LIB 0x70000024
+#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
+#define DT_MIPS_LOCAL_GOTIDX 0x70000026
+#define DT_MIPS_HIDDEN_GOTIDX 0x70000027
+#define DT_MIPS_PROTECTED_GOTIDX 0x70000028
+#define DT_MIPS_OPTIONS 0x70000029
+#define DT_MIPS_INTERFACE 0x7000002A
+#define DT_MIPS_DYNSTR_ALIGN 0x7000002B
+#define DT_MIPS_INTERFACE_SIZE 0x7000002C
+#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002D
+#define DT_MIPS_PERF_SUFFIX 0x7000002E
+#define DT_MIPS_COMPACT_SIZE 0x7000002F
+#define DT_MIPS_GP_VALUE 0x70000030
+#define DT_MIPS_AUX_DYNAMIC 0x70000031
+#define DT_MIPS_PLTGOT 0x70000032
+#define DT_MIPS_RLD_OBJ_UPDATE 0x70000033
+#define DT_MIPS_RWPLT 0x70000034
+#define DT_MIPS_RLD_MAP_REL 0x70000035
+
+#define DT_PPC_GOT 0x70000000
+#define DT_PPC_TLSOPT 0x70000001
+
+#define DT_PPC64_GLINK 0x70000000
+#define DT_PPC64_OPD 0x70000001
+#define DT_PPC64_OPDSZ 0x70000002
+#define DT_PPC64_TLSOPT 0x70000003
+
+#define DT_AUXILIARY 0x7ffffffd /* shared library auxiliary name */
+#define DT_USED 0x7ffffffe /* ignored - same as needed */
+#define DT_FILTER 0x7fffffff /* shared library filter name */
+#define DT_HIPROC 0x7fffffff /* Last processor-specific type. */
+
+/* Values for DT_FLAGS */
+#define DF_ORIGIN 0x0001 /* Indicates that the object being loaded may
+ make reference to the $ORIGIN substitution
+ string */
+#define DF_SYMBOLIC 0x0002 /* Indicates "symbolic" linking. */
+#define DF_TEXTREL 0x0004 /* Indicates there may be relocations in
+ non-writable segments. */
+#define DF_BIND_NOW 0x0008 /* Indicates that the dynamic linker should
+ process all relocations for the object
+ containing this entry before transferring
+ control to the program. */
+#define DF_STATIC_TLS 0x0010 /* Indicates that the shared object or
+ executable contains code using a static
+ thread-local storage scheme. */
+
+/* Values for DT_FLAGS_1 */
+#define DF_1_BIND_NOW 0x00000001 /* Same as DF_BIND_NOW */
+#define DF_1_GLOBAL 0x00000002 /* Set the RTLD_GLOBAL for object */
+#define DF_1_NODELETE 0x00000008 /* Set the RTLD_NODELETE for object */
+#define DF_1_LOADFLTR 0x00000010 /* Immediate loading of filtees */
+#define DF_1_NOOPEN 0x00000040 /* Do not allow loading on dlopen() */
+#define DF_1_ORIGIN 0x00000080 /* Process $ORIGIN */
+#define DF_1_INTERPOSE 0x00000400 /* Interpose all objects but main */
+#define DF_1_NODEFLIB 0x00000800 /* Do not search default paths */
+#define DF_1_PIE 0x08000000 /* Is position-independent executable */
+
+/* Values for l_flags. */
+#define LL_NONE 0x0 /* no flags */
+#define LL_EXACT_MATCH 0x1 /* require an exact match */
+#define LL_IGNORE_INT_VER 0x2 /* ignore version incompatibilities */
+#define LL_REQUIRE_MINOR 0x4
+#define LL_EXPORTS 0x8
+#define LL_DELAY_LOAD 0x10
+#define LL_DELTA 0x20
+
+/* Note section names */
+#define ELF_NOTE_FREEBSD "FreeBSD"
+#define ELF_NOTE_NETBSD "NetBSD"
+#define ELF_NOTE_SOLARIS "SUNW Solaris"
+#define ELF_NOTE_GNU "GNU"
+
+/* Values for n_type used in executables. */
+#define NT_FREEBSD_ABI_TAG 1
+#define NT_FREEBSD_NOINIT_TAG 2
+#define NT_FREEBSD_ARCH_TAG 3
+#define NT_FREEBSD_FEATURE_CTL 4
+
+/* NT_FREEBSD_FEATURE_CTL desc[0] bits */
+#define NT_FREEBSD_FCTL_ASLR_DISABLE 0x00000001
+#define NT_FREEBSD_FCTL_PROTMAX_DISABLE 0x00000002
+#define NT_FREEBSD_FCTL_STKGAP_DISABLE 0x00000004
+#define NT_FREEBSD_FCTL_WXNEEDED 0x00000008
+#define NT_FREEBSD_FCTL_LA48 0x00000010
+#define NT_FREEBSD_FCTL_ASG_DISABLE 0x00000020 /* ASLR STACK GAP Disable */
+
+/* Values for n_type. Used in core files. */
+#define NT_PRSTATUS 1 /* Process status. */
+#define NT_FPREGSET 2 /* Floating point registers. */
+#define NT_PRPSINFO 3 /* Process state info. */
+#define NT_THRMISC 7 /* Thread miscellaneous info. */
+#define NT_PROCSTAT_PROC 8 /* Procstat proc data. */
+#define NT_PROCSTAT_FILES 9 /* Procstat files data. */
+#define NT_PROCSTAT_VMMAP 10 /* Procstat vmmap data. */
+#define NT_PROCSTAT_GROUPS 11 /* Procstat groups data. */
+#define NT_PROCSTAT_UMASK 12 /* Procstat umask data. */
+#define NT_PROCSTAT_RLIMIT 13 /* Procstat rlimit data. */
+#define NT_PROCSTAT_OSREL 14 /* Procstat osreldate data. */
+#define NT_PROCSTAT_PSSTRINGS 15 /* Procstat ps_strings data. */
+#define NT_PROCSTAT_AUXV 16 /* Procstat auxv data. */
+#define NT_PTLWPINFO 17 /* Thread ptrace miscellaneous info. */
+#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */
+#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */
+#define NT_X86_XSTATE 0x202 /* x86 XSAVE extended state. */
+#define NT_ARM_VFP 0x400 /* ARM VFP registers */
+
+/* GNU note types. */
+#define NT_GNU_ABI_TAG 1
+#define NT_GNU_HWCAP 2
+#define NT_GNU_BUILD_ID 3
+#define NT_GNU_GOLD_VERSION 4
+#define NT_GNU_PROPERTY_TYPE_0 5
+
+#define GNU_PROPERTY_LOPROC 0xc0000000
+#define GNU_PROPERTY_HIPROC 0xdfffffff
+
+#define GNU_PROPERTY_X86_FEATURE_1_AND 0xc0000002
+
+#define GNU_PROPERTY_X86_FEATURE_1_IBT 0x00000001
+#define GNU_PROPERTY_X86_FEATURE_1_SHSTK 0x00000002
+
+/* Symbol Binding - ELFNN_ST_BIND - st_info */
+#define STB_LOCAL 0 /* Local symbol */
+#define STB_GLOBAL 1 /* Global symbol */
+#define STB_WEAK 2 /* like global - lower precedence */
+#define STB_LOOS 10 /* Start of operating system reserved range. */
+#define STB_GNU_UNIQUE 10 /* Unique symbol (GNU) */
+#define STB_HIOS 12 /* End of operating system reserved range. */
+#define STB_LOPROC 13 /* reserved range for processor */
+#define STB_HIPROC 15 /* specific semantics. */
+
+/* Symbol type - ELFNN_ST_TYPE - st_info */
+#define STT_NOTYPE 0 /* Unspecified type. */
+#define STT_OBJECT 1 /* Data object. */
+#define STT_FUNC 2 /* Function. */
+#define STT_SECTION 3 /* Section. */
+#define STT_FILE 4 /* Source file. */
+#define STT_COMMON 5 /* Uninitialized common block. */
+#define STT_TLS 6 /* TLS object. */
+#define STT_NUM 7
+#define STT_LOOS 10 /* Reserved range for operating system */
+#define STT_GNU_IFUNC 10
+#define STT_HIOS 12 /* specific semantics. */
+#define STT_LOPROC 13 /* Start of processor reserved range. */
+#define STT_SPARC_REGISTER 13 /* SPARC register information. */
+#define STT_HIPROC 15 /* End of processor reserved range. */
+
+/* Symbol visibility - ELFNN_ST_VISIBILITY - st_other */
+#define STV_DEFAULT 0x0 /* Default visibility (see binding). */
+#define STV_INTERNAL 0x1 /* Special meaning in relocatable objects. */
+#define STV_HIDDEN 0x2 /* Not visible. */
+#define STV_PROTECTED 0x3 /* Visible but not preemptible. */
+#define STV_EXPORTED 0x4
+#define STV_SINGLETON 0x5
+#define STV_ELIMINATE 0x6
+
+/* Special symbol table indexes. */
+#define STN_UNDEF 0 /* Undefined symbol index. */
+
+/* Symbol versioning flags. */
+#define VER_DEF_CURRENT 1
+#define VER_DEF_IDX(x) VER_NDX(x)
+
+#define VER_FLG_BASE 0x01
+#define VER_FLG_WEAK 0x02
+
+#define VER_NEED_CURRENT 1
+#define VER_NEED_WEAK (1u << 15)
+#define VER_NEED_HIDDEN VER_NDX_HIDDEN
+#define VER_NEED_IDX(x) VER_NDX(x)
+
+#define VER_NDX_LOCAL 0
+#define VER_NDX_GLOBAL 1
+#define VER_NDX_GIVEN 2
+
+#define VER_NDX_HIDDEN (1u << 15)
+#define VER_NDX(x) ((x) & ~(1u << 15))
+
+#define CA_SUNW_NULL 0
+#define CA_SUNW_HW_1 1 /* first hardware capabilities entry */
+#define CA_SUNW_SF_1 2 /* first software capabilities entry */
+
+/*
+ * Syminfo flag values
+ */
+#define SYMINFO_FLG_DIRECT 0x0001 /* symbol ref has direct association */
+ /* to object containing defn. */
+#define SYMINFO_FLG_PASSTHRU 0x0002 /* ignored - see SYMINFO_FLG_FILTER */
+#define SYMINFO_FLG_COPY 0x0004 /* symbol is a copy-reloc */
+#define SYMINFO_FLG_LAZYLOAD 0x0008 /* object containing defn should be */
+ /* lazily-loaded */
+#define SYMINFO_FLG_DIRECTBIND 0x0010 /* ref should be bound directly to */
+ /* object containing defn. */
+#define SYMINFO_FLG_NOEXTDIRECT 0x0020 /* don't let an external reference */
+ /* directly bind to this symbol */
+#define SYMINFO_FLG_FILTER 0x0002 /* symbol ref is associated to a */
+#define SYMINFO_FLG_AUXILIARY 0x0040 /* standard or auxiliary filter */
+
+/*
+ * Syminfo.si_boundto values.
+ */
+#define SYMINFO_BT_SELF 0xffff /* symbol bound to self */
+#define SYMINFO_BT_PARENT 0xfffe /* symbol bound to parent */
+#define SYMINFO_BT_NONE 0xfffd /* no special symbol binding */
+#define SYMINFO_BT_EXTERN 0xfffc /* symbol defined as external */
+#define SYMINFO_BT_LOWRESERVE 0xff00 /* beginning of reserved entries */
+
+/*
+ * Syminfo version values.
+ */
+#define SYMINFO_NONE 0 /* Syminfo version */
+#define SYMINFO_CURRENT 1
+#define SYMINFO_NUM 2
+
+/* Values for ch_type (compressed section headers). */
+#define ELFCOMPRESS_ZLIB 1 /* ZLIB/DEFLATE */
+#define ELFCOMPRESS_LOOS 0x60000000 /* OS-specific */
+#define ELFCOMPRESS_HIOS 0x6fffffff
+#define ELFCOMPRESS_LOPROC 0x70000000 /* Processor-specific */
+#define ELFCOMPRESS_HIPROC 0x7fffffff
+
+/* Values for a_type. */
+#define AT_NULL 0 /* Terminates the vector. */
+#define AT_IGNORE 1 /* Ignored entry. */
+#define AT_EXECFD 2 /* File descriptor of program to load. */
+#define AT_PHDR 3 /* Program header of program already loaded. */
+#define AT_PHENT 4 /* Size of each program header entry. */
+#define AT_PHNUM 5 /* Number of program header entries. */
+#define AT_PAGESZ 6 /* Page size in bytes. */
+#define AT_BASE 7 /* Interpreter's base address. */
+#define AT_FLAGS 8 /* Flags. */
+#define AT_ENTRY 9 /* Where interpreter should transfer control. */
+#define AT_NOTELF 10 /* Program is not ELF ?? */
+#define AT_UID 11 /* Real uid. */
+#define AT_EUID 12 /* Effective uid. */
+#define AT_GID 13 /* Real gid. */
+#define AT_EGID 14 /* Effective gid. */
+#define AT_EXECPATH 15 /* Path to the executable. */
+#define AT_CANARY 16 /* Canary for SSP. */
+#define AT_CANARYLEN 17 /* Length of the canary. */
+#define AT_OSRELDATE 18 /* OSRELDATE. */
+#define AT_NCPUS 19 /* Number of CPUs. */
+#define AT_PAGESIZES 20 /* Pagesizes. */
+#define AT_PAGESIZESLEN 21 /* Number of pagesizes. */
+#define AT_TIMEKEEP 22 /* Pointer to timehands. */
+#define AT_STACKPROT 23 /* Initial stack protection. */
+#define AT_EHDRFLAGS 24 /* e_flags field from elf hdr */
+#define AT_HWCAP 25 /* CPU feature flags. */
+#define AT_HWCAP2 26 /* CPU feature flags 2. */
+#define AT_BSDFLAGS 27 /* ELF BSD Flags. */
+#define AT_ARGC 28 /* Argument count */
+#define AT_ARGV 29 /* Argument vector */
+#define AT_ENVC 30 /* Environment count */
+#define AT_ENVV 31 /* Environment vector */
+#define AT_PS_STRINGS 32 /* struct ps_strings */
+#define AT_FXRNG 33 /* Pointer to root RNG seed version. */
+
+#define AT_COUNT 34 /* Count of defined aux entry types. */
+
+/*
+ * Relocation types.
+ *
+ * All machine architectures are defined here to allow tools on one to
+ * handle others.
+ */
+
+#define R_386_NONE 0 /* No relocation. */
+#define R_386_32 1 /* Add symbol value. */
+#define R_386_PC32 2 /* Add PC-relative symbol value. */
+#define R_386_GOT32 3 /* Add PC-relative GOT offset. */
+#define R_386_PLT32 4 /* Add PC-relative PLT offset. */
+#define R_386_COPY 5 /* Copy data from shared object. */
+#define R_386_GLOB_DAT 6 /* Set GOT entry to data address. */
+#define R_386_JMP_SLOT 7 /* Set GOT entry to code address. */
+#define R_386_RELATIVE 8 /* Add load address of shared object. */
+#define R_386_GOTOFF 9 /* Add GOT-relative symbol address. */
+#define R_386_GOTPC 10 /* Add PC-relative GOT table address. */
+#define R_386_32PLT 11
+#define R_386_TLS_TPOFF 14 /* Negative offset in static TLS block */
+#define R_386_TLS_IE 15 /* Absolute address of GOT for -ve static TLS */
+#define R_386_TLS_GOTIE 16 /* GOT entry for negative static TLS block */
+#define R_386_TLS_LE 17 /* Negative offset relative to static TLS */
+#define R_386_TLS_GD 18 /* 32 bit offset to GOT (index,off) pair */
+#define R_386_TLS_LDM 19 /* 32 bit offset to GOT (index,zero) pair */
+#define R_386_16 20
+#define R_386_PC16 21
+#define R_386_8 22
+#define R_386_PC8 23
+#define R_386_TLS_GD_32 24 /* 32 bit offset to GOT (index,off) pair */
+#define R_386_TLS_GD_PUSH 25 /* pushl instruction for Sun ABI GD sequence */
+#define R_386_TLS_GD_CALL 26 /* call instruction for Sun ABI GD sequence */
+#define R_386_TLS_GD_POP 27 /* popl instruction for Sun ABI GD sequence */
+#define R_386_TLS_LDM_32 28 /* 32 bit offset to GOT (index,zero) pair */
+#define R_386_TLS_LDM_PUSH 29 /* pushl instruction for Sun ABI LD sequence */
+#define R_386_TLS_LDM_CALL 30 /* call instruction for Sun ABI LD sequence */
+#define R_386_TLS_LDM_POP 31 /* popl instruction for Sun ABI LD sequence */
+#define R_386_TLS_LDO_32 32 /* 32 bit offset from start of TLS block */
+#define R_386_TLS_IE_32 33 /* 32 bit offset to GOT static TLS offset entry */
+#define R_386_TLS_LE_32 34 /* 32 bit offset within static TLS block */
+#define R_386_TLS_DTPMOD32 35 /* GOT entry containing TLS index */
+#define R_386_TLS_DTPOFF32 36 /* GOT entry containing TLS offset */
+#define R_386_TLS_TPOFF32 37 /* GOT entry of -ve static TLS offset */
+#define R_386_SIZE32 38
+#define R_386_TLS_GOTDESC 39
+#define R_386_TLS_DESC_CALL 40
+#define R_386_TLS_DESC 41
+#define R_386_IRELATIVE 42 /* PLT entry resolved indirectly at runtime */
+#define R_386_GOT32X 43
+
+#define R_AARCH64_NONE 0 /* No relocation */
+#define R_AARCH64_ABS64 257 /* Absolute offset */
+#define R_AARCH64_ABS32 258 /* Absolute, 32-bit overflow check */
+#define R_AARCH64_ABS16 259 /* Absolute, 16-bit overflow check */
+#define R_AARCH64_PREL64 260 /* PC relative */
+#define R_AARCH64_PREL32 261 /* PC relative, 32-bit overflow check */
+#define R_AARCH64_PREL16 262 /* PC relative, 16-bit overflow check */
+#define R_AARCH64_TSTBR14 279 /* TBZ/TBNZ immediate */
+#define R_AARCH64_CONDBR19 280 /* Conditional branch immediate */
+#define R_AARCH64_JUMP26 282 /* Branch immediate */
+#define R_AARCH64_CALL26 283 /* Call immediate */
+#define R_AARCH64_COPY 1024 /* Copy data from shared object */
+#define R_AARCH64_GLOB_DAT 1025 /* Set GOT entry to data address */
+#define R_AARCH64_JUMP_SLOT 1026 /* Set GOT entry to code address */
+#define R_AARCH64_RELATIVE 1027 /* Add load address of shared object */
+#define R_AARCH64_TLS_DTPREL64 1028
+#define R_AARCH64_TLS_DTPMOD64 1029
+#define R_AARCH64_TLS_TPREL64 1030
+#define R_AARCH64_TLSDESC 1031 /* Identify the TLS descriptor */
+#define R_AARCH64_IRELATIVE 1032
+
+#define R_ARM_NONE 0 /* No relocation. */
+#define R_ARM_PC24 1
+#define R_ARM_ABS32 2
+#define R_ARM_REL32 3
+#define R_ARM_PC13 4
+#define R_ARM_ABS16 5
+#define R_ARM_ABS12 6
+#define R_ARM_THM_ABS5 7
+#define R_ARM_ABS8 8
+#define R_ARM_SBREL32 9
+#define R_ARM_THM_PC22 10
+#define R_ARM_THM_PC8 11
+#define R_ARM_AMP_VCALL9 12
+#define R_ARM_SWI24 13
+#define R_ARM_THM_SWI8 14
+#define R_ARM_XPC25 15
+#define R_ARM_THM_XPC22 16
+/* TLS relocations */
+#define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */
+#define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */
+#define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */
+#define R_ARM_COPY 20 /* Copy data from shared object. */
+#define R_ARM_GLOB_DAT 21 /* Set GOT entry to data address. */
+#define R_ARM_JUMP_SLOT 22 /* Set GOT entry to code address. */
+#define R_ARM_RELATIVE 23 /* Add load address of shared object. */
+#define R_ARM_GOTOFF 24 /* Add GOT-relative symbol address. */
+#define R_ARM_GOTPC 25 /* Add PC-relative GOT table address. */
+#define R_ARM_GOT32 26 /* Add PC-relative GOT offset. */
+#define R_ARM_PLT32 27 /* Add PC-relative PLT offset. */
+#define R_ARM_GNU_VTENTRY 100
+#define R_ARM_GNU_VTINHERIT 101
+#define R_ARM_RSBREL32 250
+#define R_ARM_THM_RPC22 251
+#define R_ARM_RREL32 252
+#define R_ARM_RABS32 253
+#define R_ARM_RPC24 254
+#define R_ARM_RBASE 255
+
+/* Name Value Field Calculation */
+#define R_IA_64_NONE 0 /* None */
+#define R_IA_64_IMM14 0x21 /* immediate14 S + A */
+#define R_IA_64_IMM22 0x22 /* immediate22 S + A */
+#define R_IA_64_IMM64 0x23 /* immediate64 S + A */
+#define R_IA_64_DIR32MSB 0x24 /* word32 MSB S + A */
+#define R_IA_64_DIR32LSB 0x25 /* word32 LSB S + A */
+#define R_IA_64_DIR64MSB 0x26 /* word64 MSB S + A */
+#define R_IA_64_DIR64LSB 0x27 /* word64 LSB S + A */
+#define R_IA_64_GPREL22 0x2a /* immediate22 @gprel(S + A) */
+#define R_IA_64_GPREL64I 0x2b /* immediate64 @gprel(S + A) */
+#define R_IA_64_GPREL32MSB 0x2c /* word32 MSB @gprel(S + A) */
+#define R_IA_64_GPREL32LSB 0x2d /* word32 LSB @gprel(S + A) */
+#define R_IA_64_GPREL64MSB 0x2e /* word64 MSB @gprel(S + A) */
+#define R_IA_64_GPREL64LSB 0x2f /* word64 LSB @gprel(S + A) */
+#define R_IA_64_LTOFF22 0x32 /* immediate22 @ltoff(S + A) */
+#define R_IA_64_LTOFF64I 0x33 /* immediate64 @ltoff(S + A) */
+#define R_IA_64_PLTOFF22 0x3a /* immediate22 @pltoff(S + A) */
+#define R_IA_64_PLTOFF64I 0x3b /* immediate64 @pltoff(S + A) */
+#define R_IA_64_PLTOFF64MSB 0x3e /* word64 MSB @pltoff(S + A) */
+#define R_IA_64_PLTOFF64LSB 0x3f /* word64 LSB @pltoff(S + A) */
+#define R_IA_64_FPTR64I 0x43 /* immediate64 @fptr(S + A) */
+#define R_IA_64_FPTR32MSB 0x44 /* word32 MSB @fptr(S + A) */
+#define R_IA_64_FPTR32LSB 0x45 /* word32 LSB @fptr(S + A) */
+#define R_IA_64_FPTR64MSB 0x46 /* word64 MSB @fptr(S + A) */
+#define R_IA_64_FPTR64LSB 0x47 /* word64 LSB @fptr(S + A) */
+#define R_IA_64_PCREL60B 0x48 /* immediate60 form1 S + A - P */
+#define R_IA_64_PCREL21B 0x49 /* immediate21 form1 S + A - P */
+#define R_IA_64_PCREL21M 0x4a /* immediate21 form2 S + A - P */
+#define R_IA_64_PCREL21F 0x4b /* immediate21 form3 S + A - P */
+#define R_IA_64_PCREL32MSB 0x4c /* word32 MSB S + A - P */
+#define R_IA_64_PCREL32LSB 0x4d /* word32 LSB S + A - P */
+#define R_IA_64_PCREL64MSB 0x4e /* word64 MSB S + A - P */
+#define R_IA_64_PCREL64LSB 0x4f /* word64 LSB S + A - P */
+#define R_IA_64_LTOFF_FPTR22 0x52 /* immediate22 @ltoff(@fptr(S + A)) */
+#define R_IA_64_LTOFF_FPTR64I 0x53 /* immediate64 @ltoff(@fptr(S + A)) */
+#define R_IA_64_LTOFF_FPTR32MSB 0x54 /* word32 MSB @ltoff(@fptr(S + A)) */
+#define R_IA_64_LTOFF_FPTR32LSB 0x55 /* word32 LSB @ltoff(@fptr(S + A)) */
+#define R_IA_64_LTOFF_FPTR64MSB 0x56 /* word64 MSB @ltoff(@fptr(S + A)) */
+#define R_IA_64_LTOFF_FPTR64LSB 0x57 /* word64 LSB @ltoff(@fptr(S + A)) */
+#define R_IA_64_SEGREL32MSB 0x5c /* word32 MSB @segrel(S + A) */
+#define R_IA_64_SEGREL32LSB 0x5d /* word32 LSB @segrel(S + A) */
+#define R_IA_64_SEGREL64MSB 0x5e /* word64 MSB @segrel(S + A) */
+#define R_IA_64_SEGREL64LSB 0x5f /* word64 LSB @segrel(S + A) */
+#define R_IA_64_SECREL32MSB 0x64 /* word32 MSB @secrel(S + A) */
+#define R_IA_64_SECREL32LSB 0x65 /* word32 LSB @secrel(S + A) */
+#define R_IA_64_SECREL64MSB 0x66 /* word64 MSB @secrel(S + A) */
+#define R_IA_64_SECREL64LSB 0x67 /* word64 LSB @secrel(S + A) */
+#define R_IA_64_REL32MSB 0x6c /* word32 MSB BD + A */
+#define R_IA_64_REL32LSB 0x6d /* word32 LSB BD + A */
+#define R_IA_64_REL64MSB 0x6e /* word64 MSB BD + A */
+#define R_IA_64_REL64LSB 0x6f /* word64 LSB BD + A */
+#define R_IA_64_LTV32MSB 0x74 /* word32 MSB S + A */
+#define R_IA_64_LTV32LSB 0x75 /* word32 LSB S + A */
+#define R_IA_64_LTV64MSB 0x76 /* word64 MSB S + A */
+#define R_IA_64_LTV64LSB 0x77 /* word64 LSB S + A */
+#define R_IA_64_PCREL21BI 0x79 /* immediate21 form1 S + A - P */
+#define R_IA_64_PCREL22 0x7a /* immediate22 S + A - P */
+#define R_IA_64_PCREL64I 0x7b /* immediate64 S + A - P */
+#define R_IA_64_IPLTMSB 0x80 /* function descriptor MSB special */
+#define R_IA_64_IPLTLSB 0x81 /* function descriptor LSB speciaal */
+#define R_IA_64_SUB 0x85 /* immediate64 A - S */
+#define R_IA_64_LTOFF22X 0x86 /* immediate22 special */
+#define R_IA_64_LDXMOV 0x87 /* immediate22 special */
+#define R_IA_64_TPREL14 0x91 /* imm14 @tprel(S + A) */
+#define R_IA_64_TPREL22 0x92 /* imm22 @tprel(S + A) */
+#define R_IA_64_TPREL64I 0x93 /* imm64 @tprel(S + A) */
+#define R_IA_64_TPREL64MSB 0x96 /* word64 MSB @tprel(S + A) */
+#define R_IA_64_TPREL64LSB 0x97 /* word64 LSB @tprel(S + A) */
+#define R_IA_64_LTOFF_TPREL22 0x9a /* imm22 @ltoff(@tprel(S+A)) */
+#define R_IA_64_DTPMOD64MSB 0xa6 /* word64 MSB @dtpmod(S + A) */
+#define R_IA_64_DTPMOD64LSB 0xa7 /* word64 LSB @dtpmod(S + A) */
+#define R_IA_64_LTOFF_DTPMOD22 0xaa /* imm22 @ltoff(@dtpmod(S+A)) */
+#define R_IA_64_DTPREL14 0xb1 /* imm14 @dtprel(S + A) */
+#define R_IA_64_DTPREL22 0xb2 /* imm22 @dtprel(S + A) */
+#define R_IA_64_DTPREL64I 0xb3 /* imm64 @dtprel(S + A) */
+#define R_IA_64_DTPREL32MSB 0xb4 /* word32 MSB @dtprel(S + A) */
+#define R_IA_64_DTPREL32LSB 0xb5 /* word32 LSB @dtprel(S + A) */
+#define R_IA_64_DTPREL64MSB 0xb6 /* word64 MSB @dtprel(S + A) */
+#define R_IA_64_DTPREL64LSB 0xb7 /* word64 LSB @dtprel(S + A) */
+#define R_IA_64_LTOFF_DTPREL22 0xba /* imm22 @ltoff(@dtprel(S+A)) */
+
+#define R_MIPS_NONE 0 /* No reloc */
+#define R_MIPS_16 1 /* Direct 16 bit */
+#define R_MIPS_32 2 /* Direct 32 bit */
+#define R_MIPS_REL32 3 /* PC relative 32 bit */
+#define R_MIPS_26 4 /* Direct 26 bit shifted */
+#define R_MIPS_HI16 5 /* High 16 bit */
+#define R_MIPS_LO16 6 /* Low 16 bit */
+#define R_MIPS_GPREL16 7 /* GP relative 16 bit */
+#define R_MIPS_LITERAL 8 /* 16 bit literal entry */
+#define R_MIPS_GOT16 9 /* 16 bit GOT entry */
+#define R_MIPS_PC16 10 /* PC relative 16 bit */
+#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */
+#define R_MIPS_GPREL32 12 /* GP relative 32 bit */
+#define R_MIPS_64 18 /* Direct 64 bit */
+#define R_MIPS_GOT_DISP 19
+#define R_MIPS_GOT_PAGE 20
+#define R_MIPS_GOT_OFST 21
+#define R_MIPS_GOT_HI16 22 /* GOT HI 16 bit */
+#define R_MIPS_GOT_LO16 23 /* GOT LO 16 bit */
+#define R_MIPS_SUB 24
+#define R_MIPS_CALLHI16 30 /* upper 16 bit GOT entry for function */
+#define R_MIPS_CALLLO16 31 /* lower 16 bit GOT entry for function */
+#define R_MIPS_JALR 37
+#define R_MIPS_TLS_GD 42
+#define R_MIPS_COPY 126
+#define R_MIPS_JUMP_SLOT 127
+
+#define R_PPC_NONE 0 /* No relocation. */
+#define R_PPC_ADDR32 1
+#define R_PPC_ADDR24 2
+#define R_PPC_ADDR16 3
+#define R_PPC_ADDR16_LO 4
+#define R_PPC_ADDR16_HI 5
+#define R_PPC_ADDR16_HA 6
+#define R_PPC_ADDR14 7
+#define R_PPC_ADDR14_BRTAKEN 8
+#define R_PPC_ADDR14_BRNTAKEN 9
+#define R_PPC_REL24 10
+#define R_PPC_REL14 11
+#define R_PPC_REL14_BRTAKEN 12
+#define R_PPC_REL14_BRNTAKEN 13
+#define R_PPC_GOT16 14
+#define R_PPC_GOT16_LO 15
+#define R_PPC_GOT16_HI 16
+#define R_PPC_GOT16_HA 17
+#define R_PPC_PLTREL24 18
+#define R_PPC_COPY 19
+#define R_PPC_GLOB_DAT 20
+#define R_PPC_JMP_SLOT 21
+#define R_PPC_RELATIVE 22
+#define R_PPC_LOCAL24PC 23
+#define R_PPC_UADDR32 24
+#define R_PPC_UADDR16 25
+#define R_PPC_REL32 26
+#define R_PPC_PLT32 27
+#define R_PPC_PLTREL32 28
+#define R_PPC_PLT16_LO 29
+#define R_PPC_PLT16_HI 30
+#define R_PPC_PLT16_HA 31
+#define R_PPC_SDAREL16 32
+#define R_PPC_SECTOFF 33
+#define R_PPC_SECTOFF_LO 34
+#define R_PPC_SECTOFF_HI 35
+#define R_PPC_SECTOFF_HA 36
+#define R_PPC_IRELATIVE 248
+
+/*
+ * 64-bit relocations
+ */
+#define R_PPC64_ADDR64 38
+#define R_PPC64_ADDR16_HIGHER 39
+#define R_PPC64_ADDR16_HIGHERA 40
+#define R_PPC64_ADDR16_HIGHEST 41
+#define R_PPC64_ADDR16_HIGHESTA 42
+#define R_PPC64_UADDR64 43
+#define R_PPC64_REL64 44
+#define R_PPC64_PLT64 45
+#define R_PPC64_PLTREL64 46
+#define R_PPC64_TOC16 47
+#define R_PPC64_TOC16_LO 48
+#define R_PPC64_TOC16_HI 49
+#define R_PPC64_TOC16_HA 50
+#define R_PPC64_TOC 51
+#define R_PPC64_DTPMOD64 68
+#define R_PPC64_TPREL64 73
+#define R_PPC64_DTPREL64 78
+
+/*
+ * TLS relocations
+ */
+#define R_PPC_TLS 67
+#define R_PPC_DTPMOD32 68
+#define R_PPC_TPREL16 69
+#define R_PPC_TPREL16_LO 70
+#define R_PPC_TPREL16_HI 71
+#define R_PPC_TPREL16_HA 72
+#define R_PPC_TPREL32 73
+#define R_PPC_DTPREL16 74
+#define R_PPC_DTPREL16_LO 75
+#define R_PPC_DTPREL16_HI 76
+#define R_PPC_DTPREL16_HA 77
+#define R_PPC_DTPREL32 78
+#define R_PPC_GOT_TLSGD16 79
+#define R_PPC_GOT_TLSGD16_LO 80
+#define R_PPC_GOT_TLSGD16_HI 81
+#define R_PPC_GOT_TLSGD16_HA 82
+#define R_PPC_GOT_TLSLD16 83
+#define R_PPC_GOT_TLSLD16_LO 84
+#define R_PPC_GOT_TLSLD16_HI 85
+#define R_PPC_GOT_TLSLD16_HA 86
+#define R_PPC_GOT_TPREL16 87
+#define R_PPC_GOT_TPREL16_LO 88
+#define R_PPC_GOT_TPREL16_HI 89
+#define R_PPC_GOT_TPREL16_HA 90
+
+/*
+ * The remaining relocs are from the Embedded ELF ABI, and are not in the
+ * SVR4 ELF ABI.
+ */
+
+#define R_PPC_EMB_NADDR32 101
+#define R_PPC_EMB_NADDR16 102
+#define R_PPC_EMB_NADDR16_LO 103
+#define R_PPC_EMB_NADDR16_HI 104
+#define R_PPC_EMB_NADDR16_HA 105
+#define R_PPC_EMB_SDAI16 106
+#define R_PPC_EMB_SDA2I16 107
+#define R_PPC_EMB_SDA2REL 108
+#define R_PPC_EMB_SDA21 109
+#define R_PPC_EMB_MRKREF 110
+#define R_PPC_EMB_RELSEC16 111
+#define R_PPC_EMB_RELST_LO 112
+#define R_PPC_EMB_RELST_HI 113
+#define R_PPC_EMB_RELST_HA 114
+#define R_PPC_EMB_BIT_FLD 115
+#define R_PPC_EMB_RELSDA 116
+
+/*
+ * RISC-V relocation types.
+ */
+
+/* Relocation types used by the dynamic linker. */
+#define R_RISCV_NONE 0
+#define R_RISCV_32 1
+#define R_RISCV_64 2
+#define R_RISCV_RELATIVE 3
+#define R_RISCV_COPY 4
+#define R_RISCV_JUMP_SLOT 5
+#define R_RISCV_TLS_DTPMOD32 6
+#define R_RISCV_TLS_DTPMOD64 7
+#define R_RISCV_TLS_DTPREL32 8
+#define R_RISCV_TLS_DTPREL64 9
+#define R_RISCV_TLS_TPREL32 10
+#define R_RISCV_TLS_TPREL64 11
+
+/* Relocation types not used by the dynamic linker. */
+#define R_RISCV_BRANCH 16
+#define R_RISCV_JAL 17
+#define R_RISCV_CALL 18
+#define R_RISCV_CALL_PLT 19
+#define R_RISCV_GOT_HI20 20
+#define R_RISCV_TLS_GOT_HI20 21
+#define R_RISCV_TLS_GD_HI20 22
+#define R_RISCV_PCREL_HI20 23
+#define R_RISCV_PCREL_LO12_I 24
+#define R_RISCV_PCREL_LO12_S 25
+#define R_RISCV_HI20 26
+#define R_RISCV_LO12_I 27
+#define R_RISCV_LO12_S 28
+#define R_RISCV_TPREL_HI20 29
+#define R_RISCV_TPREL_LO12_I 30
+#define R_RISCV_TPREL_LO12_S 31
+#define R_RISCV_TPREL_ADD 32
+#define R_RISCV_ADD8 33
+#define R_RISCV_ADD16 34
+#define R_RISCV_ADD32 35
+#define R_RISCV_ADD64 36
+#define R_RISCV_SUB8 37
+#define R_RISCV_SUB16 38
+#define R_RISCV_SUB32 39
+#define R_RISCV_SUB64 40
+#define R_RISCV_GNU_VTINHERIT 41
+#define R_RISCV_GNU_VTENTRY 42
+#define R_RISCV_ALIGN 43
+#define R_RISCV_RVC_BRANCH 44
+#define R_RISCV_RVC_JUMP 45
+#define R_RISCV_RVC_LUI 46
+#define R_RISCV_GPREL_I 47
+#define R_RISCV_GPREL_S 48
+#define R_RISCV_TPREL_I 49
+#define R_RISCV_TPREL_S 50
+#define R_RISCV_RELAX 51
+#define R_RISCV_SUB6 52
+#define R_RISCV_SET6 53
+#define R_RISCV_SET8 54
+#define R_RISCV_SET16 55
+#define R_RISCV_SET32 56
+#define R_RISCV_32_PCREL 57
+#define R_RISCV_IRELATIVE 58
+
+#define R_SPARC_NONE 0
+#define R_SPARC_8 1
+#define R_SPARC_16 2
+#define R_SPARC_32 3
+#define R_SPARC_DISP8 4
+#define R_SPARC_DISP16 5
+#define R_SPARC_DISP32 6
+#define R_SPARC_WDISP30 7
+#define R_SPARC_WDISP22 8
+#define R_SPARC_HI22 9
+#define R_SPARC_22 10
+#define R_SPARC_13 11
+#define R_SPARC_LO10 12
+#define R_SPARC_GOT10 13
+#define R_SPARC_GOT13 14
+#define R_SPARC_GOT22 15
+#define R_SPARC_PC10 16
+#define R_SPARC_PC22 17
+#define R_SPARC_WPLT30 18
+#define R_SPARC_COPY 19
+#define R_SPARC_GLOB_DAT 20
+#define R_SPARC_JMP_SLOT 21
+#define R_SPARC_RELATIVE 22
+#define R_SPARC_UA32 23
+#define R_SPARC_PLT32 24
+#define R_SPARC_HIPLT22 25
+#define R_SPARC_LOPLT10 26
+#define R_SPARC_PCPLT32 27
+#define R_SPARC_PCPLT22 28
+#define R_SPARC_PCPLT10 29
+#define R_SPARC_10 30
+#define R_SPARC_11 31
+#define R_SPARC_64 32
+#define R_SPARC_OLO10 33
+#define R_SPARC_HH22 34
+#define R_SPARC_HM10 35
+#define R_SPARC_LM22 36
+#define R_SPARC_PC_HH22 37
+#define R_SPARC_PC_HM10 38
+#define R_SPARC_PC_LM22 39
+#define R_SPARC_WDISP16 40
+#define R_SPARC_WDISP19 41
+#define R_SPARC_GLOB_JMP 42
+#define R_SPARC_7 43
+#define R_SPARC_5 44
+#define R_SPARC_6 45
+#define R_SPARC_DISP64 46
+#define R_SPARC_PLT64 47
+#define R_SPARC_HIX22 48
+#define R_SPARC_LOX10 49
+#define R_SPARC_H44 50
+#define R_SPARC_M44 51
+#define R_SPARC_L44 52
+#define R_SPARC_REGISTER 53
+#define R_SPARC_UA64 54
+#define R_SPARC_UA16 55
+#define R_SPARC_TLS_GD_HI22 56
+#define R_SPARC_TLS_GD_LO10 57
+#define R_SPARC_TLS_GD_ADD 58
+#define R_SPARC_TLS_GD_CALL 59
+#define R_SPARC_TLS_LDM_HI22 60
+#define R_SPARC_TLS_LDM_LO10 61
+#define R_SPARC_TLS_LDM_ADD 62
+#define R_SPARC_TLS_LDM_CALL 63
+#define R_SPARC_TLS_LDO_HIX22 64
+#define R_SPARC_TLS_LDO_LOX10 65
+#define R_SPARC_TLS_LDO_ADD 66
+#define R_SPARC_TLS_IE_HI22 67
+#define R_SPARC_TLS_IE_LO10 68
+#define R_SPARC_TLS_IE_LD 69
+#define R_SPARC_TLS_IE_LDX 70
+#define R_SPARC_TLS_IE_ADD 71
+#define R_SPARC_TLS_LE_HIX22 72
+#define R_SPARC_TLS_LE_LOX10 73
+#define R_SPARC_TLS_DTPMOD32 74
+#define R_SPARC_TLS_DTPMOD64 75
+#define R_SPARC_TLS_DTPOFF32 76
+#define R_SPARC_TLS_DTPOFF64 77
+#define R_SPARC_TLS_TPOFF32 78
+#define R_SPARC_TLS_TPOFF64 79
+
+#define R_X86_64_NONE 0 /* No relocation. */
+#define R_X86_64_64 1 /* Add 64 bit symbol value. */
+#define R_X86_64_PC32 2 /* PC-relative 32 bit signed sym value. */
+#define R_X86_64_GOT32 3 /* PC-relative 32 bit GOT offset. */
+#define R_X86_64_PLT32 4 /* PC-relative 32 bit PLT offset. */
+#define R_X86_64_COPY 5 /* Copy data from shared object. */
+#define R_X86_64_GLOB_DAT 6 /* Set GOT entry to data address. */
+#define R_X86_64_JMP_SLOT 7 /* Set GOT entry to code address. */
+#define R_X86_64_RELATIVE 8 /* Add load address of shared object. */
+#define R_X86_64_GOTPCREL 9 /* Add 32 bit signed pcrel offset to GOT. */
+#define R_X86_64_32 10 /* Add 32 bit zero extended symbol value */
+#define R_X86_64_32S 11 /* Add 32 bit sign extended symbol value */
+#define R_X86_64_16 12 /* Add 16 bit zero extended symbol value */
+#define R_X86_64_PC16 13 /* Add 16 bit signed extended pc relative symbol value */
+#define R_X86_64_8 14 /* Add 8 bit zero extended symbol value */
+#define R_X86_64_PC8 15 /* Add 8 bit signed extended pc relative symbol value */
+#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */
+#define R_X86_64_DTPOFF64 17 /* Offset in TLS block */
+#define R_X86_64_TPOFF64 18 /* Offset in static TLS block */
+#define R_X86_64_TLSGD 19 /* PC relative offset to GD GOT entry */
+#define R_X86_64_TLSLD 20 /* PC relative offset to LD GOT entry */
+#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */
+#define R_X86_64_GOTTPOFF 22 /* PC relative offset to IE GOT entry */
+#define R_X86_64_TPOFF32 23 /* Offset in static TLS block */
+#define R_X86_64_PC64 24 /* PC-relative 64 bit signed sym value. */
+#define R_X86_64_GOTOFF64 25
+#define R_X86_64_GOTPC32 26
+#define R_X86_64_GOT64 27
+#define R_X86_64_GOTPCREL64 28
+#define R_X86_64_GOTPC64 29
+#define R_X86_64_GOTPLT64 30
+#define R_X86_64_PLTOFF64 31
+#define R_X86_64_SIZE32 32
+#define R_X86_64_SIZE64 33
+#define R_X86_64_GOTPC32_TLSDESC 34
+#define R_X86_64_TLSDESC_CALL 35
+#define R_X86_64_TLSDESC 36
+#define R_X86_64_IRELATIVE 37
+#define R_X86_64_RELATIVE64 38
+/* 39 and 40 were BND-related, already decomissioned */
+#define R_X86_64_GOTPCRELX 41
+#define R_X86_64_REX_GOTPCRELX 42
+
+#define ELF_BSDF_SIGFASTBLK 0x0001 /* Kernel supports fast sigblock */
+
+#endif /* !_SYS_ELF_COMMON_H_ */
diff --git a/Utilities/cmlibarchive/CMakeLists.txt b/Utilities/cmlibarchive/CMakeLists.txt
index 79452ff..ba65470 100644
--- a/Utilities/cmlibarchive/CMakeLists.txt
+++ b/Utilities/cmlibarchive/CMakeLists.txt
@@ -171,32 +171,32 @@ IF (MSVC)
# This is added into CMAKE_C_FLAGS when CMAKE_BUILD_TYPE is "Debug"
# Enable level 4 C4062: The enumerate has no associated handler in a switch
# statement and there is no default that can catch it.
- SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4062")
+ SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /w14062")
# Enable level 4 C4254: A larger bit field was assigned to a smaller bit
# field.
- SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4254")
+ SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /w14254")
# Enable level 4 C4295: An array was initialized but the last character in
# the array is not a null; accessing the array may
# produce unexpected results.
- SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4295")
+ SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /w14295")
# Enable level 4 C4296: An unsigned variable was used in a comparison
# operation with zero.
- SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4296")
+ SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /w14296")
# Enable level 4 C4389: An operation involved signed and unsigned variables.
# This could result in a loss of data.
- SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4389")
+ SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /w14389")
# Enable level 4 C4505: The given function is local and not referenced in
# the body of the module; therefore, the function is
# dead code.
- SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4505")
+ SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /w14505")
# Enable level 4 C4514: The optimizer removed an inline function that is not
# called.
- SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4514")
+ SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /w14514")
# Enable level 4 C4702: Unreachable code.
- SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4702")
+ SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /w14702")
# Enable level 4 C4706: The test value in a conditional expression was the
# result of an assignment.
- SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /we4706")
+ SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /w14706")
# /Oi option enables built-in functions.
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Oi")
#################################################################
@@ -1404,6 +1404,7 @@ CHECK_FUNCTION_EXISTS_GLIBC(strchr HAVE_STRCHR)
CHECK_FUNCTION_EXISTS_GLIBC(strdup HAVE_STRDUP)
CHECK_FUNCTION_EXISTS_GLIBC(strerror HAVE_STRERROR)
CHECK_FUNCTION_EXISTS_GLIBC(strncpy_s HAVE_STRNCPY_S)
+CHECK_FUNCTION_EXISTS_GLIBC(strnlen HAVE_STRNLEN)
CHECK_FUNCTION_EXISTS_GLIBC(strrchr HAVE_STRRCHR)
CHECK_FUNCTION_EXISTS_GLIBC(symlink HAVE_SYMLINK)
CHECK_FUNCTION_EXISTS_GLIBC(timegm HAVE_TIMEGM)
@@ -1475,15 +1476,19 @@ CHECK_C_SOURCE_COMPILES(
"#include <sys/sysmacros.h>\nint main() { return major(256); }"
MAJOR_IN_SYSMACROS)
+IF(ENABLE_LZMA)
CMAKE_PUSH_CHECK_STATE()
SET(CMAKE_REQUIRED_LIBRARIES ${LIBLZMA_LIBRARIES})
SET(CMAKE_REQUIRED_INCLUDES ${LIBLZMA_INCLUDE_DIR})
CHECK_C_SOURCE_COMPILES(
"#include <lzma.h>\n#if LZMA_VERSION < 50020000\n#error unsupported\n#endif\nint main(void){lzma_stream_encoder_mt(0, 0); return 0;}"
-HAVE_LZMA_STREAM_ENCODER_MT)
+ HAVE_LZMA_STREAM_ENCODER_MT)
CMAKE_POP_CHECK_STATE()
+ELSE()
+ SET(HAVE_LZMA_STREAM_ENCODER_MT 0)
+ENDIF(ENABLE_LZMA)
IF(HAVE_STRERROR_R)
SET(HAVE_DECL_STRERROR_R 1)
@@ -2007,6 +2012,11 @@ IF(MSVC)
ADD_DEFINITIONS(-D_CRT_SECURE_NO_DEPRECATE)
ENDIF(MSVC)
+IF(APPLE)
+ # CC_MD5_Init() functions are deprecated on macOS 10.15, but we want to use them
+ ADD_DEFINITIONS(-Wno-deprecated-declarations)
+ENDIF(APPLE)
+
IF(0) # CMake does not build libarchive's tests.
IF(ENABLE_TEST)
ADD_CUSTOM_TARGET(run_all_tests)
diff --git a/Utilities/cmlibarchive/COPYING b/Utilities/cmlibarchive/COPYING
index 14bbefa..1b97235 100644
--- a/Utilities/cmlibarchive/COPYING
+++ b/Utilities/cmlibarchive/COPYING
@@ -15,7 +15,6 @@ the actual statements in the files are controlling.
* The following source files are also subject in whole or in part to
a 3-clause UC Regents copyright; please read the individual source
files for details:
- libarchive/archive_entry.c
libarchive/archive_read_support_filter_compress.c
libarchive/archive_write_add_filter_compress.c
libarchive/mtree.5
diff --git a/Utilities/cmlibarchive/build/cmake/CreatePkgConfigFile.cmake b/Utilities/cmlibarchive/build/cmake/CreatePkgConfigFile.cmake
index fc8529a..bc5a43f 100644
--- a/Utilities/cmlibarchive/build/cmake/CreatePkgConfigFile.cmake
+++ b/Utilities/cmlibarchive/build/cmake/CreatePkgConfigFile.cmake
@@ -24,10 +24,10 @@ ENDFOREACH()
# thus there's a good chance it'll make some binutils versions unhappy...
# This only affects Libs.private (looked up for static builds) though.
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/build/pkgconfig/libarchive.pc.in
- ${CMAKE_CURRENT_SOURCE_DIR}/build/pkgconfig/libarchive.pc
+ ${CMAKE_CURRENT_BINARY_DIR}/build/pkgconfig/libarchive.pc
@ONLY)
# And install it, of course ;).
IF(ENABLE_INSTALL)
- INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/build/pkgconfig/libarchive.pc
+ INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/build/pkgconfig/libarchive.pc
DESTINATION "lib/pkgconfig")
ENDIF()
diff --git a/Utilities/cmlibarchive/build/cmake/config.h.in b/Utilities/cmlibarchive/build/cmake/config.h.in
index f38601f..9bd2667 100644
--- a/Utilities/cmlibarchive/build/cmake/config.h.in
+++ b/Utilities/cmlibarchive/build/cmake/config.h.in
@@ -1,4 +1,5 @@
/* config.h. Generated from build/cmake/config.h.in by cmake configure */
+#define __LIBARCHIVE_CONFIG_H_INCLUDED 1
#if defined(__osf__)
# define _OSF_SOURCE
#endif
@@ -742,6 +743,9 @@
/* Define to 1 if you have the `strchr' function. */
#cmakedefine HAVE_STRCHR 1
+/* Define to 1 if you have the `strnlen' function. */
+#cmakedefine HAVE_STRNLEN 1
+
/* Define to 1 if you have the `strdup' function. */
#cmakedefine HAVE_STRDUP 1
diff --git a/Utilities/cmlibarchive/build/version b/Utilities/cmlibarchive/build/version
index 78be3ab..205791c 100644
--- a/Utilities/cmlibarchive/build/version
+++ b/Utilities/cmlibarchive/build/version
@@ -1 +1 @@
-3004002
+3005001
diff --git a/Utilities/cmlibarchive/libarchive/archive.h b/Utilities/cmlibarchive/libarchive/archive.h
index 574e087..a1f0b87 100644
--- a/Utilities/cmlibarchive/libarchive/archive.h
+++ b/Utilities/cmlibarchive/libarchive/archive.h
@@ -36,7 +36,7 @@
* assert that ARCHIVE_VERSION_NUMBER >= 2012108.
*/
/* Note: Compiler will complain if this does not match archive_entry.h! */
-#define ARCHIVE_VERSION_NUMBER 3004002
+#define ARCHIVE_VERSION_NUMBER 3005001
#include <sys/stat.h>
#include <stddef.h> /* for wchar_t */
@@ -152,7 +152,7 @@ __LA_DECL int archive_version_number(void);
/*
* Textual name/version of the library, useful for version displays.
*/
-#define ARCHIVE_VERSION_ONLY_STRING "3.4.2"
+#define ARCHIVE_VERSION_ONLY_STRING "3.5.1"
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
__LA_DECL const char * archive_version_string(void);
@@ -243,6 +243,8 @@ typedef int archive_open_callback(struct archive *, void *_client_data);
typedef int archive_close_callback(struct archive *, void *_client_data);
+typedef int archive_free_callback(struct archive *, void *_client_data);
+
/* Switches from one client data object to the next/prev client data object.
* This is useful for reading from different data blocks such as a set of files
* that make up one large file.
@@ -415,6 +417,7 @@ __LA_DECL int archive_read_support_compression_xz(struct archive *)
#endif
__LA_DECL int archive_read_support_filter_all(struct archive *);
+__LA_DECL int archive_read_support_filter_by_code(struct archive *, int);
__LA_DECL int archive_read_support_filter_bzip2(struct archive *);
__LA_DECL int archive_read_support_filter_compress(struct archive *);
__LA_DECL int archive_read_support_filter_gzip(struct archive *);
@@ -814,9 +817,13 @@ __LA_DECL int archive_write_set_format_filter_by_ext(struct archive *a, const ch
__LA_DECL int archive_write_set_format_filter_by_ext_def(struct archive *a, const char *filename, const char * def_ext);
__LA_DECL int archive_write_zip_set_compression_deflate(struct archive *);
__LA_DECL int archive_write_zip_set_compression_store(struct archive *);
+/* Deprecated; use archive_write_open2 instead */
__LA_DECL int archive_write_open(struct archive *, void *,
archive_open_callback *, archive_write_callback *,
archive_close_callback *);
+__LA_DECL int archive_write_open2(struct archive *, void *,
+ archive_open_callback *, archive_write_callback *,
+ archive_close_callback *, archive_free_callback *);
__LA_DECL int archive_write_open_fd(struct archive *, int _fd);
__LA_DECL int archive_write_open_filename(struct archive *, const char *_file);
__LA_DECL int archive_write_open_filename_w(struct archive *,
diff --git a/Utilities/cmlibarchive/libarchive/archive_acl.c b/Utilities/cmlibarchive/libarchive/archive_acl.c
index 952e20d..ead7e36 100644
--- a/Utilities/cmlibarchive/libarchive/archive_acl.c
+++ b/Utilities/cmlibarchive/libarchive/archive_acl.c
@@ -595,7 +595,7 @@ archive_acl_text_len(struct archive_acl *acl, int want_type, int flags,
else
length += sizeof(uid_t) * 3 + 1;
} else {
- r = archive_mstring_get_mbs_l(&ap->name, &name,
+ r = archive_mstring_get_mbs_l(a, &ap->name, &name,
&len, sc);
if (r != 0)
return (0);
@@ -968,7 +968,7 @@ archive_acl_to_text_l(struct archive_acl *acl, ssize_t *text_len, int flags,
else
prefix = NULL;
r = archive_mstring_get_mbs_l(
- &ap->name, &name, &len, sc);
+ NULL, &ap->name, &name, &len, sc);
if (r != 0) {
free(s);
return (NULL);
@@ -1402,14 +1402,14 @@ isint_w(const wchar_t *start, const wchar_t *end, int *result)
if (start >= end)
return (0);
while (start < end) {
- if (*start < '0' || *start > '9')
+ if (*start < L'0' || *start > L'9')
return (0);
if (n > (INT_MAX / 10) ||
- (n == INT_MAX / 10 && (*start - '0') > INT_MAX % 10)) {
+ (n == INT_MAX / 10 && (*start - L'0') > INT_MAX % 10)) {
n = INT_MAX;
} else {
n *= 10;
- n += *start - '0';
+ n += *start - L'0';
}
start++;
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_check_magic.c b/Utilities/cmlibarchive/libarchive/archive_check_magic.c
index 288ce23..1f40072 100644
--- a/Utilities/cmlibarchive/libarchive/archive_check_magic.c
+++ b/Utilities/cmlibarchive/libarchive/archive_check_magic.c
@@ -54,7 +54,7 @@ errmsg(const char *m)
ssize_t written;
while (s > 0) {
- written = write(2, m, strlen(m));
+ written = write(2, m, s);
if (written <= 0)
return;
m += written;
diff --git a/Utilities/cmlibarchive/libarchive/archive_cryptor.c b/Utilities/cmlibarchive/libarchive/archive_cryptor.c
index 8ab2b09..d4bca90 100644
--- a/Utilities/cmlibarchive/libarchive/archive_cryptor.c
+++ b/Utilities/cmlibarchive/libarchive/archive_cryptor.c
@@ -347,8 +347,31 @@ aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
static int
aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
{
+#if NETTLE_VERSION_MAJOR < 3
aes_set_encrypt_key(&ctx->ctx, ctx->key_len, ctx->key);
aes_encrypt(&ctx->ctx, AES_BLOCK_SIZE, ctx->encr_buf, ctx->nonce);
+#else
+ switch(ctx->key_len) {
+ case AES128_KEY_SIZE:
+ aes128_set_encrypt_key(&ctx->ctx.c128, ctx->key);
+ aes128_encrypt(&ctx->ctx.c128, AES_BLOCK_SIZE, ctx->encr_buf,
+ ctx->nonce);
+ break;
+ case AES192_KEY_SIZE:
+ aes192_set_encrypt_key(&ctx->ctx.c192, ctx->key);
+ aes192_encrypt(&ctx->ctx.c192, AES_BLOCK_SIZE, ctx->encr_buf,
+ ctx->nonce);
+ break;
+ case AES256_KEY_SIZE:
+ aes256_set_encrypt_key(&ctx->ctx.c256, ctx->key);
+ aes256_encrypt(&ctx->ctx.c256, AES_BLOCK_SIZE, ctx->encr_buf,
+ ctx->nonce);
+ break;
+ default:
+ return -1;
+ break;
+ }
+#endif
return 0;
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_cryptor_private.h b/Utilities/cmlibarchive/libarchive/archive_cryptor_private.h
index 64a2055..16b6d16 100644
--- a/Utilities/cmlibarchive/libarchive/archive_cryptor_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_cryptor_private.h
@@ -104,9 +104,18 @@ typedef struct {
#include <nettle/pbkdf2.h>
#endif
#include <nettle/aes.h>
+#include <nettle/version.h>
typedef struct {
+#if NETTLE_VERSION_MAJOR < 3
struct aes_ctx ctx;
+#else
+ union {
+ struct aes128_ctx c128;
+ struct aes192_ctx c192;
+ struct aes256_ctx c256;
+ } ctx;
+#endif
uint8_t key[AES_MAX_KEY_SIZE];
unsigned key_len;
uint8_t nonce[AES_BLOCK_SIZE];
diff --git a/Utilities/cmlibarchive/libarchive/archive_digest.c b/Utilities/cmlibarchive/libarchive/archive_digest.c
index 34c58ac..410df01 100644
--- a/Utilities/cmlibarchive/libarchive/archive_digest.c
+++ b/Utilities/cmlibarchive/libarchive/archive_digest.c
@@ -109,14 +109,14 @@ win_crypto_Final(unsigned char *buf, size_t bufsize, Digest_CTX *ctx)
#if defined(ARCHIVE_CRYPTO_MD5_LIBC)
static int
-__archive_libc_md5init(archive_md5_ctx *ctx)
+__archive_md5init(archive_md5_ctx *ctx)
{
MD5Init(ctx);
return (ARCHIVE_OK);
}
static int
-__archive_libc_md5update(archive_md5_ctx *ctx, const void *indata,
+__archive_md5update(archive_md5_ctx *ctx, const void *indata,
size_t insize)
{
MD5Update(ctx, indata, insize);
@@ -124,7 +124,7 @@ __archive_libc_md5update(archive_md5_ctx *ctx, const void *indata,
}
static int
-__archive_libc_md5final(archive_md5_ctx *ctx, void *md)
+__archive_md5final(archive_md5_ctx *ctx, void *md)
{
MD5Final(md, ctx);
return (ARCHIVE_OK);
@@ -133,14 +133,14 @@ __archive_libc_md5final(archive_md5_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_MD5_LIBMD)
static int
-__archive_libmd_md5init(archive_md5_ctx *ctx)
+__archive_md5init(archive_md5_ctx *ctx)
{
MD5Init(ctx);
return (ARCHIVE_OK);
}
static int
-__archive_libmd_md5update(archive_md5_ctx *ctx, const void *indata,
+__archive_md5update(archive_md5_ctx *ctx, const void *indata,
size_t insize)
{
MD5Update(ctx, indata, insize);
@@ -148,7 +148,7 @@ __archive_libmd_md5update(archive_md5_ctx *ctx, const void *indata,
}
static int
-__archive_libmd_md5final(archive_md5_ctx *ctx, void *md)
+__archive_md5final(archive_md5_ctx *ctx, void *md)
{
MD5Final(md, ctx);
return (ARCHIVE_OK);
@@ -157,14 +157,14 @@ __archive_libmd_md5final(archive_md5_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM)
static int
-__archive_libsystem_md5init(archive_md5_ctx *ctx)
+__archive_md5init(archive_md5_ctx *ctx)
{
CC_MD5_Init(ctx);
return (ARCHIVE_OK);
}
static int
-__archive_libsystem_md5update(archive_md5_ctx *ctx, const void *indata,
+__archive_md5update(archive_md5_ctx *ctx, const void *indata,
size_t insize)
{
CC_MD5_Update(ctx, indata, insize);
@@ -172,7 +172,7 @@ __archive_libsystem_md5update(archive_md5_ctx *ctx, const void *indata,
}
static int
-__archive_libsystem_md5final(archive_md5_ctx *ctx, void *md)
+__archive_md5final(archive_md5_ctx *ctx, void *md)
{
CC_MD5_Final(md, ctx);
return (ARCHIVE_OK);
@@ -181,7 +181,7 @@ __archive_libsystem_md5final(archive_md5_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_MD5_MBEDTLS)
static int
-__archive_mbedtls_md5init(archive_md5_ctx *ctx)
+__archive_md5init(archive_md5_ctx *ctx)
{
mbedtls_md5_init(ctx);
if (mbedtls_md5_starts_ret(ctx) == 0)
@@ -191,7 +191,7 @@ __archive_mbedtls_md5init(archive_md5_ctx *ctx)
}
static int
-__archive_mbedtls_md5update(archive_md5_ctx *ctx, const void *indata,
+__archive_md5update(archive_md5_ctx *ctx, const void *indata,
size_t insize)
{
if (mbedtls_md5_update_ret(ctx, indata, insize) == 0)
@@ -201,7 +201,7 @@ __archive_mbedtls_md5update(archive_md5_ctx *ctx, const void *indata,
}
static int
-__archive_mbedtls_md5final(archive_md5_ctx *ctx, void *md)
+__archive_md5final(archive_md5_ctx *ctx, void *md)
{
if (mbedtls_md5_finish_ret(ctx, md) == 0) {
mbedtls_md5_free(ctx);
@@ -215,14 +215,14 @@ __archive_mbedtls_md5final(archive_md5_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_MD5_NETTLE)
static int
-__archive_nettle_md5init(archive_md5_ctx *ctx)
+__archive_md5init(archive_md5_ctx *ctx)
{
md5_init(ctx);
return (ARCHIVE_OK);
}
static int
-__archive_nettle_md5update(archive_md5_ctx *ctx, const void *indata,
+__archive_md5update(archive_md5_ctx *ctx, const void *indata,
size_t insize)
{
md5_update(ctx, insize, indata);
@@ -230,7 +230,7 @@ __archive_nettle_md5update(archive_md5_ctx *ctx, const void *indata,
}
static int
-__archive_nettle_md5final(archive_md5_ctx *ctx, void *md)
+__archive_md5final(archive_md5_ctx *ctx, void *md)
{
md5_digest(ctx, MD5_DIGEST_SIZE, md);
return (ARCHIVE_OK);
@@ -239,7 +239,7 @@ __archive_nettle_md5final(archive_md5_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_MD5_OPENSSL)
static int
-__archive_openssl_md5init(archive_md5_ctx *ctx)
+__archive_md5init(archive_md5_ctx *ctx)
{
if ((*ctx = EVP_MD_CTX_new()) == NULL)
return (ARCHIVE_FAILED);
@@ -248,7 +248,7 @@ __archive_openssl_md5init(archive_md5_ctx *ctx)
}
static int
-__archive_openssl_md5update(archive_md5_ctx *ctx, const void *indata,
+__archive_md5update(archive_md5_ctx *ctx, const void *indata,
size_t insize)
{
EVP_DigestUpdate(*ctx, indata, insize);
@@ -256,7 +256,7 @@ __archive_openssl_md5update(archive_md5_ctx *ctx, const void *indata,
}
static int
-__archive_openssl_md5final(archive_md5_ctx *ctx, void *md)
+__archive_md5final(archive_md5_ctx *ctx, void *md)
{
/* HACK: archive_write_set_format_xar.c is finalizing empty contexts, so
* this is meant to cope with that. Real fix is probably to fix
@@ -273,20 +273,20 @@ __archive_openssl_md5final(archive_md5_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_MD5_WIN)
static int
-__archive_windowsapi_md5init(archive_md5_ctx *ctx)
+__archive_md5init(archive_md5_ctx *ctx)
{
return (win_crypto_init(ctx, CALG_MD5));
}
static int
-__archive_windowsapi_md5update(archive_md5_ctx *ctx, const void *indata,
+__archive_md5update(archive_md5_ctx *ctx, const void *indata,
size_t insize)
{
return (win_crypto_Update(ctx, indata, insize));
}
static int
-__archive_windowsapi_md5final(archive_md5_ctx *ctx, void *md)
+__archive_md5final(archive_md5_ctx *ctx, void *md)
{
return (win_crypto_Final(md, 16, ctx));
}
@@ -294,14 +294,14 @@ __archive_windowsapi_md5final(archive_md5_ctx *ctx, void *md)
#else
static int
-__archive_stub_md5init(archive_md5_ctx *ctx)
+__archive_md5init(archive_md5_ctx *ctx)
{
(void)ctx; /* UNUSED */
return (ARCHIVE_FAILED);
}
static int
-__archive_stub_md5update(archive_md5_ctx *ctx, const void *indata,
+__archive_md5update(archive_md5_ctx *ctx, const void *indata,
size_t insize)
{
(void)ctx; /* UNUSED */
@@ -311,7 +311,7 @@ __archive_stub_md5update(archive_md5_ctx *ctx, const void *indata,
}
static int
-__archive_stub_md5final(archive_md5_ctx *ctx, void *md)
+__archive_md5final(archive_md5_ctx *ctx, void *md)
{
(void)ctx; /* UNUSED */
(void)md; /* UNUSED */
@@ -324,14 +324,14 @@ __archive_stub_md5final(archive_md5_ctx *ctx, void *md)
#if defined(ARCHIVE_CRYPTO_RMD160_LIBC)
static int
-__archive_libc_ripemd160init(archive_rmd160_ctx *ctx)
+__archive_ripemd160init(archive_rmd160_ctx *ctx)
{
RMD160Init(ctx);
return (ARCHIVE_OK);
}
static int
-__archive_libc_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
+__archive_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
size_t insize)
{
RMD160Update(ctx, indata, insize);
@@ -339,7 +339,7 @@ __archive_libc_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
}
static int
-__archive_libc_ripemd160final(archive_rmd160_ctx *ctx, void *md)
+__archive_ripemd160final(archive_rmd160_ctx *ctx, void *md)
{
RMD160Final(md, ctx);
return (ARCHIVE_OK);
@@ -348,14 +348,14 @@ __archive_libc_ripemd160final(archive_rmd160_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_RMD160_LIBMD)
static int
-__archive_libmd_ripemd160init(archive_rmd160_ctx *ctx)
+__archive_ripemd160init(archive_rmd160_ctx *ctx)
{
RIPEMD160_Init(ctx);
return (ARCHIVE_OK);
}
static int
-__archive_libmd_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
+__archive_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
size_t insize)
{
RIPEMD160_Update(ctx, indata, insize);
@@ -363,7 +363,7 @@ __archive_libmd_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
}
static int
-__archive_libmd_ripemd160final(archive_rmd160_ctx *ctx, void *md)
+__archive_ripemd160final(archive_rmd160_ctx *ctx, void *md)
{
RIPEMD160_Final(md, ctx);
return (ARCHIVE_OK);
@@ -372,7 +372,7 @@ __archive_libmd_ripemd160final(archive_rmd160_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS)
static int
-__archive_mbedtls_ripemd160init(archive_rmd160_ctx *ctx)
+__archive_ripemd160init(archive_rmd160_ctx *ctx)
{
mbedtls_ripemd160_init(ctx);
if (mbedtls_ripemd160_starts_ret(ctx) == 0)
@@ -382,7 +382,7 @@ __archive_mbedtls_ripemd160init(archive_rmd160_ctx *ctx)
}
static int
-__archive_mbedtls_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
+__archive_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
size_t insize)
{
if (mbedtls_ripemd160_update_ret(ctx, indata, insize) == 0)
@@ -392,7 +392,7 @@ __archive_mbedtls_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
}
static int
-__archive_mbedtls_ripemd160final(archive_rmd160_ctx *ctx, void *md)
+__archive_ripemd160final(archive_rmd160_ctx *ctx, void *md)
{
if (mbedtls_ripemd160_finish_ret(ctx, md) == 0) {
mbedtls_ripemd160_free(ctx);
@@ -406,14 +406,14 @@ __archive_mbedtls_ripemd160final(archive_rmd160_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_RMD160_NETTLE)
static int
-__archive_nettle_ripemd160init(archive_rmd160_ctx *ctx)
+__archive_ripemd160init(archive_rmd160_ctx *ctx)
{
ripemd160_init(ctx);
return (ARCHIVE_OK);
}
static int
-__archive_nettle_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
+__archive_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
size_t insize)
{
ripemd160_update(ctx, insize, indata);
@@ -421,7 +421,7 @@ __archive_nettle_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
}
static int
-__archive_nettle_ripemd160final(archive_rmd160_ctx *ctx, void *md)
+__archive_ripemd160final(archive_rmd160_ctx *ctx, void *md)
{
ripemd160_digest(ctx, RIPEMD160_DIGEST_SIZE, md);
return (ARCHIVE_OK);
@@ -430,7 +430,7 @@ __archive_nettle_ripemd160final(archive_rmd160_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_RMD160_OPENSSL)
static int
-__archive_openssl_ripemd160init(archive_rmd160_ctx *ctx)
+__archive_ripemd160init(archive_rmd160_ctx *ctx)
{
if ((*ctx = EVP_MD_CTX_new()) == NULL)
return (ARCHIVE_FAILED);
@@ -439,7 +439,7 @@ __archive_openssl_ripemd160init(archive_rmd160_ctx *ctx)
}
static int
-__archive_openssl_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
+__archive_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
size_t insize)
{
EVP_DigestUpdate(*ctx, indata, insize);
@@ -447,7 +447,7 @@ __archive_openssl_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
}
static int
-__archive_openssl_ripemd160final(archive_rmd160_ctx *ctx, void *md)
+__archive_ripemd160final(archive_rmd160_ctx *ctx, void *md)
{
if (*ctx) {
EVP_DigestFinal(*ctx, md, NULL);
@@ -460,14 +460,14 @@ __archive_openssl_ripemd160final(archive_rmd160_ctx *ctx, void *md)
#else
static int
-__archive_stub_ripemd160init(archive_rmd160_ctx *ctx)
+__archive_ripemd160init(archive_rmd160_ctx *ctx)
{
(void)ctx; /* UNUSED */
return (ARCHIVE_FAILED);
}
static int
-__archive_stub_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
+__archive_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
size_t insize)
{
(void)ctx; /* UNUSED */
@@ -477,7 +477,7 @@ __archive_stub_ripemd160update(archive_rmd160_ctx *ctx, const void *indata,
}
static int
-__archive_stub_ripemd160final(archive_rmd160_ctx *ctx, void *md)
+__archive_ripemd160final(archive_rmd160_ctx *ctx, void *md)
{
(void)ctx; /* UNUSED */
(void)md; /* UNUSED */
@@ -490,14 +490,14 @@ __archive_stub_ripemd160final(archive_rmd160_ctx *ctx, void *md)
#if defined(ARCHIVE_CRYPTO_SHA1_LIBC)
static int
-__archive_libc_sha1init(archive_sha1_ctx *ctx)
+__archive_sha1init(archive_sha1_ctx *ctx)
{
SHA1Init(ctx);
return (ARCHIVE_OK);
}
static int
-__archive_libc_sha1update(archive_sha1_ctx *ctx, const void *indata,
+__archive_sha1update(archive_sha1_ctx *ctx, const void *indata,
size_t insize)
{
SHA1Update(ctx, indata, insize);
@@ -505,7 +505,7 @@ __archive_libc_sha1update(archive_sha1_ctx *ctx, const void *indata,
}
static int
-__archive_libc_sha1final(archive_sha1_ctx *ctx, void *md)
+__archive_sha1final(archive_sha1_ctx *ctx, void *md)
{
SHA1Final(md, ctx);
return (ARCHIVE_OK);
@@ -514,14 +514,14 @@ __archive_libc_sha1final(archive_sha1_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_SHA1_LIBMD)
static int
-__archive_libmd_sha1init(archive_sha1_ctx *ctx)
+__archive_sha1init(archive_sha1_ctx *ctx)
{
SHA1_Init(ctx);
return (ARCHIVE_OK);
}
static int
-__archive_libmd_sha1update(archive_sha1_ctx *ctx, const void *indata,
+__archive_sha1update(archive_sha1_ctx *ctx, const void *indata,
size_t insize)
{
SHA1_Update(ctx, indata, insize);
@@ -529,7 +529,7 @@ __archive_libmd_sha1update(archive_sha1_ctx *ctx, const void *indata,
}
static int
-__archive_libmd_sha1final(archive_sha1_ctx *ctx, void *md)
+__archive_sha1final(archive_sha1_ctx *ctx, void *md)
{
SHA1_Final(md, ctx);
return (ARCHIVE_OK);
@@ -538,14 +538,14 @@ __archive_libmd_sha1final(archive_sha1_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM)
static int
-__archive_libsystem_sha1init(archive_sha1_ctx *ctx)
+__archive_sha1init(archive_sha1_ctx *ctx)
{
CC_SHA1_Init(ctx);
return (ARCHIVE_OK);
}
static int
-__archive_libsystem_sha1update(archive_sha1_ctx *ctx, const void *indata,
+__archive_sha1update(archive_sha1_ctx *ctx, const void *indata,
size_t insize)
{
CC_SHA1_Update(ctx, indata, insize);
@@ -553,7 +553,7 @@ __archive_libsystem_sha1update(archive_sha1_ctx *ctx, const void *indata,
}
static int
-__archive_libsystem_sha1final(archive_sha1_ctx *ctx, void *md)
+__archive_sha1final(archive_sha1_ctx *ctx, void *md)
{
CC_SHA1_Final(md, ctx);
return (ARCHIVE_OK);
@@ -562,7 +562,7 @@ __archive_libsystem_sha1final(archive_sha1_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS)
static int
-__archive_mbedtls_sha1init(archive_sha1_ctx *ctx)
+__archive_sha1init(archive_sha1_ctx *ctx)
{
mbedtls_sha1_init(ctx);
if (mbedtls_sha1_starts_ret(ctx) == 0)
@@ -572,7 +572,7 @@ __archive_mbedtls_sha1init(archive_sha1_ctx *ctx)
}
static int
-__archive_mbedtls_sha1update(archive_sha1_ctx *ctx, const void *indata,
+__archive_sha1update(archive_sha1_ctx *ctx, const void *indata,
size_t insize)
{
if (mbedtls_sha1_update_ret(ctx, indata, insize) == 0)
@@ -582,7 +582,7 @@ __archive_mbedtls_sha1update(archive_sha1_ctx *ctx, const void *indata,
}
static int
-__archive_mbedtls_sha1final(archive_sha1_ctx *ctx, void *md)
+__archive_sha1final(archive_sha1_ctx *ctx, void *md)
{
if (mbedtls_sha1_finish_ret(ctx, md) == 0) {
mbedtls_sha1_free(ctx);
@@ -596,14 +596,14 @@ __archive_mbedtls_sha1final(archive_sha1_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_SHA1_NETTLE)
static int
-__archive_nettle_sha1init(archive_sha1_ctx *ctx)
+__archive_sha1init(archive_sha1_ctx *ctx)
{
sha1_init(ctx);
return (ARCHIVE_OK);
}
static int
-__archive_nettle_sha1update(archive_sha1_ctx *ctx, const void *indata,
+__archive_sha1update(archive_sha1_ctx *ctx, const void *indata,
size_t insize)
{
sha1_update(ctx, insize, indata);
@@ -611,7 +611,7 @@ __archive_nettle_sha1update(archive_sha1_ctx *ctx, const void *indata,
}
static int
-__archive_nettle_sha1final(archive_sha1_ctx *ctx, void *md)
+__archive_sha1final(archive_sha1_ctx *ctx, void *md)
{
sha1_digest(ctx, SHA1_DIGEST_SIZE, md);
return (ARCHIVE_OK);
@@ -620,7 +620,7 @@ __archive_nettle_sha1final(archive_sha1_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_SHA1_OPENSSL)
static int
-__archive_openssl_sha1init(archive_sha1_ctx *ctx)
+__archive_sha1init(archive_sha1_ctx *ctx)
{
if ((*ctx = EVP_MD_CTX_new()) == NULL)
return (ARCHIVE_FAILED);
@@ -629,7 +629,7 @@ __archive_openssl_sha1init(archive_sha1_ctx *ctx)
}
static int
-__archive_openssl_sha1update(archive_sha1_ctx *ctx, const void *indata,
+__archive_sha1update(archive_sha1_ctx *ctx, const void *indata,
size_t insize)
{
EVP_DigestUpdate(*ctx, indata, insize);
@@ -637,7 +637,7 @@ __archive_openssl_sha1update(archive_sha1_ctx *ctx, const void *indata,
}
static int
-__archive_openssl_sha1final(archive_sha1_ctx *ctx, void *md)
+__archive_sha1final(archive_sha1_ctx *ctx, void *md)
{
/* HACK: archive_write_set_format_xar.c is finalizing empty contexts, so
* this is meant to cope with that. Real fix is probably to fix
@@ -654,20 +654,20 @@ __archive_openssl_sha1final(archive_sha1_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_SHA1_WIN)
static int
-__archive_windowsapi_sha1init(archive_sha1_ctx *ctx)
+__archive_sha1init(archive_sha1_ctx *ctx)
{
return (win_crypto_init(ctx, CALG_SHA1));
}
static int
-__archive_windowsapi_sha1update(archive_sha1_ctx *ctx, const void *indata,
+__archive_sha1update(archive_sha1_ctx *ctx, const void *indata,
size_t insize)
{
return (win_crypto_Update(ctx, indata, insize));
}
static int
-__archive_windowsapi_sha1final(archive_sha1_ctx *ctx, void *md)
+__archive_sha1final(archive_sha1_ctx *ctx, void *md)
{
return (win_crypto_Final(md, 20, ctx));
}
@@ -675,14 +675,14 @@ __archive_windowsapi_sha1final(archive_sha1_ctx *ctx, void *md)
#else
static int
-__archive_stub_sha1init(archive_sha1_ctx *ctx)
+__archive_sha1init(archive_sha1_ctx *ctx)
{
(void)ctx; /* UNUSED */
return (ARCHIVE_FAILED);
}
static int
-__archive_stub_sha1update(archive_sha1_ctx *ctx, const void *indata,
+__archive_sha1update(archive_sha1_ctx *ctx, const void *indata,
size_t insize)
{
(void)ctx; /* UNUSED */
@@ -692,7 +692,7 @@ __archive_stub_sha1update(archive_sha1_ctx *ctx, const void *indata,
}
static int
-__archive_stub_sha1final(archive_sha1_ctx *ctx, void *md)
+__archive_sha1final(archive_sha1_ctx *ctx, void *md)
{
(void)ctx; /* UNUSED */
(void)md; /* UNUSED */
@@ -705,14 +705,14 @@ __archive_stub_sha1final(archive_sha1_ctx *ctx, void *md)
#if defined(ARCHIVE_CRYPTO_SHA256_LIBC)
static int
-__archive_libc_sha256init(archive_sha256_ctx *ctx)
+__archive_sha256init(archive_sha256_ctx *ctx)
{
SHA256_Init(ctx);
return (ARCHIVE_OK);
}
static int
-__archive_libc_sha256update(archive_sha256_ctx *ctx, const void *indata,
+__archive_sha256update(archive_sha256_ctx *ctx, const void *indata,
size_t insize)
{
SHA256_Update(ctx, indata, insize);
@@ -720,7 +720,7 @@ __archive_libc_sha256update(archive_sha256_ctx *ctx, const void *indata,
}
static int
-__archive_libc_sha256final(archive_sha256_ctx *ctx, void *md)
+__archive_sha256final(archive_sha256_ctx *ctx, void *md)
{
SHA256_Final(md, ctx);
return (ARCHIVE_OK);
@@ -729,14 +729,14 @@ __archive_libc_sha256final(archive_sha256_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC2)
static int
-__archive_libc2_sha256init(archive_sha256_ctx *ctx)
+__archive_sha256init(archive_sha256_ctx *ctx)
{
SHA256Init(ctx);
return (ARCHIVE_OK);
}
static int
-__archive_libc2_sha256update(archive_sha256_ctx *ctx, const void *indata,
+__archive_sha256update(archive_sha256_ctx *ctx, const void *indata,
size_t insize)
{
SHA256Update(ctx, indata, insize);
@@ -744,7 +744,7 @@ __archive_libc2_sha256update(archive_sha256_ctx *ctx, const void *indata,
}
static int
-__archive_libc2_sha256final(archive_sha256_ctx *ctx, void *md)
+__archive_sha256final(archive_sha256_ctx *ctx, void *md)
{
SHA256Final(md, ctx);
return (ARCHIVE_OK);
@@ -753,14 +753,14 @@ __archive_libc2_sha256final(archive_sha256_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC3)
static int
-__archive_libc3_sha256init(archive_sha256_ctx *ctx)
+__archive_sha256init(archive_sha256_ctx *ctx)
{
SHA256Init(ctx);
return (ARCHIVE_OK);
}
static int
-__archive_libc3_sha256update(archive_sha256_ctx *ctx, const void *indata,
+__archive_sha256update(archive_sha256_ctx *ctx, const void *indata,
size_t insize)
{
SHA256Update(ctx, indata, insize);
@@ -768,7 +768,7 @@ __archive_libc3_sha256update(archive_sha256_ctx *ctx, const void *indata,
}
static int
-__archive_libc3_sha256final(archive_sha256_ctx *ctx, void *md)
+__archive_sha256final(archive_sha256_ctx *ctx, void *md)
{
SHA256Final(md, ctx);
return (ARCHIVE_OK);
@@ -777,14 +777,14 @@ __archive_libc3_sha256final(archive_sha256_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_SHA256_LIBMD)
static int
-__archive_libmd_sha256init(archive_sha256_ctx *ctx)
+__archive_sha256init(archive_sha256_ctx *ctx)
{
SHA256_Init(ctx);
return (ARCHIVE_OK);
}
static int
-__archive_libmd_sha256update(archive_sha256_ctx *ctx, const void *indata,
+__archive_sha256update(archive_sha256_ctx *ctx, const void *indata,
size_t insize)
{
SHA256_Update(ctx, indata, insize);
@@ -792,7 +792,7 @@ __archive_libmd_sha256update(archive_sha256_ctx *ctx, const void *indata,
}
static int
-__archive_libmd_sha256final(archive_sha256_ctx *ctx, void *md)
+__archive_sha256final(archive_sha256_ctx *ctx, void *md)
{
SHA256_Final(md, ctx);
return (ARCHIVE_OK);
@@ -801,14 +801,14 @@ __archive_libmd_sha256final(archive_sha256_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM)
static int
-__archive_libsystem_sha256init(archive_sha256_ctx *ctx)
+__archive_sha256init(archive_sha256_ctx *ctx)
{
CC_SHA256_Init(ctx);
return (ARCHIVE_OK);
}
static int
-__archive_libsystem_sha256update(archive_sha256_ctx *ctx, const void *indata,
+__archive_sha256update(archive_sha256_ctx *ctx, const void *indata,
size_t insize)
{
CC_SHA256_Update(ctx, indata, insize);
@@ -816,7 +816,7 @@ __archive_libsystem_sha256update(archive_sha256_ctx *ctx, const void *indata,
}
static int
-__archive_libsystem_sha256final(archive_sha256_ctx *ctx, void *md)
+__archive_sha256final(archive_sha256_ctx *ctx, void *md)
{
CC_SHA256_Final(md, ctx);
return (ARCHIVE_OK);
@@ -825,7 +825,7 @@ __archive_libsystem_sha256final(archive_sha256_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS)
static int
-__archive_mbedtls_sha256init(archive_sha256_ctx *ctx)
+__archive_sha256init(archive_sha256_ctx *ctx)
{
mbedtls_sha256_init(ctx);
if (mbedtls_sha256_starts_ret(ctx, 0) == 0)
@@ -835,7 +835,7 @@ __archive_mbedtls_sha256init(archive_sha256_ctx *ctx)
}
static int
-__archive_mbedtls_sha256update(archive_sha256_ctx *ctx, const void *indata,
+__archive_sha256update(archive_sha256_ctx *ctx, const void *indata,
size_t insize)
{
if (mbedtls_sha256_update_ret(ctx, indata, insize) == 0)
@@ -845,7 +845,7 @@ __archive_mbedtls_sha256update(archive_sha256_ctx *ctx, const void *indata,
}
static int
-__archive_mbedtls_sha256final(archive_sha256_ctx *ctx, void *md)
+__archive_sha256final(archive_sha256_ctx *ctx, void *md)
{
if (mbedtls_sha256_finish_ret(ctx, md) == 0) {
mbedtls_sha256_free(ctx);
@@ -859,14 +859,14 @@ __archive_mbedtls_sha256final(archive_sha256_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_SHA256_NETTLE)
static int
-__archive_nettle_sha256init(archive_sha256_ctx *ctx)
+__archive_sha256init(archive_sha256_ctx *ctx)
{
sha256_init(ctx);
return (ARCHIVE_OK);
}
static int
-__archive_nettle_sha256update(archive_sha256_ctx *ctx, const void *indata,
+__archive_sha256update(archive_sha256_ctx *ctx, const void *indata,
size_t insize)
{
sha256_update(ctx, insize, indata);
@@ -874,7 +874,7 @@ __archive_nettle_sha256update(archive_sha256_ctx *ctx, const void *indata,
}
static int
-__archive_nettle_sha256final(archive_sha256_ctx *ctx, void *md)
+__archive_sha256final(archive_sha256_ctx *ctx, void *md)
{
sha256_digest(ctx, SHA256_DIGEST_SIZE, md);
return (ARCHIVE_OK);
@@ -883,7 +883,7 @@ __archive_nettle_sha256final(archive_sha256_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_SHA256_OPENSSL)
static int
-__archive_openssl_sha256init(archive_sha256_ctx *ctx)
+__archive_sha256init(archive_sha256_ctx *ctx)
{
if ((*ctx = EVP_MD_CTX_new()) == NULL)
return (ARCHIVE_FAILED);
@@ -892,7 +892,7 @@ __archive_openssl_sha256init(archive_sha256_ctx *ctx)
}
static int
-__archive_openssl_sha256update(archive_sha256_ctx *ctx, const void *indata,
+__archive_sha256update(archive_sha256_ctx *ctx, const void *indata,
size_t insize)
{
EVP_DigestUpdate(*ctx, indata, insize);
@@ -900,7 +900,7 @@ __archive_openssl_sha256update(archive_sha256_ctx *ctx, const void *indata,
}
static int
-__archive_openssl_sha256final(archive_sha256_ctx *ctx, void *md)
+__archive_sha256final(archive_sha256_ctx *ctx, void *md)
{
if (*ctx) {
EVP_DigestFinal(*ctx, md, NULL);
@@ -913,20 +913,20 @@ __archive_openssl_sha256final(archive_sha256_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_SHA256_WIN)
static int
-__archive_windowsapi_sha256init(archive_sha256_ctx *ctx)
+__archive_sha256init(archive_sha256_ctx *ctx)
{
return (win_crypto_init(ctx, CALG_SHA_256));
}
static int
-__archive_windowsapi_sha256update(archive_sha256_ctx *ctx, const void *indata,
+__archive_sha256update(archive_sha256_ctx *ctx, const void *indata,
size_t insize)
{
return (win_crypto_Update(ctx, indata, insize));
}
static int
-__archive_windowsapi_sha256final(archive_sha256_ctx *ctx, void *md)
+__archive_sha256final(archive_sha256_ctx *ctx, void *md)
{
return (win_crypto_Final(md, 32, ctx));
}
@@ -934,14 +934,14 @@ __archive_windowsapi_sha256final(archive_sha256_ctx *ctx, void *md)
#else
static int
-__archive_stub_sha256init(archive_sha256_ctx *ctx)
+__archive_sha256init(archive_sha256_ctx *ctx)
{
(void)ctx; /* UNUSED */
return (ARCHIVE_FAILED);
}
static int
-__archive_stub_sha256update(archive_sha256_ctx *ctx, const void *indata,
+__archive_sha256update(archive_sha256_ctx *ctx, const void *indata,
size_t insize)
{
(void)ctx; /* UNUSED */
@@ -951,7 +951,7 @@ __archive_stub_sha256update(archive_sha256_ctx *ctx, const void *indata,
}
static int
-__archive_stub_sha256final(archive_sha256_ctx *ctx, void *md)
+__archive_sha256final(archive_sha256_ctx *ctx, void *md)
{
(void)ctx; /* UNUSED */
(void)md; /* UNUSED */
@@ -964,14 +964,14 @@ __archive_stub_sha256final(archive_sha256_ctx *ctx, void *md)
#if defined(ARCHIVE_CRYPTO_SHA384_LIBC)
static int
-__archive_libc_sha384init(archive_sha384_ctx *ctx)
+__archive_sha384init(archive_sha384_ctx *ctx)
{
SHA384_Init(ctx);
return (ARCHIVE_OK);
}
static int
-__archive_libc_sha384update(archive_sha384_ctx *ctx, const void *indata,
+__archive_sha384update(archive_sha384_ctx *ctx, const void *indata,
size_t insize)
{
SHA384_Update(ctx, indata, insize);
@@ -979,7 +979,7 @@ __archive_libc_sha384update(archive_sha384_ctx *ctx, const void *indata,
}
static int
-__archive_libc_sha384final(archive_sha384_ctx *ctx, void *md)
+__archive_sha384final(archive_sha384_ctx *ctx, void *md)
{
SHA384_Final(md, ctx);
return (ARCHIVE_OK);
@@ -988,14 +988,14 @@ __archive_libc_sha384final(archive_sha384_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC2)
static int
-__archive_libc2_sha384init(archive_sha384_ctx *ctx)
+__archive_sha384init(archive_sha384_ctx *ctx)
{
SHA384Init(ctx);
return (ARCHIVE_OK);
}
static int
-__archive_libc2_sha384update(archive_sha384_ctx *ctx, const void *indata,
+__archive_sha384update(archive_sha384_ctx *ctx, const void *indata,
size_t insize)
{
SHA384Update(ctx, indata, insize);
@@ -1003,7 +1003,7 @@ __archive_libc2_sha384update(archive_sha384_ctx *ctx, const void *indata,
}
static int
-__archive_libc2_sha384final(archive_sha384_ctx *ctx, void *md)
+__archive_sha384final(archive_sha384_ctx *ctx, void *md)
{
SHA384Final(md, ctx);
return (ARCHIVE_OK);
@@ -1012,14 +1012,14 @@ __archive_libc2_sha384final(archive_sha384_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC3)
static int
-__archive_libc3_sha384init(archive_sha384_ctx *ctx)
+__archive_sha384init(archive_sha384_ctx *ctx)
{
SHA384Init(ctx);
return (ARCHIVE_OK);
}
static int
-__archive_libc3_sha384update(archive_sha384_ctx *ctx, const void *indata,
+__archive_sha384update(archive_sha384_ctx *ctx, const void *indata,
size_t insize)
{
SHA384Update(ctx, indata, insize);
@@ -1027,7 +1027,7 @@ __archive_libc3_sha384update(archive_sha384_ctx *ctx, const void *indata,
}
static int
-__archive_libc3_sha384final(archive_sha384_ctx *ctx, void *md)
+__archive_sha384final(archive_sha384_ctx *ctx, void *md)
{
SHA384Final(md, ctx);
return (ARCHIVE_OK);
@@ -1036,14 +1036,14 @@ __archive_libc3_sha384final(archive_sha384_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM)
static int
-__archive_libsystem_sha384init(archive_sha384_ctx *ctx)
+__archive_sha384init(archive_sha384_ctx *ctx)
{
CC_SHA384_Init(ctx);
return (ARCHIVE_OK);
}
static int
-__archive_libsystem_sha384update(archive_sha384_ctx *ctx, const void *indata,
+__archive_sha384update(archive_sha384_ctx *ctx, const void *indata,
size_t insize)
{
CC_SHA384_Update(ctx, indata, insize);
@@ -1051,7 +1051,7 @@ __archive_libsystem_sha384update(archive_sha384_ctx *ctx, const void *indata,
}
static int
-__archive_libsystem_sha384final(archive_sha384_ctx *ctx, void *md)
+__archive_sha384final(archive_sha384_ctx *ctx, void *md)
{
CC_SHA384_Final(md, ctx);
return (ARCHIVE_OK);
@@ -1060,7 +1060,7 @@ __archive_libsystem_sha384final(archive_sha384_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS)
static int
-__archive_mbedtls_sha384init(archive_sha384_ctx *ctx)
+__archive_sha384init(archive_sha384_ctx *ctx)
{
mbedtls_sha512_init(ctx);
if (mbedtls_sha512_starts_ret(ctx, 1) == 0)
@@ -1070,7 +1070,7 @@ __archive_mbedtls_sha384init(archive_sha384_ctx *ctx)
}
static int
-__archive_mbedtls_sha384update(archive_sha384_ctx *ctx, const void *indata,
+__archive_sha384update(archive_sha384_ctx *ctx, const void *indata,
size_t insize)
{
if (mbedtls_sha512_update_ret(ctx, indata, insize) == 0)
@@ -1080,7 +1080,7 @@ __archive_mbedtls_sha384update(archive_sha384_ctx *ctx, const void *indata,
}
static int
-__archive_mbedtls_sha384final(archive_sha384_ctx *ctx, void *md)
+__archive_sha384final(archive_sha384_ctx *ctx, void *md)
{
if (mbedtls_sha512_finish_ret(ctx, md) == 0) {
mbedtls_sha512_free(ctx);
@@ -1094,14 +1094,14 @@ __archive_mbedtls_sha384final(archive_sha384_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_SHA384_NETTLE)
static int
-__archive_nettle_sha384init(archive_sha384_ctx *ctx)
+__archive_sha384init(archive_sha384_ctx *ctx)
{
sha384_init(ctx);
return (ARCHIVE_OK);
}
static int
-__archive_nettle_sha384update(archive_sha384_ctx *ctx, const void *indata,
+__archive_sha384update(archive_sha384_ctx *ctx, const void *indata,
size_t insize)
{
sha384_update(ctx, insize, indata);
@@ -1109,7 +1109,7 @@ __archive_nettle_sha384update(archive_sha384_ctx *ctx, const void *indata,
}
static int
-__archive_nettle_sha384final(archive_sha384_ctx *ctx, void *md)
+__archive_sha384final(archive_sha384_ctx *ctx, void *md)
{
sha384_digest(ctx, SHA384_DIGEST_SIZE, md);
return (ARCHIVE_OK);
@@ -1118,7 +1118,7 @@ __archive_nettle_sha384final(archive_sha384_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_SHA384_OPENSSL)
static int
-__archive_openssl_sha384init(archive_sha384_ctx *ctx)
+__archive_sha384init(archive_sha384_ctx *ctx)
{
if ((*ctx = EVP_MD_CTX_new()) == NULL)
return (ARCHIVE_FAILED);
@@ -1127,7 +1127,7 @@ __archive_openssl_sha384init(archive_sha384_ctx *ctx)
}
static int
-__archive_openssl_sha384update(archive_sha384_ctx *ctx, const void *indata,
+__archive_sha384update(archive_sha384_ctx *ctx, const void *indata,
size_t insize)
{
EVP_DigestUpdate(*ctx, indata, insize);
@@ -1135,7 +1135,7 @@ __archive_openssl_sha384update(archive_sha384_ctx *ctx, const void *indata,
}
static int
-__archive_openssl_sha384final(archive_sha384_ctx *ctx, void *md)
+__archive_sha384final(archive_sha384_ctx *ctx, void *md)
{
if (*ctx) {
EVP_DigestFinal(*ctx, md, NULL);
@@ -1148,20 +1148,20 @@ __archive_openssl_sha384final(archive_sha384_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_SHA384_WIN)
static int
-__archive_windowsapi_sha384init(archive_sha384_ctx *ctx)
+__archive_sha384init(archive_sha384_ctx *ctx)
{
return (win_crypto_init(ctx, CALG_SHA_384));
}
static int
-__archive_windowsapi_sha384update(archive_sha384_ctx *ctx, const void *indata,
+__archive_sha384update(archive_sha384_ctx *ctx, const void *indata,
size_t insize)
{
return (win_crypto_Update(ctx, indata, insize));
}
static int
-__archive_windowsapi_sha384final(archive_sha384_ctx *ctx, void *md)
+__archive_sha384final(archive_sha384_ctx *ctx, void *md)
{
return (win_crypto_Final(md, 48, ctx));
}
@@ -1169,14 +1169,14 @@ __archive_windowsapi_sha384final(archive_sha384_ctx *ctx, void *md)
#else
static int
-__archive_stub_sha384init(archive_sha384_ctx *ctx)
+__archive_sha384init(archive_sha384_ctx *ctx)
{
(void)ctx; /* UNUSED */
return (ARCHIVE_FAILED);
}
static int
-__archive_stub_sha384update(archive_sha384_ctx *ctx, const void *indata,
+__archive_sha384update(archive_sha384_ctx *ctx, const void *indata,
size_t insize)
{
(void)ctx; /* UNUSED */
@@ -1186,7 +1186,7 @@ __archive_stub_sha384update(archive_sha384_ctx *ctx, const void *indata,
}
static int
-__archive_stub_sha384final(archive_sha384_ctx *ctx, void *md)
+__archive_sha384final(archive_sha384_ctx *ctx, void *md)
{
(void)ctx; /* UNUSED */
(void)md; /* UNUSED */
@@ -1199,14 +1199,14 @@ __archive_stub_sha384final(archive_sha384_ctx *ctx, void *md)
#if defined(ARCHIVE_CRYPTO_SHA512_LIBC)
static int
-__archive_libc_sha512init(archive_sha512_ctx *ctx)
+__archive_sha512init(archive_sha512_ctx *ctx)
{
SHA512_Init(ctx);
return (ARCHIVE_OK);
}
static int
-__archive_libc_sha512update(archive_sha512_ctx *ctx, const void *indata,
+__archive_sha512update(archive_sha512_ctx *ctx, const void *indata,
size_t insize)
{
SHA512_Update(ctx, indata, insize);
@@ -1214,7 +1214,7 @@ __archive_libc_sha512update(archive_sha512_ctx *ctx, const void *indata,
}
static int
-__archive_libc_sha512final(archive_sha512_ctx *ctx, void *md)
+__archive_sha512final(archive_sha512_ctx *ctx, void *md)
{
SHA512_Final(md, ctx);
return (ARCHIVE_OK);
@@ -1223,14 +1223,14 @@ __archive_libc_sha512final(archive_sha512_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC2)
static int
-__archive_libc2_sha512init(archive_sha512_ctx *ctx)
+__archive_sha512init(archive_sha512_ctx *ctx)
{
SHA512Init(ctx);
return (ARCHIVE_OK);
}
static int
-__archive_libc2_sha512update(archive_sha512_ctx *ctx, const void *indata,
+__archive_sha512update(archive_sha512_ctx *ctx, const void *indata,
size_t insize)
{
SHA512Update(ctx, indata, insize);
@@ -1238,7 +1238,7 @@ __archive_libc2_sha512update(archive_sha512_ctx *ctx, const void *indata,
}
static int
-__archive_libc2_sha512final(archive_sha512_ctx *ctx, void *md)
+__archive_sha512final(archive_sha512_ctx *ctx, void *md)
{
SHA512Final(md, ctx);
return (ARCHIVE_OK);
@@ -1247,14 +1247,14 @@ __archive_libc2_sha512final(archive_sha512_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC3)
static int
-__archive_libc3_sha512init(archive_sha512_ctx *ctx)
+__archive_sha512init(archive_sha512_ctx *ctx)
{
SHA512Init(ctx);
return (ARCHIVE_OK);
}
static int
-__archive_libc3_sha512update(archive_sha512_ctx *ctx, const void *indata,
+__archive_sha512update(archive_sha512_ctx *ctx, const void *indata,
size_t insize)
{
SHA512Update(ctx, indata, insize);
@@ -1262,7 +1262,7 @@ __archive_libc3_sha512update(archive_sha512_ctx *ctx, const void *indata,
}
static int
-__archive_libc3_sha512final(archive_sha512_ctx *ctx, void *md)
+__archive_sha512final(archive_sha512_ctx *ctx, void *md)
{
SHA512Final(md, ctx);
return (ARCHIVE_OK);
@@ -1271,14 +1271,14 @@ __archive_libc3_sha512final(archive_sha512_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_SHA512_LIBMD)
static int
-__archive_libmd_sha512init(archive_sha512_ctx *ctx)
+__archive_sha512init(archive_sha512_ctx *ctx)
{
SHA512_Init(ctx);
return (ARCHIVE_OK);
}
static int
-__archive_libmd_sha512update(archive_sha512_ctx *ctx, const void *indata,
+__archive_sha512update(archive_sha512_ctx *ctx, const void *indata,
size_t insize)
{
SHA512_Update(ctx, indata, insize);
@@ -1286,7 +1286,7 @@ __archive_libmd_sha512update(archive_sha512_ctx *ctx, const void *indata,
}
static int
-__archive_libmd_sha512final(archive_sha512_ctx *ctx, void *md)
+__archive_sha512final(archive_sha512_ctx *ctx, void *md)
{
SHA512_Final(md, ctx);
return (ARCHIVE_OK);
@@ -1295,14 +1295,14 @@ __archive_libmd_sha512final(archive_sha512_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM)
static int
-__archive_libsystem_sha512init(archive_sha512_ctx *ctx)
+__archive_sha512init(archive_sha512_ctx *ctx)
{
CC_SHA512_Init(ctx);
return (ARCHIVE_OK);
}
static int
-__archive_libsystem_sha512update(archive_sha512_ctx *ctx, const void *indata,
+__archive_sha512update(archive_sha512_ctx *ctx, const void *indata,
size_t insize)
{
CC_SHA512_Update(ctx, indata, insize);
@@ -1310,7 +1310,7 @@ __archive_libsystem_sha512update(archive_sha512_ctx *ctx, const void *indata,
}
static int
-__archive_libsystem_sha512final(archive_sha512_ctx *ctx, void *md)
+__archive_sha512final(archive_sha512_ctx *ctx, void *md)
{
CC_SHA512_Final(md, ctx);
return (ARCHIVE_OK);
@@ -1319,7 +1319,7 @@ __archive_libsystem_sha512final(archive_sha512_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS)
static int
-__archive_mbedtls_sha512init(archive_sha512_ctx *ctx)
+__archive_sha512init(archive_sha512_ctx *ctx)
{
mbedtls_sha512_init(ctx);
if (mbedtls_sha512_starts_ret(ctx, 0) == 0)
@@ -1329,7 +1329,7 @@ __archive_mbedtls_sha512init(archive_sha512_ctx *ctx)
}
static int
-__archive_mbedtls_sha512update(archive_sha512_ctx *ctx, const void *indata,
+__archive_sha512update(archive_sha512_ctx *ctx, const void *indata,
size_t insize)
{
if (mbedtls_sha512_update_ret(ctx, indata, insize) == 0)
@@ -1339,7 +1339,7 @@ __archive_mbedtls_sha512update(archive_sha512_ctx *ctx, const void *indata,
}
static int
-__archive_mbedtls_sha512final(archive_sha512_ctx *ctx, void *md)
+__archive_sha512final(archive_sha512_ctx *ctx, void *md)
{
if (mbedtls_sha512_finish_ret(ctx, md) == 0) {
mbedtls_sha512_free(ctx);
@@ -1353,14 +1353,14 @@ __archive_mbedtls_sha512final(archive_sha512_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_SHA512_NETTLE)
static int
-__archive_nettle_sha512init(archive_sha512_ctx *ctx)
+__archive_sha512init(archive_sha512_ctx *ctx)
{
sha512_init(ctx);
return (ARCHIVE_OK);
}
static int
-__archive_nettle_sha512update(archive_sha512_ctx *ctx, const void *indata,
+__archive_sha512update(archive_sha512_ctx *ctx, const void *indata,
size_t insize)
{
sha512_update(ctx, insize, indata);
@@ -1368,7 +1368,7 @@ __archive_nettle_sha512update(archive_sha512_ctx *ctx, const void *indata,
}
static int
-__archive_nettle_sha512final(archive_sha512_ctx *ctx, void *md)
+__archive_sha512final(archive_sha512_ctx *ctx, void *md)
{
sha512_digest(ctx, SHA512_DIGEST_SIZE, md);
return (ARCHIVE_OK);
@@ -1377,7 +1377,7 @@ __archive_nettle_sha512final(archive_sha512_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_SHA512_OPENSSL)
static int
-__archive_openssl_sha512init(archive_sha512_ctx *ctx)
+__archive_sha512init(archive_sha512_ctx *ctx)
{
if ((*ctx = EVP_MD_CTX_new()) == NULL)
return (ARCHIVE_FAILED);
@@ -1386,7 +1386,7 @@ __archive_openssl_sha512init(archive_sha512_ctx *ctx)
}
static int
-__archive_openssl_sha512update(archive_sha512_ctx *ctx, const void *indata,
+__archive_sha512update(archive_sha512_ctx *ctx, const void *indata,
size_t insize)
{
EVP_DigestUpdate(*ctx, indata, insize);
@@ -1394,7 +1394,7 @@ __archive_openssl_sha512update(archive_sha512_ctx *ctx, const void *indata,
}
static int
-__archive_openssl_sha512final(archive_sha512_ctx *ctx, void *md)
+__archive_sha512final(archive_sha512_ctx *ctx, void *md)
{
if (*ctx) {
EVP_DigestFinal(*ctx, md, NULL);
@@ -1407,20 +1407,20 @@ __archive_openssl_sha512final(archive_sha512_ctx *ctx, void *md)
#elif defined(ARCHIVE_CRYPTO_SHA512_WIN)
static int
-__archive_windowsapi_sha512init(archive_sha512_ctx *ctx)
+__archive_sha512init(archive_sha512_ctx *ctx)
{
return (win_crypto_init(ctx, CALG_SHA_512));
}
static int
-__archive_windowsapi_sha512update(archive_sha512_ctx *ctx, const void *indata,
+__archive_sha512update(archive_sha512_ctx *ctx, const void *indata,
size_t insize)
{
return (win_crypto_Update(ctx, indata, insize));
}
static int
-__archive_windowsapi_sha512final(archive_sha512_ctx *ctx, void *md)
+__archive_sha512final(archive_sha512_ctx *ctx, void *md)
{
return (win_crypto_Final(md, 64, ctx));
}
@@ -1428,14 +1428,14 @@ __archive_windowsapi_sha512final(archive_sha512_ctx *ctx, void *md)
#else
static int
-__archive_stub_sha512init(archive_sha512_ctx *ctx)
+__archive_sha512init(archive_sha512_ctx *ctx)
{
(void)ctx; /* UNUSED */
return (ARCHIVE_FAILED);
}
static int
-__archive_stub_sha512update(archive_sha512_ctx *ctx, const void *indata,
+__archive_sha512update(archive_sha512_ctx *ctx, const void *indata,
size_t insize)
{
(void)ctx; /* UNUSED */
@@ -1445,7 +1445,7 @@ __archive_stub_sha512update(archive_sha512_ctx *ctx, const void *indata,
}
static int
-__archive_stub_sha512final(archive_sha512_ctx *ctx, void *md)
+__archive_sha512final(archive_sha512_ctx *ctx, void *md)
{
(void)ctx; /* UNUSED */
(void)md; /* UNUSED */
@@ -1468,224 +1468,32 @@ __archive_stub_sha512final(archive_sha512_ctx *ctx, void *md)
const struct archive_digest __archive_digest =
{
/* MD5 */
-#if defined(ARCHIVE_CRYPTO_MD5_LIBC)
- &__archive_libc_md5init,
- &__archive_libc_md5update,
- &__archive_libc_md5final,
-#elif defined(ARCHIVE_CRYPTO_MD5_LIBMD)
- &__archive_libmd_md5init,
- &__archive_libmd_md5update,
- &__archive_libmd_md5final,
-#elif defined(ARCHIVE_CRYPTO_MD5_LIBSYSTEM)
- &__archive_libsystem_md5init,
- &__archive_libsystem_md5update,
- &__archive_libsystem_md5final,
-#elif defined(ARCHIVE_CRYPTO_MD5_MBEDTLS)
- &__archive_mbedtls_md5init,
- &__archive_mbedtls_md5update,
- &__archive_mbedtls_md5final,
-#elif defined(ARCHIVE_CRYPTO_MD5_NETTLE)
- &__archive_nettle_md5init,
- &__archive_nettle_md5update,
- &__archive_nettle_md5final,
-#elif defined(ARCHIVE_CRYPTO_MD5_OPENSSL)
- &__archive_openssl_md5init,
- &__archive_openssl_md5update,
- &__archive_openssl_md5final,
-#elif defined(ARCHIVE_CRYPTO_MD5_WIN)
- &__archive_windowsapi_md5init,
- &__archive_windowsapi_md5update,
- &__archive_windowsapi_md5final,
-#elif !defined(ARCHIVE_MD5_COMPILE_TEST)
- &__archive_stub_md5init,
- &__archive_stub_md5update,
- &__archive_stub_md5final,
-#endif
+ &__archive_md5init,
+ &__archive_md5update,
+ &__archive_md5final,
/* RIPEMD160 */
-#if defined(ARCHIVE_CRYPTO_RMD160_LIBC)
- &__archive_libc_ripemd160init,
- &__archive_libc_ripemd160update,
- &__archive_libc_ripemd160final,
-#elif defined(ARCHIVE_CRYPTO_RMD160_LIBMD)
- &__archive_libmd_ripemd160init,
- &__archive_libmd_ripemd160update,
- &__archive_libmd_ripemd160final,
-#elif defined(ARCHIVE_CRYPTO_RMD160_MBEDTLS)
- &__archive_mbedtls_ripemd160init,
- &__archive_mbedtls_ripemd160update,
- &__archive_mbedtls_ripemd160final,
-#elif defined(ARCHIVE_CRYPTO_RMD160_NETTLE)
- &__archive_nettle_ripemd160init,
- &__archive_nettle_ripemd160update,
- &__archive_nettle_ripemd160final,
-#elif defined(ARCHIVE_CRYPTO_RMD160_OPENSSL)
- &__archive_openssl_ripemd160init,
- &__archive_openssl_ripemd160update,
- &__archive_openssl_ripemd160final,
-#elif !defined(ARCHIVE_RMD160_COMPILE_TEST)
- &__archive_stub_ripemd160init,
- &__archive_stub_ripemd160update,
- &__archive_stub_ripemd160final,
-#endif
+ &__archive_ripemd160init,
+ &__archive_ripemd160update,
+ &__archive_ripemd160final,
/* SHA1 */
-#if defined(ARCHIVE_CRYPTO_SHA1_LIBC)
- &__archive_libc_sha1init,
- &__archive_libc_sha1update,
- &__archive_libc_sha1final,
-#elif defined(ARCHIVE_CRYPTO_SHA1_LIBMD)
- &__archive_libmd_sha1init,
- &__archive_libmd_sha1update,
- &__archive_libmd_sha1final,
-#elif defined(ARCHIVE_CRYPTO_SHA1_LIBSYSTEM)
- &__archive_libsystem_sha1init,
- &__archive_libsystem_sha1update,
- &__archive_libsystem_sha1final,
-#elif defined(ARCHIVE_CRYPTO_SHA1_MBEDTLS)
- &__archive_mbedtls_sha1init,
- &__archive_mbedtls_sha1update,
- &__archive_mbedtls_sha1final,
-#elif defined(ARCHIVE_CRYPTO_SHA1_NETTLE)
- &__archive_nettle_sha1init,
- &__archive_nettle_sha1update,
- &__archive_nettle_sha1final,
-#elif defined(ARCHIVE_CRYPTO_SHA1_OPENSSL)
- &__archive_openssl_sha1init,
- &__archive_openssl_sha1update,
- &__archive_openssl_sha1final,
-#elif defined(ARCHIVE_CRYPTO_SHA1_WIN)
- &__archive_windowsapi_sha1init,
- &__archive_windowsapi_sha1update,
- &__archive_windowsapi_sha1final,
-#elif !defined(ARCHIVE_SHA1_COMPILE_TEST)
- &__archive_stub_sha1init,
- &__archive_stub_sha1update,
- &__archive_stub_sha1final,
-#endif
+ &__archive_sha1init,
+ &__archive_sha1update,
+ &__archive_sha1final,
/* SHA256 */
-#if defined(ARCHIVE_CRYPTO_SHA256_LIBC)
- &__archive_libc_sha256init,
- &__archive_libc_sha256update,
- &__archive_libc_sha256final,
-#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC2)
- &__archive_libc2_sha256init,
- &__archive_libc2_sha256update,
- &__archive_libc2_sha256final,
-#elif defined(ARCHIVE_CRYPTO_SHA256_LIBC3)
- &__archive_libc3_sha256init,
- &__archive_libc3_sha256update,
- &__archive_libc3_sha256final,
-#elif defined(ARCHIVE_CRYPTO_SHA256_LIBMD)
- &__archive_libmd_sha256init,
- &__archive_libmd_sha256update,
- &__archive_libmd_sha256final,
-#elif defined(ARCHIVE_CRYPTO_SHA256_LIBSYSTEM)
- &__archive_libsystem_sha256init,
- &__archive_libsystem_sha256update,
- &__archive_libsystem_sha256final,
-#elif defined(ARCHIVE_CRYPTO_SHA256_MBEDTLS)
- &__archive_mbedtls_sha256init,
- &__archive_mbedtls_sha256update,
- &__archive_mbedtls_sha256final,
-#elif defined(ARCHIVE_CRYPTO_SHA256_NETTLE)
- &__archive_nettle_sha256init,
- &__archive_nettle_sha256update,
- &__archive_nettle_sha256final,
-#elif defined(ARCHIVE_CRYPTO_SHA256_OPENSSL)
- &__archive_openssl_sha256init,
- &__archive_openssl_sha256update,
- &__archive_openssl_sha256final,
-#elif defined(ARCHIVE_CRYPTO_SHA256_WIN)
- &__archive_windowsapi_sha256init,
- &__archive_windowsapi_sha256update,
- &__archive_windowsapi_sha256final,
-#elif !defined(ARCHIVE_SHA256_COMPILE_TEST)
- &__archive_stub_sha256init,
- &__archive_stub_sha256update,
- &__archive_stub_sha256final,
-#endif
+ &__archive_sha256init,
+ &__archive_sha256update,
+ &__archive_sha256final,
/* SHA384 */
-#if defined(ARCHIVE_CRYPTO_SHA384_LIBC)
- &__archive_libc_sha384init,
- &__archive_libc_sha384update,
- &__archive_libc_sha384final,
-#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC2)
- &__archive_libc2_sha384init,
- &__archive_libc2_sha384update,
- &__archive_libc2_sha384final,
-#elif defined(ARCHIVE_CRYPTO_SHA384_LIBC3)
- &__archive_libc3_sha384init,
- &__archive_libc3_sha384update,
- &__archive_libc3_sha384final,
-#elif defined(ARCHIVE_CRYPTO_SHA384_LIBSYSTEM)
- &__archive_libsystem_sha384init,
- &__archive_libsystem_sha384update,
- &__archive_libsystem_sha384final,
-#elif defined(ARCHIVE_CRYPTO_SHA384_MBEDTLS)
- &__archive_mbedtls_sha384init,
- &__archive_mbedtls_sha384update,
- &__archive_mbedtls_sha384final,
-#elif defined(ARCHIVE_CRYPTO_SHA384_NETTLE)
- &__archive_nettle_sha384init,
- &__archive_nettle_sha384update,
- &__archive_nettle_sha384final,
-#elif defined(ARCHIVE_CRYPTO_SHA384_OPENSSL)
- &__archive_openssl_sha384init,
- &__archive_openssl_sha384update,
- &__archive_openssl_sha384final,
-#elif defined(ARCHIVE_CRYPTO_SHA384_WIN)
- &__archive_windowsapi_sha384init,
- &__archive_windowsapi_sha384update,
- &__archive_windowsapi_sha384final,
-#elif !defined(ARCHIVE_SHA384_COMPILE_TEST)
- &__archive_stub_sha384init,
- &__archive_stub_sha384update,
- &__archive_stub_sha384final,
-#endif
+ &__archive_sha384init,
+ &__archive_sha384update,
+ &__archive_sha384final,
/* SHA512 */
-#if defined(ARCHIVE_CRYPTO_SHA512_LIBC)
- &__archive_libc_sha512init,
- &__archive_libc_sha512update,
- &__archive_libc_sha512final
-#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC2)
- &__archive_libc2_sha512init,
- &__archive_libc2_sha512update,
- &__archive_libc2_sha512final
-#elif defined(ARCHIVE_CRYPTO_SHA512_LIBC3)
- &__archive_libc3_sha512init,
- &__archive_libc3_sha512update,
- &__archive_libc3_sha512final
-#elif defined(ARCHIVE_CRYPTO_SHA512_LIBMD)
- &__archive_libmd_sha512init,
- &__archive_libmd_sha512update,
- &__archive_libmd_sha512final
-#elif defined(ARCHIVE_CRYPTO_SHA512_LIBSYSTEM)
- &__archive_libsystem_sha512init,
- &__archive_libsystem_sha512update,
- &__archive_libsystem_sha512final
-#elif defined(ARCHIVE_CRYPTO_SHA512_MBEDTLS)
- &__archive_mbedtls_sha512init,
- &__archive_mbedtls_sha512update,
- &__archive_mbedtls_sha512final
-#elif defined(ARCHIVE_CRYPTO_SHA512_NETTLE)
- &__archive_nettle_sha512init,
- &__archive_nettle_sha512update,
- &__archive_nettle_sha512final
-#elif defined(ARCHIVE_CRYPTO_SHA512_OPENSSL)
- &__archive_openssl_sha512init,
- &__archive_openssl_sha512update,
- &__archive_openssl_sha512final
-#elif defined(ARCHIVE_CRYPTO_SHA512_WIN)
- &__archive_windowsapi_sha512init,
- &__archive_windowsapi_sha512update,
- &__archive_windowsapi_sha512final
-#elif !defined(ARCHIVE_SHA512_COMPILE_TEST)
- &__archive_stub_sha512init,
- &__archive_stub_sha512update,
- &__archive_stub_sha512final
-#endif
+ &__archive_sha512init,
+ &__archive_sha512update,
+ &__archive_sha512final
};
diff --git a/Utilities/cmlibarchive/libarchive/archive_digest_private.h b/Utilities/cmlibarchive/libarchive/archive_digest_private.h
index 15312ee..9b3bd66 100644
--- a/Utilities/cmlibarchive/libarchive/archive_digest_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_digest_private.h
@@ -30,6 +30,10 @@
#ifndef __LIBARCHIVE_BUILD
#error This header is only to be used internally to libarchive.
#endif
+#ifndef __LIBARCHIVE_CONFIG_H_INCLUDED
+#error "Should have include config.h first!"
+#endif
+
/*
* Crypto support in various Operating Systems:
*
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry.c b/Utilities/cmlibarchive/libarchive/archive_entry.c
index a15e98c..ca7a4bd 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry.c
+++ b/Utilities/cmlibarchive/libarchive/archive_entry.c
@@ -208,6 +208,19 @@ archive_entry_clone(struct archive_entry *entry)
/* Copy encryption status */
entry2->encryption = entry->encryption;
+
+ /* Copy digests */
+#define copy_digest(_e2, _e, _t) \
+ memcpy(_e2->digest._t, _e->digest._t, sizeof(_e2->digest._t))
+
+ copy_digest(entry2, entry, md5);
+ copy_digest(entry2, entry, rmd160);
+ copy_digest(entry2, entry, sha1);
+ copy_digest(entry2, entry, sha256);
+ copy_digest(entry2, entry, sha384);
+ copy_digest(entry2, entry, sha512);
+
+#undef copy_digest
/* Copy ACL data over. */
archive_acl_copy(&entry2->acl, &entry->acl);
@@ -353,7 +366,7 @@ archive_entry_devminor(struct archive_entry *entry)
return minor(entry->ae_stat.aest_dev);
}
-mode_t
+__LA_MODE_T
archive_entry_filetype(struct archive_entry *entry)
{
return (AE_IFMT & entry->acl.mode);
@@ -450,7 +463,7 @@ int
_archive_entry_gname_l(struct archive_entry *entry,
const char **p, size_t *len, struct archive_string_conv *sc)
{
- return (archive_mstring_get_mbs_l(&entry->ae_gname, p, len, sc));
+ return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_gname, p, len, sc));
}
const char *
@@ -504,7 +517,7 @@ _archive_entry_hardlink_l(struct archive_entry *entry,
*len = 0;
return (0);
}
- return (archive_mstring_get_mbs_l(&entry->ae_hardlink, p, len, sc));
+ return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_hardlink, p, len, sc));
}
la_int64_t
@@ -525,7 +538,7 @@ archive_entry_ino64(struct archive_entry *entry)
return (entry->ae_stat.aest_ino);
}
-mode_t
+__LA_MODE_T
archive_entry_mode(struct archive_entry *entry)
{
return (entry->acl.mode);
@@ -595,10 +608,10 @@ int
_archive_entry_pathname_l(struct archive_entry *entry,
const char **p, size_t *len, struct archive_string_conv *sc)
{
- return (archive_mstring_get_mbs_l(&entry->ae_pathname, p, len, sc));
+ return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_pathname, p, len, sc));
}
-mode_t
+__LA_MODE_T
archive_entry_perm(struct archive_entry *entry)
{
return (~AE_IFMT & entry->acl.mode);
@@ -723,7 +736,7 @@ _archive_entry_symlink_l(struct archive_entry *entry,
*len = 0;
return (0);
}
- return (archive_mstring_get_mbs_l( &entry->ae_symlink, p, len, sc));
+ return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_symlink, p, len, sc));
}
la_int64_t
@@ -769,7 +782,7 @@ int
_archive_entry_uname_l(struct archive_entry *entry,
const char **p, size_t *len, struct archive_string_conv *sc)
{
- return (archive_mstring_get_mbs_l(&entry->ae_uname, p, len, sc));
+ return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_uname, p, len, sc));
}
int
@@ -1416,6 +1429,62 @@ archive_entry_copy_mac_metadata(struct archive_entry *entry,
}
}
+/* Digest handling */
+const unsigned char *
+archive_entry_digest(struct archive_entry *entry, int type)
+{
+ switch (type) {
+ case ARCHIVE_ENTRY_DIGEST_MD5:
+ return entry->digest.md5;
+ case ARCHIVE_ENTRY_DIGEST_RMD160:
+ return entry->digest.rmd160;
+ case ARCHIVE_ENTRY_DIGEST_SHA1:
+ return entry->digest.sha1;
+ case ARCHIVE_ENTRY_DIGEST_SHA256:
+ return entry->digest.sha256;
+ case ARCHIVE_ENTRY_DIGEST_SHA384:
+ return entry->digest.sha384;
+ case ARCHIVE_ENTRY_DIGEST_SHA512:
+ return entry->digest.sha512;
+ default:
+ return NULL;
+ }
+}
+
+int
+archive_entry_set_digest(struct archive_entry *entry, int type,
+ const unsigned char *digest)
+{
+#define copy_digest(_e, _t, _d)\
+ memcpy(_e->digest._t, _d, sizeof(_e->digest._t))
+
+ switch (type) {
+ case ARCHIVE_ENTRY_DIGEST_MD5:
+ copy_digest(entry, md5, digest);
+ break;
+ case ARCHIVE_ENTRY_DIGEST_RMD160:
+ copy_digest(entry, rmd160, digest);
+ break;
+ case ARCHIVE_ENTRY_DIGEST_SHA1:
+ copy_digest(entry, sha1, digest);
+ break;
+ case ARCHIVE_ENTRY_DIGEST_SHA256:
+ copy_digest(entry, sha256, digest);
+ break;
+ case ARCHIVE_ENTRY_DIGEST_SHA384:
+ copy_digest(entry, sha384, digest);
+ break;
+ case ARCHIVE_ENTRY_DIGEST_SHA512:
+ copy_digest(entry, sha512, digest);
+ break;
+ default:
+ return ARCHIVE_WARN;
+ }
+
+ return ARCHIVE_OK;
+#undef copy_digest
+}
+
/*
* ACL management. The following would, of course, be a lot simpler
* if: 1) the last draft of POSIX.1e were a really thorough and
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry.h b/Utilities/cmlibarchive/libarchive/archive_entry.h
index 0053faa..21e89d2 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry.h
+++ b/Utilities/cmlibarchive/libarchive/archive_entry.h
@@ -30,7 +30,7 @@
#define ARCHIVE_ENTRY_H_INCLUDED
/* Note: Compiler will complain if this does not match archive.h! */
-#define ARCHIVE_VERSION_NUMBER 3004002
+#define ARCHIVE_VERSION_NUMBER 3005001
/*
* Note: archive_entry.h is for use outside of libarchive; the
@@ -394,6 +394,19 @@ __LA_DECL const void * archive_entry_mac_metadata(struct archive_entry *, size_t
__LA_DECL void archive_entry_copy_mac_metadata(struct archive_entry *, const void *, size_t);
/*
+ * Digest routine. This is used to query the raw hex digest for the
+ * given entry. The type of digest is provided as an argument.
+ */
+#define ARCHIVE_ENTRY_DIGEST_MD5 0x00000001
+#define ARCHIVE_ENTRY_DIGEST_RMD160 0x00000002
+#define ARCHIVE_ENTRY_DIGEST_SHA1 0x00000003
+#define ARCHIVE_ENTRY_DIGEST_SHA256 0x00000004
+#define ARCHIVE_ENTRY_DIGEST_SHA384 0x00000005
+#define ARCHIVE_ENTRY_DIGEST_SHA512 0x00000006
+
+__LA_DECL const unsigned char * archive_entry_digest(struct archive_entry *, int /* type */);
+
+/*
* ACL routines. This used to simply store and return text-format ACL
* strings, but that proved insufficient for a number of reasons:
* = clients need control over uname/uid and gname/gid mappings
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_private.h b/Utilities/cmlibarchive/libarchive/archive_entry_private.h
index 2b9a084..cf4deb2 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_private.h
@@ -50,6 +50,15 @@ struct ae_sparse {
int64_t length;
};
+struct ae_digest {
+ unsigned char md5[16];
+ unsigned char rmd160[20];
+ unsigned char sha1[20];
+ unsigned char sha256[32];
+ unsigned char sha384[48];
+ unsigned char sha512[64];
+};
+
/*
* Description of an archive entry.
*
@@ -162,6 +171,9 @@ struct archive_entry {
void *mac_metadata;
size_t mac_metadata_size;
+ /* Digest support. */
+ struct ae_digest digest;
+
/* ACL support. */
struct archive_acl acl;
@@ -181,4 +193,8 @@ struct archive_entry {
int ae_symlink_type;
};
+int
+archive_entry_set_digest(struct archive_entry *entry, int type,
+ const unsigned char *digest);
+
#endif /* ARCHIVE_ENTRY_PRIVATE_H_INCLUDED */
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry_stat.3 b/Utilities/cmlibarchive/libarchive/archive_entry_stat.3
index aa5c8e0..29a53f7 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry_stat.3
+++ b/Utilities/cmlibarchive/libarchive/archive_entry_stat.3
@@ -215,9 +215,9 @@ and
set and unset the size, respectively.
.Pp
The number of references (hardlinks) can be obtained by calling
-.Fn archive_entry_nlinks
+.Fn archive_entry_nlink
and set with
-.Fn archive_entry_set_nlinks .
+.Fn archive_entry_set_nlink .
.Ss Identifying unique files
The functions
.Fn archive_entry_dev
diff --git a/Utilities/cmlibarchive/libarchive/archive_ppmd7.c b/Utilities/cmlibarchive/libarchive/archive_ppmd7.c
index 4029395..cc3f778 100644
--- a/Utilities/cmlibarchive/libarchive/archive_ppmd7.c
+++ b/Utilities/cmlibarchive/libarchive/archive_ppmd7.c
@@ -4,7 +4,7 @@ This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#include "archive_platform.h"
-#include <memory.h>
+#include <stdlib.h>
#include "archive_ppmd7_private.h"
diff --git a/Utilities/cmlibarchive/libarchive/archive_read.c b/Utilities/cmlibarchive/libarchive/archive_read.c
index 4a933b2..c59f051 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read.c
@@ -892,15 +892,16 @@ archive_read_data(struct archive *_a, void *buff, size_t s)
len = a->read_data_remaining;
if (len > s)
len = s;
- if (len)
+ if (len) {
memcpy(dest, a->read_data_block, len);
- s -= len;
- a->read_data_block += len;
- a->read_data_remaining -= len;
- a->read_data_output_offset += len;
- a->read_data_offset += len;
- dest += len;
- bytes_read += len;
+ s -= len;
+ a->read_data_block += len;
+ a->read_data_remaining -= len;
+ a->read_data_output_offset += len;
+ a->read_data_offset += len;
+ dest += len;
+ bytes_read += len;
+ }
}
}
a->read_data_is_posix_read = 0;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_add_passphrase.c b/Utilities/cmlibarchive/libarchive/archive_read_add_passphrase.c
index cf821b5..f0b1ab9 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_add_passphrase.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_add_passphrase.c
@@ -57,6 +57,10 @@ insert_passphrase_to_head(struct archive_read *a,
{
p->next = a->passphrases.first;
a->passphrases.first = p;
+ if (&a->passphrases.first == a->passphrases.last) {
+ a->passphrases.last = &p->next;
+ p->next = NULL;
+ }
}
static struct archive_read_passphrase *
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c b/Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c
index 2a8cec8..9c9cf38 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk_entry_from_file.c
@@ -103,6 +103,10 @@ __FBSDID("$FreeBSD");
static int setup_mac_metadata(struct archive_read_disk *,
struct archive_entry *, int *fd);
+#ifdef ARCHIVE_XATTR_FREEBSD
+static int setup_xattrs_namespace(struct archive_read_disk *,
+ struct archive_entry *, int *, int);
+#endif
static int setup_xattrs(struct archive_read_disk *,
struct archive_entry *, int *fd);
static int setup_sparse(struct archive_read_disk *,
@@ -701,14 +705,13 @@ setup_xattr(struct archive_read_disk *a, struct archive_entry *entry,
}
static int
-setup_xattrs(struct archive_read_disk *a,
- struct archive_entry *entry, int *fd)
+setup_xattrs_namespace(struct archive_read_disk *a,
+ struct archive_entry *entry, int *fd, int namespace)
{
char buff[512];
char *list, *p;
ssize_t list_size;
const char *path;
- int namespace = EXTATTR_NAMESPACE_USER;
path = NULL;
@@ -727,6 +730,8 @@ setup_xattrs(struct archive_read_disk *a,
if (list_size == -1 && errno == EOPNOTSUPP)
return (ARCHIVE_OK);
+ if (list_size == -1 && errno == EPERM)
+ return (ARCHIVE_OK);
if (list_size == -1) {
archive_set_error(&a->archive, errno,
"Couldn't list extended attributes");
@@ -760,7 +765,17 @@ setup_xattrs(struct archive_read_disk *a,
size_t len = 255 & (int)*p;
char *name;
- strcpy(buff, "user.");
+ if (namespace == EXTATTR_NAMESPACE_SYSTEM) {
+ if (!strcmp(p + 1, "nfs4.acl") ||
+ !strcmp(p + 1, "posix1e.acl_access") ||
+ !strcmp(p + 1, "posix1e.acl_default")) {
+ p += 1 + len;
+ continue;
+ }
+ strcpy(buff, "system.");
+ } else {
+ strcpy(buff, "user.");
+ }
name = buff + strlen(buff);
memcpy(name, p + 1, len);
name[len] = '\0';
@@ -772,6 +787,31 @@ setup_xattrs(struct archive_read_disk *a,
return (ARCHIVE_OK);
}
+static int
+setup_xattrs(struct archive_read_disk *a,
+ struct archive_entry *entry, int *fd)
+{
+ int namespaces[2];
+ int i, res;
+
+ namespaces[0] = EXTATTR_NAMESPACE_USER;
+ namespaces[1] = EXTATTR_NAMESPACE_SYSTEM;
+
+ for (i = 0; i < 2; i++) {
+ res = setup_xattrs_namespace(a, entry, fd,
+ namespaces[i]);
+ switch (res) {
+ case (ARCHIVE_OK):
+ case (ARCHIVE_WARN):
+ break;
+ default:
+ return (res);
+ }
+ }
+
+ return (ARCHIVE_OK);
+}
+
#else
/*
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c b/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c
index 52fec7b..2898206 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c
@@ -1658,7 +1658,7 @@ static int
setup_current_filesystem(struct archive_read_disk *a)
{
struct tree *t = a->tree;
- struct statvfs sfs;
+ struct statvfs svfs;
int r, xr = 0;
t->current_filesystem->synthetic = -1;
@@ -1667,16 +1667,16 @@ setup_current_filesystem(struct archive_read_disk *a)
return (ARCHIVE_FAILED);
}
if (tree_current_is_symblic_link_target(t)) {
- r = statvfs(tree_current_access_path(t), &sfs);
+ r = statvfs(tree_current_access_path(t), &svfs);
if (r == 0)
xr = get_xfer_size(t, -1, tree_current_access_path(t));
} else {
#ifdef HAVE_FSTATVFS
- r = fstatvfs(tree_current_dir_fd(t), &sfs);
+ r = fstatvfs(tree_current_dir_fd(t), &svfs);
if (r == 0)
xr = get_xfer_size(t, tree_current_dir_fd(t), NULL);
#else
- r = statvfs(".", &sfs);
+ r = statvfs(".", &svfs);
if (r == 0)
xr = get_xfer_size(t, -1, ".");
#endif
@@ -1688,30 +1688,30 @@ setup_current_filesystem(struct archive_read_disk *a)
} else if (xr == 1) {
/* Usually come here unless NetBSD supports _PC_REC_XFER_ALIGN
* for pathconf() function. */
- t->current_filesystem->xfer_align = sfs.f_frsize;
+ t->current_filesystem->xfer_align = svfs.f_frsize;
t->current_filesystem->max_xfer_size = -1;
#if defined(HAVE_STRUCT_STATVFS_F_IOSIZE)
- t->current_filesystem->min_xfer_size = sfs.f_iosize;
- t->current_filesystem->incr_xfer_size = sfs.f_iosize;
+ t->current_filesystem->min_xfer_size = svfs.f_iosize;
+ t->current_filesystem->incr_xfer_size = svfs.f_iosize;
#else
- t->current_filesystem->min_xfer_size = sfs.f_bsize;
- t->current_filesystem->incr_xfer_size = sfs.f_bsize;
+ t->current_filesystem->min_xfer_size = svfs.f_bsize;
+ t->current_filesystem->incr_xfer_size = svfs.f_bsize;
#endif
}
- if (sfs.f_flag & ST_LOCAL)
+ if (svfs.f_flag & ST_LOCAL)
t->current_filesystem->remote = 0;
else
t->current_filesystem->remote = 1;
#if defined(ST_NOATIME)
- if (sfs.f_flag & ST_NOATIME)
+ if (svfs.f_flag & ST_NOATIME)
t->current_filesystem->noatime = 1;
else
#endif
t->current_filesystem->noatime = 0;
/* Set maximum filename length. */
- t->current_filesystem->name_max = sfs.f_namemax;
+ t->current_filesystem->name_max = svfs.f_namemax;
return (ARCHIVE_OK);
}
@@ -1840,7 +1840,7 @@ setup_current_filesystem(struct archive_read_disk *a)
#if defined(HAVE_STATVFS)
if (svfs.f_flag & ST_NOATIME)
#else
- if (sfs.f_flag & ST_NOATIME)
+ if (sfs.f_flags & ST_NOATIME)
#endif
t->current_filesystem->noatime = 1;
else
@@ -1864,7 +1864,7 @@ static int
setup_current_filesystem(struct archive_read_disk *a)
{
struct tree *t = a->tree;
- struct statvfs sfs;
+ struct statvfs svfs;
int r, xr = 0;
t->current_filesystem->synthetic = -1;/* Not supported */
@@ -1883,7 +1883,7 @@ setup_current_filesystem(struct archive_read_disk *a)
"openat failed");
return (ARCHIVE_FAILED);
}
- r = fstatvfs(fd, &sfs);
+ r = fstatvfs(fd, &svfs);
if (r == 0)
xr = get_xfer_size(t, fd, NULL);
close(fd);
@@ -1892,13 +1892,13 @@ setup_current_filesystem(struct archive_read_disk *a)
archive_set_error(&a->archive, errno, "fchdir failed");
return (ARCHIVE_FAILED);
}
- r = statvfs(tree_current_access_path(t), &sfs);
+ r = statvfs(tree_current_access_path(t), &svfs);
if (r == 0)
xr = get_xfer_size(t, -1, tree_current_access_path(t));
#endif
} else {
#ifdef HAVE_FSTATVFS
- r = fstatvfs(tree_current_dir_fd(t), &sfs);
+ r = fstatvfs(tree_current_dir_fd(t), &svfs);
if (r == 0)
xr = get_xfer_size(t, tree_current_dir_fd(t), NULL);
#else
@@ -1906,7 +1906,7 @@ setup_current_filesystem(struct archive_read_disk *a)
archive_set_error(&a->archive, errno, "fchdir failed");
return (ARCHIVE_FAILED);
}
- r = statvfs(".", &sfs);
+ r = statvfs(".", &svfs);
if (r == 0)
xr = get_xfer_size(t, -1, ".");
#endif
@@ -1918,14 +1918,14 @@ setup_current_filesystem(struct archive_read_disk *a)
return (ARCHIVE_FAILED);
} else if (xr == 1) {
/* pathconf(_PC_REX_*) operations are not supported. */
- t->current_filesystem->xfer_align = sfs.f_frsize;
+ t->current_filesystem->xfer_align = svfs.f_frsize;
t->current_filesystem->max_xfer_size = -1;
- t->current_filesystem->min_xfer_size = sfs.f_bsize;
- t->current_filesystem->incr_xfer_size = sfs.f_bsize;
+ t->current_filesystem->min_xfer_size = svfs.f_bsize;
+ t->current_filesystem->incr_xfer_size = svfs.f_bsize;
}
#if defined(ST_NOATIME)
- if (sfs.f_flag & ST_NOATIME)
+ if (svfs.f_flag & ST_NOATIME)
t->current_filesystem->noatime = 1;
else
#endif
@@ -1933,7 +1933,7 @@ setup_current_filesystem(struct archive_read_disk *a)
#if defined(USE_READDIR_R)
/* Set maximum filename length. */
- t->current_filesystem->name_max = sfs.f_namemax;
+ t->current_filesystem->name_max = svfs.f_namemax;
#endif
return (ARCHIVE_OK);
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_filter.3 b/Utilities/cmlibarchive/libarchive/archive_read_filter.3
index 1ba5fcb..4f5c351 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_filter.3
+++ b/Utilities/cmlibarchive/libarchive/archive_read_filter.3
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd August 14, 2014
+.Dd June 9, 2020
.Dt ARCHIVE_READ_FILTER 3
.Os
.Sh NAME
@@ -50,6 +50,8 @@ Streaming Archive Library (libarchive, -larchive)
.Ft int
.Fn archive_read_support_filter_all "struct archive *"
.Ft int
+.Fn archive_read_support_filter_by_code "struct archive *" "int"
+.Ft int
.Fn archive_read_support_filter_bzip2 "struct archive *"
.Ft int
.Fn archive_read_support_filter_compress "struct archive *"
@@ -116,6 +118,14 @@ Note that
is always enabled by default.
.It Fn archive_read_support_filter_all
Enables all available decompression filters.
+.It Fn archive_read_support_filter_by_code
+Enables a single filter specified by the filter code.
+This function does not work with
+.Cm ARCHIVE_FILTER_PROGRAM .
+Note: In statically-linked executables, this will cause
+your program to include support for every filter.
+If executable size is a concern, you may wish to avoid
+using this function.
.It Fn archive_read_support_filter_program
Data is fed through the specified external program before being dearchived.
Note that this disables automatic detection of the compression format,
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_open_filename.c b/Utilities/cmlibarchive/libarchive/archive_read_open_filename.c
index 86635e2..561289b 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_open_filename.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_open_filename.c
@@ -221,7 +221,9 @@ file_open(struct archive *a, void *client_data)
struct read_file_data *mine = (struct read_file_data *)client_data;
void *buffer;
const char *filename = NULL;
+#if defined(_WIN32) && !defined(__CYGWIN__)
const wchar_t *wfilename = NULL;
+#endif
int fd = -1;
int is_disk_like = 0;
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
@@ -281,10 +283,12 @@ file_open(struct archive *a, void *client_data)
#endif
}
if (fstat(fd, &st) != 0) {
+#if defined(_WIN32) && !defined(__CYGWIN__)
if (mine->filename_type == FNT_WCS)
archive_set_error(a, errno, "Can't stat '%S'",
wfilename);
else
+#endif
archive_set_error(a, errno, "Can't stat '%s'",
filename);
goto fail;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_set_format.c b/Utilities/cmlibarchive/libarchive/archive_read_set_format.c
index 1d3e49d..796dcdc 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_set_format.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_set_format.c
@@ -61,6 +61,9 @@ archive_read_set_format(struct archive *_a, int code)
case ARCHIVE_FORMAT_CPIO:
strcpy(str, "cpio");
break;
+ case ARCHIVE_FORMAT_EMPTY:
+ strcpy(str, "empty");
+ break;
case ARCHIVE_FORMAT_ISO9660:
strcpy(str, "iso9660");
break;
@@ -76,9 +79,15 @@ archive_read_set_format(struct archive *_a, int code)
case ARCHIVE_FORMAT_RAR_V5:
strcpy(str, "rar5");
break;
+ case ARCHIVE_FORMAT_RAW:
+ strcpy(str, "raw");
+ break;
case ARCHIVE_FORMAT_TAR:
strcpy(str, "tar");
break;
+ case ARCHIVE_FORMAT_WARC:
+ strcpy(str, "warc");
+ break;
case ARCHIVE_FORMAT_XAR:
strcpy(str, "xar");
break;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_by_code.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_by_code.c
new file mode 100644
index 0000000..94c4af6
--- /dev/null
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_by_code.c
@@ -0,0 +1,83 @@
+/*-
+ * Copyright (c) 2020 Martin Matuska
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD$");
+
+#include "archive.h"
+#include "archive_private.h"
+
+int
+archive_read_support_filter_by_code(struct archive *a, int filter_code)
+{
+ archive_check_magic(a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_filter_by_code");
+
+ switch (filter_code) {
+ case ARCHIVE_FILTER_NONE:
+ return archive_read_support_filter_none(a);
+ break;
+ case ARCHIVE_FILTER_GZIP:
+ return archive_read_support_filter_gzip(a);
+ break;
+ case ARCHIVE_FILTER_BZIP2:
+ return archive_read_support_filter_bzip2(a);
+ break;
+ case ARCHIVE_FILTER_COMPRESS:
+ return archive_read_support_filter_compress(a);
+ break;
+ case ARCHIVE_FILTER_LZMA:
+ return archive_read_support_filter_lzma(a);
+ break;
+ case ARCHIVE_FILTER_XZ:
+ return archive_read_support_filter_xz(a);
+ break;
+ case ARCHIVE_FILTER_UU:
+ return archive_read_support_filter_uu(a);
+ break;
+ case ARCHIVE_FILTER_RPM:
+ return archive_read_support_filter_rpm(a);
+ break;
+ case ARCHIVE_FILTER_LZIP:
+ return archive_read_support_filter_lzip(a);
+ break;
+ case ARCHIVE_FILTER_LRZIP:
+ return archive_read_support_filter_lrzip(a);
+ break;
+ case ARCHIVE_FILTER_LZOP:
+ return archive_read_support_filter_lzop(a);
+ break;
+ case ARCHIVE_FILTER_GRZIP:
+ return archive_read_support_filter_grzip(a);
+ break;
+ case ARCHIVE_FILTER_LZ4:
+ return archive_read_support_filter_lz4(a);
+ break;
+ case ARCHIVE_FILTER_ZSTD:
+ return archive_read_support_filter_zstd(a);
+ break;
+ }
+ return (ARCHIVE_FATAL);
+}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_program.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_program.c
index b8bf128..bf5b6f2 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_program.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_program.c
@@ -400,7 +400,7 @@ __archive_read_program(struct archive_read_filter *self, const char *cmd)
static const size_t out_buf_len = 65536;
char *out_buf;
const char *prefix = "Program: ";
- pid_t child;
+ int ret;
size_t l;
l = strlen(prefix) + strlen(cmd) + 1;
@@ -426,9 +426,9 @@ __archive_read_program(struct archive_read_filter *self, const char *cmd)
state->out_buf = out_buf;
state->out_buf_len = out_buf_len;
- child = __archive_create_child(cmd, &state->child_stdin,
- &state->child_stdout);
- if (child == -1) {
+ ret = __archive_create_child(cmd, &state->child_stdin,
+ &state->child_stdout, &state->child);
+ if (ret != ARCHIVE_OK) {
free(state->out_buf);
archive_string_free(&state->description);
free(state);
@@ -437,21 +437,6 @@ __archive_read_program(struct archive_read_filter *self, const char *cmd)
cmd);
return (ARCHIVE_FATAL);
}
-#if defined(_WIN32) && !defined(__CYGWIN__)
- state->child = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, child);
- if (state->child == NULL) {
- child_stop(self, state);
- free(state->out_buf);
- archive_string_free(&state->description);
- free(state);
- archive_set_error(&self->archive->archive, EINVAL,
- "Can't initialize filter; unable to run program \"%s\"",
- cmd);
- return (ARCHIVE_FATAL);
- }
-#else
- state->child = child;
-#endif
self->data = state;
self->read = program_filter_read;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_zstd.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_zstd.c
index e1ec60e..c4e8ec7 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_zstd.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_zstd.c
@@ -119,6 +119,8 @@ zstd_bidder_bid(struct archive_read_filter_bidder *self,
/* Zstd frame magic values */
const unsigned zstd_magic = 0xFD2FB528U;
+ const unsigned zstd_magic_skippable_start = 0x184D2A50U;
+ const unsigned zstd_magic_skippable_mask = 0xFFFFFFF0;
(void) self; /* UNUSED */
@@ -129,6 +131,8 @@ zstd_bidder_bid(struct archive_read_filter_bidder *self,
prefix = archive_le32dec(buffer);
if (prefix == zstd_magic)
return (32);
+ if ((prefix & zstd_magic_skippable_mask) == zstd_magic_skippable_start)
+ return (32);
return (0);
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_by_code.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_by_code.c
index 034353d..89e96f1 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_by_code.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_by_code.c
@@ -26,6 +26,10 @@
#include "archive_platform.h"
__FBSDID("$FreeBSD$");
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+
#include "archive.h"
#include "archive_private.h"
@@ -48,6 +52,9 @@ archive_read_support_format_by_code(struct archive *a, int format_code)
case ARCHIVE_FORMAT_CPIO:
return archive_read_support_format_cpio(a);
break;
+ case ARCHIVE_FORMAT_EMPTY:
+ return archive_read_support_format_empty(a);
+ break;
case ARCHIVE_FORMAT_ISO9660:
return archive_read_support_format_iso9660(a);
break;
@@ -63,9 +70,15 @@ archive_read_support_format_by_code(struct archive *a, int format_code)
case ARCHIVE_FORMAT_RAR_V5:
return archive_read_support_format_rar5(a);
break;
+ case ARCHIVE_FORMAT_RAW:
+ return archive_read_support_format_raw(a);
+ break;
case ARCHIVE_FORMAT_TAR:
return archive_read_support_format_tar(a);
break;
+ case ARCHIVE_FORMAT_WARC:
+ return archive_read_support_format_warc(a);
+ break;
case ARCHIVE_FORMAT_XAR:
return archive_read_support_format_xar(a);
break;
@@ -73,5 +86,7 @@ archive_read_support_format_by_code(struct archive *a, int format_code)
return archive_read_support_format_zip(a);
break;
}
+ archive_set_error(a, ARCHIVE_ERRNO_PROGRAMMER,
+ "Invalid format code specified");
return (ARCHIVE_FATAL);
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c
index 58644ba..57547d4 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c
@@ -1172,7 +1172,7 @@ cab_checksum_finish(struct archive_read *a)
cfdata->memimage + CFDATA_cbData, l, cfdata->sum_calculated);
if (cfdata->sum_calculated != cfdata->sum) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Checksum error CFDATA[%d] %x:%x in %d bytes",
+ "Checksum error CFDATA[%d] %" PRIx32 ":%" PRIx32 " in %d bytes",
cab->entry_cffolder->cfdata_index -1,
cfdata->sum, cfdata->sum_calculated,
cfdata->compressed_size);
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_empty.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_empty.c
index c641eb9..53fb6cc 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_empty.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_empty.c
@@ -47,7 +47,7 @@ archive_read_support_format_empty(struct archive *_a)
r = __archive_read_register_format(a,
NULL,
- NULL,
+ "empty",
archive_read_format_empty_bid,
NULL,
archive_read_format_empty_read_header,
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c
index 332944a..93ba295 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_mtree.c 2011
#include "archive.h"
#include "archive_entry.h"
+#include "archive_entry_private.h"
#include "archive_private.h"
#include "archive_rb.h"
#include "archive_read_private.h"
@@ -135,6 +136,9 @@ static int skip(struct archive_read *a);
static int read_header(struct archive_read *,
struct archive_entry *);
static int64_t mtree_atol(char **, int base);
+#ifndef HAVE_STRNLEN
+static size_t mtree_strnlen(const char *, size_t);
+#endif
/*
* There's no standard for TIME_T_MAX/TIME_T_MIN. So we compute them
@@ -186,6 +190,24 @@ get_time_t_min(void)
#endif
}
+#ifdef HAVE_STRNLEN
+#define mtree_strnlen(a,b) strnlen(a,b)
+#else
+static size_t
+mtree_strnlen(const char *p, size_t maxlen)
+{
+ size_t i;
+
+ for (i = 0; i <= maxlen; i++) {
+ if (p[i] == 0)
+ break;
+ }
+ if (i > maxlen)
+ return (-1);/* invalid */
+ return (i);
+}
+#endif
+
static int
archive_read_format_mtree_options(struct archive_read *a,
const char *key, const char *val)
@@ -1482,6 +1504,84 @@ parse_device(dev_t *pdev, struct archive *a, char *val)
#undef MAX_PACK_ARGS
}
+static int
+parse_hex_nibble(char c)
+{
+ if (c >= '0' && c <= '9')
+ return c - '0';
+ if (c >= 'a' && c <= 'f')
+ return 10 + c - 'a';
+#if 0
+ /* XXX: Is uppercase something we should support? */
+ if (c >= 'A' && c <= 'F')
+ return 10 + c - 'A';
+#endif
+
+ return -1;
+}
+
+static int
+parse_digest(struct archive_read *a, struct archive_entry *entry,
+ const char *digest, int type)
+{
+ unsigned char digest_buf[64];
+ int high, low;
+ size_t i, j, len;
+
+ switch (type) {
+ case ARCHIVE_ENTRY_DIGEST_MD5:
+ len = sizeof(entry->digest.md5);
+ break;
+ case ARCHIVE_ENTRY_DIGEST_RMD160:
+ len = sizeof(entry->digest.rmd160);
+ break;
+ case ARCHIVE_ENTRY_DIGEST_SHA1:
+ len = sizeof(entry->digest.sha1);
+ break;
+ case ARCHIVE_ENTRY_DIGEST_SHA256:
+ len = sizeof(entry->digest.sha256);
+ break;
+ case ARCHIVE_ENTRY_DIGEST_SHA384:
+ len = sizeof(entry->digest.sha384);
+ break;
+ case ARCHIVE_ENTRY_DIGEST_SHA512:
+ len = sizeof(entry->digest.sha512);
+ break;
+ default:
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
+ "Internal error: Unknown digest type");
+ return ARCHIVE_FATAL;
+ }
+
+ if (len > sizeof(digest_buf)) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
+ "Internal error: Digest storage too large");
+ return ARCHIVE_FATAL;
+ }
+
+ len *= 2;
+
+ if (mtree_strnlen(digest, len+1) != len) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "incorrect digest length, ignoring");
+ return ARCHIVE_WARN;
+ }
+
+ for (i = 0, j = 0; i < len; i += 2, j++) {
+ high = parse_hex_nibble(digest[i]);
+ low = parse_hex_nibble(digest[i+1]);
+ if (high == -1 || low == -1) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "invalid digest data, ignoring");
+ return ARCHIVE_WARN;
+ }
+
+ digest_buf[j] = high << 4 | low;
+ }
+
+ return archive_entry_set_digest(entry, type, digest_buf);
+}
+
/*
* Parse a single keyword and its value.
*/
@@ -1580,8 +1680,10 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
}
__LA_FALLTHROUGH;
case 'm':
- if (strcmp(key, "md5") == 0 || strcmp(key, "md5digest") == 0)
- break;
+ if (strcmp(key, "md5") == 0 || strcmp(key, "md5digest") == 0) {
+ return parse_digest(a, entry, val,
+ ARCHIVE_ENTRY_DIGEST_MD5);
+ }
if (strcmp(key, "mode") == 0) {
if (val[0] >= '0' && val[0] <= '7') {
*parsed_kws |= MTREE_HAS_PERM;
@@ -1617,21 +1719,32 @@ parse_keyword(struct archive_read *a, struct mtree *mtree,
return r;
}
if (strcmp(key, "rmd160") == 0 ||
- strcmp(key, "rmd160digest") == 0)
- break;
+ strcmp(key, "rmd160digest") == 0) {
+ return parse_digest(a, entry, val,
+ ARCHIVE_ENTRY_DIGEST_RMD160);
+ }
__LA_FALLTHROUGH;
case 's':
- if (strcmp(key, "sha1") == 0 || strcmp(key, "sha1digest") == 0)
- break;
+ if (strcmp(key, "sha1") == 0 ||
+ strcmp(key, "sha1digest") == 0) {
+ return parse_digest(a, entry, val,
+ ARCHIVE_ENTRY_DIGEST_SHA1);
+ }
if (strcmp(key, "sha256") == 0 ||
- strcmp(key, "sha256digest") == 0)
- break;
+ strcmp(key, "sha256digest") == 0) {
+ return parse_digest(a, entry, val,
+ ARCHIVE_ENTRY_DIGEST_SHA256);
+ }
if (strcmp(key, "sha384") == 0 ||
- strcmp(key, "sha384digest") == 0)
- break;
+ strcmp(key, "sha384digest") == 0) {
+ return parse_digest(a, entry, val,
+ ARCHIVE_ENTRY_DIGEST_SHA384);
+ }
if (strcmp(key, "sha512") == 0 ||
- strcmp(key, "sha512digest") == 0)
- break;
+ strcmp(key, "sha512digest") == 0) {
+ return parse_digest(a, entry, val,
+ ARCHIVE_ENTRY_DIGEST_SHA512);
+ }
if (strcmp(key, "size") == 0) {
archive_entry_set_size(entry, mtree_atol(&val, 10));
break;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c
index 61f2330..6dca350 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c
@@ -151,6 +151,9 @@
#undef minimum
#define minimum(a, b) ((a)<(b)?(a):(b))
+/* Stack overflow check */
+#define MAX_COMPRESS_DEPTH 1024
+
/* Fields common to all headers */
struct rar_header
{
@@ -340,7 +343,7 @@ static int read_symlink_stored(struct archive_read *, struct archive_entry *,
static int read_data_stored(struct archive_read *, const void **, size_t *,
int64_t *);
static int read_data_compressed(struct archive_read *, const void **, size_t *,
- int64_t *);
+ int64_t *, size_t);
static int rar_br_preparation(struct archive_read *, struct rar_br *);
static int parse_codes(struct archive_read *);
static void free_codes(struct archive_read *);
@@ -1026,7 +1029,7 @@ archive_read_format_rar_read_data(struct archive_read *a, const void **buff,
case COMPRESS_METHOD_NORMAL:
case COMPRESS_METHOD_GOOD:
case COMPRESS_METHOD_BEST:
- ret = read_data_compressed(a, buff, size, offset);
+ ret = read_data_compressed(a, buff, size, offset, 0);
if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN) {
__archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context);
rar->start_new_table = 1;
@@ -1883,8 +1886,11 @@ read_data_stored(struct archive_read *a, const void **buff, size_t *size,
static int
read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
- int64_t *offset)
+ int64_t *offset, size_t looper)
{
+ if (looper++ > MAX_COMPRESS_DEPTH)
+ return (ARCHIVE_FATAL);
+
struct rar *rar;
int64_t start, end, actualend;
size_t bs;
@@ -1982,7 +1988,7 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
{
case 0:
rar->start_new_table = 1;
- return read_data_compressed(a, buff, size, offset);
+ return read_data_compressed(a, buff, size, offset, looper);
case 2:
rar->ppmd_eod = 1;/* End Of ppmd Data. */
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c
index d3a1c1b..3131955 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c
@@ -3084,12 +3084,6 @@ static int do_uncompress_block(struct archive_read* a, const uint8_t* p) {
continue;
}
-
- /* The program counter shouldn't reach here. */
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Unsupported block code: 0x%x", num);
-
- return ARCHIVE_FATAL;
}
return ARCHIVE_OK;
@@ -3837,7 +3831,7 @@ static int verify_checksums(struct archive_read* a) {
DEBUG_CODE {
printf("Checksum error: CRC32 "
- "(was: %08x, expected: %08x)\n",
+ "(was: %08" PRIx32 ", expected: %08" PRIx32 ")\n",
rar->file.calculated_crc32,
rar->file.stored_crc32);
}
@@ -3851,7 +3845,7 @@ static int verify_checksums(struct archive_read* a) {
} else {
DEBUG_CODE {
printf("Checksum OK: CRC32 "
- "(%08x/%08x)\n",
+ "(%08" PRIx32 "/%08" PRIx32 ")\n",
rar->file.stored_crc32,
rar->file.calculated_crc32);
}
@@ -3912,6 +3906,9 @@ static int rar5_read_data(struct archive_read *a, const void **buff,
int ret;
struct rar5* rar = get_context(a);
+ if (size)
+ *size = 0;
+
if(rar->file.dir > 0) {
/* Don't process any data if this file entry was declared
* as a directory. This is needed, because entries marked as
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c
index c63d46f..96d8101 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c
@@ -1797,6 +1797,16 @@ pax_attribute_schily_xattr(struct archive_entry *entry,
}
static int
+pax_attribute_rht_security_selinux(struct archive_entry *entry,
+ const char *value, size_t value_length)
+{
+ archive_entry_xattr_add_entry(entry, "security.selinux",
+ value, value_length);
+
+ return 0;
+}
+
+static int
pax_attribute_acl(struct archive_read *a, struct tar *tar,
struct archive_entry *entry, const char *value, int type)
{
@@ -1966,6 +1976,14 @@ pax_attribute(struct archive_read *a, struct tar *tar,
if (memcmp(key, "LIBARCHIVE.xattr.", 17) == 0)
pax_attribute_xattr(entry, key, value);
break;
+ case 'R':
+ /* GNU tar uses RHT.security header to store SELinux xattrs
+ * SCHILY.xattr.security.selinux == RHT.security.selinux */
+ if (strcmp(key, "RHT.security.selinux") == 0) {
+ pax_attribute_rht_security_selinux(entry, value,
+ value_length);
+ }
+ break;
case 'S':
/* We support some keys used by the "star" archiver */
if (strcmp(key, "SCHILY.acl.access") == 0) {
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c
index 72977b8..2732996 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_warc.c
@@ -127,7 +127,7 @@ static int _warc_skip(struct archive_read *a);
static int _warc_rdhdr(struct archive_read *a, struct archive_entry *e);
/* private routines */
-static unsigned int _warc_rdver(const char buf[10], size_t bsz);
+static unsigned int _warc_rdver(const char *buf, size_t bsz);
static unsigned int _warc_rdtyp(const char *buf, size_t bsz);
static warc_string_t _warc_rduri(const char *buf, size_t bsz);
static ssize_t _warc_rdlen(const char *buf, size_t bsz);
@@ -337,6 +337,14 @@ start_over:
mtime = rtime;
}
break;
+ case WT_NONE:
+ case WT_INFO:
+ case WT_META:
+ case WT_REQ:
+ case WT_RVIS:
+ case WT_CONV:
+ case WT_CONT:
+ case LAST_WT:
default:
fnam.len = 0U;
fnam.str = NULL;
@@ -361,6 +369,14 @@ start_over:
break;
}
/* FALLTHROUGH */
+ case WT_NONE:
+ case WT_INFO:
+ case WT_META:
+ case WT_REQ:
+ case WT_RVIS:
+ case WT_CONV:
+ case WT_CONT:
+ case LAST_WT:
default:
/* consume the content and start over */
_warc_skip(a);
@@ -427,7 +443,7 @@ _warc_skip(struct archive_read *a)
static void*
deconst(const void *c)
{
- return (char *)0x1 + (((const char *)c) - (const char *)0x1);
+ return (void *)(uintptr_t)c;
}
static char*
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c
index 9489e51..2e60cf7 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c
@@ -36,7 +36,7 @@ __FBSDID("$FreeBSD$");
#elif HAVE_BSDXML_H
#include <bsdxml.h>
#elif HAVE_EXPAT_H
-#include <expat.h>
+#include <cm3p/expat.h>
#endif
#ifdef HAVE_BZLIB_H
#include <cm3p/bzlib.h>
@@ -458,6 +458,11 @@ archive_read_support_format_xar(struct archive *_a)
return (ARCHIVE_FATAL);
}
+ /* initialize xar->file_queue */
+ xar->file_queue.allocated = 0;
+ xar->file_queue.used = 0;
+ xar->file_queue.files = NULL;
+
r = __archive_read_register_format(a,
xar,
"xar",
@@ -1221,10 +1226,12 @@ heap_add_entry(struct archive_read *a,
/* Expand our pending files list as necessary. */
if (heap->used >= heap->allocated) {
struct xar_file **new_pending_files;
- int new_size = heap->allocated * 2;
+ int new_size;
if (heap->allocated < 1024)
new_size = 1024;
+ else
+ new_size = heap->allocated * 2;
/* Overflow might keep us from growing the list. */
if (new_size <= heap->allocated) {
archive_set_error(&a->archive,
@@ -1238,9 +1245,11 @@ heap_add_entry(struct archive_read *a,
ENOMEM, "Out of memory");
return (ARCHIVE_FATAL);
}
- memcpy(new_pending_files, heap->files,
- heap->allocated * sizeof(new_pending_files[0]));
- free(heap->files);
+ if (heap->allocated) {
+ memcpy(new_pending_files, heap->files,
+ heap->allocated * sizeof(new_pending_files[0]));
+ free(heap->files);
+ }
heap->files = new_pending_files;
heap->allocated = new_size;
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
index 4d71f98..6314c68 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
@@ -53,10 +53,10 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_support_format_zip.c 201102
#include <cm3p/zlib.h>
#endif
#ifdef HAVE_BZLIB_H
-#include <bzlib.h>
+#include <cm3p/bzlib.h>
#endif
#ifdef HAVE_LZMA_H
-#include <lzma.h>
+#include <cm3p/lzma.h>
#endif
#include "archive.h"
@@ -899,6 +899,81 @@ process_extra(struct archive_read *a, struct archive_entry *entry,
return ARCHIVE_OK;
}
+#if HAVE_LZMA_H && HAVE_LIBLZMA
+/*
+ * Auxiliary function to uncompress data chunk from zipx archive
+ * (zip with lzma compression).
+ */
+static int
+zipx_lzma_uncompress_buffer(const char *compressed_buffer,
+ size_t compressed_buffer_size,
+ char *uncompressed_buffer,
+ size_t uncompressed_buffer_size)
+{
+ int status = ARCHIVE_FATAL;
+ // length of 'lzma properties data' in lzma compressed
+ // data segment (stream) inside zip archive
+ const size_t lzma_params_length = 5;
+ // offset of 'lzma properties data' from the beginning of lzma stream
+ const size_t lzma_params_offset = 4;
+ // end position of 'lzma properties data' in lzma stream
+ const size_t lzma_params_end = lzma_params_offset + lzma_params_length;
+ if (compressed_buffer == NULL ||
+ compressed_buffer_size < lzma_params_end ||
+ uncompressed_buffer == NULL)
+ return status;
+
+ // prepare header for lzma_alone_decoder to replace zipx header
+ // (see comments in 'zipx_lzma_alone_init' for justification)
+#pragma pack(push)
+#pragma pack(1)
+ struct _alone_header
+ {
+ uint8_t bytes[5]; // lzma_params_length
+ uint64_t uncompressed_size;
+ } alone_header;
+#pragma pack(pop)
+ // copy 'lzma properties data' blob
+ memcpy(&alone_header.bytes[0], compressed_buffer + lzma_params_offset,
+ lzma_params_length);
+ alone_header.uncompressed_size = UINT64_MAX;
+
+ // prepare new compressed buffer, see 'zipx_lzma_alone_init' for details
+ const size_t lzma_alone_buffer_size =
+ compressed_buffer_size - lzma_params_end + sizeof(alone_header);
+ unsigned char *lzma_alone_compressed_buffer =
+ (unsigned char*) malloc(lzma_alone_buffer_size);
+ if (lzma_alone_compressed_buffer == NULL)
+ return status;
+ // copy lzma_alone header into new buffer
+ memcpy(lzma_alone_compressed_buffer, (void*) &alone_header,
+ sizeof(alone_header));
+ // copy compressed data into new buffer
+ memcpy(lzma_alone_compressed_buffer + sizeof(alone_header),
+ compressed_buffer + lzma_params_end,
+ compressed_buffer_size - lzma_params_end);
+
+ // create and fill in lzma_alone_decoder stream
+ lzma_stream stream = LZMA_STREAM_INIT;
+ lzma_ret ret = lzma_alone_decoder(&stream, UINT64_MAX);
+ if (ret == LZMA_OK)
+ {
+ stream.next_in = lzma_alone_compressed_buffer;
+ stream.avail_in = lzma_alone_buffer_size;
+ stream.total_in = 0;
+ stream.next_out = (unsigned char*)uncompressed_buffer;
+ stream.avail_out = uncompressed_buffer_size;
+ stream.total_out = 0;
+ ret = lzma_code(&stream, LZMA_RUN);
+ if (ret == LZMA_OK || ret == LZMA_STREAM_END)
+ status = ARCHIVE_OK;
+ }
+ lzma_end(&stream);
+ free(lzma_alone_compressed_buffer);
+ return status;
+}
+#endif
+
/*
* Assumes file pointer is at beginning of local file header.
*/
@@ -1173,18 +1248,64 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
"Truncated Zip file");
return ARCHIVE_FATAL;
}
+ // take into account link compression if any
+ size_t linkname_full_length = linkname_length;
+ if (zip->entry->compression != 0)
+ {
+ // symlink target string appeared to be compressed
+ int status = ARCHIVE_FATAL;
+ char *uncompressed_buffer =
+ (char*) malloc(zip_entry->uncompressed_size);
+ if (uncompressed_buffer == NULL)
+ {
+ archive_set_error(&a->archive, ENOMEM,
+ "No memory for lzma decompression");
+ return status;
+ }
+
+ switch (zip->entry->compression)
+ {
+#if HAVE_LZMA_H && HAVE_LIBLZMA
+ case 14: /* ZIPx LZMA compression. */
+ /*(see zip file format specification, section 4.4.5)*/
+ status = zipx_lzma_uncompress_buffer(p,
+ linkname_length,
+ uncompressed_buffer,
+ (size_t)zip_entry->uncompressed_size);
+ break;
+#endif
+ default: /* Unsupported compression. */
+ break;
+ }
+ if (status == ARCHIVE_OK)
+ {
+ p = uncompressed_buffer;
+ linkname_full_length =
+ (size_t)zip_entry->uncompressed_size;
+ }
+ else
+ {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Unsupported ZIP compression method "
+ "during decompression of link entry (%d: %s)",
+ zip->entry->compression,
+ compression_name(zip->entry->compression));
+ return ARCHIVE_FAILED;
+ }
+ }
sconv = zip->sconv;
if (sconv == NULL && (zip->entry->zip_flags & ZIP_UTF8_NAME))
sconv = zip->sconv_utf8;
if (sconv == NULL)
sconv = zip->sconv_default;
- if (archive_entry_copy_symlink_l(entry, p, linkname_length,
+ if (archive_entry_copy_symlink_l(entry, p, linkname_full_length,
sconv) != 0) {
if (errno != ENOMEM && sconv == zip->sconv_utf8 &&
(zip->entry->zip_flags & ZIP_UTF8_NAME))
archive_entry_copy_symlink_l(entry, p,
- linkname_length, NULL);
+ linkname_full_length, NULL);
if (errno == ENOMEM) {
archive_set_error(&a->archive, ENOMEM,
"Can't allocate memory for Symlink");
@@ -1901,15 +2022,15 @@ zipx_ppmd8_init(struct archive_read *a, struct zip *zip)
if(order < 2 || restore_method > 2) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Invalid parameter set in PPMd8 stream (order=%d, "
- "restore=%d)", order, restore_method);
+ "Invalid parameter set in PPMd8 stream (order=%" PRId32 ", "
+ "restore=%" PRId32 ")", order, restore_method);
return (ARCHIVE_FAILED);
}
/* Allocate the memory needed to properly decompress the file. */
if(!__archive_ppmd8_functions.Ppmd8_Alloc(&zip->ppmd8, mem << 20)) {
archive_set_error(&a->archive, ENOMEM,
- "Unable to allocate memory for PPMd8 stream: %d bytes",
+ "Unable to allocate memory for PPMd8 stream: %" PRId32 " bytes",
mem << 20);
return (ARCHIVE_FATAL);
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_string.c b/Utilities/cmlibarchive/libarchive/archive_string.c
index c77dcf5..7460ded 100644
--- a/Utilities/cmlibarchive/libarchive/archive_string.c
+++ b/Utilities/cmlibarchive/libarchive/archive_string.c
@@ -3881,6 +3881,11 @@ archive_mstring_get_utf8(struct archive *a, struct archive_mstring *aes,
}
*p = NULL;
+ /* Try converting WCS to MBS first if MBS does not exist yet. */
+ if ((aes->aes_set & AES_SET_MBS) == 0) {
+ const char *pm; /* unused */
+ archive_mstring_get_mbs(a, aes, &pm); /* ignore errors, we'll handle it later */
+ }
if (aes->aes_set & AES_SET_MBS) {
sc = archive_string_conversion_to_charset(a, "UTF-8", 1);
if (sc == NULL)
@@ -3903,9 +3908,9 @@ int
archive_mstring_get_mbs(struct archive *a, struct archive_mstring *aes,
const char **p)
{
+ struct archive_string_conv *sc;
int r, ret = 0;
- (void)a; /* UNUSED */
/* If we already have an MBS form, return that immediately. */
if (aes->aes_set & AES_SET_MBS) {
*p = aes->aes_mbs.s;
@@ -3926,10 +3931,23 @@ archive_mstring_get_mbs(struct archive *a, struct archive_mstring *aes,
ret = -1;
}
- /*
- * Only a UTF-8 form cannot avail because its conversion already
- * failed at archive_mstring_update_utf8().
- */
+ /* If there's a UTF-8 form, try converting with the native locale. */
+ if (aes->aes_set & AES_SET_UTF8) {
+ archive_string_empty(&(aes->aes_mbs));
+ sc = archive_string_conversion_from_charset(a, "UTF-8", 1);
+ if (sc == NULL)
+ return (-1);/* Couldn't allocate memory for sc. */
+ r = archive_strncpy_l(&(aes->aes_mbs),
+ aes->aes_utf8.s, aes->aes_utf8.length, sc);
+ if (a == NULL)
+ free_sconv_object(sc);
+ *p = aes->aes_mbs.s;
+ if (r == 0) {
+ aes->aes_set |= AES_SET_MBS;
+ ret = 0;/* success; overwrite previous error. */
+ } else
+ ret = -1;/* failure. */
+ }
return (ret);
}
@@ -3947,6 +3965,11 @@ archive_mstring_get_wcs(struct archive *a, struct archive_mstring *aes,
}
*wp = NULL;
+ /* Try converting UTF8 to MBS first if MBS does not exist yet. */
+ if ((aes->aes_set & AES_SET_MBS) == 0) {
+ const char *p; /* unused */
+ archive_mstring_get_mbs(a, aes, &p); /* ignore errors, we'll handle it later */
+ }
/* Try converting MBS to WCS using native locale. */
if (aes->aes_set & AES_SET_MBS) {
archive_wstring_empty(&(aes->aes_wcs));
@@ -3962,11 +3985,12 @@ archive_mstring_get_wcs(struct archive *a, struct archive_mstring *aes,
}
int
-archive_mstring_get_mbs_l(struct archive_mstring *aes,
+archive_mstring_get_mbs_l(struct archive *a, struct archive_mstring *aes,
const char **p, size_t *length, struct archive_string_conv *sc)
{
int r, ret = 0;
+ (void)r; /* UNUSED */
#if defined(_WIN32) && !defined(__CYGWIN__)
/*
* Internationalization programming on Windows must use Wide
@@ -3989,20 +4013,12 @@ archive_mstring_get_mbs_l(struct archive_mstring *aes,
}
#endif
- /* If there is not an MBS form but is a WCS form, try converting
+ /* If there is not an MBS form but there is a WCS or UTF8 form, try converting
* with the native locale to be used for translating it to specified
* character-set. */
- if ((aes->aes_set & AES_SET_MBS) == 0 &&
- (aes->aes_set & AES_SET_WCS) != 0) {
- archive_string_empty(&(aes->aes_mbs));
- r = archive_string_append_from_wcs(&(aes->aes_mbs),
- aes->aes_wcs.s, aes->aes_wcs.length);
- if (r == 0)
- aes->aes_set |= AES_SET_MBS;
- else if (errno == ENOMEM)
- return (-1);
- else
- ret = -1;
+ if ((aes->aes_set & AES_SET_MBS) == 0) {
+ const char *pm; /* unused */
+ archive_mstring_get_mbs(a, aes, &pm); /* ignore errors, we'll handle it later */
}
/* If we already have an MBS form, use it to be translated to
* specified character-set. */
diff --git a/Utilities/cmlibarchive/libarchive/archive_string.h b/Utilities/cmlibarchive/libarchive/archive_string.h
index 27e1ad6..49d7d30 100644
--- a/Utilities/cmlibarchive/libarchive/archive_string.h
+++ b/Utilities/cmlibarchive/libarchive/archive_string.h
@@ -226,7 +226,7 @@ void archive_mstring_copy(struct archive_mstring *dest, struct archive_mstring *
int archive_mstring_get_mbs(struct archive *, struct archive_mstring *, const char **);
int archive_mstring_get_utf8(struct archive *, struct archive_mstring *, const char **);
int archive_mstring_get_wcs(struct archive *, struct archive_mstring *, const wchar_t **);
-int archive_mstring_get_mbs_l(struct archive_mstring *, const char **,
+int archive_mstring_get_mbs_l(struct archive *, struct archive_mstring *, const char **,
size_t *, struct archive_string_conv *);
int archive_mstring_copy_mbs(struct archive_mstring *, const char *mbs);
int archive_mstring_copy_mbs_len(struct archive_mstring *, const char *mbs,
diff --git a/Utilities/cmlibarchive/libarchive/archive_util.c b/Utilities/cmlibarchive/libarchive/archive_util.c
index 10dca73..83586b5 100644
--- a/Utilities/cmlibarchive/libarchive/archive_util.c
+++ b/Utilities/cmlibarchive/libarchive/archive_util.c
@@ -365,6 +365,7 @@ __archive_mktempx(const char *tmpdir, wchar_t *template)
}
fd = _open_osfhandle((intptr_t)h, _O_BINARY | _O_RDWR);
if (fd == -1) {
+ la_dosmaperr(GetLastError());
CloseHandle(h);
goto exit_tmpfile;
} else
@@ -432,6 +433,11 @@ __archive_mktemp(const char *tmpdir)
if (temp_name.s[temp_name.length-1] != '/')
archive_strappend_char(&temp_name, '/');
}
+#ifdef O_TMPFILE
+ fd = open(temp_name.s, O_RDWR|O_CLOEXEC|O_TMPFILE|O_EXCL, 0600);
+ if(fd >= 0)
+ goto exit_tmpfile;
+#endif
archive_strcat(&temp_name, "libarchive_XXXXXX");
fd = mkstemp(temp_name.s);
if (fd < 0)
diff --git a/Utilities/cmlibarchive/libarchive/archive_write.c b/Utilities/cmlibarchive/libarchive/archive_write.c
index 98a55fb..8d70f51 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write.c
@@ -456,6 +456,25 @@ archive_write_client_write(struct archive_write_filter *f,
}
static int
+archive_write_client_free(struct archive_write_filter *f)
+{
+ struct archive_write *a = (struct archive_write *)f->archive;
+
+ if (a->client_freer)
+ (*a->client_freer)(&a->archive, a->client_data);
+ a->client_data = NULL;
+
+ /* Clear passphrase. */
+ if (a->passphrase != NULL) {
+ memset(a->passphrase, 0, strlen(a->passphrase));
+ free(a->passphrase);
+ a->passphrase = NULL;
+ }
+
+ return (ARCHIVE_OK);
+}
+
+static int
archive_write_client_close(struct archive_write_filter *f)
{
struct archive_write *a = (struct archive_write *)f->archive;
@@ -493,13 +512,7 @@ archive_write_client_close(struct archive_write_filter *f)
(*a->client_closer)(&a->archive, a->client_data);
free(state->buffer);
free(state);
- a->client_data = NULL;
- /* Clear passphrase. */
- if (a->passphrase != NULL) {
- memset(a->passphrase, 0, strlen(a->passphrase));
- free(a->passphrase);
- a->passphrase = NULL;
- }
+
/* Clear the close handler myself not to be called again. */
f->state = ARCHIVE_WRITE_FILTER_STATE_CLOSED;
return (ret);
@@ -509,9 +522,9 @@ archive_write_client_close(struct archive_write_filter *f)
* Open the archive using the current settings.
*/
int
-archive_write_open(struct archive *_a, void *client_data,
+archive_write_open2(struct archive *_a, void *client_data,
archive_open_callback *opener, archive_write_callback *writer,
- archive_close_callback *closer)
+ archive_close_callback *closer, archive_free_callback *freer)
{
struct archive_write *a = (struct archive_write *)_a;
struct archive_write_filter *client_filter;
@@ -524,12 +537,14 @@ archive_write_open(struct archive *_a, void *client_data,
a->client_writer = writer;
a->client_opener = opener;
a->client_closer = closer;
+ a->client_freer = freer;
a->client_data = client_data;
client_filter = __archive_write_allocate_filter(_a);
client_filter->open = archive_write_client_open;
client_filter->write = archive_write_client_write;
client_filter->close = archive_write_client_close;
+ client_filter->free = archive_write_client_free;
ret = __archive_write_filters_open(a);
if (ret < ARCHIVE_WARN) {
@@ -544,6 +559,15 @@ archive_write_open(struct archive *_a, void *client_data,
return (ret);
}
+int
+archive_write_open(struct archive *_a, void *client_data,
+ archive_open_callback *opener, archive_write_callback *writer,
+ archive_close_callback *closer)
+{
+ return archive_write_open2(_a, client_data, opener, writer,
+ closer, NULL);
+}
+
/*
* Close out the archive.
*/
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_program.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_program.c
index a4bc1d9..c096e72 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_program.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_program.c
@@ -196,10 +196,6 @@ __archive_write_program_free(struct archive_write_program_data *data)
{
if (data) {
-#if defined(_WIN32) && !defined(__CYGWIN__)
- if (data->child)
- CloseHandle(data->child);
-#endif
free(data->program_name);
free(data->child_buf);
free(data);
@@ -211,7 +207,7 @@ int
__archive_write_program_open(struct archive_write_filter *f,
struct archive_write_program_data *data, const char *cmd)
{
- pid_t child;
+ int ret;
if (data->child_buf == NULL) {
data->child_buf_len = 65536;
@@ -225,27 +221,13 @@ __archive_write_program_open(struct archive_write_filter *f,
}
}
- child = __archive_create_child(cmd, &data->child_stdin,
- &data->child_stdout);
- if (child == -1) {
+ ret = __archive_create_child(cmd, &data->child_stdin,
+ &data->child_stdout, &data->child);
+ if (ret != ARCHIVE_OK) {
archive_set_error(f->archive, EINVAL,
"Can't launch external program: %s", cmd);
return (ARCHIVE_FATAL);
}
-#if defined(_WIN32) && !defined(__CYGWIN__)
- data->child = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, child);
- if (data->child == NULL) {
- close(data->child_stdin);
- data->child_stdin = -1;
- close(data->child_stdout);
- data->child_stdout = -1;
- archive_set_error(f->archive, EINVAL,
- "Can't launch external program: %s", cmd);
- return (ARCHIVE_FATAL);
- }
-#else
- data->child = child;
-#endif
return (ARCHIVE_OK);
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_xz.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_xz.c
index d567ac9..00df8da 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_xz.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_xz.c
@@ -382,8 +382,12 @@ archive_compressor_xz_options(struct archive_write_filter *f,
value[1] != '\0')
return (ARCHIVE_WARN);
data->compression_level = value[0] - '0';
+ if (data->compression_level > 9)
+ data->compression_level = 9;
+#ifdef _AIX
if (data->compression_level > 6)
data->compression_level = 6;
+#endif
return (ARCHIVE_OK);
} else if (strcmp(key, "threads") == 0) {
char *endptr;
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_zstd.c b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_zstd.c
index f67b025..6d71628 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_add_filter_zstd.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_add_filter_zstd.c
@@ -59,6 +59,16 @@ struct private_data {
#endif
};
+/* If we don't have the library use default range values (zstdcli.c v1.4.0) */
+#define CLEVEL_MIN -99
+#define CLEVEL_STD_MIN 0 /* prior to 1.3.4 and more recent without using --fast */
+#define CLEVEL_DEFAULT 3
+#define CLEVEL_STD_MAX 19 /* without using --ultra */
+#define CLEVEL_MAX 22
+
+#define MINVER_NEGCLEVEL 10304
+#define MINVER_MINCLEVEL 10306
+
static int archive_compressor_zstd_options(struct archive_write_filter *,
const char *, const char *);
static int archive_compressor_zstd_open(struct archive_write_filter *);
@@ -96,7 +106,7 @@ archive_write_add_filter_zstd(struct archive *_a)
f->free = &archive_compressor_zstd_free;
f->code = ARCHIVE_FILTER_ZSTD;
f->name = "zstd";
- data->compression_level = 3; /* Default level used by the zstd CLI */
+ data->compression_level = CLEVEL_DEFAULT;
#if HAVE_ZSTD_H && HAVE_LIBZSTD
data->cstream = ZSTD_createCStream();
if (data->cstream == NULL) {
@@ -135,6 +145,31 @@ archive_compressor_zstd_free(struct archive_write_filter *f)
return (ARCHIVE_OK);
}
+static int string_is_numeric (const char* value)
+{
+ size_t len = strlen(value);
+ size_t i;
+
+ if (len == 0) {
+ return (ARCHIVE_WARN);
+ }
+ else if (len == 1 && !(value[0] >= '0' && value[0] <= '9')) {
+ return (ARCHIVE_WARN);
+ }
+ else if (!(value[0] >= '0' && value[0] <= '9') &&
+ value[0] != '-' && value[0] != '+') {
+ return (ARCHIVE_WARN);
+ }
+
+ for (i = 1; i < len; i++) {
+ if (!(value[i] >= '0' && value[i] <= '9')) {
+ return (ARCHIVE_WARN);
+ }
+ }
+
+ return (ARCHIVE_OK);
+}
+
/*
* Set write options.
*/
@@ -146,12 +181,25 @@ archive_compressor_zstd_options(struct archive_write_filter *f, const char *key,
if (strcmp(key, "compression-level") == 0) {
int level = atoi(value);
-#if HAVE_ZSTD_H && HAVE_LIBZSTD
- if (level < 1 || level > ZSTD_maxCLevel()) {
-#else
/* If we don't have the library, hard-code the max level */
- if (level < 1 || level > 22) {
+ int minimum = CLEVEL_MIN;
+ int maximum = CLEVEL_MAX;
+ if (string_is_numeric(value) != ARCHIVE_OK) {
+ return (ARCHIVE_WARN);
+ }
+#if HAVE_ZSTD_H && HAVE_LIBZSTD
+ maximum = ZSTD_maxCLevel();
+#if ZSTD_VERSION_NUMBER >= MINVER_MINCLEVEL
+ if (ZSTD_versionNumber() >= MINVER_MINCLEVEL) {
+ minimum = ZSTD_minCLevel();
+ }
+ else
+#endif
+ if (ZSTD_versionNumber() < MINVER_NEGCLEVEL) {
+ minimum = CLEVEL_STD_MIN;
+ }
#endif
+ if (level < minimum || level > maximum) {
return (ARCHIVE_WARN);
}
data->compression_level = level;
@@ -297,7 +345,26 @@ archive_compressor_zstd_open(struct archive_write_filter *f)
int r;
archive_string_init(&as);
- archive_string_sprintf(&as, "zstd -%d", data->compression_level);
+ /* --no-check matches library default */
+ archive_strcpy(&as, "zstd --no-check");
+
+ if (data->compression_level < CLEVEL_STD_MIN) {
+ struct archive_string as2;
+ archive_string_init(&as2);
+ archive_string_sprintf(&as2, " --fast=%d", -data->compression_level);
+ archive_string_concat(&as, &as2);
+ archive_string_free(&as2);
+ } else {
+ struct archive_string as2;
+ archive_string_init(&as2);
+ archive_string_sprintf(&as2, " -%d", data->compression_level);
+ archive_string_concat(&as, &as2);
+ archive_string_free(&as2);
+ }
+
+ if (data->compression_level > CLEVEL_STD_MAX) {
+ archive_strcat(&as, " --ultra");
+ }
f->write = archive_compressor_zstd_write;
r = __archive_write_program_open(f, data->pdata, as.s);
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c b/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c
index c4be9b0..2551ebe 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c
@@ -546,6 +546,7 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
{
struct archive_write_disk *a = (struct archive_write_disk *)_a;
struct fixup_entry *fe;
+ const char *linkname;
int ret, r;
archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
@@ -591,6 +592,17 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
return (ret);
/*
+ * Check if we have a hardlink that points to itself.
+ */
+ linkname = archive_entry_hardlink(a->entry);
+ if (linkname != NULL && strcmp(a->name, linkname) == 0) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+ "Skipping hardlink pointing to itself: %s",
+ a->name);
+ return (ARCHIVE_WARN);
+ }
+
+ /*
* Query the umask so we get predictable mode settings.
* This gets done on every call to _write_header in case the
* user edits their umask during the extraction for some
@@ -1856,8 +1868,9 @@ finish_metadata:
if (a->tmpname) {
if (rename(a->tmpname, a->name) == -1) {
archive_set_error(&a->archive, errno,
- "rename failed");
- ret = ARCHIVE_FATAL;
+ "Failed to rename temporary file");
+ ret = ARCHIVE_FAILED;
+ unlink(a->tmpname);
}
a->tmpname = NULL;
}
@@ -2144,8 +2157,11 @@ restore_entry(struct archive_write_disk *a)
if ((a->flags & ARCHIVE_EXTRACT_SAFE_WRITES) &&
S_ISREG(a->st.st_mode)) {
/* Use a temporary file to extract */
- if ((a->fd = la_mktemp(a)) == -1)
+ if ((a->fd = la_mktemp(a)) == -1) {
+ archive_set_error(&a->archive, errno,
+ "Can't create temporary file");
return ARCHIVE_FAILED;
+ }
a->pst = NULL;
en = 0;
} else {
@@ -4407,10 +4423,19 @@ set_xattrs(struct archive_write_disk *a)
int e;
int namespace;
+ namespace = EXTATTR_NAMESPACE_USER;
+
if (strncmp(name, "user.", 5) == 0) {
/* "user." attributes go to user namespace */
name += 5;
namespace = EXTATTR_NAMESPACE_USER;
+ } else if (strncmp(name, "system.", 7) == 0) {
+ name += 7;
+ namespace = EXTATTR_NAMESPACE_SYSTEM;
+ if (!strcmp(name, "nfs4.acl") ||
+ !strcmp(name, "posix1e.acl_access") ||
+ !strcmp(name, "posix1e.acl_default"))
+ continue;
} else {
/* Other namespaces are unsupported */
archive_strcat(&errlist, name);
@@ -4421,8 +4446,29 @@ set_xattrs(struct archive_write_disk *a)
}
if (a->fd >= 0) {
+ /*
+ * On FreeBSD, extattr_set_fd does not
+ * return the same as
+ * extattr_set_file. It returns zero
+ * on success, non-zero on failure.
+ *
+ * We can detect the failure by
+ * manually setting errno prior to the
+ * call and checking after.
+ *
+ * If errno remains zero, fake the
+ * return value by setting e to size.
+ *
+ * This is a hack for now until I
+ * (Shawn Webb) get FreeBSD to fix the
+ * issue, if that's even possible.
+ */
+ errno = 0;
e = extattr_set_fd(a->fd, namespace, name,
value, size);
+ if (e == 0 && errno == 0) {
+ e = size;
+ }
} else {
e = extattr_set_link(
archive_entry_pathname(entry), namespace,
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c b/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
index 77e36c4..0c60017 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
@@ -549,6 +549,8 @@ la_mktemp(struct archive_write_disk *a)
a->tmpname = a->_tmpname_data.s;
fd = __archive_mkstemp(a->tmpname);
+ if (fd == -1)
+ return -1;
mode = a->mode & 0777 & ~a->user_umask;
if (la_chmod(a->tmpname, mode) == -1) {
@@ -1281,9 +1283,11 @@ _archive_write_disk_finish_entry(struct archive *_a)
/* Windows does not support atomic rename */
disk_unlink(a->name);
if (_wrename(a->tmpname, a->name) != 0) {
+ la_dosmaperr(GetLastError());
archive_set_error(&a->archive, errno,
- "rename failed");
- ret = ARCHIVE_FATAL;
+ "Failed to rename temporary file");
+ ret = ARCHIVE_FAILED;
+ disk_unlink(a->tmpname);
}
a->tmpname = NULL;
}
@@ -1573,12 +1577,17 @@ restore_entry(struct archive_write_disk *a)
S_ISREG(st_mode)) {
int fd = la_mktemp(a);
- if (fd == -1)
+ if (fd == -1) {
+ la_dosmaperr(GetLastError());
+ archive_set_error(&a->archive, errno,
+ "Can't create temporary file");
return (ARCHIVE_FAILED);
+ }
a->fh = (HANDLE)_get_osfhandle(fd);
- if (a->fh == INVALID_HANDLE_VALUE)
+ if (a->fh == INVALID_HANDLE_VALUE) {
+ la_dosmaperr(GetLastError());
return (ARCHIVE_FAILED);
-
+ }
a->pst = NULL;
en = 0;
} else {
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_open.3 b/Utilities/cmlibarchive/libarchive/archive_write_open.3
index 0129d10..29bffe4 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_open.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_open.3
@@ -24,11 +24,12 @@
.\"
.\" $FreeBSD$
.\"
-.Dd February 2, 2012
+.Dd November 12, 2020
.Dt ARCHIVE_WRITE_OPEN 3
.Os
.Sh NAME
.Nm archive_write_open ,
+.Nm archive_write_open2 ,
.Nm archive_write_open_fd ,
.Nm archive_write_open_FILE ,
.Nm archive_write_open_filename ,
@@ -47,6 +48,15 @@ Streaming Archive Library (libarchive, -larchive)
.Fa "archive_close_callback *"
.Fc
.Ft int
+.Fo archive_write_open2
+.Fa "struct archive *"
+.Fa "void *client_data"
+.Fa "archive_open_callback *"
+.Fa "archive_write_callback *"
+.Fa "archive_close_callback *"
+.Fa "archive_free_callback *"
+.Fc
+.Ft int
.Fn archive_write_open_fd "struct archive *" "int fd"
.Ft int
.Fn archive_write_open_FILE "struct archive *" "FILE *file"
@@ -67,6 +77,11 @@ This is the most generic form of this function, which accepts
pointers to three callback functions which will be invoked by
the compression layer to write the constructed archive.
This does not alter the default archive padding.
+.It Fn archive_write_open2
+Same as
+.Fn archive_write_open
+with an additional fourth free callback. This function should be preferred to
+.Fn archive_write_open .
.It Fn archive_write_open_fd
A convenience form of
.Fn archive_write_open
@@ -106,14 +121,14 @@ to a character or block device node, it will disable padding otherwise.
You can override this by manually invoking
.Fn archive_write_set_bytes_in_last_block
before calling
-.Fn archive_write_open .
+.Fn archive_write_open2 .
The
.Fn archive_write_open_filename
function is safe for use with tape drives or other
block-oriented devices.
.It Fn archive_write_open_memory
A convenience form of
-.Fn archive_write_open
+.Fn archive_write_open2
that accepts a pointer to a block of memory that will receive
the archive.
The final
@@ -145,7 +160,7 @@ To use this library, you will need to define and register
callback functions that will be invoked to write data to the
resulting archive.
These functions are registered by calling
-.Fn archive_write_open :
+.Fn archive_write_open2 :
.Bl -item -offset indent
.It
.Ft typedef int
@@ -162,6 +177,8 @@ If the open fails, it should call
.Fn archive_set_error
to register an error code and message and return
.Cm ARCHIVE_FATAL .
+Please note that if open fails, close is not called and resources must be
+freed inside the open callback or with the free callback.
.Bl -item -offset indent
.It
.Ft typedef la_ssize_t
@@ -192,7 +209,8 @@ to register an error code and message and return -1.
.El
.Pp
The close callback is invoked by archive_close when
-the archive processing is complete.
+the archive processing is complete. If the open callback fails, the close
+callback is not invoked.
The callback should return
.Cm ARCHIVE_OK
on success.
@@ -200,7 +218,14 @@ On failure, the callback should invoke
.Fn archive_set_error
to register an error code and message and
return
-.Cm ARCHIVE_FATAL .
+.Bl -item -offset indent
+.It
+.Ft typedef int
+.Fn archive_free_callback "struct archive *" "void *client_data"
+.El
+.Pp
+The free callback is always invoked on archive_free.
+The return code of this callback is not processed.
.Pp
Note that if the client-provided write callback function
returns a non-zero value, that error will be propagated back to the caller
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_open_fd.c b/Utilities/cmlibarchive/libarchive/archive_write_open_fd.c
index d5c426c..b8d491f 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_open_fd.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_open_fd.c
@@ -54,7 +54,7 @@ struct write_fd_data {
int fd;
};
-static int file_close(struct archive *, void *);
+static int file_free(struct archive *, void *);
static int file_open(struct archive *, void *);
static ssize_t file_write(struct archive *, void *, const void *buff, size_t);
@@ -72,8 +72,8 @@ archive_write_open_fd(struct archive *a, int fd)
#if defined(__CYGWIN__) || defined(_WIN32)
setmode(mine->fd, O_BINARY);
#endif
- return (archive_write_open(a, mine,
- file_open, file_write, file_close));
+ return (archive_write_open2(a, mine,
+ file_open, file_write, NULL, file_free));
}
static int
@@ -134,11 +134,13 @@ file_write(struct archive *a, void *client_data, const void *buff, size_t length
}
static int
-file_close(struct archive *a, void *client_data)
+file_free(struct archive *a, void *client_data)
{
struct write_fd_data *mine = (struct write_fd_data *)client_data;
(void)a; /* UNUSED */
+ if (mine == NULL)
+ return (ARCHIVE_OK);
free(mine);
return (ARCHIVE_OK);
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_open_file.c b/Utilities/cmlibarchive/libarchive/archive_write_open_file.c
index f6b1412..bf5b55a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_open_file.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_open_file.c
@@ -51,7 +51,7 @@ struct write_FILE_data {
FILE *f;
};
-static int file_close(struct archive *, void *);
+static int file_free(struct archive *, void *);
static int file_open(struct archive *, void *);
static ssize_t file_write(struct archive *, void *, const void *buff, size_t);
@@ -66,8 +66,8 @@ archive_write_open_FILE(struct archive *a, FILE *f)
return (ARCHIVE_FATAL);
}
mine->f = f;
- return (archive_write_open(a, mine,
- file_open, file_write, file_close));
+ return (archive_write_open2(a, mine, file_open, file_write,
+ NULL, file_free));
}
static int
@@ -99,11 +99,13 @@ file_write(struct archive *a, void *client_data, const void *buff, size_t length
}
static int
-file_close(struct archive *a, void *client_data)
+file_free(struct archive *a, void *client_data)
{
struct write_FILE_data *mine = client_data;
(void)a; /* UNUSED */
+ if (mine == NULL)
+ return (ARCHIVE_OK);
free(mine);
return (ARCHIVE_OK);
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_open_filename.c b/Utilities/cmlibarchive/libarchive/archive_write_open_filename.c
index 66e0dfe..9ceefb1 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_open_filename.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_open_filename.c
@@ -62,6 +62,7 @@ struct write_file_data {
};
static int file_close(struct archive *, void *);
+static int file_free(struct archive *, void *);
static int file_open(struct archive *, void *);
static ssize_t file_write(struct archive *, void *, const void *buff, size_t);
static int open_filename(struct archive *, int, const void *);
@@ -123,8 +124,8 @@ open_filename(struct archive *a, int mbs_fn, const void *filename)
return (ARCHIVE_FAILED);
}
mine->fd = -1;
- return (archive_write_open(a, mine,
- file_open, file_write, file_close));
+ return (archive_write_open2(a, mine,
+ file_open, file_write, file_close, file_free));
}
static int
@@ -244,9 +245,25 @@ file_close(struct archive *a, void *client_data)
(void)a; /* UNUSED */
+ if (mine == NULL)
+ return (ARCHIVE_FATAL);
+
if (mine->fd >= 0)
close(mine->fd);
+ return (ARCHIVE_OK);
+}
+
+static int
+file_free(struct archive *a, void *client_data)
+{
+ struct write_file_data *mine = (struct write_file_data *)client_data;
+
+ (void)a; /* UNUSED */
+
+ if (mine == NULL)
+ return (ARCHIVE_OK);
+
archive_mstring_clean(&mine->filename);
free(mine);
return (ARCHIVE_OK);
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_open_memory.c b/Utilities/cmlibarchive/libarchive/archive_write_open_memory.c
index ea6ae0a..a8a0b81 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_open_memory.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_open_memory.c
@@ -39,7 +39,7 @@ struct write_memory_data {
unsigned char * buff;
};
-static int memory_write_close(struct archive *, void *);
+static int memory_write_free(struct archive *, void *);
static int memory_write_open(struct archive *, void *);
static ssize_t memory_write(struct archive *, void *, const void *buff, size_t);
@@ -61,8 +61,8 @@ archive_write_open_memory(struct archive *a, void *buff, size_t buffSize, size_t
mine->buff = buff;
mine->size = buffSize;
mine->client_size = used;
- return (archive_write_open(a, mine,
- memory_write_open, memory_write, memory_write_close));
+ return (archive_write_open2(a, mine,
+ memory_write_open, memory_write, NULL, memory_write_free));
}
static int
@@ -103,11 +103,13 @@ memory_write(struct archive *a, void *client_data, const void *buff, size_t leng
}
static int
-memory_write_close(struct archive *a, void *client_data)
+memory_write_free(struct archive *a, void *client_data)
{
struct write_memory_data *mine;
(void)a; /* UNUSED */
mine = client_data;
+ if (mine == NULL)
+ return (ARCHIVE_OK);
free(mine);
return (ARCHIVE_OK);
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_private.h b/Utilities/cmlibarchive/libarchive/archive_write_private.h
index 27cba03..155fdd7 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_write_private.h
@@ -89,6 +89,7 @@ struct archive_write {
archive_open_callback *client_opener;
archive_write_callback *client_writer;
archive_close_callback *client_closer;
+ archive_free_callback *client_freer;
void *client_data;
/*
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format.c
index 12de080..7dbe7b9 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format.c
@@ -82,7 +82,7 @@ void
__archive_write_entry_filetype_unsupported(struct archive *a,
struct archive_entry *entry, const char *format)
{
- char *name = NULL;
+ const char *name = NULL;
switch (archive_entry_filetype(entry)) {
/*
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c
index 69af814..7f2e6ac 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_7zip.c
@@ -1927,8 +1927,8 @@ compression_init_encoder_lzma(struct archive *a,
return (ARCHIVE_FATAL);
}
lzmafilters = (lzma_filter *)(strm+1);
- if (level > 6)
- level = 6;
+ if (level > 9)
+ level = 9;
if (lzma_lzma_preset(&lzma_opt, level)) {
free(strm);
lastrm->real_stream = NULL;
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio.c
index 729f9c7..e066733 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio.c
@@ -250,7 +250,7 @@ archive_write_cpio_header(struct archive_write *a, struct archive_entry *entry)
const char *path;
size_t len;
- if (archive_entry_filetype(entry) == 0) {
+ if (archive_entry_filetype(entry) == 0 && archive_entry_hardlink(entry) == NULL) {
archive_set_error(&a->archive, -1, "Filetype required");
return (ARCHIVE_FAILED);
}
@@ -348,7 +348,7 @@ write_header(struct archive_write *a, struct archive_entry *entry)
format_octal(archive_entry_nlink(entry), h + c_nlink_offset, c_nlink_size);
if (archive_entry_filetype(entry) == AE_IFBLK
|| archive_entry_filetype(entry) == AE_IFCHR)
- format_octal(archive_entry_dev(entry), h + c_rdev_offset, c_rdev_size);
+ format_octal(archive_entry_rdev(entry), h + c_rdev_offset, c_rdev_size);
else
format_octal(0, h + c_rdev_offset, c_rdev_size);
format_octal(archive_entry_mtime(entry), h + c_mtime_offset, c_mtime_size);
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_newc.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_newc.c
index 172fda6..f0f3980 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_newc.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_newc.c
@@ -190,7 +190,7 @@ archive_write_newc_header(struct archive_write *a, struct archive_entry *entry)
const char *path;
size_t len;
- if (archive_entry_filetype(entry) == 0) {
+ if (archive_entry_filetype(entry) == 0 && archive_entry_hardlink(entry) == NULL) {
archive_set_error(&a->archive, -1, "Filetype required");
return (ARCHIVE_FAILED);
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_iso9660.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_iso9660.c
index 5db414f..68e3fe3 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_iso9660.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_iso9660.c
@@ -2178,7 +2178,8 @@ get_system_identitier(char *system_id, size_t size)
strncpy(system_id, "Windows", size-1);
system_id[size-1] = '\0';
#else
-#error no way to get the system identifier on your platform.
+ strncpy(system_id, "Unknown", size-1);
+ system_id[size-1] = '\0';
#endif
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_mtree.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_mtree.c
index aa41e9a..619b771 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_mtree.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_mtree.c
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_mtree.c 201171
#include "archive.h"
#include "archive_digest_private.h"
#include "archive_entry.h"
+#include "archive_entry_private.h"
#include "archive_private.h"
#include "archive_rb.h"
#include "archive_string.h"
@@ -82,24 +83,7 @@ struct dir_info {
struct reg_info {
int compute_sum;
uint32_t crc;
-#ifdef ARCHIVE_HAS_MD5
- unsigned char buf_md5[16];
-#endif
-#ifdef ARCHIVE_HAS_RMD160
- unsigned char buf_rmd160[20];
-#endif
-#ifdef ARCHIVE_HAS_SHA1
- unsigned char buf_sha1[20];
-#endif
-#ifdef ARCHIVE_HAS_SHA256
- unsigned char buf_sha256[32];
-#endif
-#ifdef ARCHIVE_HAS_SHA384
- unsigned char buf_sha384[48];
-#endif
-#ifdef ARCHIVE_HAS_SHA512
- unsigned char buf_sha512[64];
-#endif
+ struct ae_digest digest;
};
struct mtree_entry {
@@ -1571,27 +1555,27 @@ sum_final(struct mtree_writer *mtree, struct reg_info *reg)
}
#ifdef ARCHIVE_HAS_MD5
if (mtree->compute_sum & F_MD5)
- archive_md5_final(&mtree->md5ctx, reg->buf_md5);
+ archive_md5_final(&mtree->md5ctx, reg->digest.md5);
#endif
#ifdef ARCHIVE_HAS_RMD160
if (mtree->compute_sum & F_RMD160)
- archive_rmd160_final(&mtree->rmd160ctx, reg->buf_rmd160);
+ archive_rmd160_final(&mtree->rmd160ctx, reg->digest.rmd160);
#endif
#ifdef ARCHIVE_HAS_SHA1
if (mtree->compute_sum & F_SHA1)
- archive_sha1_final(&mtree->sha1ctx, reg->buf_sha1);
+ archive_sha1_final(&mtree->sha1ctx, reg->digest.sha1);
#endif
#ifdef ARCHIVE_HAS_SHA256
if (mtree->compute_sum & F_SHA256)
- archive_sha256_final(&mtree->sha256ctx, reg->buf_sha256);
+ archive_sha256_final(&mtree->sha256ctx, reg->digest.sha256);
#endif
#ifdef ARCHIVE_HAS_SHA384
if (mtree->compute_sum & F_SHA384)
- archive_sha384_final(&mtree->sha384ctx, reg->buf_sha384);
+ archive_sha384_final(&mtree->sha384ctx, reg->digest.sha384);
#endif
#ifdef ARCHIVE_HAS_SHA512
if (mtree->compute_sum & F_SHA512)
- archive_sha512_final(&mtree->sha512ctx, reg->buf_sha512);
+ archive_sha512_final(&mtree->sha512ctx, reg->digest.sha512);
#endif
/* Save what types of sum are computed. */
reg->compute_sum = mtree->compute_sum;
@@ -1621,42 +1605,47 @@ sum_write(struct archive_string *str, struct reg_info *reg)
archive_string_sprintf(str, " cksum=%ju",
(uintmax_t)reg->crc);
}
+
+#define append_digest(_s, _r, _t) \
+ strappend_bin(_s, _r->digest._t, sizeof(_r->digest._t))
+
#ifdef ARCHIVE_HAS_MD5
if (reg->compute_sum & F_MD5) {
archive_strcat(str, " md5digest=");
- strappend_bin(str, reg->buf_md5, sizeof(reg->buf_md5));
+ append_digest(str, reg, md5);
}
#endif
#ifdef ARCHIVE_HAS_RMD160
if (reg->compute_sum & F_RMD160) {
archive_strcat(str, " rmd160digest=");
- strappend_bin(str, reg->buf_rmd160, sizeof(reg->buf_rmd160));
+ append_digest(str, reg, rmd160);
}
#endif
#ifdef ARCHIVE_HAS_SHA1
if (reg->compute_sum & F_SHA1) {
archive_strcat(str, " sha1digest=");
- strappend_bin(str, reg->buf_sha1, sizeof(reg->buf_sha1));
+ append_digest(str, reg, sha1);
}
#endif
#ifdef ARCHIVE_HAS_SHA256
if (reg->compute_sum & F_SHA256) {
archive_strcat(str, " sha256digest=");
- strappend_bin(str, reg->buf_sha256, sizeof(reg->buf_sha256));
+ append_digest(str, reg, sha256);
}
#endif
#ifdef ARCHIVE_HAS_SHA384
if (reg->compute_sum & F_SHA384) {
archive_strcat(str, " sha384digest=");
- strappend_bin(str, reg->buf_sha384, sizeof(reg->buf_sha384));
+ append_digest(str, reg, sha384);
}
#endif
#ifdef ARCHIVE_HAS_SHA512
if (reg->compute_sum & F_SHA512) {
archive_strcat(str, " sha512digest=");
- strappend_bin(str, reg->buf_sha512, sizeof(reg->buf_sha512));
+ append_digest(str, reg, sha512);
}
#endif
+#undef append_digest
}
static int
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c
index 3b0ffb3..1e35375 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_xar.c
@@ -681,7 +681,8 @@ xar_write_data(struct archive_write *a, const void *buff, size_t s)
{
struct xar *xar;
enum la_zaction run;
- size_t size, rsize;
+ size_t size = 0;
+ size_t rsize;
int r;
xar = (struct xar *)a->format_data;
@@ -2930,8 +2931,8 @@ compression_init_encoder_xz(struct archive *a,
return (ARCHIVE_FATAL);
}
lzmafilters = (lzma_filter *)(strm+1);
- if (level > 6)
- level = 6;
+ if (level > 9)
+ level = 9;
if (lzma_lzma_preset(&lzma_opt, level)) {
free(strm);
lastrm->real_stream = NULL;
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c
index b0cd215..66a1f84 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_zip.c
@@ -584,6 +584,7 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
zip->entry_flags |= ZIP_ENTRY_FLAG_ENCRYPTED;
zip->entry_encryption = zip->encryption_type;
break;
+ case ENCRYPTION_NONE:
default:
break;
}
@@ -710,6 +711,7 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
+ AUTH_CODE_SIZE;
version_needed = 20;
break;
+ case ENCRYPTION_NONE:
default:
break;
}
@@ -762,6 +764,7 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
if (version_needed < 20)
version_needed = 20;
break;
+ case ENCRYPTION_NONE:
default:
break;
}
@@ -1029,6 +1032,7 @@ archive_write_zip_data(struct archive_write *a, const void *buff, size_t s)
zip->cctx_valid = zip->hctx_valid = 1;
}
break;
+ case ENCRYPTION_NONE:
default:
break;
}
@@ -1117,6 +1121,7 @@ archive_write_zip_data(struct archive_write *a, const void *buff, size_t s)
break;
#endif
+ case COMPRESSION_UNSPECIFIED:
default:
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Invalid ZIP compression type");
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_options.3 b/Utilities/cmlibarchive/libarchive/archive_write_set_options.3
index cffe571..d4a52e3 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_options.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_options.3
@@ -255,7 +255,8 @@ If supported, the default value is read from
.Bl -tag -compact -width indent
.It Cm compression-level
The value is interpreted as a decimal integer specifying the
-compression level. Supported values are from 1 to 22.
+compression level. Supported values depend on the library version,
+common values are from 1 to 22.
.El
.It Format 7zip
.Bl -tag -compact -width indent
diff --git a/Utilities/cmlibarchive/libarchive/config_freebsd.h b/Utilities/cmlibarchive/libarchive/config_freebsd.h
index f16fd34..a484618 100644
--- a/Utilities/cmlibarchive/libarchive/config_freebsd.h
+++ b/Utilities/cmlibarchive/libarchive/config_freebsd.h
@@ -24,6 +24,7 @@
*
* $FreeBSD$
*/
+#define __LIBARCHIVE_CONFIG_H_INCLUDED 1
#include <osreldate.h>
@@ -183,6 +184,7 @@
#define HAVE_STRFTIME 1
#define HAVE_STRINGS_H 1
#define HAVE_STRING_H 1
+#define HAVE_STRNLEN 1
#define HAVE_STRRCHR 1
#define HAVE_STRUCT_STATFS_F_NAMEMAX 1
#define HAVE_STRUCT_STAT_ST_BIRTHTIME 1
diff --git a/Utilities/cmlibarchive/libarchive/cpio.5 b/Utilities/cmlibarchive/libarchive/cpio.5
index 1a2886f..a91f0c5 100644
--- a/Utilities/cmlibarchive/libarchive/cpio.5
+++ b/Utilities/cmlibarchive/libarchive/cpio.5
@@ -244,7 +244,7 @@ Note that this format supports only 4 gigabyte files (unlike the
older ASCII format, which supports 8 gigabyte files).
.Pp
In this format, hardlinked files are handled by setting the
-filesize to zero for each entry except the last one that
+filesize to zero for each entry except the first one that
appears in the archive.
.Ss New CRC Format
The CRC format is identical to the new ASCII format described
diff --git a/Utilities/cmlibarchive/libarchive/filter_fork.h b/Utilities/cmlibarchive/libarchive/filter_fork.h
index 908e7cd..2bf290c 100644
--- a/Utilities/cmlibarchive/libarchive/filter_fork.h
+++ b/Utilities/cmlibarchive/libarchive/filter_fork.h
@@ -32,8 +32,13 @@
#error This header is only to be used internally to libarchive.
#endif
-pid_t
-__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout);
+int
+__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout,
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ HANDLE *out_child);
+#else
+ pid_t *out_child);
+#endif
void
__archive_check_child(int in, int out);
diff --git a/Utilities/cmlibarchive/libarchive/filter_fork_posix.c b/Utilities/cmlibarchive/libarchive/filter_fork_posix.c
index 02dbd4b..ac255c4 100644
--- a/Utilities/cmlibarchive/libarchive/filter_fork_posix.c
+++ b/Utilities/cmlibarchive/libarchive/filter_fork_posix.c
@@ -72,8 +72,9 @@ __FBSDID("$FreeBSD: head/lib/libarchive/filter_fork.c 182958 2008-09-12 05:33:00
#include "filter_fork.h"
-pid_t
-__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout)
+int
+__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout,
+ pid_t *out_child)
{
pid_t child;
int stdin_pipe[2], stdout_pipe[2], tmp;
@@ -177,7 +178,8 @@ __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout)
fcntl(*child_stdout, F_SETFL, O_NONBLOCK);
__archive_cmdline_free(cmdline);
- return child;
+ *out_child = child;
+ return ARCHIVE_OK;
#if HAVE_POSIX_SPAWNP
actions_inited:
@@ -192,7 +194,7 @@ stdin_opened:
close(stdin_pipe[1]);
state_allocated:
__archive_cmdline_free(cmdline);
- return -1;
+ return ARCHIVE_FAILED;
}
void
diff --git a/Utilities/cmlibarchive/libarchive/filter_fork_windows.c b/Utilities/cmlibarchive/libarchive/filter_fork_windows.c
index ad271fe..8d11179 100644
--- a/Utilities/cmlibarchive/libarchive/filter_fork_windows.c
+++ b/Utilities/cmlibarchive/libarchive/filter_fork_windows.c
@@ -31,8 +31,9 @@
#include "filter_fork.h"
-pid_t
-__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout)
+int
+__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout,
+ HANDLE *out_child)
{
HANDLE childStdout[2], childStdin[2],childStderr;
SECURITY_ATTRIBUTES secAtts;
@@ -44,6 +45,7 @@ __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout)
char *arg0, *ext;
int i, l;
DWORD fl, fl_old;
+ HANDLE child;
childStdout[0] = childStdout[1] = INVALID_HANDLE_VALUE;
childStdin[0] = childStdin[1] = INVALID_HANDLE_VALUE;
@@ -154,13 +156,20 @@ __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout)
*child_stdout = _open_osfhandle((intptr_t)childStdout[0], _O_RDONLY);
*child_stdin = _open_osfhandle((intptr_t)childStdin[1], _O_WRONLY);
+ child = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE,
+ childInfo.dwProcessId);
+ if (child == NULL) // INVALID_HANDLE_VALUE ?
+ goto fail;
+
+ *out_child = child;
+
CloseHandle(childStdout[1]);
CloseHandle(childStdin[0]);
archive_string_free(&cmdline);
archive_string_free(&fullpath);
__archive_cmdline_free(acmd);
- return (childInfo.dwProcessId);
+ return ARCHIVE_OK;
fail:
if (childStdout[0] != INVALID_HANDLE_VALUE)
@@ -176,7 +185,7 @@ fail:
archive_string_free(&cmdline);
archive_string_free(&fullpath);
__archive_cmdline_free(acmd);
- return (-1);
+ return ARCHIVE_FAILED;
}
void
diff --git a/Utilities/cmlibuv/src/win/process.c b/Utilities/cmlibuv/src/win/process.c
index 04718db..aada889 100644
--- a/Utilities/cmlibuv/src/win/process.c
+++ b/Utilities/cmlibuv/src/win/process.c
@@ -169,7 +169,10 @@ static WCHAR* search_path_join_test(const WCHAR* dir,
size_t cwd_len) {
WCHAR *result, *result_pos;
DWORD attrs;
- if (dir_len > 2 && dir[0] == L'\\' && dir[1] == L'\\') {
+ if (
+ (dir_len > 2 && dir[0] == L'\\' && dir[1] == L'\\') ||
+ (dir_len > 2 && dir[0] == L'/' && dir[1] == L'/')
+ ) {
/* It's a UNC path so ignore cwd */
cwd_len = 0;
} else if (dir_len >= 1 && (dir[0] == L'/' || dir[0] == L'\\')) {
diff --git a/bootstrap b/bootstrap
index dc5ed0b..d0329fb 100755
--- a/bootstrap
+++ b/bootstrap
@@ -324,6 +324,7 @@ CMAKE_CXX_SOURCES="\
cmDefinePropertyCommand \
cmDefinitions \
cmDocumentationFormatter \
+ cmELF \
cmEnableLanguageCommand \
cmEnableTestingCommand \
cmExecProgramCommand \
@@ -425,6 +426,7 @@ CMAKE_CXX_SOURCES="\
cmPolicies \
cmProcessOutput \
cmProjectCommand \
+ cmProperty \
cmPropertyDefinition \
cmPropertyMap \
cmGccDepfileLexerHelper \