summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab-ci.yml44
-rw-r--r--.gitlab/.gitignore2
-rw-r--r--.gitlab/ci/configure_windows_intelclassic_ninja.cmake1
-rw-r--r--.gitlab/ci/configure_windows_intelcompiler_common.cmake5
-rw-r--r--.gitlab/ci/configure_windows_inteloneapi_ninja.cmake1
-rw-r--r--.gitlab/ci/configure_windows_vs2022_x64_ninja.cmake1
-rwxr-xr-x.gitlab/ci/env_windows_intelclassic_ninja.ps19
-rwxr-xr-x.gitlab/ci/env_windows_inteloneapi_ninja.ps19
-rwxr-xr-x.gitlab/ci/env_windows_vs2022_x64_ninja.ps11
-rwxr-xr-x.gitlab/ci/innosetup-env.ps14
-rwxr-xr-x.gitlab/ci/innosetup.ps120
-rwxr-xr-x.gitlab/ci/intel-env.ps14
-rwxr-xr-x.gitlab/ci/intel-vars.ps19
-rwxr-xr-x.gitlab/ci/intel.ps142
-rw-r--r--.gitlab/os-windows.yml16
-rw-r--r--Auxiliary/cmake-mode.el4
-rw-r--r--Auxiliary/vim/syntax/cmake.vim3
-rw-r--r--Help/command/FIND_XXX.txt9
-rw-r--r--Help/command/find_file.rst7
-rw-r--r--Help/command/find_library.rst6
-rw-r--r--Help/command/find_package.rst4
-rw-r--r--Help/command/find_path.rst6
-rw-r--r--Help/command/find_program.rst5
-rw-r--r--Help/command/list.rst30
-rw-r--r--Help/command/string.rst3
-rw-r--r--Help/cpack_gen/innosetup.rst420
-rw-r--r--Help/envvar/CMAKE_APPBUNDLE_PATH.rst14
-rw-r--r--Help/envvar/CMAKE_FRAMEWORK_PATH.rst15
-rw-r--r--Help/envvar/CMAKE_INCLUDE_PATH.rst13
-rw-r--r--Help/envvar/CMAKE_LIBRARY_PATH.rst13
-rw-r--r--Help/envvar/CMAKE_PROGRAM_PATH.rst13
-rw-r--r--Help/guide/tutorial/Adding Generator Expressions.rst191
-rw-r--r--Help/guide/tutorial/Adding Usage Requirements for a Library.rst188
-rw-r--r--Help/guide/tutorial/Adding a Library.rst5
-rw-r--r--Help/guide/tutorial/Step3/CMakeLists.txt8
-rw-r--r--Help/guide/tutorial/Step3/MathFunctions/CMakeLists.txt4
-rw-r--r--Help/guide/tutorial/Step4/CMakeLists.txt22
-rw-r--r--Help/guide/tutorial/Step4/MathFunctions/CMakeLists.txt7
-rw-r--r--Help/manual/cmake-env-variables.7.rst5
-rw-r--r--Help/manual/cmake-generator-expressions.7.rst264
-rw-r--r--Help/manual/cmake-policies.7.rst2
-rw-r--r--Help/manual/cmake-presets.7.rst9
-rw-r--r--Help/manual/cmake-properties.7.rst1
-rw-r--r--Help/manual/cmake-variables.7.rst6
-rw-r--r--Help/manual/cpack-generators.7.rst1
-rw-r--r--Help/policy/CMP0105.rst5
-rw-r--r--Help/policy/CMP0150.rst39
-rw-r--r--Help/policy/CMP0151.rst28
-rw-r--r--Help/prop_tgt/AUTOGEN_USE_SYSTEM_INCLUDE.rst17
-rw-r--r--Help/prop_tgt/VS_DEBUGGER_COMMAND.rst4
-rw-r--r--Help/prop_tgt/VS_DEBUGGER_COMMAND_ARGUMENTS.rst4
-rw-r--r--Help/prop_tgt/VS_DEBUGGER_ENVIRONMENT.rst4
-rw-r--r--Help/prop_tgt/VS_DEBUGGER_WORKING_DIRECTORY.rst4
-rw-r--r--Help/release/dev/ExternalProject-FetchContent-relative-git-remotes.rst7
-rw-r--r--Help/release/dev/FindDoxygen-custom-config-file.rst5
-rw-r--r--Help/release/dev/GenEx-LIST.rst4
-rw-r--r--Help/release/dev/autogen-system-include.rst7
-rw-r--r--Help/release/dev/cpack-innosetup.rst12
-rw-r--r--Help/release/dev/preset-includes-macro-expansion.rst7
-rw-r--r--Help/release/dev/use-linker-depfile.rst11
-rw-r--r--Help/release/dev/vs-debugger-init.rst8
-rw-r--r--Help/variable/CMAKE_APPBUNDLE_PATH.rst3
-rw-r--r--Help/variable/CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE.rst10
-rw-r--r--Help/variable/CMAKE_FRAMEWORK_PATH.rst3
-rw-r--r--Help/variable/CMAKE_INCLUDE_PATH.rst9
-rw-r--r--Help/variable/CMAKE_LANG_COMPILER_ID.rst3
-rw-r--r--Help/variable/CMAKE_LIBRARY_PATH.rst8
-rw-r--r--Help/variable/CMAKE_LINK_DEPENDS_USE_LINKER.rst12
-rw-r--r--Help/variable/CMAKE_PREFIX_PATH.rst3
-rw-r--r--Help/variable/CMAKE_PROGRAM_PATH.rst8
-rw-r--r--Help/variable/CMAKE_VS_DEBUGGER_COMMAND.rst8
-rw-r--r--Help/variable/CMAKE_VS_DEBUGGER_COMMAND_ARGUMENTS.rst8
-rw-r--r--Help/variable/CMAKE_VS_DEBUGGER_ENVIRONMENT.rst8
-rw-r--r--Help/variable/CMAKE_VS_DEBUGGER_WORKING_DIRECTORY.rst8
-rw-r--r--Modules/CMakeASMCompiler.cmake.in1
-rw-r--r--Modules/CMakeCCompiler.cmake.in1
-rw-r--r--Modules/CMakeCUDACompiler.cmake.in1
-rw-r--r--Modules/CMakeCXXCompiler.cmake.in1
-rw-r--r--Modules/CMakeDetermineCXXCompiler.cmake6
-rw-r--r--Modules/CMakeDetermineCompilerId.cmake4
-rw-r--r--Modules/CMakeFortranCompiler.cmake.in1
-rw-r--r--Modules/CMakeHIPCompiler.cmake.in1
-rw-r--r--Modules/CMakeOBJCCompiler.cmake.in1
-rw-r--r--Modules/CMakeOBJCXXCompiler.cmake.in1
-rw-r--r--Modules/CPack.cmake24
-rw-r--r--Modules/Compiler/Clang-HIP.cmake9
-rw-r--r--Modules/Compiler/GNU.cmake38
-rw-r--r--Modules/Compiler/IAR.cmake10
-rw-r--r--Modules/Compiler/NVHPC-Fortran.cmake1
-rw-r--r--Modules/Compiler/NVHPC.cmake2
-rw-r--r--Modules/CompilerId/VS-10.vcxproj.in3
-rw-r--r--Modules/ExternalProject.cmake20
-rw-r--r--Modules/ExternalProject/shared_internal_commands.cmake182
-rw-r--r--Modules/FetchContent.cmake27
-rw-r--r--Modules/FindBLAS.cmake37
-rw-r--r--Modules/FindCUDAToolkit.cmake92
-rw-r--r--Modules/FindDoxygen.cmake20
-rw-r--r--Modules/FindJNI.cmake7
-rw-r--r--Modules/FindLAPACK.cmake23
-rw-r--r--Modules/FindPython.cmake4
-rw-r--r--Modules/FindPython2.cmake4
-rw-r--r--Modules/FindPython3.cmake4
-rw-r--r--Modules/FindX11.cmake572
-rw-r--r--Modules/FortranCInterface.cmake1
-rw-r--r--Modules/Internal/CPack/ISComponents.pas88
-rw-r--r--Modules/Internal/CPack/ISScript.template.in34
-rw-r--r--Modules/Platform/Android-Determine.cmake34
-rw-r--r--Modules/Platform/Android/VCXProjInspect.vcxproj.in3
-rw-r--r--Source/CMakeLists.txt1
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CPack/IFW/cmCPackIFWCommon.cxx15
-rw-r--r--Source/CPack/IFW/cmCPackIFWGenerator.cxx5
-rw-r--r--Source/CPack/IFW/cmCPackIFWInstaller.cxx1
-rw-r--r--Source/CPack/IFW/cmCPackIFWPackage.cxx11
-rw-r--r--Source/CPack/WiX/cmCPackWIXGenerator.cxx20
-rw-r--r--Source/CPack/WiX/cmWIXAccessControlList.cxx5
-rw-r--r--Source/CPack/WiX/cmWIXShortcut.cxx5
-rw-r--r--Source/CPack/cmCPackBundleGenerator.cxx3
-rw-r--r--Source/CPack/cmCPackDebGenerator.cxx4
-rw-r--r--Source/CPack/cmCPackDragNDropGenerator.cxx10
-rw-r--r--Source/CPack/cmCPackExternalGenerator.cxx4
-rw-r--r--Source/CPack/cmCPackFreeBSDGenerator.cxx27
-rw-r--r--Source/CPack/cmCPackGenerator.cxx80
-rw-r--r--Source/CPack/cmCPackGeneratorFactory.cxx5
-rw-r--r--Source/CPack/cmCPackInnoSetupGenerator.cxx1159
-rw-r--r--Source/CPack/cmCPackInnoSetupGenerator.h116
-rw-r--r--Source/CPack/cmCPackNSISGenerator.cxx36
-rw-r--r--Source/CPack/cpack.cxx5
-rw-r--r--Source/CTest/cmCTestBuildHandler.cxx1
-rw-r--r--Source/CTest/cmCTestConfigureCommand.cxx6
-rw-r--r--Source/CTest/cmCTestGIT.cxx3
-rw-r--r--Source/CTest/cmCTestP4.cxx4
-rw-r--r--Source/CTest/cmCTestScriptHandler.cxx7
-rw-r--r--Source/CTest/cmCTestSubmitCommand.cxx6
-rw-r--r--Source/CTest/cmCTestSubmitHandler.cxx5
-rw-r--r--Source/CTest/cmCTestTestHandler.cxx28
-rw-r--r--Source/CursesDialog/cmCursesCacheEntryComposite.cxx5
-rw-r--r--Source/Modules/CMakeBuildUtilities.cmake2
-rw-r--r--Source/cmCMakeHostSystemInformationCommand.cxx15
-rw-r--r--Source/cmCMakePathCommand.cxx7
-rw-r--r--Source/cmCMakePresetsGraph.cxx29
-rw-r--r--Source/cmCMakePresetsGraphInternal.h10
-rw-r--r--Source/cmCMakePresetsGraphReadJSON.cxx37
-rw-r--r--Source/cmCTest.cxx10
-rw-r--r--Source/cmCacheManager.cxx9
-rw-r--r--Source/cmCommonTargetGenerator.cxx4
-rw-r--r--Source/cmComputeLinkDepends.cxx3
-rw-r--r--Source/cmComputeLinkInformation.cxx63
-rw-r--r--Source/cmConditionEvaluator.cxx5
-rw-r--r--Source/cmCoreTryCompile.cxx7
-rw-r--r--Source/cmCoreTryCompile.h3
-rw-r--r--Source/cmCustomCommandGenerator.cxx5
-rw-r--r--Source/cmDepends.cxx5
-rw-r--r--Source/cmDependsC.cxx7
-rw-r--r--Source/cmDependsCompiler.cxx24
-rw-r--r--Source/cmDependsFortran.cxx10
-rw-r--r--Source/cmEvaluatedTargetProperty.cxx2
-rw-r--r--Source/cmExportBuildAndroidMKGenerator.cxx8
-rw-r--r--Source/cmExportFileGenerator.cxx22
-rw-r--r--Source/cmExportTryCompileFileGenerator.cxx3
-rw-r--r--Source/cmExtraCodeBlocksGenerator.cxx5
-rw-r--r--Source/cmExtraEclipseCDT4Generator.cxx11
-rw-r--r--Source/cmExtraSublimeTextGenerator.cxx3
-rw-r--r--Source/cmFileAPIToolchains.cxx8
-rw-r--r--Source/cmFileCopier.cxx4
-rw-r--r--Source/cmFileSet.cxx9
-rw-r--r--Source/cmFindBase.cxx5
-rw-r--r--Source/cmFindCommon.cxx17
-rw-r--r--Source/cmFindLibraryCommand.cxx16
-rw-r--r--Source/cmFindPackageCommand.cxx36
-rw-r--r--Source/cmForEachCommand.cxx9
-rw-r--r--Source/cmGccDepfileLexerHelper.cxx6
-rw-r--r--Source/cmGeneratorExpression.cxx1
-rw-r--r--Source/cmGeneratorExpressionNode.cxx750
-rw-r--r--Source/cmGeneratorTarget.cxx223
-rw-r--r--Source/cmGeneratorTarget.h5
-rw-r--r--Source/cmGhsMultiTargetGenerator.cxx3
-rw-r--r--Source/cmGlobalGenerator.cxx52
-rw-r--r--Source/cmGlobalGenerator.h2
-rw-r--r--Source/cmGlobalGhsMultiGenerator.cxx3
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx28
-rw-r--r--Source/cmGlobalNinjaGenerator.h2
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.h6
-rw-r--r--Source/cmGlobalVisualStudio71Generator.cxx5
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx3
-rw-r--r--Source/cmGlobalVisualStudio8Generator.cxx44
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx30
-rw-r--r--Source/cmGraphVizWriter.cxx6
-rw-r--r--Source/cmIDEOptions.cxx1
-rw-r--r--Source/cmInstallCommand.cxx11
-rw-r--r--Source/cmInstallDirectoryGenerator.cxx10
-rw-r--r--Source/cmInstallFilesGenerator.cxx14
-rw-r--r--Source/cmInstalledFile.cxx9
-rw-r--r--Source/cmInstalledFile.h3
-rw-r--r--Source/cmLDConfigLDConfigTool.cxx4
-rw-r--r--Source/cmList.cxx47
-rw-r--r--Source/cmList.h330
-rw-r--r--Source/cmListCommand.cxx4
-rw-r--r--Source/cmListFileCache.cxx7
-rw-r--r--Source/cmListFileCache.h3
-rw-r--r--Source/cmLocalCommonGenerator.cxx16
-rw-r--r--Source/cmLocalCommonGenerator.h15
-rw-r--r--Source/cmLocalGenerator.cxx116
-rw-r--r--Source/cmLocalGenerator.h11
-rw-r--r--Source/cmLocalNinjaGenerator.cxx44
-rw-r--r--Source/cmLocalNinjaGenerator.h11
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx50
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.h3
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx13
-rw-r--r--Source/cmMakefile.cxx57
-rw-r--r--Source/cmMakefile.h2
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx24
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx40
-rw-r--r--Source/cmMakefileTargetGenerator.cxx77
-rw-r--r--Source/cmMakefileTargetGenerator.h2
-rw-r--r--Source/cmMessageCommand.cxx7
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx96
-rw-r--r--Source/cmNinjaNormalTargetGenerator.h2
-rw-r--r--Source/cmNinjaTargetGenerator.cxx75
-rw-r--r--Source/cmOutputConverter.cxx12
-rw-r--r--Source/cmOutputConverter.h10
-rw-r--r--Source/cmOutputRequiredFilesCommand.cxx5
-rw-r--r--Source/cmParseArgumentsCommand.cxx11
-rw-r--r--Source/cmPolicies.h11
-rw-r--r--Source/cmQtAutoGenInitializer.cxx50
-rw-r--r--Source/cmRemoveCommand.cxx7
-rw-r--r--Source/cmRuntimeDependencyArchive.cxx18
-rw-r--r--Source/cmSearchPath.cxx5
-rw-r--r--Source/cmStandardLevelResolver.cxx5
-rw-r--r--Source/cmStringAlgorithms.cxx71
-rw-r--r--Source/cmStringAlgorithms.h57
-rw-r--r--Source/cmTarget.cxx22
-rw-r--r--Source/cmTargetSourcesCommand.cxx3
-rw-r--r--Source/cmTestGenerator.cxx22
-rw-r--r--Source/cmTryRunCommand.cxx3
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx94
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h4
-rw-r--r--Source/cmXCodeScheme.cxx5
-rw-r--r--Source/cmake.cxx31
-rw-r--r--Source/cmakemain.cxx3
-rw-r--r--Source/cmcmd.cxx30
-rw-r--r--Templates/TestDriver.cxx.in18
-rw-r--r--Tests/CMakeLib/testGccDepfileReader_data/deps1.txt30
-rw-r--r--Tests/CMakeLib/testGccDepfileReader_data/deps3.txt8
-rw-r--r--Tests/CMakeLib/testList.cxx70
-rw-r--r--Tests/CMakeLists.txt24
-rw-r--r--Tests/CPackInnoSetupGenerator/CMakeLists.txt55
-rw-r--r--Tests/CPackInnoSetupGenerator/Code.pas4
-rw-r--r--Tests/CPackInnoSetupGenerator/RunCPackVerifyResult.cmake136
-rw-r--r--Tests/CPackInnoSetupGenerator/main.c7
-rw-r--r--Tests/CPackInnoSetupGenerator/my_bitmap.bmpbin0 -> 9294 bytes
-rw-r--r--Tests/CPackInnoSetupGenerator/my_file.txt1
-rw-r--r--Tests/CompileFeatures/default_dialect.c3
-rw-r--r--Tests/Cuda/Toolkit/CMakeLists.txt14
-rw-r--r--Tests/FindX11/Test/CMakeLists.txt51
-rw-r--r--Tests/FindX11/Test/main.c527
-rw-r--r--Tests/QtAutogen/GlobalAutogenSystemUseInclude/CMakeLists.txt28
-rw-r--r--Tests/QtAutogen/GlobalAutogenSystemUseInclude/main.cpp4
-rw-r--r--Tests/QtAutogen/RccAutogenBuildDir/CMakeLists.txt33
-rw-r--r--Tests/QtAutogen/RccAutogenBuildDir/lib.cpp6
-rw-r--r--Tests/QtAutogen/RccAutogenBuildDir/lib.h6
-rw-r--r--Tests/QtAutogen/RccAutogenBuildDir/main.cpp7
-rw-r--r--Tests/QtAutogen/RccAutogenBuildDir/resource.qrc2
-rw-r--r--Tests/QtAutogen/Tests.cmake6
-rw-r--r--Tests/RunCMake/Autogen/AutogenUseSystemIncludeCommon.cmake10
-rw-r--r--Tests/RunCMake/Autogen/AutogenUseSystemIncludeOff.cmake3
-rw-r--r--Tests/RunCMake/Autogen/AutogenUseSystemIncludeOn.cmake3
-rw-r--r--Tests/RunCMake/Autogen/CMP0151-common.cmake10
-rw-r--r--Tests/RunCMake/Autogen/CMP0151-new.cmake1
-rw-r--r--Tests/RunCMake/Autogen/CMP0151-old.cmake1
-rw-r--r--Tests/RunCMake/Autogen/Inspect.cmake13
-rw-r--r--Tests/RunCMake/Autogen/RunCMakeTest.cmake66
-rw-r--r--Tests/RunCMake/BuildDepends/LinkDepends.cmake22
-rw-r--r--Tests/RunCMake/BuildDepends/LinkDepends.step1.cmake23
-rw-r--r--Tests/RunCMake/BuildDepends/LinkDepends.step2.cmake4
-rw-r--r--Tests/RunCMake/BuildDepends/LinkDependsCheck.cmake11
-rw-r--r--Tests/RunCMake/BuildDepends/LinkDependsExternalLibrary.cmake13
-rw-r--r--Tests/RunCMake/BuildDepends/LinkDependsExternalLibrary.step1.cmake11
-rw-r--r--Tests/RunCMake/BuildDepends/RunCMakeTest.cmake12
-rw-r--r--Tests/RunCMake/CMP0121/CMP0121-ERANGE-OLD-stderr.txt2
-rw-r--r--Tests/RunCMake/CMP0121/CMP0121-ERANGE-WARN-stderr.txt2
-rw-r--r--Tests/RunCMake/CMP0150/CMP0150-NEW-build-stdout.txt7
-rw-r--r--Tests/RunCMake/CMP0150/CMP0150-NEW-resolve.cmake107
-rw-r--r--Tests/RunCMake/CMP0150/CMP0150-NEW-stdout.txt4
-rw-r--r--Tests/RunCMake/CMP0150/CMP0150-NEW.cmake45
-rw-r--r--Tests/RunCMake/CMP0150/CMP0150-OLD-build-stdout.txt3
-rw-r--r--Tests/RunCMake/CMP0150/CMP0150-OLD-common.cmake21
-rw-r--r--Tests/RunCMake/CMP0150/CMP0150-OLD-stdout.txt3
-rw-r--r--Tests/RunCMake/CMP0150/CMP0150-OLD.cmake2
-rw-r--r--Tests/RunCMake/CMP0150/CMP0150-WARN-build-stdout.txt3
-rw-r--r--Tests/RunCMake/CMP0150/CMP0150-WARN-stderr.txt25
-rw-r--r--Tests/RunCMake/CMP0150/CMP0150-WARN-stdout.txt3
-rw-r--r--Tests/RunCMake/CMP0150/CMP0150-WARN.cmake2
-rw-r--r--Tests/RunCMake/CMP0150/CMakeLists.txt27
-rw-r--r--Tests/RunCMake/CMP0150/CMakeLists.txt.in23
-rw-r--r--Tests/RunCMake/CMP0150/RunCMakeTest.cmake17
-rw-r--r--Tests/RunCMake/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMakePresets/EmptyPenvInInclude-result.txt1
-rw-r--r--Tests/RunCMake/CMakePresets/EmptyPenvInInclude-stderr.txt5
-rw-r--r--Tests/RunCMake/CMakePresets/EmptyPenvInInclude.json.in11
-rw-r--r--Tests/RunCMake/CMakePresets/IncludeExpansion-stdout.txt5
-rw-r--r--Tests/RunCMake/CMakePresets/IncludeExpansion.json.in10
-rw-r--r--Tests/RunCMake/CMakePresets/RunCMakeTest.cmake7
-rw-r--r--Tests/RunCMake/CTestResourceAllocation/ctresalloc.cxx3
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-check.py214
-rw-r--r--Tests/RunCMake/GenEx-LIST/APPEND.cmake.in34
-rw-r--r--Tests/RunCMake/GenEx-LIST/CMakeLists.txt5
-rw-r--r--Tests/RunCMake/GenEx-LIST/FILTER-wrong-operator-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/FILTER-wrong-operator-stderr.txt9
-rw-r--r--Tests/RunCMake/GenEx-LIST/FILTER-wrong-operator.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/FILTER-wrong-regex-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/FILTER-wrong-regex-stderr.txt8
-rw-r--r--Tests/RunCMake/GenEx-LIST/FILTER-wrong-regex.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/FIND.cmake.in20
-rw-r--r--Tests/RunCMake/GenEx-LIST/GET-wrong-index1-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/GET-wrong-index1-stderr.txt8
-rw-r--r--Tests/RunCMake/GenEx-LIST/GET-wrong-index1.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/GET-wrong-index2-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/GET-wrong-index2-stderr.txt8
-rw-r--r--Tests/RunCMake/GenEx-LIST/GET-wrong-index2.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/GET-wrong-index3-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/GET-wrong-index3-stderr.txt8
-rw-r--r--Tests/RunCMake/GenEx-LIST/GET-wrong-index3.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/GET.cmake.in20
-rw-r--r--Tests/RunCMake/GenEx-LIST/INSERT-wrong-index1-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/INSERT-wrong-index1-stderr.txt8
-rw-r--r--Tests/RunCMake/GenEx-LIST/INSERT-wrong-index1.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/INSERT-wrong-index2-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/INSERT-wrong-index2-stderr.txt8
-rw-r--r--Tests/RunCMake/GenEx-LIST/INSERT-wrong-index2.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/INSERT.cmake.in50
-rw-r--r--Tests/RunCMake/GenEx-LIST/JOIN.cmake.in35
-rw-r--r--Tests/RunCMake/GenEx-LIST/LENGTH.cmake.in30
-rw-r--r--Tests/RunCMake/GenEx-LIST/POP_BACK.cmake.in18
-rw-r--r--Tests/RunCMake/GenEx-LIST/POP_FRONT.cmake.in18
-rw-r--r--Tests/RunCMake/GenEx-LIST/PREPEND.cmake.in34
-rw-r--r--Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index1-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index1-stderr.txt8
-rw-r--r--Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index1.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index2-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index2-stderr.txt8
-rw-r--r--Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index2.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index3-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index3-stderr.txt8
-rw-r--r--Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index3.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/REMOVE_AT.cmake.in25
-rw-r--r--Tests/RunCMake/GenEx-LIST/REMOVE_DUPLICATES.cmake.in20
-rw-r--r--Tests/RunCMake/GenEx-LIST/REMOVE_ITEM.cmake.in32
-rw-r--r--Tests/RunCMake/GenEx-LIST/REVERSE.cmake.in19
-rw-r--r--Tests/RunCMake/GenEx-LIST/RunCMakeTest.cmake130
-rw-r--r--Tests/RunCMake/GenEx-LIST/SORT-duplicate-CASE-option-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/SORT-duplicate-CASE-option-stderr.txt8
-rw-r--r--Tests/RunCMake/GenEx-LIST/SORT-duplicate-CASE-option.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/SORT-duplicate-COMPARE-option-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/SORT-duplicate-COMPARE-option-stderr.txt8
-rw-r--r--Tests/RunCMake/GenEx-LIST/SORT-duplicate-COMPARE-option.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/SORT-duplicate-ORDER-option-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/SORT-duplicate-ORDER-option-stderr.txt8
-rw-r--r--Tests/RunCMake/GenEx-LIST/SORT-duplicate-ORDER-option.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/SORT-wrong-CASE-option-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/SORT-wrong-CASE-option-stderr.txt9
-rw-r--r--Tests/RunCMake/GenEx-LIST/SORT-wrong-CASE-option.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/SORT-wrong-COMPARE-option-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/SORT-wrong-COMPARE-option-stderr.txt9
-rw-r--r--Tests/RunCMake/GenEx-LIST/SORT-wrong-COMPARE-option.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/SORT-wrong-ORDER-option-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/SORT-wrong-ORDER-option-stderr.txt9
-rw-r--r--Tests/RunCMake/GenEx-LIST/SORT-wrong-ORDER-option.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/SORT-wrong-option-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/SORT-wrong-option-stderr.txt8
-rw-r--r--Tests/RunCMake/GenEx-LIST/SORT-wrong-option.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/SORT.cmake.in92
-rw-r--r--Tests/RunCMake/GenEx-LIST/SUBLIST-wrong-argument1-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/SUBLIST-wrong-argument1-stderr.txt8
-rw-r--r--Tests/RunCMake/GenEx-LIST/SUBLIST-wrong-argument1.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/SUBLIST-wrong-argument2-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/SUBLIST-wrong-argument2-stderr.txt8
-rw-r--r--Tests/RunCMake/GenEx-LIST/SUBLIST-wrong-argument2.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/SUBLIST.cmake.in32
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-APPEND.cmake.in50
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-PREPEND.cmake.in50
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-invalid-replace1-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-invalid-replace1-stderr.txt9
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-invalid-replace1.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-invalid-replace2-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-invalid-replace2-stderr.txt9
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-invalid-replace2.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-wrong-regex-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-wrong-regex-stderr.txt8
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-wrong-regex.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE.cmake.in50
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-STRIP.cmake.in50
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-TOLOWER.cmake.in50
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-TOUPPER.cmake.in50
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-missing-arg-stderr.txt8
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-no-arguments-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-no-arguments-stderr.txt8
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-no-arguments.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-wrong-argument-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-wrong-argument-stderr.txt8
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-wrong-argument.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-wrong-index-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-wrong-index-stderr.txt8
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-wrong-index.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-backwards-range-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-backwards-range-stderr.txt9
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-backwards-range.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-missing-arguments-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-missing-arguments-stderr.txt8
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-missing-arguments.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-negative-step-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-negative-step-stderr.txt9
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-negative-step.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-no-arguments-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-no-arguments-stderr.txt8
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-no-arguments.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-wrong-argument-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-wrong-argument-stderr.txt8
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-wrong-argument.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-wrong-index-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-wrong-index-stderr.txt8
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-wrong-index.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-zero-step-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-zero-step-stderr.txt9
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-zero-step.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-REGEX-no-arguments-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-REGEX-no-arguments-stderr.txt9
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-REGEX-no-arguments.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-REGEX-wrong-regex-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-REGEX-wrong-regex-stderr.txt8
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-REGEX-wrong-regex.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-unexpected-arg-stderr.txt8
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-wrong-action-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-wrong-action-stderr.txt7
-rw-r--r--Tests/RunCMake/GenEx-LIST/TRANSFORM-wrong-action.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/bad-option-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/bad-option-stderr.txt8
-rw-r--r--Tests/RunCMake/GenEx-LIST/bad-option.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/check_errors.cmake13
-rw-r--r--Tests/RunCMake/GenEx-LIST/generate.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/missing-arg-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/missing-arg-stderr.txt8
-rw-r--r--Tests/RunCMake/GenEx-LIST/missing-arg.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/no-arguments-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/no-arguments-stderr.txt8
-rw-r--r--Tests/RunCMake/GenEx-LIST/no-arguments.cmake2
-rw-r--r--Tests/RunCMake/GenEx-LIST/unexpected-arg-result.txt1
-rw-r--r--Tests/RunCMake/GenEx-LIST/unexpected-arg-stderr.txt8
-rw-r--r--Tests/RunCMake/GenEx-LIST/unexpected-arg.cmake2
-rw-r--r--Tests/RunCMake/IncludeWhatYouUse/C-error-Build-result.txt1
-rw-r--r--Tests/RunCMake/IncludeWhatYouUse/C-error-Build-stdout.txt4
-rw-r--r--Tests/RunCMake/IncludeWhatYouUse/C-error.cmake3
-rw-r--r--Tests/RunCMake/IncludeWhatYouUse/CXX-error-Build-result.txt1
-rw-r--r--Tests/RunCMake/IncludeWhatYouUse/CXX-error-Build-stdout.txt4
-rw-r--r--Tests/RunCMake/IncludeWhatYouUse/CXX-error.cmake3
-rw-r--r--Tests/RunCMake/IncludeWhatYouUse/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/RunCMake.cmake4
-rw-r--r--Tests/RunCMake/TransformDepfile/deps-unix.d.txt8
-rw-r--r--Tests/RunCMake/TransformDepfile/deps-windows.d.txt8
-rw-r--r--Tests/RunCMake/VS10Project/CMakeInputs-check.cmake25
-rw-r--r--Tests/RunCMake/VS10Project/CMakeInputs.cmake0
-rw-r--r--Tests/RunCMake/VS10Project/RunCMakeTest.cmake1
-rwxr-xr-xUtilities/Scripts/update-libarchive.bash2
-rw-r--r--Utilities/cmlibarchive/CMakeLists.txt43
-rw-r--r--Utilities/cmlibarchive/build/cmake/FindLIBGCC.cmake (renamed from Utilities/cmlibarchive/build/cmake/FindLibGCC.cmake)0
-rw-r--r--Utilities/cmlibarchive/build/cmake/config.h.in44
-rw-r--r--Utilities/cmlibarchive/build/pkgconfig/libarchive.pc.in1
-rw-r--r--Utilities/cmlibarchive/build/version2
-rw-r--r--Utilities/cmlibarchive/libarchive/CMakeLists.txt5
-rw-r--r--Utilities/cmlibarchive/libarchive/archive.h6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_digest.c34
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry.c14
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_entry.h4
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_hmac.c29
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_hmac_private.h7
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_platform.h3
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c14
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c18
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_lzop.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_filter_xz.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c37
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c5
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c29
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c82
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c9
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c20
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c4
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_string.c6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write.c8
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c4
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c6
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_open.31
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c2
-rw-r--r--Utilities/cmlibarchive/libarchive/cpio.52
-rw-r--r--Utilities/cmlibarchive/libarchive/filter_fork_posix.c2
499 files changed, 9578 insertions, 1838 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index b26172d360..6a4140661b 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -664,6 +664,13 @@ t:intel2021.8.0-makefiles:
CMAKE_CI_BUILD_NAME: intel2021.8.0_makefiles
CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2023.0.0-el8
+t:intel2021.9.0-makefiles:
+ extends:
+ - .cmake_test_linux_intelclassic_makefiles
+ variables:
+ CMAKE_CI_BUILD_NAME: intel2021.9.0_makefiles
+ CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2023.1.0-el8
+
t:oneapi2021.1.1-makefiles:
extends:
- .cmake_test_linux_inteloneapi_makefiles
@@ -727,6 +734,13 @@ t:oneapi2023.0.0-makefiles:
CMAKE_CI_BUILD_NAME: oneapi2023.0.0_makefiles
CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2023.0.0-el8
+t:oneapi2023.1.0-makefiles:
+ extends:
+ - .cmake_test_linux_inteloneapi_makefiles
+ variables:
+ CMAKE_CI_BUILD_NAME: oneapi2023.1.0_makefiles
+ CMAKE_CI_INTELCOMPILER_IMAGE_TAG: 2023.1.0-el8
+
b:linux-x86_64-package:
extends:
- .linux_package
@@ -1164,6 +1178,36 @@ t:windows-clang16.0-gnu-nmake:
CMAKE_CI_BUILD_NAME: windows_clang16.0_gnu_nmake
CMAKE_CI_JOB_NIGHTLY: "true"
+t:windows-intel2021.9.0-ninja:
+ extends:
+ - .windows_intelclassic_ninja
+ - .cmake_test_windows_external
+ - .windows_x86_64_tags_concurrent
+ - .cmake_junit_artifacts
+ - .run_dependent
+ dependencies:
+ - t:windows-vs2022-x64-ninja
+ needs:
+ - t:windows-vs2022-x64-ninja
+ variables:
+ CMAKE_CI_BUILD_NAME: windows_intel2021.9.0_ninja
+ CMAKE_CI_JOB_NIGHTLY: "true"
+
+t:windows-oneapi2023.1.0-ninja:
+ extends:
+ - .windows_inteloneapi_ninja
+ - .cmake_test_windows_external
+ - .windows_x86_64_tags_concurrent
+ - .cmake_junit_artifacts
+ - .run_dependent
+ dependencies:
+ - t:windows-vs2022-x64-ninja
+ needs:
+ - t:windows-vs2022-x64-ninja
+ variables:
+ CMAKE_CI_BUILD_NAME: windows_oneapi2023.1.0_ninja
+ CMAKE_CI_JOB_NIGHTLY: "true"
+
t:mingw_osdn_io-mingw_makefiles:
extends:
- .mingw_osdn_io_mingw_makefiles
diff --git a/.gitlab/.gitignore b/.gitlab/.gitignore
index 10d03cacd4..852dfa64d8 100644
--- a/.gitlab/.gitignore
+++ b/.gitlab/.gitignore
@@ -2,7 +2,9 @@
/5.15.1-0-202009071110*
/bcc*
/cmake*
+/intel
/ispc*
+/innosetup
/jom
/llvm*
/mingw
diff --git a/.gitlab/ci/configure_windows_intelclassic_ninja.cmake b/.gitlab/ci/configure_windows_intelclassic_ninja.cmake
new file mode 100644
index 0000000000..c2d708baf3
--- /dev/null
+++ b/.gitlab/ci/configure_windows_intelclassic_ninja.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_intelcompiler_common.cmake")
diff --git a/.gitlab/ci/configure_windows_intelcompiler_common.cmake b/.gitlab/ci/configure_windows_intelcompiler_common.cmake
new file mode 100644
index 0000000000..55dce1d3ed
--- /dev/null
+++ b/.gitlab/ci/configure_windows_intelcompiler_common.cmake
@@ -0,0 +1,5 @@
+set(CMake_TEST_Java OFF CACHE BOOL "")
+
+set(configure_no_sccache 1)
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_windows_inteloneapi_ninja.cmake b/.gitlab/ci/configure_windows_inteloneapi_ninja.cmake
new file mode 100644
index 0000000000..c2d708baf3
--- /dev/null
+++ b/.gitlab/ci/configure_windows_inteloneapi_ninja.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_intelcompiler_common.cmake")
diff --git a/.gitlab/ci/configure_windows_vs2022_x64_ninja.cmake b/.gitlab/ci/configure_windows_vs2022_x64_ninja.cmake
index 5bf0be89e2..54abf722a4 100644
--- a/.gitlab/ci/configure_windows_vs2022_x64_ninja.cmake
+++ b/.gitlab/ci/configure_windows_vs2022_x64_ninja.cmake
@@ -1,4 +1,5 @@
if (NOT "$ENV{CMAKE_CI_NIGHTLY}" STREQUAL "")
+ set(CMake_TEST_CPACK_INNOSETUP "ON" CACHE STRING "")
set(CMake_TEST_ISPC "ON" CACHE STRING "")
endif()
set(CMake_TEST_TLS_VERIFY_URL "https://gitlab.kitware.com" CACHE STRING "")
diff --git a/.gitlab/ci/env_windows_intelclassic_ninja.ps1 b/.gitlab/ci/env_windows_intelclassic_ninja.ps1
new file mode 100755
index 0000000000..99f83b9cf1
--- /dev/null
+++ b/.gitlab/ci/env_windows_intelclassic_ninja.ps1
@@ -0,0 +1,9 @@
+. .gitlab/ci/ninja-env.ps1
+. .gitlab/ci/intel-env.ps1
+
+$env:CC = "icl"
+$env:CXX = "icl"
+$env:FC = "ifort"
+
+cmd /c "icl 2>&1" | Select -First 1
+cmd /c "ifort 2>&1" | Select -First 1
diff --git a/.gitlab/ci/env_windows_inteloneapi_ninja.ps1 b/.gitlab/ci/env_windows_inteloneapi_ninja.ps1
new file mode 100755
index 0000000000..3bd1d46b48
--- /dev/null
+++ b/.gitlab/ci/env_windows_inteloneapi_ninja.ps1
@@ -0,0 +1,9 @@
+. .gitlab/ci/ninja-env.ps1
+. .gitlab/ci/intel-env.ps1
+
+$env:CC = "icx"
+$env:CXX = "icx"
+$env:FC = "ifx"
+
+cmd /c "icx 2>&1" | Select -First 1
+cmd /c "ifx 2>&1" | Select -First 1
diff --git a/.gitlab/ci/env_windows_vs2022_x64_ninja.ps1 b/.gitlab/ci/env_windows_vs2022_x64_ninja.ps1
index a96658dd0f..50a03ca828 100755
--- a/.gitlab/ci/env_windows_vs2022_x64_ninja.ps1
+++ b/.gitlab/ci/env_windows_vs2022_x64_ninja.ps1
@@ -1,3 +1,4 @@
if ("$env:CMAKE_CI_NIGHTLY" -eq "true") {
+ . ".gitlab/ci/innosetup-env.ps1"
. ".gitlab/ci/ispc-env.ps1"
}
diff --git a/.gitlab/ci/innosetup-env.ps1 b/.gitlab/ci/innosetup-env.ps1
new file mode 100755
index 0000000000..96e9d8c322
--- /dev/null
+++ b/.gitlab/ci/innosetup-env.ps1
@@ -0,0 +1,4 @@
+$pwdpath = $pwd.Path
+& "$pwsh" -File ".gitlab/ci/innosetup.ps1"
+Set-Item -Force -Path "env:PATH" -Value "$pwdpath\.gitlab\innosetup;$env:PATH"
+ISCC 2>$null | Select -First 1
diff --git a/.gitlab/ci/innosetup.ps1 b/.gitlab/ci/innosetup.ps1
new file mode 100755
index 0000000000..a7f4eb31c3
--- /dev/null
+++ b/.gitlab/ci/innosetup.ps1
@@ -0,0 +1,20 @@
+$erroractionpreference = "stop"
+
+$version = "6.2.2-1"
+$sha256sum = "34D5311070678617424628A88C8A7F7BE41157B1A59112F9DFDA1D7EFD4469CC"
+$filename = "innosetup-$version"
+$tarball = "$filename.zip"
+
+$outdir = $pwd.Path
+$outdir = "$outdir\.gitlab"
+$ProgressPreference = 'SilentlyContinue'
+Invoke-WebRequest -Uri "https://cmake.org/files/dependencies/internal/$tarball" -OutFile "$outdir\$tarball"
+$hash = Get-FileHash "$outdir\$tarball" -Algorithm SHA256
+if ($hash.Hash -ne $sha256sum) {
+ exit 1
+}
+
+Add-Type -AssemblyName System.IO.Compression.FileSystem
+[System.IO.Compression.ZipFile]::ExtractToDirectory("$outdir\$tarball", "$outdir")
+Move-Item -Path "$outdir\$filename" -Destination "$outdir\innosetup"
+Remove-Item "$outdir\$tarball"
diff --git a/.gitlab/ci/intel-env.ps1 b/.gitlab/ci/intel-env.ps1
new file mode 100755
index 0000000000..75f7286381
--- /dev/null
+++ b/.gitlab/ci/intel-env.ps1
@@ -0,0 +1,4 @@
+$pwdpath = $pwd.Path
+& "$pwsh" -File ".gitlab/ci/intel.ps1"
+Invoke-Expression -Command .gitlab/ci/vcvarsall.ps1
+Invoke-Expression -Command .gitlab/ci/intel-vars.ps1
diff --git a/.gitlab/ci/intel-vars.ps1 b/.gitlab/ci/intel-vars.ps1
new file mode 100755
index 0000000000..dde0aa26ea
--- /dev/null
+++ b/.gitlab/ci/intel-vars.ps1
@@ -0,0 +1,9 @@
+$erroractionpreference = "stop"
+
+cmd /c "`".gitlab\intel\setvars.bat`" & set" |
+foreach {
+ if ($_ -match "=") {
+ $v = $_.split("=")
+ [Environment]::SetEnvironmentVariable($v[0], $v[1])
+ }
+}
diff --git a/.gitlab/ci/intel.ps1 b/.gitlab/ci/intel.ps1
new file mode 100755
index 0000000000..2262669d89
--- /dev/null
+++ b/.gitlab/ci/intel.ps1
@@ -0,0 +1,42 @@
+$erroractionpreference = "stop"
+
+if ("$env:CMAKE_CI_BUILD_NAME" -match "(^|_)(oneapi2023\.1\.0|intel2021\.9\.0)(_|$)") {
+ # Intel oneAPI 2023.1.0
+ $version = "2023.1.0"
+ $filename = "intel-oneapi-$version-windows-1"
+ $sha256sum = "5AFCA9E0B03894565209B1295476163ABEBB1F1388E0F3EF5B4D0F9189E65BDC"
+} else {
+ throw ('unknown CMAKE_CI_BUILD_NAME: ' + "$env:CMAKE_CI_BUILD_NAME")
+}
+$tarball = "$filename.zip"
+
+$outdir = $pwd.Path
+$outdir = "$outdir\.gitlab"
+$ProgressPreference = 'SilentlyContinue'
+# This URL is only visible inside of Kitware's network. See above filename table.
+Invoke-WebRequest -Uri "https://cmake.org/files/dependencies/internal/$tarball" -OutFile "$outdir\$tarball"
+$hash = Get-FileHash "$outdir\$tarball" -Algorithm SHA256
+if ($hash.Hash -ne $sha256sum) {
+ exit 1
+}
+
+Add-Type -AssemblyName System.IO.Compression.FileSystem
+[System.IO.Compression.ZipFile]::ExtractToDirectory("$outdir\$tarball", "$outdir")
+Move-Item -Path "$outdir\$filename" -Destination "$outdir\intel"
+Remove-Item "$outdir\$tarball"
+
+$compiler = "$outdir\intel\compiler"
+$bin = "$compiler\$version\windows\bin"
+$null = New-Item -ItemType Junction -Path "$compiler\latest" -Target "$compiler\$version"
+$null = New-Item -ItemType HardLink -Path "$bin\icx-cl.exe" -Target "$bin\icx.exe"
+$null = New-Item -ItemType HardLink -Path "$bin\icx-cc.exe" -Target "$bin\icx.exe"
+$null = New-Item -ItemType HardLink -Path "$bin\icpx.exe" -Target "$bin\icx.exe"
+$bin = "$compiler\$version\windows\bin-llvm"
+$null = New-Item -ItemType HardLink -Path "$bin\clang-cl.exe" -Target "$bin\clang.exe"
+$null = New-Item -ItemType HardLink -Path "$bin\clang-cpp.exe" -Target "$bin\clang.exe"
+$null = New-Item -ItemType HardLink -Path "$bin\clang++.exe" -Target "$bin\clang.exe"
+$null = New-Item -ItemType HardLink -Path "$bin\lld-link.exe" -Target "$bin\lld.exe"
+$null = New-Item -ItemType HardLink -Path "$bin\ld.lld.exe" -Target "$bin\lld.exe"
+$null = New-Item -ItemType HardLink -Path "$bin\llvm-lib.exe" -Target "$bin\llvm-ar.exe"
+Clear-Variable -Name bin
+Clear-Variable -Name compiler
diff --git a/.gitlab/os-windows.yml b/.gitlab/os-windows.yml
index f1e86ad3e5..07a479e045 100644
--- a/.gitlab/os-windows.yml
+++ b/.gitlab/os-windows.yml
@@ -222,6 +222,22 @@
variables:
CMAKE_CONFIGURATION: windows_msvc_v71_nmake
+.windows_intelclassic_ninja:
+ extends:
+ - .windows_ninja
+ - .windows_vcvarsall_vs2022_x64
+
+ variables:
+ CMAKE_CONFIGURATION: windows_intelclassic_ninja
+
+.windows_inteloneapi_ninja:
+ extends:
+ - .windows_ninja
+ - .windows_vcvarsall_vs2022_x64
+
+ variables:
+ CMAKE_CONFIGURATION: windows_inteloneapi_ninja
+
.windows_openwatcom:
extends: .windows
diff --git a/Auxiliary/cmake-mode.el b/Auxiliary/cmake-mode.el
index 7590ee3c1b..6bd23bf388 100644
--- a/Auxiliary/cmake-mode.el
+++ b/Auxiliary/cmake-mode.el
@@ -372,7 +372,7 @@ optional argument topic will be appended to the argument list."
(interactive "s")
(let* ((bufname (if buffer buffer (concat "*CMake" type (if topic "-") topic "*")))
(buffer (if (get-buffer bufname) (get-buffer bufname) (generate-new-buffer bufname)))
- (command (concat cmake-mode-cmake-executable " " type " " (shell-quote-argument topic)))
+ (command (concat cmake-mode-cmake-executable " " type " " (if topic (shell-quote-argument topic) topic)))
;; Turn of resizing of mini-windows for shell-command.
(resize-mini-windows nil)
)
@@ -391,7 +391,7 @@ optional argument topic will be appended to the argument list."
(interactive "s")
(let* ((bufname (if buffer buffer (concat "*CMake" type (if topic "-") topic "*")))
(buffer (if (get-buffer bufname) (get-buffer bufname) (generate-new-buffer bufname)))
- (command (concat cmake-mode-cmake-executable " " type " " (shell-quote-argument topic)))
+ (command (concat cmake-mode-cmake-executable " " type " " (if topic (shell-quote-argument topic) topic)))
;; Turn of resizing of mini-windows for shell-command.
(resize-mini-windows nil)
)
diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim
index d6b5b1946d..aefdcee281 100644
--- a/Auxiliary/vim/syntax/cmake.vim
+++ b/Auxiliary/vim/syntax/cmake.vim
@@ -73,6 +73,7 @@ syn keyword cmakeProperty contained
\ AUTOGEN_ORIGIN_DEPENDS
\ AUTOGEN_PARALLEL
\ AUTOGEN_SOURCE_GROUP
+ \ AUTOGEN_USE_SYSTEM_INCLUDE
\ AUTOGEN_TARGETS_FOLDER
\ AUTOGEN_TARGET_DEPENDS
\ AUTOMOC
@@ -683,6 +684,7 @@ syn keyword cmakeVariable contained
\ CMAKE_ASM_VISIBILITY_PRESET
\ CMAKE_AUTOGEN_ORIGIN_DEPENDS
\ CMAKE_AUTOGEN_PARALLEL
+ \ CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE
\ CMAKE_AUTOGEN_VERBOSE
\ CMAKE_AUTOMOC
\ CMAKE_AUTOMOC_COMPILER_PREDEFINES
@@ -2744,6 +2746,7 @@ syn keyword cmakeKWfile contained
\ READ_SYMLINK
\ REAL_PATH
\ REGEX
+ \ RELATIVE
\ RELATIVE_PATH
\ RELEASE
\ REMOVE
diff --git a/Help/command/FIND_XXX.txt b/Help/command/FIND_XXX.txt
index 21236fa427..fe26d2b9a5 100644
--- a/Help/command/FIND_XXX.txt
+++ b/Help/command/FIND_XXX.txt
@@ -132,6 +132,9 @@ If ``NO_DEFAULT_PATH`` is not specified, the search process is as follows:
.. |CMAKE_PREFIX_PATH_XXX_SUBDIR| replace::
|prefix_XXX_SUBDIR| for each ``<prefix>`` in :variable:`CMAKE_PREFIX_PATH`
+.. |ENV_CMAKE_PREFIX_PATH_XXX_SUBDIR| replace::
+ |prefix_XXX_SUBDIR| for each ``<prefix>`` in :envvar:`CMAKE_PREFIX_PATH`
+
.. |SYSTEM_ENVIRONMENT_PREFIX_PATH_XXX_SUBDIR| replace::
|prefix_XXX_SUBDIR| for each ``<prefix>/[s]bin`` in ``PATH``, and
|entry_XXX_SUBDIR| for other entries in ``PATH``
@@ -194,9 +197,9 @@ If ``NO_DEFAULT_PATH`` is not specified, the search process is as follows:
This can be skipped if ``NO_CMAKE_ENVIRONMENT_PATH`` is passed or
by setting the :variable:`CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH` to ``FALSE``.
- * |CMAKE_PREFIX_PATH_XXX|
- * |CMAKE_XXX_PATH|
- * |CMAKE_XXX_MAC_PATH|
+ * |ENV_CMAKE_PREFIX_PATH_XXX|
+ * |ENV_CMAKE_XXX_PATH|
+ * |ENV_CMAKE_XXX_MAC_PATH|
4. Search the paths specified by the ``HINTS`` option.
These should be paths computed by system introspection, such as a
diff --git a/Help/command/find_file.rst b/Help/command/find_file.rst
index c5c40149de..9f89f5251d 100644
--- a/Help/command/find_file.rst
+++ b/Help/command/find_file.rst
@@ -19,6 +19,13 @@ find_file
.. |CMAKE_XXX_PATH| replace:: :variable:`CMAKE_INCLUDE_PATH`
.. |CMAKE_XXX_MAC_PATH| replace:: :variable:`CMAKE_FRAMEWORK_PATH`
+.. |ENV_CMAKE_PREFIX_PATH_XXX| replace::
+ ``<prefix>/include/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE` is set,
+ and |ENV_CMAKE_PREFIX_PATH_XXX_SUBDIR|
+.. |ENV_CMAKE_XXX_PATH| replace:: :envvar:`CMAKE_INCLUDE_PATH`
+.. |ENV_CMAKE_XXX_MAC_PATH| replace:: :envvar:`CMAKE_FRAMEWORK_PATH`
+
+
.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: The directories in ``INCLUDE``
and ``PATH``.
.. |SYSTEM_ENVIRONMENT_PATH_WINDOWS_XXX| replace:: On Windows hosts:
diff --git a/Help/command/find_library.rst b/Help/command/find_library.rst
index c237e7f0d3..99e36a49b6 100644
--- a/Help/command/find_library.rst
+++ b/Help/command/find_library.rst
@@ -19,6 +19,12 @@ find_library
.. |CMAKE_XXX_PATH| replace:: :variable:`CMAKE_LIBRARY_PATH`
.. |CMAKE_XXX_MAC_PATH| replace:: :variable:`CMAKE_FRAMEWORK_PATH`
+.. |ENV_CMAKE_PREFIX_PATH_XXX| replace::
+ ``<prefix>/lib/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE` is set,
+ and |ENV_CMAKE_PREFIX_PATH_XXX_SUBDIR|
+.. |ENV_CMAKE_XXX_PATH| replace:: :envvar:`CMAKE_LIBRARY_PATH`
+.. |ENV_CMAKE_XXX_MAC_PATH| replace:: :envvar:`CMAKE_FRAMEWORK_PATH`
+
.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: The directories in ``LIB``
and ``PATH``.
.. |SYSTEM_ENVIRONMENT_PATH_WINDOWS_XXX| replace:: On Windows hosts:
diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst
index b82088eaa0..b0b6fe1112 100644
--- a/Help/command/find_package.rst
+++ b/Help/command/find_package.rst
@@ -418,8 +418,8 @@ enabled.
* ``<PackageName>_DIR``
* :envvar:`CMAKE_PREFIX_PATH`
- * ``CMAKE_FRAMEWORK_PATH``
- * ``CMAKE_APPBUNDLE_PATH``
+ * :envvar:`CMAKE_FRAMEWORK_PATH`
+ * :envvar:`CMAKE_APPBUNDLE_PATH`
4. Search paths specified by the ``HINTS`` option. These should be paths
computed by system introspection, such as a hint provided by the
diff --git a/Help/command/find_path.rst b/Help/command/find_path.rst
index 1d7648d05c..f0522f6430 100644
--- a/Help/command/find_path.rst
+++ b/Help/command/find_path.rst
@@ -19,6 +19,12 @@ find_path
.. |CMAKE_XXX_PATH| replace:: :variable:`CMAKE_INCLUDE_PATH`
.. |CMAKE_XXX_MAC_PATH| replace:: :variable:`CMAKE_FRAMEWORK_PATH`
+.. |ENV_CMAKE_PREFIX_PATH_XXX| replace::
+ ``<prefix>/include/<arch>`` if :variable:`CMAKE_LIBRARY_ARCHITECTURE` is set,
+ and |ENV_CMAKE_PREFIX_PATH_XXX_SUBDIR|
+.. |ENV_CMAKE_XXX_PATH| replace:: :envvar:`CMAKE_INCLUDE_PATH`
+.. |ENV_CMAKE_XXX_MAC_PATH| replace:: :envvar:`CMAKE_FRAMEWORK_PATH`
+
.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: The directories in ``INCLUDE``
and ``PATH``.
.. |SYSTEM_ENVIRONMENT_PATH_WINDOWS_XXX| replace:: On Windows hosts:
diff --git a/Help/command/find_program.rst b/Help/command/find_program.rst
index f4149be5ad..fe95a9a300 100644
--- a/Help/command/find_program.rst
+++ b/Help/command/find_program.rst
@@ -17,6 +17,11 @@ find_program
.. |CMAKE_XXX_PATH| replace:: :variable:`CMAKE_PROGRAM_PATH`
.. |CMAKE_XXX_MAC_PATH| replace:: :variable:`CMAKE_APPBUNDLE_PATH`
+.. |ENV_CMAKE_PREFIX_PATH_XXX| replace::
+ |ENV_CMAKE_PREFIX_PATH_XXX_SUBDIR|
+.. |ENV_CMAKE_XXX_PATH| replace:: :envvar:`CMAKE_PROGRAM_PATH`
+.. |ENV_CMAKE_XXX_MAC_PATH| replace:: :envvar:`CMAKE_APPBUNDLE_PATH`
+
.. |SYSTEM_ENVIRONMENT_PATH_XXX| replace:: The directories in ``PATH`` itself.
.. |SYSTEM_ENVIRONMENT_PATH_WINDOWS_XXX| replace:: On Windows hosts no extra search paths are included
diff --git a/Help/command/list.rst b/Help/command/list.rst
index 191003a700..0c7a562872 100644
--- a/Help/command/list.rst
+++ b/Help/command/list.rst
@@ -188,7 +188,7 @@ For more information on regular expressions look under
.. versionadded:: 3.12
- Transforms the list by applying an action to all or, by specifying a
+ Transforms the list by applying an ``<ACTION>`` to all or, by specifying a
``<SELECTOR>``, to the selected elements of the list, storing the result
in-place or in the specified output variable.
@@ -205,42 +205,42 @@ For more information on regular expressions look under
:command:`APPEND <string(APPEND)>`, :command:`PREPEND <string(PREPEND)>`
Append, prepend specified value to each element of the list.
- .. code-block:: cmake
-
- list(TRANSFORM <list> <APPEND|PREPEND> <value> ...)
+ .. signature::
+ list(TRANSFORM <list> (APPEND|PREPEND) <value> ...)
+ :target: TRANSFORM_APPEND
- :command:`TOUPPER <string(TOUPPER)>`, :command:`TOLOWER <string(TOLOWER)>`
- Convert each element of the list to upper, lower characters.
+ :command:`TOLOWER <string(TOLOWER)>`, :command:`TOUPPER <string(TOUPPER)>`
+ Convert each element of the list to lower, upper characters.
- .. code-block:: cmake
-
- list(TRANSFORM <list> <TOLOWER|TOUPPER> ...)
+ .. signature::
+ list(TRANSFORM <list> (TOLOWER|TOUPPER) ...)
+ :target: TRANSFORM_TOLOWER
:command:`STRIP <string(STRIP)>`
Remove leading and trailing spaces from each element of the list.
- .. code-block:: cmake
-
+ .. signature::
list(TRANSFORM <list> STRIP ...)
+ :target: TRANSFORM_STRIP
:command:`GENEX_STRIP <string(GENEX_STRIP)>`
Strip any
:manual:`generator expressions <cmake-generator-expressions(7)>`
from each element of the list.
- .. code-block:: cmake
-
+ .. signature::
list(TRANSFORM <list> GENEX_STRIP ...)
+ :target: TRANSFORM_GENEX_STRIP
:command:`REPLACE <string(REGEX REPLACE)>`:
Match the regular expression as many times as possible and substitute
the replacement expression for the match for each element of the list
(same semantic as :command:`string(REGEX REPLACE)`).
- .. code-block:: cmake
-
+ .. signature::
list(TRANSFORM <list> REPLACE <regular_expression>
<replace_expression> ...)
+ :target: TRANSFORM_REPLACE
``<SELECTOR>`` determines which elements of the list will be transformed.
Only one type of selector can be specified at a time.
diff --git a/Help/command/string.rst b/Help/command/string.rst
index e226aa1a48..0e69b27ebc 100644
--- a/Help/command/string.rst
+++ b/Help/command/string.rst
@@ -576,6 +576,9 @@ Functionality for querying a JSON string.
Set an element in ``<json-string>`` at the location
given by the list of ``<member|index>`` arguments to ``<value>``.
The contents of ``<value>`` should be valid JSON.
+ If ``<json-string>`` is an array, ``<value>`` can be appended to the end of
+ the array by using a number greater or equal to the array length as the
+ ``<member|index>`` argument.
.. signature::
string(JSON <out-var> [ERROR_VARIABLE <error-var>]
diff --git a/Help/cpack_gen/innosetup.rst b/Help/cpack_gen/innosetup.rst
new file mode 100644
index 0000000000..f48e7f56c6
--- /dev/null
+++ b/Help/cpack_gen/innosetup.rst
@@ -0,0 +1,420 @@
+CPack Inno Setup Generator
+--------------------------
+
+.. versionadded:: 3.27
+
+Inno Setup is a free installer for Windows programs by Jordan Russell and
+Martijn Laan (https://jrsoftware.org/isinfo.php).
+
+This documentation explains Inno Setup generator specific options.
+
+The generator provides a lot of options like components. Unfortunately, not
+all features (e.g. component dependencies) are currently supported by
+Inno Setup and they're ignored by the generator for now.
+
+CPack requires Inno Setup 6 or greater and only works on Windows.
+
+Variables specific to CPack Inno Setup generator
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+You can use the following variables to change the behavior of the CPack
+``INNOSETUP`` generator:
+
+
+General
+"""""""
+
+None of the following variables is required to be set for the Inno Setup
+generator to work. If a variable is marked as mandatory below but not set,
+its default value is taken.
+
+The variables can also contain Inno Setup constants like ``{app}``. Please
+refer to the documentation of Inno Setup for more information.
+
+If you're asked to provide the path to any file, you can always give an
+absolute path or in most cases the relative path from the top-level directory
+where all files being installed by an :command:`install` instruction reside.
+
+CPack tries to escape quotes and other special characters for you. However,
+using special characters could cause problems.
+
+The following variable simplifies the usage of Inno Setup in CMake:
+
+.. variable:: CPACK_INNOSETUP_USE_CMAKE_BOOL_FORMAT
+
+ Inno Setup only uses ``yes`` or ``no`` as boolean formats meanwhile CMake
+ uses a lot of alternative formats like ``ON`` or ``OFF``. Having this option
+ turned on enables an automatic conversion.
+
+ Consider the following example:
+
+ .. code-block:: cmake
+
+ set(CMAKE_INNOSETUP_SETUP_AllowNoIcons OFF)
+
+ If this option is turned on, the following line will be created in the output
+ script: ``AllowNoIcons=no``.
+ Else, the following erroneous line will be created: ``AllowNoIcons=OFF``
+
+ The conversion is enabled in every Inno Setup specific variable.
+
+ :Mandatory: Yes
+ :Default: ``ON``
+
+
+Setup Specific Variables
+""""""""""""""""""""""""
+
+.. variable:: CPACK_INNOSETUP_ARCHITECTURE
+
+ One of ``x86``, ``x64``, ``arm64`` or ``ia64``. This variable specifies the
+ target architecture of the installer. This also affects the Program Files
+ folder or registry keys being used.
+
+ CPack tries to determine the correct value with a try compile (see
+ :variable:`CMAKE_SIZEOF_VOID_P`), but this option can be manually specified
+ too (especially when using ``ia64`` or cross-platform compilation).
+
+ :Mandatory: Yes
+ :Default: Either ``x86`` or ``x64`` depending on the results of the try-compile
+
+.. variable:: CPACK_INNOSETUP_INSTALL_ROOT
+
+ If you don't want the installer to create the installation directory under
+ Program Files, you've to specify the installation root here.
+
+ The full directory of the installation will be:
+ ``${CPACK_INNOSETUP_INSTALL_ROOT}/${CPACK_PACKAGE_INSTALL_DIRECTORY}``.
+
+ :Mandatory: Yes
+ :Default: ``{autopf}``
+
+.. variable:: CPACK_INNOSETUP_ALLOW_CUSTOM_DIRECTORY
+
+ If turned on, the installer allows the user to change the installation
+ directory providing an extra wizard page.
+
+ :Mandatory: Yes
+ :Default: ``ON``
+
+.. variable:: CPACK_INNOSETUP_PROGRAM_MENU_FOLDER
+
+ The initial name of the start menu folder being created.
+
+ If this variable is set to ``.``, then no separate folder is created,
+ application shortcuts will appear in the top-level start menu folder.
+
+ :Mandatory: Yes
+ :Default: The value of :variable:`CPACK_PACKAGE_NAME`
+
+.. variable:: CPACK_INNOSETUP_LANGUAGES
+
+ A :ref:`semicolon-separated list <CMake Language Lists>` of languages you want
+ Inno Setup to include.
+
+ Currently available: ``armenian``, ``brazilianPortuguese``, ``bulgarian``,
+ ``catalan``, ``corsican``, ``czech``, ``danish``, ``dutch``, ``english``,
+ ``finnish``, ``french``, ``german``, ``hebrew``, ``icelandic``, ``italian``,
+ ``japanese``, ``norwegian``, ``polish``, ``portuguese``, ``russian``,
+ ``slovak``, ``slovenian``, ``spanish``, ``turkish`` and ``ukrainian``.
+ This list might differ depending on the version of Inno Setup.
+
+ :Mandatory: Yes
+ :Default: ``english``
+
+.. variable:: CPACK_INNOSETUP_IGNORE_LICENSE_PAGE
+
+ If you don't specify a license file using
+ :variable:`CPACK_RESOURCE_FILE_LICENSE`, CPack uses a file for demonstration
+ purposes. If you want the installer to ignore license files at all, you can
+ enable this option.
+
+ :Mandatory: Yes
+ :Default: ``OFF``
+
+.. variable:: CPACK_INNOSETUP_IGNORE_README_PAGE
+
+ If you don't specify a readme file using
+ :variable:`CPACK_RESOURCE_FILE_README`, CPack uses a file for demonstration
+ purposes. If you want the installer to ignore readme files at all, you can
+ enable this option. Make sure the option is disabled when using
+ a custom readme file.
+
+ :Mandatory: Yes
+ :Default: ``ON``
+
+.. variable:: CPACK_INNOSETUP_PASSWORD
+
+ Enables password protection and file encryption with the given password.
+
+ :Mandatory: No
+
+.. variable:: CPACK_INNOSETUP_USE_MODERN_WIZARD
+
+ Enables the modern look and feel provided by Inno Setup. If this option is
+ turned off, the classic style is used instead. Images and icon files are
+ also affected.
+
+ :Mandatory: Yes
+ :Default: ``OFF`` because of compatibility reasons
+
+.. variable:: CPACK_INNOSETUP_ICON_FILE
+
+ The path to a custom installer ``.ico`` file.
+
+ Use :variable:`CPACK_PACKAGE_ICON` to customize the bitmap file being shown
+ in the wizard.
+
+ :Mandatory: No
+
+.. variable:: CPACK_INNOSETUP_SETUP_<directive>
+
+ This group allows adapting any of the ``[Setup]`` section directives provided
+ by Inno Setup where ``directive`` is its name.
+
+ Here are some examples:
+
+ .. code-block:: cmake
+
+ set(CPACK_INNOSETUP_SETUP_WizardSmallImageFile "my_bitmap.bmp")
+ set(CPACK_INNOSETUP_SETUP_AllowNoIcons OFF) # This requires CPACK_INNOSETUP_USE_CMAKE_BOOL_FORMAT to be on
+
+ All of these variables have higher priority than the others.
+ Consider the following example:
+
+ .. code-block:: cmake
+
+ set(CPACK_INNOSETUP_SETUP_Password "admin")
+ set(CPACK_INNOSETUP_PASSWORD "secret")
+
+ The password will be ``admin`` at the end because ``CPACK_INNOSETUP_PASSWORD``
+ has less priority than ``CPACK_INNOSETUP_SETUP_Password``.
+
+ :Mandatory: No
+
+
+File Specific Variables
+"""""""""""""""""""""""
+
+Although all files being installed by an :command:`install` instruction are
+automatically processed and added to the installer, there are some variables
+to customize the installation process.
+
+Before using executables (only ``.exe`` or ``.com``) in shortcuts
+(e.g. :variable:`CPACK_CREATE_DESKTOP_LINKS`) or ``[Run]`` entries, you've to
+add the raw file name (without path and extension) to
+:variable:`CPACK_PACKAGE_EXECUTABLES` and create a start menu shortcut
+for them.
+
+If you have two files with the same raw name (e.g. ``a/executable.exe`` and
+``b/executable.com``), an entry in the section is created twice. This will
+result in undefined behavior and is not recommended.
+
+.. variable:: CPACK_INNOSETUP_CUSTOM_INSTALL_INSTRUCTIONS
+
+ This variable should contain a
+ :ref:`semicolon-separated list <CMake Language Lists>` of pairs ``path``,
+ ``instruction`` and can be used to customize the install command being
+ automatically created for each file or directory.
+
+ CPack creates the following Inno Setup instruction for every file...
+
+ .. code-block::
+
+ Source: "absolute\path\to\my_file.txt"; DestDir: "{app}"; Flags: ignoreversion
+
+ ...and the following line for every directory:
+
+ .. code-block::
+
+ Name: "{app}\my_folder"
+
+ You might want to change the destination directory or the flags of
+ ``my_file.txt``. Since we can also provide a relative path, the line you'd
+ like to have, is the following:
+
+ .. code-block::
+
+ Source: "my_file.txt"; DestDir: "{userdocs}"; Flags: ignoreversion uninsneveruninstall
+
+ You would do this by using ``my_file.txt`` as ``path`` and
+ ``Source: "my_file.txt"; DestDir: "{userdocs}"; Flags: ignoreversion uninsneveruninstall``
+ as ``instruction``.
+
+ You've to take care of the `escaping problem <https://cmake.org/cmake/help/book/mastering-cmake/chapter/Packaging%20With%20CPack.html#adding-custom-cpack-options>`_.
+ So the CMake command would be:
+
+ .. code-block:: cmake
+
+ set(CPACK_INNOSETUP_CUSTOM_INSTALL_INSTRUCTIONS "my_file.txt;Source: \\\"my_file.txt\\\"\\; DestDir: \\\"{userdocs}\\\"\\; Flags: ignoreversion uninsneveruninstall")
+
+ To improve readability, you should go around the escaping problem by using
+ :variable:`CPACK_VERBATIM_VARIABLES` or by placing the instruction into a
+ separate CPack project config file.
+
+ If you customize the install instruction of a specific file, you lose the
+ connection to its component. To go around, manually add
+ ``Components: <component>``. You also need to add its shortcuts and ``[Run]``
+ entries by yourself in a custom section, since the executable won't be found
+ anymore by :variable:`CPACK_PACKAGE_EXECUTABLES`.
+
+ Here's another example (Note: You've to go around the escaping problem for
+ the example to work):
+
+ .. code-block:: cmake
+
+ set(CPACK_INNOSETUP_CUSTOM_INSTALL_INSTRUCTIONS
+ "component1/my_folder" "Name: \"{userdocs}\\my_folder\"\; Components: component1"
+ "component2/my_folder2/my_file.txt" "Source: \"component2\\my_folder2\\my_file.txt\"\; DestDir: \"{app}\\my_folder2\\my_file.txt\"\; Flags: ignoreversion uninsneveruninstall\; Components: component2")
+
+ :Mandatory: No
+
+.. variable:: CPACK_INNOSETUP_MENU_LINKS
+
+ This variable should contain a
+ :ref:`semicolon-separated list <CMake Language Lists>` of pairs ``link``,
+ ``link name`` and can be used to add shortcuts into the start menu folder
+ beside those of the executables (see :variable:`CPACK_PACKAGE_EXECUTABLES`).
+ While ``link name`` is the label, ``link`` can be a URL or a path relative to
+ the installation directory.
+
+ Here's an example:
+
+ .. code-block:: cmake
+
+ set(CPACK_INNOSETUP_MENU_LINKS
+ "doc/cmake-@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@/cmake.html"
+ "CMake Help" "https://cmake.org" "CMake Web Site")
+
+ :Mandatory: No
+
+.. variable:: CPACK_INNOSETUP_CREATE_UNINSTALL_LINK
+
+ If this option is turned on, a shortcut to the application's uninstaller is
+ automatically added to the start menu folder.
+
+ :Mandatory: Yes
+ :Default: ``OFF``
+
+.. variable:: CPACK_INNOSETUP_RUN_EXECUTABLES
+
+ A :ref:`semicolon-separated list <CMake Language Lists>` of executables being
+ specified in :variable:`CPACK_PACKAGE_EXECUTABLES` which the user can run
+ when the installer finishes.
+
+ They're internally added to the ``[Run]`` section.
+
+ :Mandatory: No
+
+
+Components Specific Variables
+"""""""""""""""""""""""""""""
+
+The generator supports components and also downloaded components. However,
+there are some features of components that aren't supported yet (especially
+component dependencies). These variables are ignored for now.
+
+CPack will change a component's name in Inno Setup if it has a parent group
+for technical reasons. Consider using ``group\component`` as component name in
+Inno Setup scripts if you have the component ``component`` and its parent
+group ``group``.
+
+Here are some additional variables for components:
+
+.. variable:: CPACK_INNOSETUP_<compName>_INSTALL_DIRECTORY
+
+ If you don't want the component ``compName`` to be installed under ``{app}``,
+ you've to specify its installation directory here.
+
+ :Mandatory: No
+
+.. variable:: CPACK_INNOSETUP_VERIFY_DOWNLOADS
+
+ This option only affects downloaded components.
+
+ If this option is turned on, the hashes of the downloaded archives are
+ calculated during compile and
+ download time. The installer will only proceed if they match.
+
+ :Mandatory: Yes
+ :Default: ``ON``
+
+
+Compilation and Scripting Specific Variables
+""""""""""""""""""""""""""""""""""""""""""""
+
+.. variable:: CPACK_INNOSETUP_EXECUTABLE
+
+ The filename of the Inno Setup Script Compiler command.
+
+ :Mandatory: Yes
+ :Default: ``ISCC``
+
+.. variable:: CPACK_INNOSETUP_EXECUTABLE_ARGUMENTS
+
+ A :ref:`semicolon-separated list <CMake Language Lists>` of extra
+ command-line options for the Inno Setup Script Compiler command.
+
+ For example: ``/Qp;/Smysigntool=$p``
+
+ Take care of the `escaping problem <https://cmake.org/cmake/help/book/mastering-cmake/chapter/Packaging%20With%20CPack.html#adding-custom-cpack-options>`_.
+
+ :Mandatory: No
+
+.. variable:: CPACK_INNOSETUP_DEFINE_<macro>
+
+ This group allows to add custom define directives as command-line options to
+ the Inno Setup Preprocessor command. Each entry emulates a
+ ``#define public <macro>`` directive. Its macro is accessible from anywhere
+ (``public``), so it can also be used in extra script files.
+
+ Macro names must not contain any special characters. Refer to the Inno Setup
+ Preprocessor documentation for the detailed rules.
+
+ Consider the following example:
+
+ .. code-block:: cmake
+
+ # The following line emulates: #define public MyMacro "Hello, World!"
+ set(CPACK_INNOSETUP_DEFINE_MyMacro "Hello, World!")
+
+ At this point, you can use ``MyMacro`` anywhere. For example in the following
+ extra script:
+
+ .. code-block::
+
+ AppComments={#emit "'My Macro' has the value: " + MyMacro}
+
+ Take care of the `escaping problem <https://cmake.org/cmake/help/book/mastering-cmake/chapter/Packaging%20With%20CPack.html#adding-custom-cpack-options>`_.
+
+ :Mandatory: No
+
+.. variable:: CPACK_INNOSETUP_EXTRA_SCRIPTS
+
+ A :ref:`semicolon-separated list <CMake Language Lists>` of paths to
+ additional ``.iss`` script files to be processed.
+
+ They're internally included at the top of the output script file using a
+ ``#include`` directive.
+
+ You can add any section in your file to extend the installer (e.g. adding
+ additional tasks or registry keys). Prefer using
+ :variable:`CPACK_INNOSETUP_SETUP_<directive>` when extending the
+ ``[Setup]`` section.
+
+ :Mandatory: No
+
+.. variable:: CPACK_INNOSETUP_CODE_FILES
+
+ A :ref:`semicolon-separated list <CMake Language Lists>` of paths to
+ additional Pascal files to be processed.
+
+ This variable is actually the same as
+ :variable:`CPACK_INNOSETUP_EXTRA_SCRIPTS`, except you don't have to
+ add ``[Code]`` at the top of your file. Never change the current section in
+ a code file. This will result in undefined behavior! Treat them as normal
+ Pascal scripts instead.
+
+ Code files are included at the very bottom of the output script.
+
+ :Mandatory: No
diff --git a/Help/envvar/CMAKE_APPBUNDLE_PATH.rst b/Help/envvar/CMAKE_APPBUNDLE_PATH.rst
new file mode 100644
index 0000000000..d80e08dcf7
--- /dev/null
+++ b/Help/envvar/CMAKE_APPBUNDLE_PATH.rst
@@ -0,0 +1,14 @@
+CMAKE_APPBUNDLE_PATH
+--------------------
+
+.. include:: ENV_VAR.txt
+
+The ``CMAKE_APPBUNDLE_PATH`` environment variable may be set to a list of
+directories to be searched for macOS application bundles
+by the :command:`find_program` and :command:`find_package` commands.
+
+This variable may hold a single directory or a list of directories separated
+by ``:`` on UNIX or ``;`` on Windows (the same as the ``PATH`` environment
+variable convention on those platforms).
+
+See also the :variable:`CMAKE_APPBUNDLE_PATH` CMake variable.
diff --git a/Help/envvar/CMAKE_FRAMEWORK_PATH.rst b/Help/envvar/CMAKE_FRAMEWORK_PATH.rst
new file mode 100644
index 0000000000..f543132dbc
--- /dev/null
+++ b/Help/envvar/CMAKE_FRAMEWORK_PATH.rst
@@ -0,0 +1,15 @@
+CMAKE_FRAMEWORK_PATH
+--------------------
+
+.. include:: ENV_VAR.txt
+
+The ``CMAKE_FRAMEWORK_PATH`` environment variable may be set to a list of
+directories to be searched for macOS frameworks by the :command:`find_library`,
+:command:`find_package`, :command:`find_path` and :command:`find_file` commands.
+
+
+This variable may hold a single directory or a list of directories separated
+by ``:`` on UNIX or ``;`` on Windows (the same as the ``PATH`` environment
+variable convention on those platforms).
+
+See also the :variable:`CMAKE_FRAMEWORK_PATH` CMake variable.
diff --git a/Help/envvar/CMAKE_INCLUDE_PATH.rst b/Help/envvar/CMAKE_INCLUDE_PATH.rst
new file mode 100644
index 0000000000..a42460d9d6
--- /dev/null
+++ b/Help/envvar/CMAKE_INCLUDE_PATH.rst
@@ -0,0 +1,13 @@
+CMAKE_INCLUDE_PATH
+------------------
+
+.. include:: ENV_VAR.txt
+
+The ``CMAKE_INCLUDE_PATH`` environment variable may be set to a list of
+directories to be searched by the :command:`find_file` and :command:`find_path` commands.
+
+This variable may hold a single directory or a list of directories separated
+by ``:`` on UNIX or ``;`` on Windows (the same as the ``PATH`` environment
+variable convention on those platforms).
+
+See also the :variable:`CMAKE_INCLUDE_PATH` CMake variable.
diff --git a/Help/envvar/CMAKE_LIBRARY_PATH.rst b/Help/envvar/CMAKE_LIBRARY_PATH.rst
new file mode 100644
index 0000000000..a51100d2ea
--- /dev/null
+++ b/Help/envvar/CMAKE_LIBRARY_PATH.rst
@@ -0,0 +1,13 @@
+CMAKE_LIBRARY_PATH
+------------------
+
+.. include:: ENV_VAR.txt
+
+The ``CMAKE_LIBRARY_PATH`` environment variable may be set to a list of
+directories to be searched by the :command:`find_library` command.
+
+This variable may hold a single directory or a list of directories separated
+by ``:`` on UNIX or ``;`` on Windows (the same as the ``PATH`` environment
+variable convention on those platforms).
+
+See also the :variable:`CMAKE_LIBRARY_PATH` CMake variable.
diff --git a/Help/envvar/CMAKE_PROGRAM_PATH.rst b/Help/envvar/CMAKE_PROGRAM_PATH.rst
new file mode 100644
index 0000000000..bfc7a306ce
--- /dev/null
+++ b/Help/envvar/CMAKE_PROGRAM_PATH.rst
@@ -0,0 +1,13 @@
+CMAKE_PROGRAM_PATH
+------------------
+
+.. include:: ENV_VAR.txt
+
+The ``CMAKE_PROGRAM_PATH`` environment variable may be set to a list of
+directories to be searched by the :command:`find_program` command.
+
+This variable may hold a single directory or a list of directories separated
+by ``:`` on UNIX or ``;`` on Windows (the same as the ``PATH`` environment
+variable convention on those platforms).
+
+See also the :variable:`CMAKE_PROGRAM_PATH` CMake variable.
diff --git a/Help/guide/tutorial/Adding Generator Expressions.rst b/Help/guide/tutorial/Adding Generator Expressions.rst
index aba9f7ad4d..3dab97ff04 100644
--- a/Help/guide/tutorial/Adding Generator Expressions.rst
+++ b/Help/guide/tutorial/Adding Generator Expressions.rst
@@ -27,168 +27,7 @@ expressions are the ``0`` and ``1`` expressions. A ``$<0:...>`` results in the
empty string, and ``<1:...>`` results in the content of ``...``. They can also
be nested.
-Exercise 1 - Setting the C++ Standard with Interface Libraries
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Before we use :manual:`generator expressions <cmake-generator-expressions(7)>`
-let's refactor our existing code to use an ``INTERFACE`` library. We will
-use that library in the next step to demonstrate a common use for
-:manual:`generator expressions <cmake-generator-expressions(7)>`.
-
-Goal
-----
-
-Add an ``INTERFACE`` library target to specify the required C++ standard.
-
-Helpful Resources
------------------
-
-* :command:`add_library`
-* :command:`target_compile_features`
-* :command:`target_link_libraries`
-
-Files to Edit
--------------
-
-* ``CMakeLists.txt``
-* ``MathFunctions/CMakeLists.txt``
-
-Getting Started
----------------
-
-In this exercise, we will refactor our code to use an ``INTERFACE`` library to
-specify the C++ standard.
-
-The starting source code is provided in the ``Step4`` directory. In this
-exercise, complete ``TODO 1`` through ``TODO 3``.
-
-Start by editing the top level ``CMakeLists.txt`` file. Construct an
-``INTERFACE`` library target called ``tutorial_compiler_flags`` and
-specify ``cxx_std_11`` as a target compiler feature.
-
-Modify ``CMakeLists.txt`` and ``MathFunctions/CMakeLists.txt`` so that all
-targets have a :command:`target_link_libraries` call to
-``tutorial_compiler_flags``.
-
-Build and Run
--------------
-
-Make a new directory called ``Step4_build``, run the :manual:`cmake <cmake(1)>`
-executable or the :manual:`cmake-gui <cmake-gui(1)>` to configure the project
-and then build it with your chosen build tool or by using ``cmake --build .``
-from the build directory.
-
-Here's a refresher of what that looks like from the command line:
-
-.. code-block:: console
-
- mkdir Step4_build
- cd Step4_build
- cmake ../Step4
- cmake --build .
-
-Next, use the newly built ``Tutorial`` and verify that it is working as
-expected.
-
-Solution
---------
-
-Let's update our code from the previous step to use interface libraries
-to set our C++ requirements.
-
-To start, we need to remove the two :command:`set` calls on the variables
-:variable:`CMAKE_CXX_STANDARD` and :variable:`CMAKE_CXX_STANDARD_REQUIRED`.
-The specific lines to remove are as follows:
-
-.. literalinclude:: Step4/CMakeLists.txt
- :caption: CMakeLists.txt
- :name: CMakeLists.txt-CXX_STANDARD-variable-remove
- :language: cmake
- :start-after: # specify the C++ standard
- :end-before: # TODO 6: Create helper variables
-
-Next, we need to create an interface library, ``tutorial_compiler_flags``. And
-then use :command:`target_compile_features` to add the compiler feature
-``cxx_std_11``.
-
-
-.. raw:: html
-
- <details><summary>TODO 1: Click to show/hide answer</summary>
-
-.. literalinclude:: Step5/CMakeLists.txt
- :caption: TODO 1: CMakeLists.txt
- :name: CMakeLists.txt-cxx_std-feature
- :language: cmake
- :start-after: # specify the C++ standard
- :end-before: # add compiler warning flags just
-
-.. raw:: html
-
- </details>
-
-Finally, with our interface library set up, we need to link our
-executable ``Target``, our ``MathFunctions`` library, and our ``SqrtLibrary``
-library to our new
-``tutorial_compiler_flags`` library. Respectively, the code will look like
-this:
-
-.. raw:: html
-
- <details><summary>TODO 2: Click to show/hide answer</summary>
-
-.. literalinclude:: Step5/CMakeLists.txt
- :caption: TODO 2: CMakeLists.txt
- :name: CMakeLists.txt-target_link_libraries-step4
- :language: cmake
- :start-after: add_executable(Tutorial tutorial.cxx)
- :end-before: # add the binary tree to the search path for include file
-
-.. raw:: html
-
- </details>
-
-this:
-
-.. raw:: html
-
- <details><summary>TODO 3: Click to show/hide answer</summary>
-
-.. literalinclude:: Step5/MathFunctions/CMakeLists.txt
- :caption: TODO 3: MathFunctions/CMakeLists.txt
- :name: MathFunctions-CMakeLists.txt-target_link_libraries-step4
- :language: cmake
- :start-after: # link our compiler flags interface library
- :end-before: target_link_libraries(MathFunctions
-
-.. raw:: html
-
- </details>
-
-and this:
-
-.. raw:: html
-
- <details><summary>TODO 4: Click to show/hide answer</summary>
-
-.. literalinclude:: Step5/MathFunctions/CMakeLists.txt
- :caption: TODO 4: MathFunctions/CMakeLists.txt
- :name: MathFunctions-SqrtLibrary-target_link_libraries-step4
- :language: cmake
- :start-after: target_link_libraries(SqrtLibrary
- :end-before: endif()
-
-.. raw:: html
-
- </details>
-
-
-With this, all of our code still requires C++ 11 to build. Notice
-though that with this method, it gives us the ability to be specific about
-which targets get specific requirements. In addition, we create a single
-source of truth in our interface library.
-
-Exercise 2 - Adding Compiler Warning Flags with Generator Expressions
+Exercise 1 - Adding Compiler Warning Flags with Generator Expressions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A common usage of
@@ -218,8 +57,8 @@ Files to Edit
Getting Started
---------------
-Start with the resulting files from Exercise 1. Complete ``TODO 5`` through
-``TODO 8``.
+Open the file ``Step4/CMakeLists.txt`` and complete ``TODO 1`` through
+``TODO 4``.
First, in the top level ``CMakeLists.txt`` file, we need to set the
:command:`cmake_minimum_required` to ``3.15``. In this exercise we are going
@@ -233,12 +72,16 @@ given a language and a set of compiler ids.
Build and Run
-------------
-Since we have our build directory already configured from Exercise 1, simply
-rebuild our code by calling the following:
+Make a new directory called ``Step4_build``, run the :manual:`cmake <cmake(1)>`
+executable or the :manual:`cmake-gui <cmake-gui(1)>` to configure the project
+and then build it with your chosen build tool or by using ``cmake --build .``
+from the build directory.
.. code-block:: console
+ mkdir Step4_build
cd Step4_build
+ cmake ../Step4
cmake --build .
Solution
@@ -249,10 +92,10 @@ version ``3.15``:
.. raw:: html
- <details><summary>TODO 5: Click to show/hide answer</summary>
+ <details><summary>TODO 1: Click to show/hide answer</summary>
.. literalinclude:: Step5/CMakeLists.txt
- :caption: TODO 5: CMakeLists.txt
+ :caption: TODO 1: CMakeLists.txt
:name: MathFunctions-CMakeLists.txt-minimum-required-step4
:language: cmake
:end-before: # set the project name and version
@@ -268,10 +111,10 @@ variables ``gcc_like_cxx`` and ``msvc_cxx`` as follows:
.. raw:: html
- <details><summary>TODO 6: Click to show/hide answer</summary>
+ <details><summary>TODO 2: Click to show/hide answer</summary>
.. literalinclude:: Step5/CMakeLists.txt
- :caption: TODO 6: CMakeLists.txt
+ :caption: TODO 2: CMakeLists.txt
:name: CMakeLists.txt-compile_lang_and_id
:language: cmake
:start-after: # the BUILD_INTERFACE genex
@@ -289,10 +132,10 @@ interface library.
.. raw:: html
- <details><summary>TODO 7: Click to show/hide answer</summary>
+ <details><summary>TODO 3: Click to show/hide answer</summary>
.. code-block:: cmake
- :caption: TODO 7: CMakeLists.txt
+ :caption: TODO 3: CMakeLists.txt
:name: CMakeLists.txt-compile_flags
target_compile_options(tutorial_compiler_flags INTERFACE
@@ -311,10 +154,10 @@ condition. The resulting full code looks like the following:
.. raw:: html
- <details><summary>TODO 8: Click to show/hide answer</summary>
+ <details><summary>TODO 4: Click to show/hide answer</summary>
.. literalinclude:: Step5/CMakeLists.txt
- :caption: TODO 8: CMakeLists.txt
+ :caption: TODO 4: CMakeLists.txt
:name: CMakeLists.txt-target_compile_options-genex
:language: cmake
:start-after: set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
diff --git a/Help/guide/tutorial/Adding Usage Requirements for a Library.rst b/Help/guide/tutorial/Adding Usage Requirements for a Library.rst
index 74b7496688..227306393e 100644
--- a/Help/guide/tutorial/Adding Usage Requirements for a Library.rst
+++ b/Help/guide/tutorial/Adding Usage Requirements for a Library.rst
@@ -100,7 +100,7 @@ follows:
:name: MathFunctions/CMakeLists.txt-target_include_directories-INTERFACE
:language: cmake
:start-after: # to find MathFunctions.h
- :end-before: option
+ :end-before: # should we use our own
.. raw:: html
@@ -108,24 +108,26 @@ follows:
Now that we've specified usage requirements for ``MathFunctions`` we can
safely remove our uses of the ``EXTRA_INCLUDES`` variable from the top-level
-``CMakeLists.txt``, here:
+``CMakeLists.txt``.
+
+Remove this line:
.. raw:: html
<details><summary>TODO 2: Click to show/hide answer</summary>
-.. literalinclude:: Step4/CMakeLists.txt
+.. literalinclude:: Step3/CMakeLists.txt
:caption: TODO 2: CMakeLists.txt
:name: CMakeLists.txt-remove-EXTRA_INCLUDES
:language: cmake
- :start-after: # add the MathFunctions library
- :end-before: # TODO 2: Link to tutorial_compiler_flags
+ :start-after: add_subdirectory(MathFunctions)
+ :end-before: # add the executable
.. raw:: html
</details>
-And here:
+And the lines:
.. raw:: html
@@ -141,7 +143,181 @@ And here:
</details>
+The remaining code looks like:
+
+.. raw:: html
+
+ <details><summary>Click to show/hide the resulting code</summary>
+
+.. literalinclude:: Step4/CMakeLists.txt
+ :caption: Remaining code after removing EXTRA_INCLUDES
+ :name: CMakeLists.txt-after-removing-EXTRA_INCLUDES
+ :language: cmake
+ :start-after: add_subdirectory(MathFunctions)
+
+.. raw:: html
+
+ </details>
+
+
Notice that with this technique, the only thing our executable target does to
use our library is call :command:`target_link_libraries` with the name
of the library target. In larger projects, the classic method of specifying
library dependencies manually becomes very complicated very quickly.
+
+Exercise 2 - Setting the C++ Standard with Interface Libraries
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Now that we have switched our code to a more modern approach, let's demonstrate
+a modern technique to set properties to multiple targets.
+
+Let's refactor our existing code to use an ``INTERFACE`` library. We will
+use that library in the next step to demonstrate a common use for
+:manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+Goal
+----
+
+Add an ``INTERFACE`` library target to specify the required C++ standard.
+
+Helpful Resources
+-----------------
+
+* :command:`add_library`
+* :command:`target_compile_features`
+* :command:`target_link_libraries`
+
+Files to Edit
+-------------
+
+* ``CMakeLists.txt``
+* ``MathFunctions/CMakeLists.txt``
+
+Getting Started
+---------------
+
+In this exercise, we will refactor our code to use an ``INTERFACE`` library to
+specify the C++ standard.
+
+Start this exercise from what we left at the end of Step3 exercise 1. You will
+have to complete ``TODO 4`` through ``TODO 7``.
+
+Start by editing the top level ``CMakeLists.txt`` file. Construct an
+``INTERFACE`` library target called ``tutorial_compiler_flags`` and
+specify ``cxx_std_11`` as a target compiler feature.
+
+Modify ``CMakeLists.txt`` and ``MathFunctions/CMakeLists.txt`` so that all
+targets have a :command:`target_link_libraries` call to
+``tutorial_compiler_flags``.
+
+Build and Run
+-------------
+
+Since we have our build directory already configured from Exercise 1, simply
+rebuild our code by calling the following:
+
+.. code-block:: console
+
+ cd Step3_build
+ cmake --build .
+
+Next, use the newly built ``Tutorial`` and verify that it is working as
+expected.
+
+Solution
+--------
+
+Let's update our code from the previous step to use interface libraries
+to set our C++ requirements.
+
+To start, we need to remove the two :command:`set` calls on the variables
+:variable:`CMAKE_CXX_STANDARD` and :variable:`CMAKE_CXX_STANDARD_REQUIRED`.
+The specific lines to remove are as follows:
+
+.. literalinclude:: Step3/CMakeLists.txt
+ :caption: CMakeLists.txt
+ :name: CMakeLists.txt-CXX_STANDARD-variable-remove
+ :language: cmake
+ :start-after: # specify the C++ standard
+ :end-before: # configure a header file
+
+Next, we need to create an interface library, ``tutorial_compiler_flags``. And
+then use :command:`target_compile_features` to add the compiler feature
+``cxx_std_11``.
+
+
+.. raw:: html
+
+ <details><summary>TODO 4: Click to show/hide answer</summary>
+
+.. literalinclude:: Step4/CMakeLists.txt
+ :caption: TODO 4: CMakeLists.txt
+ :name: CMakeLists.txt-cxx_std-feature
+ :language: cmake
+ :start-after: # specify the C++ standard
+ :end-before: # TODO 2: Create helper
+
+.. raw:: html
+
+ </details>
+
+Finally, with our interface library set up, we need to link our
+executable ``Target``, our ``MathFunctions`` library, and our ``SqrtLibrary``
+library to our new
+``tutorial_compiler_flags`` library. Respectively, the code will look like
+this:
+
+.. raw:: html
+
+ <details><summary>TODO 5: Click to show/hide answer</summary>
+
+.. literalinclude:: Step4/CMakeLists.txt
+ :caption: TODO 5: CMakeLists.txt
+ :name: CMakeLists.txt-target_link_libraries-step4
+ :language: cmake
+ :start-after: add_executable(Tutorial tutorial.cxx)
+ :end-before: # add the binary tree to the search path for include file
+
+.. raw:: html
+
+ </details>
+
+this:
+
+.. raw:: html
+
+ <details><summary>TODO 6: Click to show/hide answer</summary>
+
+.. literalinclude:: Step4/MathFunctions/CMakeLists.txt
+ :caption: TODO 6: MathFunctions/CMakeLists.txt
+ :name: MathFunctions-CMakeLists.txt-target_link_libraries-step4
+ :language: cmake
+ :start-after: # link our compiler flags interface library
+ :end-before: target_link_libraries(MathFunctions
+
+.. raw:: html
+
+ </details>
+
+and this:
+
+.. raw:: html
+
+ <details><summary>TODO 7: Click to show/hide answer</summary>
+
+.. literalinclude:: Step4/MathFunctions/CMakeLists.txt
+ :caption: TODO 7: MathFunctions/CMakeLists.txt
+ :name: MathFunctions-SqrtLibrary-target_link_libraries-step4
+ :language: cmake
+ :start-after: target_link_libraries(SqrtLibrary
+ :end-before: endif()
+
+.. raw:: html
+
+ </details>
+
+
+With this, all of our code still requires C++ 11 to build. Notice
+though that with this method, it gives us the ability to be specific about
+which targets get specific requirements. In addition, we create a single
+source of truth in our interface library.
diff --git a/Help/guide/tutorial/Adding a Library.rst b/Help/guide/tutorial/Adding a Library.rst
index d606f305e8..694dfaf621 100644
--- a/Help/guide/tutorial/Adding a Library.rst
+++ b/Help/guide/tutorial/Adding a Library.rst
@@ -409,7 +409,7 @@ that has sources ``mysqrt.cxx``.
:name: MathFunctions/CMakeLists.txt-add_library-SqrtLibrary
:language: cmake
:start-after: # library that just does sqrt
- :end-before: target_link_libraries(MathFunctions
+ :end-before: # TODO 7: Link
.. raw:: html
@@ -426,7 +426,8 @@ enabled.
:caption: TODO 13 : MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-target_link_libraries-SqrtLibrary
:language: cmake
- :lines: 16-18
+ :start-after: to tutorial_compiler_flags
+ :end-before: endif()
.. raw:: html
diff --git a/Help/guide/tutorial/Step3/CMakeLists.txt b/Help/guide/tutorial/Step3/CMakeLists.txt
index f051826a7d..ac3e9f1ed7 100644
--- a/Help/guide/tutorial/Step3/CMakeLists.txt
+++ b/Help/guide/tutorial/Step3/CMakeLists.txt
@@ -3,6 +3,12 @@ cmake_minimum_required(VERSION 3.10)
# set the project name and version
project(Tutorial VERSION 1.0)
+# TODO 4: Replace the following code by:
+# * Creating an interface library called tutorial_compiler_flags
+# Hint: use add_library() with the INTERFACE signature
+# * Add compiler feature cxx_std_11 to tutorial_compiler_flags
+# Hint: Use target_compile_features()
+
# specify the C++ standard
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
@@ -20,6 +26,8 @@ list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions")
# add the executable
add_executable(Tutorial tutorial.cxx)
+# TODO 5: Link Tutorial to tutorial_compiler_flags
+
target_link_libraries(Tutorial PUBLIC MathFunctions)
# TODO 3: Remove use of EXTRA_INCLUDES
diff --git a/Help/guide/tutorial/Step3/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step3/MathFunctions/CMakeLists.txt
index 6f86ffef5b..0ffb9e1f5b 100644
--- a/Help/guide/tutorial/Step3/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step3/MathFunctions/CMakeLists.txt
@@ -14,5 +14,9 @@ if (USE_MYMATH)
mysqrt.cxx
)
+ # TODO 7: Link SqrtLibrary to tutorial_compiler_flags
+
target_link_libraries(MathFunctions PUBLIC SqrtLibrary)
endif()
+
+# TODO 6: Link MathFunctions to tutorial_compiler_flags
diff --git a/Help/guide/tutorial/Step4/CMakeLists.txt b/Help/guide/tutorial/Step4/CMakeLists.txt
index 7531fb41ab..fba97669b4 100644
--- a/Help/guide/tutorial/Step4/CMakeLists.txt
+++ b/Help/guide/tutorial/Step4/CMakeLists.txt
@@ -1,33 +1,27 @@
-# TODO 5: Update the minimum required version to 3.15
+# TODO 1: Update the minimum required version to 3.15
cmake_minimum_required(VERSION 3.10)
# set the project name and version
project(Tutorial VERSION 1.0)
-# TODO 1: Replace the following code by:
-# * Creating an interface library called tutorial_compiler_flags
-# Hint: use add_library() with the INTERFACE signature
-# * Add compiler feature cxx_std_11 to tutorial_compiler_flags
-# Hint: Use target_compile_features()
-
# specify the C++ standard
-set(CMAKE_CXX_STANDARD 11)
-set(CMAKE_CXX_STANDARD_REQUIRED True)
+add_library(tutorial_compiler_flags INTERFACE)
+target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
-# TODO 6: Create helper variables to determine which compiler we are using:
+# TODO 2: Create helper variables to determine which compiler we are using:
# * Create a new variable gcc_like_cxx that is true if we are using CXX and
# any of the following compilers: ARMClang, AppleClang, Clang, GNU, LCC
# * Create a new variable msvc_cxx that is true if we are using CXX and MSVC
# Hint: Use set() and COMPILE_LANG_AND_ID
-# TODO 7: Add warning flag compile options to the interface library
+# TODO 3: Add warning flag compile options to the interface library
# tutorial_compiler_flags.
# * For gcc_like_cxx, add flags -Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused
# * For msvc_cxx, add flags -W3
# Hint: Use target_compile_options()
-# TODO 8: With nested generator expressions, only use the flags for the
+# TODO 4: With nested generator expressions, only use the flags for the
# build-tree
# Hint: Use BUILD_INTERFACE
@@ -41,9 +35,7 @@ add_subdirectory(MathFunctions)
# add the executable
add_executable(Tutorial tutorial.cxx)
-# TODO 2: Link to tutorial_compiler_flags
-
-target_link_libraries(Tutorial PUBLIC MathFunctions)
+target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
diff --git a/Help/guide/tutorial/Step4/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step4/MathFunctions/CMakeLists.txt
index ffab4f0a80..48561eb23b 100644
--- a/Help/guide/tutorial/Step4/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step4/MathFunctions/CMakeLists.txt
@@ -17,9 +17,10 @@ if (USE_MYMATH)
mysqrt.cxx
)
- # TODO 4: Link to tutorial_compiler_flags
-
+ # link our compiler flags interface library
+ target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
target_link_libraries(MathFunctions PUBLIC SqrtLibrary)
endif()
-# TODO 3: Link to tutorial_compiler_flags
+# link our compiler flags interface library
+target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
diff --git a/Help/manual/cmake-env-variables.7.rst b/Help/manual/cmake-env-variables.7.rst
index 1f0c9111aa..f7ae94d339 100644
--- a/Help/manual/cmake-env-variables.7.rst
+++ b/Help/manual/cmake-env-variables.7.rst
@@ -20,8 +20,13 @@ Environment Variables that Change Behavior
.. toctree::
:maxdepth: 1
+ /envvar/CMAKE_APPBUNDLE_PATH
+ /envvar/CMAKE_FRAMEWORK_PATH
+ /envvar/CMAKE_INCLUDE_PATH
+ /envvar/CMAKE_LIBRARY_PATH
/envvar/CMAKE_MAXIMUM_RECURSION_DEPTH
/envvar/CMAKE_PREFIX_PATH
+ /envvar/CMAKE_PROGRAM_PATH
/envvar/SSL_CERT_DIR
/envvar/SSL_CERT_FILE
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index da7df70fa2..473e8d7cf1 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -104,6 +104,17 @@ improved further like so:
VERBATIM
)
+Finally, the above example can be expressed in a more simple and robust way
+using an alternate generator expression:
+
+.. code-block:: cmake
+
+ add_custom_target(run_some_tool
+ COMMAND some_tool "$<LIST:TRANSFORM,$<TARGET_PROPERTY:tgt,INCLUDE_DIRECTORIES>,PREPEND,-I>"
+ COMMAND_EXPAND_LISTS
+ VERBATIM
+ )
+
A common mistake is to try to split a generator expression across multiple
lines with indenting:
@@ -318,6 +329,15 @@ String Transformations
List Expressions
----------------
+Most of the expressions in this section are closely associated with the
+:command:`list` command, providing the same capabilities, but in
+the form of a generator expression.
+
+.. _GenEx List Comparisons:
+
+List Comparisons
+^^^^^^^^^^^^^^^^
+
.. genex:: $<IN_LIST:string,list>
.. versionadded:: 3.12
@@ -325,9 +345,186 @@ List Expressions
``1`` if ``string`` is an item in the semicolon-separated ``list``, else ``0``.
It uses case-sensitive comparisons.
-.. genex:: $<JOIN:list,string>
+.. _GenEx List Queries:
+
+List Queries
+^^^^^^^^^^^^
+
+.. genex:: $<LIST:LENGTH,list>
+
+ .. versionadded:: 3.27
+
+ Returns the list's length.
+
+.. genex:: $<LIST:GET,list,index,...>
+
+ .. versionadded:: 3.27
+
+ Returns the list of elements specified by indices from the list.
+
+.. genex:: $<LIST:SUBLIST,list,begin,length>
+
+ .. versionadded:: 3.27
+
+ Returns a sublist of the given list. If <length> is 0, an empty list will be
+ returned. If <length> is -1 or the list is smaller than <begin>+<length> then
+ the remaining elements of the list starting at <begin> will be returned.
+
+.. genex:: $<LIST:FIND,list,value>
+
+ .. versionadded:: 3.27
+
+ Returns the index of the element specified in the list or -1 if it wasn't
+ found.
+
+.. _GenEx List Transformations:
+
+List Transformations
+^^^^^^^^^^^^^^^^^^^^
+
+.. genex:: $<LIST:JOIN,list,glue>
+
+ .. versionadded:: 3.27
+
+ Returns a string which joins the list with the content of the ``glue`` string
+ inserted between each item.
+
+.. genex:: $<LIST:APPEND,list,element,...>
+
+ .. versionadded:: 3.27
+
+ Returns a list with the elements appended.
+
+.. genex:: $<LIST:PREPEND,list,element,...>
+
+ .. versionadded:: 3.27
+
+ Returns a list with the elements inserted at the beginning of the list.
+
+.. genex:: $<LIST:INSERT,list,index,element,...>
+
+ .. versionadded:: 3.27
+
+ Returns a list with the elements inserted at the specified index. It is an
+ error to specify an out-of-range index. Valid indexes are 0 to N where N is
+ the length of the list, inclusive. An empty list has length 0.
+
+.. genex:: $<LIST:POP_BACK,list>
+
+ .. versionadded:: 3.27
+
+ Returns a list with the last element was removed.
+
+.. genex:: $<LIST:POP_FRONT,list>
+
+ .. versionadded:: 3.27
+
+ Returns a list with the first element was removed.
+
+.. genex:: $<LIST:REMOVE_ITEM,list,value,...>
+
+ .. versionadded:: 3.27
+
+ Returns a list with all instances of the given values were removed.
+
+.. genex:: $<LIST:REMOVE_AT,list,index,...>
+
+ .. versionadded:: 3.27
- Joins the list with the content of ``string`` inserted between each item.
+ Returns a list with all values at given indices were removed.
+
+.. genex:: $<LIST:REMOVE_DUPLICATES,list>
+
+ .. versionadded:: 3.27
+
+ Returns a list where duplicated items were removed. The relative order of
+ items is preserved, but if duplicates are encountered, only the first
+ instance is preserved.
+
+.. genex:: $<LIST:FILTER,list,INCLUDE|EXCLUDE,regex>
+
+ .. versionadded:: 3.27
+
+ Returns a list with the items that match the regular expression ``regex``
+ were included or removed.
+
+.. genex:: $<LIST:TRANSFORM,list,ACTION[,SELECTOR]>
+
+ .. versionadded:: 3.27
+
+ Returns the list transformed by applying an ``ACTION`` to all or, by
+ specifying a ``SELECTOR``, to the selected elements of the list.
+
+ .. note::
+
+ The ``TRANSFORM`` sub-command does not change the number of elements in the
+ list. If a ``SELECTOR`` is specified, only some elements will be changed,
+ the other ones will remain the same as before the transformation.
+
+ ``ACTION`` specifies the action to apply to the elements of the list.
+ The actions have exactly the same semantics as of the
+ :command:`list(TRANSFORM)` command. ``ACTION`` must be one of the following:
+
+ :command:`APPEND <list(TRANSFORM_APPEND)>`, :command:`PREPEND <list(TRANSFORM_APPEND)>`
+ Append, prepend specified value to each element of the list.
+
+ .. code-block:: cmake
+
+ $<LIST:TRANSFORM,list,(APPEND|PREPEND),value[,SELECTOR]>
+
+ :command:`TOLOWER <list(TRANSFORM_TOLOWER)>`, :command:`TOUPPER <list(TRANSFORM_TOLOWER)>`
+ Convert each element of the list to lower, upper characters.
+
+ .. code-block:: cmake
+
+ $<LIST:TRANSFORM,list,(TOLOWER|TOUPPER)[,SELECTOR]>
+
+ :command:`STRIP <list(TRANSFORM_STRIP)>`
+ Remove leading and trailing spaces from each element of the list.
+
+ .. code-block:: cmake
+
+ $<LIST:TRANSFORM,list,STRIP[,SELECTOR]>
+
+ :command:`REPLACE <list(TRANSFORM_REPLACE)>`:
+ Match the regular expression as many times as possible and substitute
+ the replacement expression for the match for each element of the list.
+
+ .. code-block:: cmake
+
+ $<LIST:TRANSFORM,list,REPLACE,regular_expression,replace_expression[,SELECTOR]>
+
+ ``SELECTOR`` determines which elements of the list will be transformed.
+ Only one type of selector can be specified at a time. When given,
+ ``SELECTOR`` must be one of the following:
+
+ ``AT``
+ Specify a list of indexes.
+
+ .. code-block:: cmake
+
+ $<LIST:TRANSFORM,list,ACTION,AT,index[,index...]>
+
+ ``FOR``
+ Specify a range with, optionally, an increment used to iterate over the
+ range.
+
+ .. code-block:: cmake
+
+ $<LIST:TRANSFORM,list,ACTION,FOR,start,stop[,step]>
+
+ ``REGEX``
+ Specify a regular expression.
+ Only elements matching the regular expression will be transformed.
+
+ .. code-block:: cmake
+
+ $<LIST:TRANSFORM,list,ACTION,REGEX,regular_expression>
+
+.. genex:: $<JOIN:list,glue>
+
+ Joins the list with the content of the ``glue`` string inserted between each
+ item.
.. genex:: $<REMOVE_DUPLICATES:list>
@@ -344,6 +541,69 @@ List Expressions
Includes or removes items from ``list`` that match the regular expression
``regex``.
+.. _GenEx List Ordering:
+
+List Ordering
+^^^^^^^^^^^^^
+
+.. genex:: $<LIST:REVERSE,list>
+
+ .. versionadded:: 3.27
+
+ Returns the list with the elements in reverse order.
+
+.. genex:: $<LIST:SORT,list[,(COMPARE:option|CASE:option|ORDER:option)]...>
+
+ .. versionadded:: 3.27
+
+ Returns the list sorted according the specified options.
+
+ Use one of the ``COMPARE`` options to select the comparison method
+ for sorting:
+
+ ``STRING``
+ Sorts a list of strings alphabetically.
+ This is the default behavior if the ``COMPARE`` option is not given.
+
+ ``FILE_BASENAME``
+ Sorts a list of pathnames of files by their basenames.
+
+ ``NATURAL``
+ Sorts a list of strings using natural order
+ (see ``strverscmp(3)`` manual), i.e. such that contiguous digits
+ are compared as whole numbers.
+ For example: the following list `10.0 1.1 2.1 8.0 2.0 3.1`
+ will be sorted as `1.1 2.0 2.1 3.1 8.0 10.0` if the ``NATURAL``
+ comparison is selected where it will be sorted as
+ `1.1 10.0 2.0 2.1 3.1 8.0` with the ``STRING`` comparison.
+
+ Use one of the ``CASE`` options to select a case sensitive or case
+ insensitive sort mode:
+
+ ``SENSITIVE``
+ List items are sorted in a case-sensitive manner.
+ This is the default behavior if the ``CASE`` option is not given.
+
+ ``INSENSITIVE``
+ List items are sorted case insensitively. The order of
+ items which differ only by upper/lowercase is not specified.
+
+ To control the sort order, one of the ``ORDER`` options can be given:
+
+ ``ASCENDING``
+ Sorts the list in ascending order.
+ This is the default behavior when the ``ORDER`` option is not given.
+
+ ``DESCENDING``
+ Sorts the list in descending order.
+
+ This is an error to specify multiple times the same option. Various options
+ can be specified in any order:
+
+ .. code-block:: cmake
+
+ $<LIST:SORT,list,CASE:SENSITIVE,COMPARE:STRING,ORDER:DESCENDING>
+
Path Expressions
----------------
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index 8c7189a72b..7c488060b9 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -57,6 +57,8 @@ Policies Introduced by CMake 3.27
.. toctree::
:maxdepth: 1
+ CMP0151: AUTOMOC include directory is a system include directory by default. </policy/CMP0151>
+ CMP0150: ExternalProject_Add and FetchContent_Declare treat relative git repository paths as being relative to parent project's remote. </policy/CMP0150>
CMP0149: Visual Studio generators select latest Windows SDK by default. </policy/CMP0149>
CMP0148: The FindPythonInterp and FindPythonLibs modules are removed. </policy/CMP0148>
CMP0147: Visual Studio generators build custom commands in parallel. </policy/CMP0147>
diff --git a/Help/manual/cmake-presets.7.rst b/Help/manual/cmake-presets.7.rst
index 7794e45ce5..e2366da0ac 100644
--- a/Help/manual/cmake-presets.7.rst
+++ b/Help/manual/cmake-presets.7.rst
@@ -133,6 +133,9 @@ Files directly or indirectly included from ``CMakePresets.json`` should be
guaranteed to be provided by the project. ``CMakeUserPresets.json`` may
include files from anywhere.
+Starting from version ``7``, the ``include`` field supports
+`macro expansion`_, but only ``$penv{}`` macro expansion.
+
Configure Preset
^^^^^^^^^^^^^^^^
@@ -1057,6 +1060,12 @@ fields:
a workflow preset may have the same name as a configure, build, test, or
package preset.
+``vendor``
+ An optional map containing vendor-specific information. CMake does not
+ interpret the contents of this field except to verify that it is a map
+ if it does exist. However, it should follow the same conventions as the
+ root-level ``vendor`` field.
+
``displayName``
An optional string with a human-friendly name of the preset.
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index c0e2ee2bdc..8ee5573149 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -133,6 +133,7 @@ Properties on Targets
/prop_tgt/AUTOGEN_ORIGIN_DEPENDS
/prop_tgt/AUTOGEN_PARALLEL
/prop_tgt/AUTOGEN_TARGET_DEPENDS
+ /prop_tgt/AUTOGEN_USE_SYSTEM_INCLUDE
/prop_tgt/AUTOMOC
/prop_tgt/AUTOMOC_COMPILER_PREDEFINES
/prop_tgt/AUTOMOC_DEPEND_FILTERS
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index f3212de4df..fa7a90fd8e 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -397,6 +397,7 @@ Variables that Control the Build
/variable/CMAKE_ARCHIVE_OUTPUT_DIRECTORY_CONFIG
/variable/CMAKE_AUTOGEN_ORIGIN_DEPENDS
/variable/CMAKE_AUTOGEN_PARALLEL
+ /variable/CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE
/variable/CMAKE_AUTOGEN_VERBOSE
/variable/CMAKE_AUTOMOC
/variable/CMAKE_AUTOMOC_COMPILER_PREDEFINES
@@ -479,6 +480,7 @@ Variables that Control the Build
/variable/CMAKE_LIBRARY_PATH_FLAG
/variable/CMAKE_LINK_DEF_FILE_FLAG
/variable/CMAKE_LINK_DEPENDS_NO_SHARED
+ /variable/CMAKE_LINK_DEPENDS_USE_LINKER
/variable/CMAKE_LINK_GROUP_USING_FEATURE
/variable/CMAKE_LINK_GROUP_USING_FEATURE_SUPPORTED
/variable/CMAKE_LINK_INTERFACE_LIBRARIES
@@ -535,6 +537,10 @@ Variables that Control the Build
/variable/CMAKE_USE_RELATIVE_PATHS
/variable/CMAKE_VERIFY_INTERFACE_HEADER_SETS
/variable/CMAKE_VISIBILITY_INLINES_HIDDEN
+ /variable/CMAKE_VS_DEBUGGER_COMMAND
+ /variable/CMAKE_VS_DEBUGGER_COMMAND_ARGUMENTS
+ /variable/CMAKE_VS_DEBUGGER_ENVIRONMENT
+ /variable/CMAKE_VS_DEBUGGER_WORKING_DIRECTORY
/variable/CMAKE_VS_GLOBALS
/variable/CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD
/variable/CMAKE_VS_INCLUDE_PACKAGE_TO_DEFAULT_BUILD
diff --git a/Help/manual/cpack-generators.7.rst b/Help/manual/cpack-generators.7.rst
index ade9149c18..abb291b46e 100644
--- a/Help/manual/cpack-generators.7.rst
+++ b/Help/manual/cpack-generators.7.rst
@@ -20,6 +20,7 @@ Generators
/cpack_gen/dmg
/cpack_gen/external
/cpack_gen/freebsd
+ /cpack_gen/innosetup
/cpack_gen/ifw
/cpack_gen/nsis
/cpack_gen/nuget
diff --git a/Help/policy/CMP0105.rst b/Help/policy/CMP0105.rst
index 097a59abb8..aadc8d6ee6 100644
--- a/Help/policy/CMP0105.rst
+++ b/Help/policy/CMP0105.rst
@@ -8,12 +8,13 @@ properties are now used for the device link step.
In CMake 3.17 and below, link options are not used by the device link step.
-The ``OLD`` behavior for this policy is to ignore the link options.
+The ``OLD`` behavior for this policy is to ignore the link options during the
+device link step.
The ``NEW`` behavior of this policy is to use the link options during the
device link step.
-This policy was introduced in CMake version 3.17. Use the
+This policy was introduced in CMake version 3.18. Use the
:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
Unlike many policies, CMake version |release| does *not* warn
when this policy is not set and simply uses ``OLD`` behavior.
diff --git a/Help/policy/CMP0150.rst b/Help/policy/CMP0150.rst
new file mode 100644
index 0000000000..fe646d98f4
--- /dev/null
+++ b/Help/policy/CMP0150.rst
@@ -0,0 +1,39 @@
+CMP0150
+-------
+
+.. versionadded:: 3.27
+
+:command:`ExternalProject_Add` and :command:`FetchContent_Declare` commands
+treat relative ``GIT_REPOSITORY`` paths as being relative to the parent
+project's remote.
+
+Earlier versions of these commands always treated relative paths in
+``GIT_REPOSITORY`` as local paths, but the base directory it was treated
+as relative to was both undocumented and unintuitive. The ``OLD`` behavior
+for this policy is to interpret relative paths used for ``GIT_REPOSITORY``
+as local paths relative to the following:
+
+* The parent directory of ``SOURCE_DIR`` for :command:`ExternalProject_Add`.
+* ``FETCHCONTENT_BASE_DIR`` for :command:`FetchContent_Declare`.
+
+The ``NEW`` behavior is to determine the remote from the parent project and
+interpret the path relative to that remote. The value of
+:variable:`CMAKE_CURRENT_SOURCE_DIR` when :command:`ExternalProject_Add` or
+:command:`FetchContent_Declare` is called determines the parent project.
+The remote is selected according to the following (the first match is used):
+
+* If the parent project is checked out on a branch with an upstream remote
+ defined, use that remote.
+* If only one remote is defined, use that remote.
+* If multiple remotes are defined and one of them is named ``origin``, use
+ ``origin``'s remote but also issue a warning.
+
+If an appropriate remote cannot be determined from the above, a fatal error
+will be raised.
+
+This policy was introduced in CMake version 3.27. CMake version |release|
+warns when a relative path is encountered and the policy is not set,
+falling back to using ``OLD`` behavior. Use the :command:`cmake_policy`
+command to set it to ``OLD`` or ``NEW`` explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0151.rst b/Help/policy/CMP0151.rst
new file mode 100644
index 0000000000..c12f595f16
--- /dev/null
+++ b/Help/policy/CMP0151.rst
@@ -0,0 +1,28 @@
+CMP0151
+-------
+
+.. versionadded:: 3.27
+
+AUTOMOC include directory is a system include directory by default.
+
+Headers generated for :ref:`Qt AUTOMOC` are placed in target-specific include
+directories. CMake 3.26 and older added these as normal include directories.
+CMake 3.27 and newer prefer to add them as system include directories.
+This policy provides compatibility for projects that have not been updated
+to expect this.
+
+If the :prop_tgt:`AUTOGEN_USE_SYSTEM_INCLUDE` target property is set,
+perhaps via the :variable:`CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE` variable,
+then its value is used regardless of the setting of this policy.
+
+The ``OLD`` behavior for this policy is to add autogen include directory to
+the target's include directories.
+The ``NEW`` behavior for this policy is to add autogen include directory to
+the target's system include directories.
+
+This policy was introduced in CMake version 3.27. Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+Unlike many policies, CMake version |release| does *not* warn
+when this policy is not set and simply uses ``OLD`` behavior.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/prop_tgt/AUTOGEN_USE_SYSTEM_INCLUDE.rst b/Help/prop_tgt/AUTOGEN_USE_SYSTEM_INCLUDE.rst
new file mode 100644
index 0000000000..84212c861f
--- /dev/null
+++ b/Help/prop_tgt/AUTOGEN_USE_SYSTEM_INCLUDE.rst
@@ -0,0 +1,17 @@
+AUTOGEN_USE_SYSTEM_INCLUDE
+--------------------------
+
+``AUTOGEN_USE_SYSTEM_INCLUDE`` is a boolean property that can be set
+on a target to indicate that the autogen target include directory should
+be added as a system include directory or normal include directory to the
+target.
+
+If this property is not set, the autogen target include directory is added
+as a system include directory by default. See policy :policy:`CMP0151`.
+
+See the :manual:`cmake-qt(7)` manual for more information on using CMake
+with Qt.
+
+This property is initialized by the
+:variable:`CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE` variable if it is set when
+a target is created.
diff --git a/Help/prop_tgt/VS_DEBUGGER_COMMAND.rst b/Help/prop_tgt/VS_DEBUGGER_COMMAND.rst
index 1e84c00850..5bf47a38a9 100644
--- a/Help/prop_tgt/VS_DEBUGGER_COMMAND.rst
+++ b/Help/prop_tgt/VS_DEBUGGER_COMMAND.rst
@@ -7,7 +7,9 @@ Sets the local debugger command for Visual Studio C++ targets.
The property value may use
:manual:`generator expressions <cmake-generator-expressions(7)>`.
This is defined in ``<LocalDebuggerCommand>`` in the Visual Studio
-project file.
+project file. This property is initialized by the value of the variable
+:variable:`CMAKE_VS_DEBUGGER_COMMAND` if it is set when a target is
+created.
This property only works for Visual Studio 11 2012 and above;
it is ignored on other generators.
diff --git a/Help/prop_tgt/VS_DEBUGGER_COMMAND_ARGUMENTS.rst b/Help/prop_tgt/VS_DEBUGGER_COMMAND_ARGUMENTS.rst
index e54e140b65..4b9dff7155 100644
--- a/Help/prop_tgt/VS_DEBUGGER_COMMAND_ARGUMENTS.rst
+++ b/Help/prop_tgt/VS_DEBUGGER_COMMAND_ARGUMENTS.rst
@@ -7,7 +7,9 @@ Sets the local debugger command line arguments for Visual Studio C++ targets.
The property value may use
:manual:`generator expressions <cmake-generator-expressions(7)>`.
This is defined in ``<LocalDebuggerCommandArguments>`` in the Visual Studio
-project file.
+project file. This property is initialized by the value of the variable
+:variable:`CMAKE_VS_DEBUGGER_COMMAND_ARGUMENTS` if it is set when a target is
+created.
This property only works for Visual Studio 11 2012 and above;
it is ignored on other generators.
diff --git a/Help/prop_tgt/VS_DEBUGGER_ENVIRONMENT.rst b/Help/prop_tgt/VS_DEBUGGER_ENVIRONMENT.rst
index 60bc2f076e..8373dbb5c8 100644
--- a/Help/prop_tgt/VS_DEBUGGER_ENVIRONMENT.rst
+++ b/Help/prop_tgt/VS_DEBUGGER_ENVIRONMENT.rst
@@ -7,7 +7,9 @@ Sets the local debugger environment for Visual Studio C++ targets.
The property value may use
:manual:`generator expressions <cmake-generator-expressions(7)>`.
This is defined in ``<LocalDebuggerEnvironment>`` in the Visual Studio
-project file.
+project file. This property is initialized by the value of the variable
+:variable:`CMAKE_VS_DEBUGGER_ENVIRONMENT` if it is set when a target is
+created.
This property only works for Visual Studio 11 2012 and above;
it is ignored on other generators.
diff --git a/Help/prop_tgt/VS_DEBUGGER_WORKING_DIRECTORY.rst b/Help/prop_tgt/VS_DEBUGGER_WORKING_DIRECTORY.rst
index f9ce7aa367..39420475bd 100644
--- a/Help/prop_tgt/VS_DEBUGGER_WORKING_DIRECTORY.rst
+++ b/Help/prop_tgt/VS_DEBUGGER_WORKING_DIRECTORY.rst
@@ -7,7 +7,9 @@ Sets the local debugger working directory for Visual Studio C++ targets.
The property value may use
:manual:`generator expressions <cmake-generator-expressions(7)>`.
This is defined in ``<LocalDebuggerWorkingDirectory>`` in the Visual Studio
-project file.
+project file. This property is initialized by the value of the variable
+:variable:`CMAKE_VS_DEBUGGER_WORKING_DIRECTORY` if it is set when a target is
+created.
This property only works for Visual Studio 11 2012 and above;
it is ignored on other generators.
diff --git a/Help/release/dev/ExternalProject-FetchContent-relative-git-remotes.rst b/Help/release/dev/ExternalProject-FetchContent-relative-git-remotes.rst
new file mode 100644
index 0000000000..d467620a39
--- /dev/null
+++ b/Help/release/dev/ExternalProject-FetchContent-relative-git-remotes.rst
@@ -0,0 +1,7 @@
+ExternalProject-FetchContent-Relative-git-remotes
+-------------------------------------------------
+
+* The :module:`ExternalProject` and :module:`FetchContent` modules
+ now resolve relative `GIT_REPOSITORY` paths as relative to the
+ parent project's remote, not as a relative local file system path.
+ See :policy:`CMP0150`.
diff --git a/Help/release/dev/FindDoxygen-custom-config-file.rst b/Help/release/dev/FindDoxygen-custom-config-file.rst
new file mode 100644
index 0000000000..badc26e35b
--- /dev/null
+++ b/Help/release/dev/FindDoxygen-custom-config-file.rst
@@ -0,0 +1,5 @@
+FindDoxygen-custom-config-file
+------------------------------
+
+* The :module:`FindDoxygen` module's ``doxygen_add_docs`` command gained
+ a ``CONFIG_FILE`` option to specify a custom doxygen configuration file.
diff --git a/Help/release/dev/GenEx-LIST.rst b/Help/release/dev/GenEx-LIST.rst
new file mode 100644
index 0000000000..f65a092db9
--- /dev/null
+++ b/Help/release/dev/GenEx-LIST.rst
@@ -0,0 +1,4 @@
+GenEx-LIST
+----------
+
+* The :genex:`LIST` generator expression was added to manage lists.
diff --git a/Help/release/dev/autogen-system-include.rst b/Help/release/dev/autogen-system-include.rst
new file mode 100644
index 0000000000..aea81be167
--- /dev/null
+++ b/Help/release/dev/autogen-system-include.rst
@@ -0,0 +1,7 @@
+autogen-system-include
+----------------------
+
+* The :prop_tgt:`AUTOGEN_USE_SYSTEM_INCLUDE` target property and
+ corresponding :variable:`CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE` were
+ added to explicitly control whether autogen headers are
+ considered system headers.
diff --git a/Help/release/dev/cpack-innosetup.rst b/Help/release/dev/cpack-innosetup.rst
new file mode 100644
index 0000000000..a9f8e8e331
--- /dev/null
+++ b/Help/release/dev/cpack-innosetup.rst
@@ -0,0 +1,12 @@
+cpack-innosetup
+---------------
+
+* The :cpack_gen:`CPack Inno Setup Generator` was added to package using
+ Inno Setup.
+
+ The new generator adds:
+
+ * A lot of options to customize the Inno Setup installer (e.g. custom
+ installation rules)
+ * Start menu and desktop shortcuts
+ * Components (and also downloaded components)
diff --git a/Help/release/dev/preset-includes-macro-expansion.rst b/Help/release/dev/preset-includes-macro-expansion.rst
new file mode 100644
index 0000000000..e1f00302a2
--- /dev/null
+++ b/Help/release/dev/preset-includes-macro-expansion.rst
@@ -0,0 +1,7 @@
+preset-includes-macro-expansion
+-------------------------------
+
+* :manual:`cmake-presets(7)` files now support schema version ``7``.
+
+* :manual:`cmake-presets(7)` now supports ``$penv{}`` macro expansion
+ in ``include`` fields.
diff --git a/Help/release/dev/use-linker-depfile.rst b/Help/release/dev/use-linker-depfile.rst
new file mode 100644
index 0000000000..11237071f4
--- /dev/null
+++ b/Help/release/dev/use-linker-depfile.rst
@@ -0,0 +1,11 @@
+use-linker-depfile
+------------------
+
+* GNU (and GNU-compatible) linkers gained support for a ``--dependency-file``
+ flag in GNU Binutils 2.35 and LLVM's LLD 12.0.0. The
+ :ref:`Makefile <Makefile Generators>` and :ref:`Ninja <Ninja Generators>`
+ generators will now add these flags so that files read by the linker will
+ cause a relink if they change (typically modified timestamps).
+
+ This feature can be controlled by the variable
+ :variable:`CMAKE_LINK_DEPENDS_USE_LINKER`.
diff --git a/Help/release/dev/vs-debugger-init.rst b/Help/release/dev/vs-debugger-init.rst
new file mode 100644
index 0000000000..aa86839b66
--- /dev/null
+++ b/Help/release/dev/vs-debugger-init.rst
@@ -0,0 +1,8 @@
+vs-debugger-init
+----------------
+
+* Variables :variable:`CMAKE_VS_DEBUGGER_COMMAND`,
+ :variable:`CMAKE_VS_DEBUGGER_COMMAND_ARGUMENTS`,
+ :variable:`CMAKE_VS_DEBUGGER_ENVIRONMENT`, and
+ :variable:`CMAKE_VS_DEBUGGER_WORKING_DIRECTORY` were added to initialize
+ corresponding target properties.
diff --git a/Help/variable/CMAKE_APPBUNDLE_PATH.rst b/Help/variable/CMAKE_APPBUNDLE_PATH.rst
index 1c7ca51c2a..441ee8ebb2 100644
--- a/Help/variable/CMAKE_APPBUNDLE_PATH.rst
+++ b/Help/variable/CMAKE_APPBUNDLE_PATH.rst
@@ -4,3 +4,6 @@ CMAKE_APPBUNDLE_PATH
:ref:`Semicolon-separated list <CMake Language Lists>` of directories specifying a search path
for macOS application bundles used by the :command:`find_program`, and
:command:`find_package` commands.
+
+There is also an environment variable :envvar:`CMAKE_APPBUNDLE_PATH`, which is used
+as an additional list of search directories.
diff --git a/Help/variable/CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE.rst b/Help/variable/CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE.rst
new file mode 100644
index 0000000000..80ed8479ec
--- /dev/null
+++ b/Help/variable/CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE.rst
@@ -0,0 +1,10 @@
+CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE
+--------------------------------
+
+.. versionadded:: 3.27
+
+This variable is used to initialize the :prop_tgt:`AUTOGEN_USE_SYSTEM_INCLUDE`
+property on all targets as they are created. See that target property for
+additional information.
+
+By default ``CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE`` is unset.
diff --git a/Help/variable/CMAKE_FRAMEWORK_PATH.rst b/Help/variable/CMAKE_FRAMEWORK_PATH.rst
index 13ade4e5fc..8d62b028f7 100644
--- a/Help/variable/CMAKE_FRAMEWORK_PATH.rst
+++ b/Help/variable/CMAKE_FRAMEWORK_PATH.rst
@@ -5,3 +5,6 @@ CMAKE_FRAMEWORK_PATH
for macOS frameworks used by the :command:`find_library`,
:command:`find_package`, :command:`find_path`, and :command:`find_file`
commands.
+
+There is also an environment variable :envvar:`CMAKE_FRAMEWORK_PATH`, which is used
+as an additional list of search directories.
diff --git a/Help/variable/CMAKE_INCLUDE_PATH.rst b/Help/variable/CMAKE_INCLUDE_PATH.rst
index 4918e99602..3a4472a85f 100644
--- a/Help/variable/CMAKE_INCLUDE_PATH.rst
+++ b/Help/variable/CMAKE_INCLUDE_PATH.rst
@@ -3,5 +3,10 @@ CMAKE_INCLUDE_PATH
:ref:`Semicolon-separated list <CMake Language Lists>` of directories specifying a search path
for the :command:`find_file` and :command:`find_path` commands. By default it
-is empty, it is intended to be set by the project. See also
-:variable:`CMAKE_SYSTEM_INCLUDE_PATH` and :variable:`CMAKE_PREFIX_PATH`.
+is empty, it is intended to be set by the project.
+
+
+There is also an environment variable :envvar:`CMAKE_INCLUDE_PATH`, which is used
+as an additional list of search directories.
+
+See also :variable:`CMAKE_SYSTEM_INCLUDE_PATH` and :variable:`CMAKE_PREFIX_PATH`.
diff --git a/Help/variable/CMAKE_LANG_COMPILER_ID.rst b/Help/variable/CMAKE_LANG_COMPILER_ID.rst
index 3b27fc3a6d..5eb86c603e 100644
--- a/Help/variable/CMAKE_LANG_COMPILER_ID.rst
+++ b/Help/variable/CMAKE_LANG_COMPILER_ID.rst
@@ -9,7 +9,7 @@ include:
=============================== ===============================================
Value Name
=============================== ===============================================
-``Absoft`` `Absoft Fortran`_
+``Absoft`` Absoft Fortran
``ADSP`` Analog VisualDSP++
``AppleClang`` Apple Clang
``ARMCC`` ARM Compiler
@@ -50,7 +50,6 @@ Value Name
This variable is not guaranteed to be defined for all compilers or
languages.
-.. _Absoft Fortran: https://www.absoft.com
.. _LLVM Clang: https://clang.llvm.org
.. _Embarcadero: https://www.embarcadero.com
.. _Classic Flang Fortran Compiler: https://github.com/flang-compiler/flang
diff --git a/Help/variable/CMAKE_LIBRARY_PATH.rst b/Help/variable/CMAKE_LIBRARY_PATH.rst
index 8135b65818..4265982c2c 100644
--- a/Help/variable/CMAKE_LIBRARY_PATH.rst
+++ b/Help/variable/CMAKE_LIBRARY_PATH.rst
@@ -3,5 +3,9 @@ CMAKE_LIBRARY_PATH
:ref:`Semicolon-separated list <CMake Language Lists>` of directories specifying a search path
for the :command:`find_library` command. By default it is empty, it is
-intended to be set by the project. See also
-:variable:`CMAKE_SYSTEM_LIBRARY_PATH` and :variable:`CMAKE_PREFIX_PATH`.
+intended to be set by the project.
+
+There is also an environment variable :envvar:`CMAKE_LIBRARY_PATH`, which is used
+as an additional list of search directories.
+
+See also :variable:`CMAKE_SYSTEM_LIBRARY_PATH` and :variable:`CMAKE_PREFIX_PATH`.
diff --git a/Help/variable/CMAKE_LINK_DEPENDS_USE_LINKER.rst b/Help/variable/CMAKE_LINK_DEPENDS_USE_LINKER.rst
new file mode 100644
index 0000000000..e1b37a59da
--- /dev/null
+++ b/Help/variable/CMAKE_LINK_DEPENDS_USE_LINKER.rst
@@ -0,0 +1,12 @@
+CMAKE_LINK_DEPENDS_USE_LINKER
+-----------------------------
+
+.. versionadded:: 3.27
+
+For the :ref:`Makefile <Makefile Generators>` and
+:ref:`Ninja <Ninja Generators>` generators, link dependencies are now, for a
+selection of linkers, generated by the linker itself. By defining this
+variable with value ``FALSE``, you can deactivate this feature.
+
+This feature is also deactivated if the :prop_tgt:`LINK_DEPENDS_NO_SHARED`
+target property is true.
diff --git a/Help/variable/CMAKE_PREFIX_PATH.rst b/Help/variable/CMAKE_PREFIX_PATH.rst
index 1d4fd0b426..54f2aecde0 100644
--- a/Help/variable/CMAKE_PREFIX_PATH.rst
+++ b/Help/variable/CMAKE_PREFIX_PATH.rst
@@ -10,6 +10,9 @@ documentation.
By default this is empty. It is intended to be set by the project.
+There is also an environment variable :envvar:`CMAKE_PREFIX_PATH`, which is used
+as an additional list of search prefixes.
+
See also :variable:`CMAKE_SYSTEM_PREFIX_PATH`, :variable:`CMAKE_INCLUDE_PATH`,
:variable:`CMAKE_LIBRARY_PATH`, :variable:`CMAKE_PROGRAM_PATH`, and
:variable:`CMAKE_IGNORE_PATH`.
diff --git a/Help/variable/CMAKE_PROGRAM_PATH.rst b/Help/variable/CMAKE_PROGRAM_PATH.rst
index 2d0c090df5..240bacb9a0 100644
--- a/Help/variable/CMAKE_PROGRAM_PATH.rst
+++ b/Help/variable/CMAKE_PROGRAM_PATH.rst
@@ -3,5 +3,9 @@ CMAKE_PROGRAM_PATH
:ref:`Semicolon-separated list <CMake Language Lists>` of directories specifying a search path
for the :command:`find_program` command. By default it is empty, it is
-intended to be set by the project. See also
-:variable:`CMAKE_SYSTEM_PROGRAM_PATH` and :variable:`CMAKE_PREFIX_PATH`.
+intended to be set by the project.
+
+There is also an environment variable :envvar:`CMAKE_PROGRAM_PATH`, which is used
+as an additional list of search directories.
+
+See also :variable:`CMAKE_SYSTEM_PROGRAM_PATH` and :variable:`CMAKE_PREFIX_PATH`.
diff --git a/Help/variable/CMAKE_VS_DEBUGGER_COMMAND.rst b/Help/variable/CMAKE_VS_DEBUGGER_COMMAND.rst
new file mode 100644
index 0000000000..b2c03a1d04
--- /dev/null
+++ b/Help/variable/CMAKE_VS_DEBUGGER_COMMAND.rst
@@ -0,0 +1,8 @@
+CMAKE_VS_DEBUGGER_COMMAND
+-------------------------
+
+.. versionadded:: 3.27
+
+This variable is used to initialize the :prop_tgt:`VS_DEBUGGER_COMMAND`
+property on each target as it is created. See that target property
+for additional information.
diff --git a/Help/variable/CMAKE_VS_DEBUGGER_COMMAND_ARGUMENTS.rst b/Help/variable/CMAKE_VS_DEBUGGER_COMMAND_ARGUMENTS.rst
new file mode 100644
index 0000000000..482aa67e8a
--- /dev/null
+++ b/Help/variable/CMAKE_VS_DEBUGGER_COMMAND_ARGUMENTS.rst
@@ -0,0 +1,8 @@
+CMAKE_VS_DEBUGGER_COMMAND_ARGUMENTS
+-----------------------------------
+
+.. versionadded:: 3.27
+
+This variable is used to initialize the :prop_tgt:`VS_DEBUGGER_COMMAND_ARGUMENTS`
+property on each target as it is created. See that target property
+for additional information.
diff --git a/Help/variable/CMAKE_VS_DEBUGGER_ENVIRONMENT.rst b/Help/variable/CMAKE_VS_DEBUGGER_ENVIRONMENT.rst
new file mode 100644
index 0000000000..245ac5d7f3
--- /dev/null
+++ b/Help/variable/CMAKE_VS_DEBUGGER_ENVIRONMENT.rst
@@ -0,0 +1,8 @@
+CMAKE_VS_DEBUGGER_ENVIRONMENT
+-----------------------------
+
+.. versionadded:: 3.27
+
+This variable is used to initialize the :prop_tgt:`VS_DEBUGGER_ENVIRONMENT`
+property on each target as it is created. See that target property
+for additional information.
diff --git a/Help/variable/CMAKE_VS_DEBUGGER_WORKING_DIRECTORY.rst b/Help/variable/CMAKE_VS_DEBUGGER_WORKING_DIRECTORY.rst
new file mode 100644
index 0000000000..9100adbb43
--- /dev/null
+++ b/Help/variable/CMAKE_VS_DEBUGGER_WORKING_DIRECTORY.rst
@@ -0,0 +1,8 @@
+CMAKE_VS_DEBUGGER_WORKING_DIRECTORY
+-----------------------------------
+
+.. versionadded:: 3.27
+
+This variable is used to initialize the :prop_tgt:`VS_DEBUGGER_WORKING_DIRECTORY`
+property on each target as it is created. See that target property
+for additional information.
diff --git a/Modules/CMakeASMCompiler.cmake.in b/Modules/CMakeASMCompiler.cmake.in
index e300782aee..8a1718bb48 100644
--- a/Modules/CMakeASMCompiler.cmake.in
+++ b/Modules/CMakeASMCompiler.cmake.in
@@ -17,5 +17,6 @@ set(CMAKE_ASM@ASM_DIALECT@_COMPILER_ENV_VAR "@_CMAKE_ASM_COMPILER_ENV_VAR@")
set(CMAKE_ASM@ASM_DIALECT@_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC)
set(CMAKE_ASM@ASM_DIALECT@_LINKER_PREFERENCE 0)
+set(CMAKE_ASM@ASM_DIALECT@_LINKER_DEPFILE_SUPPORTED "@CMAKE_ASM_LINKER_DEPFILE_SUPPORTED@")
@CMAKE_ASM_COMPILER_CUSTOM_CODE@
diff --git a/Modules/CMakeCCompiler.cmake.in b/Modules/CMakeCCompiler.cmake.in
index 8ae07a34e1..cf3a242a64 100644
--- a/Modules/CMakeCCompiler.cmake.in
+++ b/Modules/CMakeCCompiler.cmake.in
@@ -39,6 +39,7 @@ set(CMAKE_C_COMPILER_ID_RUN 1)
set(CMAKE_C_SOURCE_FILE_EXTENSIONS c;m)
set(CMAKE_C_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC)
set(CMAKE_C_LINKER_PREFERENCE 10)
+set(CMAKE_C_LINKER_DEPFILE_SUPPORTED "@CMAKE_C_LINKER_DEPFILE_SUPPORTED@")
# Save compiler ABI information.
set(CMAKE_C_SIZEOF_DATA_PTR "@CMAKE_C_SIZEOF_DATA_PTR@")
diff --git a/Modules/CMakeCUDACompiler.cmake.in b/Modules/CMakeCUDACompiler.cmake.in
index 57d595af30..3d7d55201b 100644
--- a/Modules/CMakeCUDACompiler.cmake.in
+++ b/Modules/CMakeCUDACompiler.cmake.in
@@ -30,6 +30,7 @@ set(CMAKE_CUDA_COMPILER_ID_RUN 1)
set(CMAKE_CUDA_SOURCE_FILE_EXTENSIONS cu)
set(CMAKE_CUDA_LINKER_PREFERENCE 15)
set(CMAKE_CUDA_LINKER_PREFERENCE_PROPAGATES 1)
+set(CMAKE_CUDA_LINKER_DEPFILE_SUPPORTED "@CMAKE_CUDA_LINKER_DEPFILE_SUPPORTED@")
set(CMAKE_CUDA_SIZEOF_DATA_PTR "@CMAKE_CUDA_SIZEOF_DATA_PTR@")
set(CMAKE_CUDA_COMPILER_ABI "@CMAKE_CUDA_COMPILER_ABI@")
diff --git a/Modules/CMakeCXXCompiler.cmake.in b/Modules/CMakeCXXCompiler.cmake.in
index 834c2e6b17..2052e7f903 100644
--- a/Modules/CMakeCXXCompiler.cmake.in
+++ b/Modules/CMakeCXXCompiler.cmake.in
@@ -50,6 +50,7 @@ endforeach()
set(CMAKE_CXX_LINKER_PREFERENCE 30)
set(CMAKE_CXX_LINKER_PREFERENCE_PROPAGATES 1)
+set(CMAKE_CXX_LINKER_DEPFILE_SUPPORTED "@CMAKE_CXX_LINKER_DEPFILE_SUPPORTED@")
# Save compiler ABI information.
set(CMAKE_CXX_SIZEOF_DATA_PTR "@CMAKE_CXX_SIZEOF_DATA_PTR@")
diff --git a/Modules/CMakeDetermineCXXCompiler.cmake b/Modules/CMakeDetermineCXXCompiler.cmake
index c4ddf75e3f..9e38566755 100644
--- a/Modules/CMakeDetermineCXXCompiler.cmake
+++ b/Modules/CMakeDetermineCXXCompiler.cmake
@@ -165,13 +165,13 @@ endif ()
if (NOT _CMAKE_TOOLCHAIN_PREFIX)
- if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU|Clang|QCC|LCC")
+ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|QCC|LCC")
get_filename_component(COMPILER_BASENAME "${CMAKE_CXX_COMPILER}" NAME)
if (COMPILER_BASENAME MATCHES "^(.+-)?(clang\\+\\+|[gc]\\+\\+|clang-cl)(-[0-9]+(\\.[0-9]+)*)?(-[^.]+)?(\\.exe)?$")
set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
set(_CMAKE_TOOLCHAIN_SUFFIX ${CMAKE_MATCH_3})
set(_CMAKE_COMPILER_SUFFIX ${CMAKE_MATCH_5})
- elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
+ elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
if(CMAKE_CXX_COMPILER_TARGET)
set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_CXX_COMPILER_TARGET}-)
endif()
@@ -186,7 +186,7 @@ if (NOT _CMAKE_TOOLCHAIN_PREFIX)
if ("${_CMAKE_TOOLCHAIN_PREFIX}" MATCHES "(.+-)?llvm-$")
set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
endif ()
- elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "TI")
+ elseif(CMAKE_CXX_COMPILER_ID MATCHES "TI")
# TI compilers are named e.g. cl6x, cl470 or armcl.exe
get_filename_component(COMPILER_BASENAME "${CMAKE_CXX_COMPILER}" NAME)
if (COMPILER_BASENAME MATCHES "^(.+)?cl([^.]+)?(\\.exe)?$")
diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake
index 67044fb3b2..403766e561 100644
--- a/Modules/CMakeDetermineCompilerId.cmake
+++ b/Modules/CMakeDetermineCompilerId.cmake
@@ -345,6 +345,7 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS}
set(id_platform ${CMAKE_VS_PLATFORM_NAME})
set(id_lang "${lang}")
set(id_PostBuildEvent_Command "")
+ set(id_api_level "")
if(CMAKE_VS_PLATFORM_TOOLSET MATCHES "^[Ll][Ll][Vv][Mm](_v[0-9]+(_xp)?)?$")
set(id_cl_var "ClangClExecutable")
elseif(CMAKE_VS_PLATFORM_TOOLSET MATCHES "^[Cc][Ll][Aa][Nn][Gg]([Cc][Ll]$|_[0-9])")
@@ -430,9 +431,10 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS}
set(id_system "")
endif()
if(id_keyword STREQUAL "Android")
+ set(id_api_level "<AndroidAPILevel>android-${CMAKE_SYSTEM_VERSION}</AndroidAPILevel>")
if(CMAKE_GENERATOR MATCHES "Visual Studio 14")
set(id_system_version "<ApplicationTypeRevision>2.0</ApplicationTypeRevision>")
- elseif(CMAKE_GENERATOR MATCHES "Visual Studio 1[56]")
+ elseif(CMAKE_GENERATOR MATCHES "Visual Studio 1[567]")
set(id_system_version "<ApplicationTypeRevision>3.0</ApplicationTypeRevision>")
else()
set(id_system_version "")
diff --git a/Modules/CMakeFortranCompiler.cmake.in b/Modules/CMakeFortranCompiler.cmake.in
index fc81d0e5f6..a7caf2be8a 100644
--- a/Modules/CMakeFortranCompiler.cmake.in
+++ b/Modules/CMakeFortranCompiler.cmake.in
@@ -29,6 +29,7 @@ set(CMAKE_Fortran_COMPILER_ID_RUN 1)
set(CMAKE_Fortran_SOURCE_FILE_EXTENSIONS f;F;fpp;FPP;f77;F77;f90;F90;for;For;FOR;f95;F95;f03;F03;f08;F08@CMAKE_Fortran_VENDOR_SOURCE_FILE_EXTENSIONS@)
set(CMAKE_Fortran_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC)
set(CMAKE_Fortran_LINKER_PREFERENCE 20)
+set(CMAKE_Fortran_LINKER_DEPFILE_SUPPORTED "@CMAKE_Fortran_LINKER_DEPFILE_SUPPORTED@")
if(UNIX)
set(CMAKE_Fortran_OUTPUT_EXTENSION .o)
else()
diff --git a/Modules/CMakeHIPCompiler.cmake.in b/Modules/CMakeHIPCompiler.cmake.in
index 8a747c67d8..32c122366e 100644
--- a/Modules/CMakeHIPCompiler.cmake.in
+++ b/Modules/CMakeHIPCompiler.cmake.in
@@ -26,6 +26,7 @@ set(CMAKE_HIP_COMPILER_ID_RUN 1)
set(CMAKE_HIP_SOURCE_FILE_EXTENSIONS hip)
set(CMAKE_HIP_LINKER_PREFERENCE 90)
set(CMAKE_HIP_LINKER_PREFERENCE_PROPAGATES 1)
+set(CMAKE_HIP_LINKER_DEPFILE_SUPPORTED "@CMAKE_HIP_LINKER_DEPFILE_SUPPORTED@")
set(CMAKE_HIP_SIZEOF_DATA_PTR "@CMAKE_HIP_SIZEOF_DATA_PTR@")
set(CMAKE_HIP_COMPILER_ABI "@CMAKE_HIP_COMPILER_ABI@")
diff --git a/Modules/CMakeOBJCCompiler.cmake.in b/Modules/CMakeOBJCCompiler.cmake.in
index ea11a7aa36..0ceb80468c 100644
--- a/Modules/CMakeOBJCCompiler.cmake.in
+++ b/Modules/CMakeOBJCCompiler.cmake.in
@@ -37,6 +37,7 @@ set(CMAKE_OBJC_COMPILER_ID_RUN 1)
set(CMAKE_OBJC_SOURCE_FILE_EXTENSIONS m)
set(CMAKE_OBJC_IGNORE_EXTENSIONS h;H;o;O)
set(CMAKE_OBJC_LINKER_PREFERENCE 5)
+set(CMAKE_OBJC_LINKER_DEPFILE_SUPPORTED "@CMAKE_OBJC_LINKER_DEPFILE_SUPPORTED@")
foreach (lang C CXX OBJCXX)
foreach(extension IN LISTS CMAKE_OBJC_SOURCE_FILE_EXTENSIONS)
diff --git a/Modules/CMakeOBJCXXCompiler.cmake.in b/Modules/CMakeOBJCXXCompiler.cmake.in
index 5d0b381257..f087ec3f52 100644
--- a/Modules/CMakeOBJCXXCompiler.cmake.in
+++ b/Modules/CMakeOBJCXXCompiler.cmake.in
@@ -54,6 +54,7 @@ endforeach()
set(CMAKE_OBJCXX_LINKER_PREFERENCE 25)
set(CMAKE_OBJCXX_LINKER_PREFERENCE_PROPAGATES 1)
+set(CMAKE_OBJCXX_LINKER_DEPFILE_SUPPORTED "@CMAKE_OBJCXX_LINKER_DEPFILE_SUPPORTED@")
# Save compiler ABI information.
set(CMAKE_OBJCXX_SIZEOF_DATA_PTR "@CMAKE_OBJCXX_SIZEOF_DATA_PTR@")
diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake
index f9cf33fa9a..ff1cb7e6fd 100644
--- a/Modules/CPack.cmake
+++ b/Modules/CPack.cmake
@@ -262,8 +262,8 @@ installers. The most commonly-used variables are:
Lists each of the executables and associated text label to be used to
create Start Menu shortcuts. For example, setting this to the list
``ccmake;CMake`` will create a shortcut named "CMake" that will execute the
- installed executable :program:`ccmake`. Not all CPack generators use it (at least
- NSIS, and WIX do).
+ installed executable :program:`ccmake`. Not all CPack generators use it (at least
+ NSIS, Inno Setup and WIX do).
.. variable:: CPACK_STRIP_FILES
@@ -738,14 +738,16 @@ if(NOT CPACK_GENERATOR)
)
endif()
else()
- option(CPACK_BINARY_7Z "Enable to build 7-Zip packages" OFF)
- option(CPACK_BINARY_NSIS "Enable to build NSIS packages" ON)
- option(CPACK_BINARY_NUGET "Enable to build NuGet packages" OFF)
- option(CPACK_BINARY_WIX "Enable to build WiX packages" OFF)
- option(CPACK_BINARY_ZIP "Enable to build ZIP packages" OFF)
+ option(CPACK_BINARY_7Z "Enable to build 7-Zip packages" OFF)
+ option(CPACK_BINARY_NSIS "Enable to build NSIS packages" ON)
+ option(CPACK_BINARY_INNOSETUP "Enable to build Inno Setup packages" OFF)
+ option(CPACK_BINARY_NUGET "Enable to build NuGet packages" OFF)
+ option(CPACK_BINARY_WIX "Enable to build WiX packages" OFF)
+ option(CPACK_BINARY_ZIP "Enable to build ZIP packages" OFF)
mark_as_advanced(
CPACK_BINARY_7Z
CPACK_BINARY_NSIS
+ CPACK_BINARY_INNOSETUP
CPACK_BINARY_NUGET
CPACK_BINARY_WIX
CPACK_BINARY_ZIP
@@ -762,6 +764,7 @@ if(NOT CPACK_GENERATOR)
cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_FREEBSD FREEBSD)
cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_IFW IFW)
cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_NSIS NSIS)
+ cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_INNOSETUP INNOSETUP)
cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_NUGET NuGet)
cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_PRODUCTBUILD productbuild)
cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_RPM RPM)
@@ -869,6 +872,13 @@ if(NOT DEFINED CPACK_DMG_SLA_USE_RESOURCE_FILE_LICENSE
unset(_CPack_CMP0133)
endif()
+# Inno Setup specific variables
+if(CMAKE_SIZEOF_VOID_P EQUAL 4)
+ _cpack_set_default(CPACK_INNOSETUP_ARCHITECTURE "x86")
+elseif(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ _cpack_set_default(CPACK_INNOSETUP_ARCHITECTURE "x64")
+endif()
+
# WiX specific variables
_cpack_set_default(CPACK_WIX_SIZEOF_VOID_P "${CMAKE_SIZEOF_VOID_P}")
diff --git a/Modules/Compiler/Clang-HIP.cmake b/Modules/Compiler/Clang-HIP.cmake
index 4dbe2e8c01..7e3c99c905 100644
--- a/Modules/Compiler/Clang-HIP.cmake
+++ b/Modules/Compiler/Clang-HIP.cmake
@@ -1,4 +1,13 @@
include(Compiler/Clang)
+
+#
+# For now, deactivate globally linker dependency file support because
+# HIP compiler is based on Clang which provides support of other languages
+#
+foreach (lang IN ITEMS "C" "CXX" "OBJC" "OBJCXX" "Fortran" "ASM")
+ set(CMAKE_${lang}_LINKER_DEPFILE_SUPPORTED FALSE)
+endforeach()
+
__compiler_clang(HIP)
__compiler_clang_cxx_standards(HIP)
diff --git a/Modules/Compiler/GNU.cmake b/Modules/Compiler/GNU.cmake
index 5930e377cb..f14020876f 100644
--- a/Modules/Compiler/GNU.cmake
+++ b/Modules/Compiler/GNU.cmake
@@ -52,6 +52,44 @@ macro(__compiler_gnu lang)
set(CMAKE_DEPFILE_FLAGS_${lang} "-MD -MT <DEP_TARGET> -MF <DEP_FILE>")
endif()
+ # define flags for linker depfile generation
+ if (NOT DEFINED CMAKE_${lang}_LINKER_DEPFILE_SUPPORTED)
+ ## Ensure ninja tool is recent enough...
+ if(CMAKE_GENERATOR MATCHES "^Ninja")
+ # Ninja 1.10 or upper is required
+ execute_process(COMMAND "${CMAKE_MAKE_PROGRAM}" --version
+ OUTPUT_VARIABLE _ninja_version
+ ERROR_VARIABLE _ninja_version)
+ if (_ninja_version MATCHES "[0-9]+(\\.[0-9]+)*")
+ set (_ninja_version "${CMAKE_MATCH_0}")
+ endif()
+ if (_ninja_version VERSION_LESS "1.10")
+ set(CMAKE_${lang}_LINKER_DEPFILE_SUPPORTED FALSE)
+ endif()
+ unset(_ninja_version)
+ endif()
+
+ if (NOT DEFINED CMAKE_${lang}_LINKER_DEPFILE_SUPPORTED)
+ ## check if this feature is supported by the linker
+ execute_process(COMMAND "${CMAKE_LINKER}" --help
+ OUTPUT_VARIABLE _linker_capabilities
+ ERROR_VARIABLE _linker_capabilities)
+ if(_linker_capabilities MATCHES "--dependency-file")
+ set(CMAKE_${lang}_LINKER_DEPFILE_SUPPORTED TRUE)
+ else()
+ set(CMAKE_${lang}_LINKER_DEPFILE_SUPPORTED FALSE)
+ endif()
+ unset(_linker_capabilities)
+ endif()
+ endif()
+ if (CMAKE_${lang}_LINKER_DEPFILE_SUPPORTED)
+ set(CMAKE_${lang}_LINKER_DEPFILE_FLAGS "LINKER:--dependency-file,<DEP_FILE>")
+ set(CMAKE_${lang}_LINKER_DEPFILE_FORMAT gcc)
+ set(CMAKE_${lang}_LINK_DEPENDS_USE_LINKER TRUE)
+ else()
+ unset(CMAKE_${lang}_LINK_DEPENDS_USE_LINKER)
+ endif()
+
# Initial configuration flags.
string(APPEND CMAKE_${lang}_FLAGS_INIT " ")
string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT " -g")
diff --git a/Modules/Compiler/IAR.cmake b/Modules/Compiler/IAR.cmake
index 0aca2838a7..32a7b3f5af 100644
--- a/Modules/Compiler/IAR.cmake
+++ b/Modules/Compiler/IAR.cmake
@@ -1,6 +1,6 @@
# This file is processed when the IAR C/C++ Compiler is used
#
-# CPU <arch> supported in CMake: 8051, Arm, AVR, MSP430, RH850, RISC-V, RL78, RX and V850
+# CPU <arch> supported in CMake: 8051, Arm, AVR, MSP430, RH850, RISC-V, RL78, RX, STM8 and V850
#
# The compiler user documentation is architecture-dependent
# and it can found with the product installation under <arch>/doc/{EW,BX}<arch>_DevelopmentGuide.ENU.pdf
@@ -35,7 +35,9 @@ macro(__compiler_iar_ilink lang)
__compiler_iar_common(${lang})
- set(CMAKE_${lang}_LINK_EXECUTABLE "<CMAKE_LINKER> --silent <OBJECTS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> -o <TARGET>")
+ string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " --silent")
+ set(CMAKE_${lang}_LINK_EXECUTABLE "<CMAKE_LINKER> <OBJECTS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> -o <TARGET>")
+
set(CMAKE_${lang}_CREATE_STATIC_LIBRARY "<CMAKE_AR> <TARGET> --create <LINK_FLAGS> <OBJECTS>")
set(CMAKE_${lang}_ARCHIVE_CREATE "<CMAKE_AR> <TARGET> --create <LINK_FLAGS> <OBJECTS>")
set(CMAKE_${lang}_ARCHIVE_APPEND "<CMAKE_AR> <TARGET> --replace <LINK_FLAGS> <OBJECTS>")
@@ -46,7 +48,9 @@ macro(__compiler_iar_xlink lang)
__compiler_iar_common(${lang})
- set(CMAKE_${lang}_LINK_EXECUTABLE "<CMAKE_LINKER> -S <OBJECTS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> -o <TARGET>")
+ string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " -S")
+ set(CMAKE_${lang}_LINK_EXECUTABLE "<CMAKE_LINKER> <OBJECTS> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES> -o <TARGET>")
+
set(CMAKE_${lang}_CREATE_STATIC_LIBRARY "<CMAKE_AR> <TARGET> <LINK_FLAGS> <OBJECTS>")
set(CMAKE_${lang}_ARCHIVE_CREATE "<CMAKE_AR> <TARGET> <LINK_FLAGS> <OBJECTS>")
set(CMAKE_${lang}_ARCHIVE_APPEND "")
diff --git a/Modules/Compiler/NVHPC-Fortran.cmake b/Modules/Compiler/NVHPC-Fortran.cmake
index 5c0645737d..59755b3a71 100644
--- a/Modules/Compiler/NVHPC-Fortran.cmake
+++ b/Modules/Compiler/NVHPC-Fortran.cmake
@@ -1,4 +1,3 @@
include(Compiler/PGI-Fortran)
include(Compiler/NVHPC)
__compiler_nvhpc(Fortran)
-set(CMAKE_Fortran_PREPROCESS_SOURCE_EXCLUDE_FLAGS_REGEX "(^| )-Werror +[a-z][a-z-]+( |$)")
diff --git a/Modules/Compiler/NVHPC.cmake b/Modules/Compiler/NVHPC.cmake
index 474ac80efe..0593456ce7 100644
--- a/Modules/Compiler/NVHPC.cmake
+++ b/Modules/Compiler/NVHPC.cmake
@@ -13,5 +13,5 @@ include(Compiler/PGI)
macro(__compiler_nvhpc lang)
# Logic specific to NVHPC.
set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-isystem ")
- set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "-Werror" "all-warnings")
+ set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "-Werror")
endmacro()
diff --git a/Modules/CompilerId/VS-10.vcxproj.in b/Modules/CompilerId/VS-10.vcxproj.in
index 3598fc7e20..fa324d8214 100644
--- a/Modules/CompilerId/VS-10.vcxproj.in
+++ b/Modules/CompilerId/VS-10.vcxproj.in
@@ -26,6 +26,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|@id_platform@'" Label="Configuration">
<ConfigurationType>@id_config_type@</ConfigurationType>
@id_toolset@
+ @id_api_level@
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
@@ -44,7 +45,7 @@
<PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
- <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <RuntimeLibrary Condition="'$(ApplicationType)'!='Android'">MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>TurnOffAllWarnings</WarningLevel>
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index 9a6cbd6bc4..e2cc497a65 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -278,6 +278,13 @@ External Project Definition
URL of the git repository. Any URL understood by the ``git`` command
may be used.
+ .. versionchanged:: 3.27
+ A relative URL will be resolved based on the parent project's
+ remote, subject to :policy:`CMP0150`. See the policy documentation
+ for how the remote is selected, including conditions where the
+ remote selection can fail. Local filesystem remotes should
+ always use absolute paths.
+
``GIT_TAG <tag>``
Git branch name, tag or commit hash. Note that branch names and tags
should generally be specified as remote names (i.e. ``origin/myBranch``
@@ -1188,6 +1195,8 @@ The custom step could then be triggered from the main build like so::
#]=======================================================================]
+include(${CMAKE_CURRENT_LIST_DIR}/ExternalProject/shared_internal_commands.cmake)
+
cmake_policy(PUSH)
cmake_policy(SET CMP0054 NEW) # if() quoted variables not dereferenced
cmake_policy(SET CMP0057 NEW) # if() supports IN_LIST
@@ -4159,6 +4168,17 @@ function(ExternalProject_Add name)
set_property(TARGET ${name} PROPERTY EXCLUDE_FROM_ALL TRUE)
endif()
+ get_property(repo TARGET ${name} PROPERTY _EP_GIT_REPOSITORY)
+ if(NOT repo STREQUAL "")
+ cmake_policy(GET CMP0150 cmp0150
+ PARENT_SCOPE # undocumented, do not use outside of CMake
+ )
+ get_property(source_dir TARGET ${name} PROPERTY _EP_SOURCE_DIR)
+ get_filename_component(work_dir "${source_dir}" PATH)
+ _ep_resolve_git_remote(resolved_git_repository "${repo}" "${cmp0150}" "${work_dir}")
+ set_property(TARGET ${name} PROPERTY _EP_GIT_REPOSITORY ${resolved_git_repository})
+ endif()
+
# The 'complete' step depends on all other steps and creates a
# 'done' mark. A dependent external project's 'configure' step
# depends on the 'done' mark so that it rebuilds when this project
diff --git a/Modules/ExternalProject/shared_internal_commands.cmake b/Modules/ExternalProject/shared_internal_commands.cmake
new file mode 100644
index 0000000000..ca3cd9fec7
--- /dev/null
+++ b/Modules/ExternalProject/shared_internal_commands.cmake
@@ -0,0 +1,182 @@
+cmake_policy(VERSION 3.25)
+
+# Determine the remote URL of the project containing the working_directory.
+# This will leave output_variable unset if the URL can't be determined.
+function(_ep_get_git_remote_url output_variable working_directory)
+ set("${output_variable}" "" PARENT_SCOPE)
+
+ find_package(Git QUIET REQUIRED)
+
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} symbolic-ref --short HEAD
+ WORKING_DIRECTORY "${working_directory}"
+ OUTPUT_VARIABLE git_symbolic_ref
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET
+ )
+
+ if(NOT git_symbolic_ref STREQUAL "")
+ # We are potentially on a branch. See if that branch is associated with
+ # an upstream remote (might be just a local one or not a branch at all).
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} config branch.${git_symbolic_ref}.remote
+ WORKING_DIRECTORY "${working_directory}"
+ OUTPUT_VARIABLE git_remote_name
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET
+ )
+ endif()
+
+ if(NOT git_remote_name)
+ # Can't select a remote based on a branch. If there's only one remote,
+ # or we have multiple remotes but one is called "origin", choose that.
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} remote
+ WORKING_DIRECTORY "${working_directory}"
+ OUTPUT_VARIABLE git_remote_list
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_QUIET
+ )
+ string(REPLACE "\n" ";" git_remote_list "${git_remote_list}")
+ list(LENGTH git_remote_list git_remote_list_length)
+
+ if(git_remote_list_length EQUAL 0)
+ message(FATAL_ERROR "Git remote not found in parent project.")
+ elseif(git_remote_list_length EQUAL 1)
+ list(GET git_remote_list 0 git_remote_name)
+ else()
+ set(base_warning_msg "Multiple git remotes found for parent project")
+ if("origin" IN_LIST git_remote_list)
+ message(WARNING "${base_warning_msg}, defaulting to origin.")
+ set(git_remote_name "origin")
+ else()
+ message(FATAL_ERROR "${base_warning_msg}, none of which are origin.")
+ endif()
+ endif()
+ endif()
+
+ if(GIT_VERSION VERSION_LESS 1.7.5)
+ set(_git_remote_url_cmd_args config remote.${git_remote_name}.url)
+ elseif(GIT_VERSION VERSION_LESS 2.7)
+ set(_git_remote_url_cmd_args ls-remote --get-url ${git_remote_name})
+ else()
+ set(_git_remote_url_cmd_args remote get-url ${git_remote_name})
+ endif()
+
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} ${_git_remote_url_cmd_args}
+ WORKING_DIRECTORY "${working_directory}"
+ OUTPUT_VARIABLE git_remote_url
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ COMMAND_ERROR_IS_FATAL LAST
+ ENCODING UTF-8 # Needed to handle non-ascii characters in local paths
+ )
+
+ set("${output_variable}" "${git_remote_url}" PARENT_SCOPE)
+endfunction()
+
+function(_ep_is_relative_git_remote output_variable remote_url)
+ if(remote_url MATCHES "^\\.\\./")
+ set("${output_variable}" TRUE PARENT_SCOPE)
+ else()
+ set("${output_variable}" FALSE PARENT_SCOPE)
+ endif()
+endfunction()
+
+# Return an absolute remote URL given an existing remote URL and relative path.
+# The output_variable will be set to an empty string if an absolute URL
+# could not be computed (no error message is output).
+function(_ep_resolve_relative_git_remote
+ output_variable
+ parent_remote_url
+ relative_remote_url
+)
+ set("${output_variable}" "" PARENT_SCOPE)
+
+ if(parent_remote_url STREQUAL "")
+ return()
+ endif()
+
+ string(REGEX MATCH
+ "^(([A-Za-z0-9][A-Za-z0-9+.-]*)://)?(([^/@]+)@)?(\\[[A-Za-z0-9:]+\\]|[^/:]+)?([/:]/?)(.+(\\.git)?/?)$"
+ git_remote_url_components
+ "${parent_remote_url}"
+ )
+
+ set(protocol "${CMAKE_MATCH_1}")
+ set(auth "${CMAKE_MATCH_3}")
+ set(host "${CMAKE_MATCH_5}")
+ set(separator "${CMAKE_MATCH_6}")
+ set(path "${CMAKE_MATCH_7}")
+
+ string(REPLACE "/" ";" remote_path_components "${path}")
+ string(REPLACE "/" ";" relative_path_components "${relative_remote_url}")
+
+ foreach(relative_path_component IN LISTS relative_path_components)
+ if(NOT relative_path_component STREQUAL "..")
+ break()
+ endif()
+
+ list(LENGTH remote_path_components remote_path_component_count)
+
+ if(remote_path_component_count LESS 1)
+ return()
+ endif()
+
+ list(POP_BACK remote_path_components)
+ list(POP_FRONT relative_path_components)
+ endforeach()
+
+ list(APPEND final_path_components ${remote_path_components} ${relative_path_components})
+ list(JOIN final_path_components "/" path)
+
+ set("${output_variable}" "${protocol}${auth}${host}${separator}${path}" PARENT_SCOPE)
+endfunction()
+
+# The output_variable will be set to the original git_repository if it
+# could not be resolved (no error message is output). The original value is
+# also returned if it doesn't need to be resolved.
+function(_ep_resolve_git_remote
+ output_variable
+ git_repository
+ cmp0150
+ cmp0150_old_base_dir
+)
+ if(git_repository STREQUAL "")
+ set("${output_variable}" "" PARENT_SCOPE)
+ return()
+ endif()
+
+ _ep_is_relative_git_remote(_git_repository_is_relative "${git_repository}")
+
+ if(NOT _git_repository_is_relative)
+ set("${output_variable}" "${git_repository}" PARENT_SCOPE)
+ return()
+ endif()
+
+ if(cmp0150 STREQUAL "NEW")
+ _ep_get_git_remote_url(_parent_git_remote_url "${CMAKE_CURRENT_SOURCE_DIR}")
+ _ep_resolve_relative_git_remote(_resolved_git_remote_url "${_parent_git_remote_url}" "${git_repository}")
+
+ if(_resolved_git_remote_url STREQUAL "")
+ message(FATAL_ERROR
+ "Failed to resolve relative git remote URL:\n"
+ " Relative URL: ${git_repository}\n"
+ " Parent URL: ${_parent_git_remote_url}"
+ )
+ endif()
+ set("${output_variable}" "${_resolved_git_remote_url}" PARENT_SCOPE)
+ return()
+ elseif(cmp0150 STREQUAL "")
+ cmake_policy(GET_WARNING CMP0150 _cmp0150_warning)
+ message(AUTHOR_WARNING
+ "${_cmp0150_warning}\n"
+ "A relative GIT_REPOSITORY path was detected. "
+ "This will be interpreted as a local path to where the project is being cloned. "
+ "Set GIT_REPOSITORY to an absolute path or set policy CMP0150 to NEW to avoid "
+ "this warning."
+ )
+ endif()
+
+ set("${output_variable}" "${cmp0150_old_base_dir}/${git_repository}" PARENT_SCOPE)
+endfunction()
diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake
index dd5f617acd..74ac8aab2a 100644
--- a/Modules/FetchContent.cmake
+++ b/Modules/FetchContent.cmake
@@ -1076,6 +1076,8 @@ current working directory.
#]=======================================================================]
+include(${CMAKE_CURRENT_LIST_DIR}/ExternalProject/shared_internal_commands.cmake)
+
#=======================================================================
# Recording and retrieving content details for later population
#=======================================================================
@@ -1223,6 +1225,7 @@ function(FetchContent_Declare contentName)
# cannot check for multi-value arguments with this method. We will have to
# handle the URL keyword differently.
set(oneValueArgs
+ GIT_REPOSITORY
SVN_REPOSITORY
DOWNLOAD_NO_EXTRACT
DOWNLOAD_EXTRACT_TIMESTAMP
@@ -1242,6 +1245,30 @@ function(FetchContent_Declare contentName)
set(ARG_SOURCE_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-src")
endif()
+ if(ARG_GIT_REPOSITORY)
+ # We resolve the GIT_REPOSITORY here so that we get the right parent in the
+ # remote selection logic. In the sub-build, ExternalProject_Add() would see
+ # the private sub-build directory as the parent project, but the parent
+ # project should be the one that called FetchContent_Declare(). We resolve
+ # a relative repo here so that the sub-build's ExternalProject_Add() only
+ # ever sees a non-relative repo.
+ # Since these checks may be non-trivial on some platforms (notably Windows),
+ # don't perform them if we won't be using these details. This also allows
+ # projects to override calls with relative URLs when they have checked out
+ # the parent project in an unexpected way, such as from a mirror or fork.
+ set(savedDetailsPropertyName "_FetchContent_${contentNameLower}_savedDetails")
+ get_property(alreadyDefined GLOBAL PROPERTY ${savedDetailsPropertyName} DEFINED)
+ if(NOT alreadyDefined)
+ cmake_policy(GET CMP0150 cmp0150
+ PARENT_SCOPE # undocumented, do not use outside of CMake
+ )
+ _ep_resolve_git_remote(_resolved_git_repository
+ "${ARG_GIT_REPOSITORY}" "${cmp0150}" "${FETCHCONTENT_BASE_DIR}"
+ )
+ set(ARG_GIT_REPOSITORY "${_resolved_git_repository}")
+ endif()
+ endif()
+
if(ARG_SVN_REPOSITORY)
# Add a hash of the svn repository URL to the source dir. This works
# around the problem where if the URL changes, the download would
diff --git a/Modules/FindBLAS.cmake b/Modules/FindBLAS.cmake
index 19bef9471c..39a1163533 100644
--- a/Modules/FindBLAS.cmake
+++ b/Modules/FindBLAS.cmake
@@ -93,6 +93,11 @@ BLAS/LAPACK Vendors
``ACML``, ``ACML_MP``, ``ACML_GPU``
AMD Core Math Library
+``AOCL``, ``AOCL_mt``
+ .. versionadded:: 3.27
+
+ AMD Optimizing CPU Libraries
+
``Apple``, ``NAS``
Apple BLAS (Accelerate), and Apple NAS (vecLib)
@@ -848,6 +853,38 @@ if(BLA_VENDOR STREQUAL "FLAME" OR BLA_VENDOR STREQUAL "All")
unset(_blas_flame_lib)
endif()
+# AOCL's blis library? (https://developer.amd.com/amd-aocl/)
+if(BLA_VENDOR MATCHES "AOCL" OR BLA_VENDOR STREQUAL "All")
+ set(_blas_aocl_lib "blis")
+
+ if(_blas_sizeof_integer EQUAL 8)
+ set(_blas_aocl_subdir "ILP64")
+ else()
+ set(_blas_aocl_subdir "LP64")
+ endif()
+
+ # Check for multi-threaded support
+ if(BLA_VENDOR MATCHES "_mt")
+ string(APPEND _blas_aocl_lib "-mt")
+ endif()
+
+ if(NOT BLAS_LIBRARIES)
+ check_blas_libraries(
+ BLAS_LIBRARIES
+ BLAS
+ sgemm
+ ""
+ "${_blas_aocl_lib}"
+ ""
+ ""
+ "${_blas_aocl_subdir}"
+ )
+ endif()
+
+ unset(_blas_aocl_lib)
+ unset(_blas_aocl_subdir)
+endif()
+
# BLAS in the ATLAS library? (http://math-atlas.sourceforge.net/)
if(BLA_VENDOR STREQUAL "ATLAS" OR BLA_VENDOR STREQUAL "All")
if(NOT BLAS_LIBRARIES)
diff --git a/Modules/FindCUDAToolkit.cmake b/Modules/FindCUDAToolkit.cmake
index 4423ebb628..107ced7f83 100644
--- a/Modules/FindCUDAToolkit.cmake
+++ b/Modules/FindCUDAToolkit.cmake
@@ -29,8 +29,8 @@ The CUDA Toolkit search behavior uses the following order:
precedence.
The directory specified here must be such that the executable ``nvcc`` or
- the appropriate ``version.txt`` file can be found underneath the specified
- directory.
+ the appropriate ``version.txt`` or ``version.json`` file can be found
+ underneath the specified directory.
3. If the CUDA_PATH environment variable is defined, it will be searched
for ``nvcc``.
@@ -388,7 +388,6 @@ nvRTC
"""""
The `nvRTC <https://docs.nvidia.com/cuda/nvrtc/index.html>`_ (Runtime Compilation) library.
-This is a shared library only.
Targets Created:
@@ -492,7 +491,7 @@ Result variables
``CUDAToolkit_VERSION``
The exact version of the CUDA Toolkit found (as reported by
- ``nvcc --version`` or ``version.txt``).
+ ``nvcc --version``, ``version.txt``, or ``version.json``).
``CUDAToolkit_VERSION_MAJOR``
The major version of the CUDA Toolkit.
@@ -519,7 +518,7 @@ Result variables
.. versionadded:: 3.18
The path to the CUDA Toolkit directory containing the nvvm directory and
- version.txt.
+ either version.txt or version.json.
``CUDAToolkit_TARGET_DIR``
The path to the CUDA Toolkit directory including the target architecture
@@ -604,7 +603,7 @@ else()
if(NOT CUDAToolkit_NVCC_EXECUTABLE)
find_file(CUDAToolkit_SENTINEL_FILE
- NAMES version.txt
+ NAMES version.txt version.json
PATHS ${arg_SEARCH_PATHS}
NO_DEFAULT_PATH
)
@@ -645,14 +644,43 @@ else()
function(_CUDAToolkit_find_version_file result_variable)
# We first check for a non-scattered installation to prefer it over a scattered installation.
- if(CUDAToolkit_ROOT AND EXISTS "${CUDAToolkit_ROOT}/version.txt")
- set(${result_variable} "${CUDAToolkit_ROOT}/version.txt" PARENT_SCOPE)
- elseif(CUDAToolkit_ROOT_DIR AND EXISTS "${CUDAToolkit_ROOT_DIR}/version.txt")
- set(${result_variable} "${CUDAToolkit_ROOT_DIR}/version.txt" PARENT_SCOPE)
- elseif(CMAKE_SYSROOT_LINK AND EXISTS "${CMAKE_SYSROOT_LINK}/usr/lib/cuda/version.txt")
- set(${result_variable} "${CMAKE_SYSROOT_LINK}/usr/lib/cuda/version.txt" PARENT_SCOPE)
- elseif(EXISTS "${CMAKE_SYSROOT}/usr/lib/cuda/version.txt")
- set(${result_variable} "${CMAKE_SYSROOT}/usr/lib/cuda/version.txt" PARENT_SCOPE)
+ set(version_files version.txt version.json)
+ foreach(vf IN LISTS version_files)
+ if(CUDAToolkit_ROOT AND EXISTS "${CUDAToolkit_ROOT}/${vf}")
+ set(${result_variable} "${CUDAToolkit_ROOT}/${vf}" PARENT_SCOPE)
+ break()
+ elseif(CUDAToolkit_ROOT_DIR AND EXISTS "${CUDAToolkit_ROOT_DIR}/${vf}")
+ set(${result_variable} "${CUDAToolkit_ROOT_DIR}/${vf}" PARENT_SCOPE)
+ break()
+ elseif(CMAKE_SYSROOT_LINK AND EXISTS "${CMAKE_SYSROOT_LINK}/usr/lib/cuda/${vf}")
+ set(${result_variable} "${CMAKE_SYSROOT_LINK}/usr/lib/cuda/${vf}" PARENT_SCOPE)
+ break()
+ elseif(EXISTS "${CMAKE_SYSROOT}/usr/lib/cuda/${vf}")
+ set(${result_variable} "${CMAKE_SYSROOT}/usr/lib/cuda/${vf}" PARENT_SCOPE)
+ break()
+ endif()
+ endforeach()
+ endfunction()
+
+ function(_CUDAToolkit_parse_version_file version_file)
+ if(version_file)
+ file(READ "${version_file}" file_conents)
+ cmake_path(GET version_file EXTENSION LAST_ONLY version_ext)
+ if(version_ext STREQUAL ".json")
+ string(JSON cuda_version_info GET "${file_conents}" "cuda" "version")
+ set(cuda_version_match_regex [=[([0-9]+)\.([0-9]+)\.([0-9]+)]=])
+ elseif(version_ext STREQUAL ".txt")
+ set(cuda_version_info "${file_conents}")
+ set(cuda_version_match_regex [=[CUDA Version ([0-9]+)\.([0-9]+)\.([0-9]+)]=])
+ endif()
+
+ if(cuda_version_info MATCHES "${cuda_version_match_regex}")
+ set(CUDAToolkit_VERSION_MAJOR "${CMAKE_MATCH_1}" PARENT_SCOPE)
+ set(CUDAToolkit_VERSION_MINOR "${CMAKE_MATCH_2}" PARENT_SCOPE)
+ set(CUDAToolkit_VERSION_PATCH "${CMAKE_MATCH_3}" PARENT_SCOPE)
+ set(CUDAToolkit_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}" PARENT_SCOPE)
+ message(STATUS "_CUDAToolkit_parse_version_file")
+ endif()
endif()
endfunction()
@@ -799,15 +827,7 @@ else()
unset(NVCC_OUT)
else()
_CUDAToolkit_find_version_file(version_file)
- if(version_file)
- file(READ "${version_file}" VERSION_INFO)
- if(VERSION_INFO MATCHES [=[CUDA Version ([0-9]+)\.([0-9]+)\.([0-9]+)]=])
- set(CUDAToolkit_VERSION_MAJOR "${CMAKE_MATCH_1}")
- set(CUDAToolkit_VERSION_MINOR "${CMAKE_MATCH_2}")
- set(CUDAToolkit_VERSION_PATCH "${CMAKE_MATCH_3}")
- set(CUDAToolkit_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}")
- endif()
- endif()
+ _CUDAToolkit_parse_version_file("${version_file}")
endif()
endif()
@@ -945,6 +965,19 @@ if(CUDAToolkit_FOUND)
file(REAL_PATH "${CUDAToolkit_LIBRARY_DIR}/../" _cmake_search_dir)
list(APPEND CUDAToolkit_LIBRARY_SEARCH_DIRS "${_cmake_search_dir}")
endif()
+
+ # If no `CUDAToolkit_LIBRARY_ROOT` exists set it based on CUDAToolkit_LIBRARY_DIR
+ if(NOT DEFINED CUDAToolkit_LIBRARY_ROOT)
+ foreach(CUDAToolkit_search_loc IN LISTS CUDAToolkit_LIBRARY_DIR CUDAToolkit_BIN_DIR)
+ get_filename_component(CUDAToolkit_possible_lib_root "${CUDAToolkit_search_loc}" DIRECTORY ABSOLUTE)
+ if(EXISTS "${CUDAToolkit_possible_lib_root}/nvvm/")
+ set(CUDAToolkit_LIBRARY_ROOT "${CUDAToolkit_possible_lib_root}")
+ break()
+ endif()
+ endforeach()
+ unset(CUDAToolkit_search_loc)
+ unset(CUDAToolkit_possible_lib_root)
+ endif()
endif()
@@ -1042,7 +1075,11 @@ if(CUDAToolkit_FOUND)
endif()
_CUDAToolkit_find_and_add_import_lib(culibos) # it's a static library
- foreach (cuda_lib cublasLt cufft curand nppc nvjpeg)
+ foreach (cuda_lib cublasLt cufft nvjpeg)
+ _CUDAToolkit_find_and_add_import_lib(${cuda_lib})
+ _CUDAToolkit_find_and_add_import_lib(${cuda_lib}_static DEPS cudart_static_deps culibos)
+ endforeach()
+ foreach (cuda_lib curand nppc)
_CUDAToolkit_find_and_add_import_lib(${cuda_lib})
_CUDAToolkit_find_and_add_import_lib(${cuda_lib}_static DEPS culibos)
endforeach()
@@ -1146,7 +1183,12 @@ if(CUDAToolkit_FOUND)
_CUDAToolkit_find_and_add_import_lib(nvrtc DEPS nvrtc_builtins nvJitLink)
if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 11.5.0)
_CUDAToolkit_find_and_add_import_lib(nvrtc_builtins_static ALT nvrtc-builtins_static DEPS cuda_driver)
- _CUDAToolkit_find_and_add_import_lib(nvrtc_static DEPS nvrtc_builtins_static nvptxcompiler_static nvJitLink_static)
+ if(NOT TARGET CUDA::nvrtc_static)
+ _CUDAToolkit_find_and_add_import_lib(nvrtc_static DEPS nvrtc_builtins_static nvptxcompiler_static nvJitLink_static)
+ if(TARGET CUDA::nvrtc_static AND WIN32 AND NOT (BORLAND OR MINGW OR CYGWIN))
+ target_link_libraries(CUDA::nvrtc_static INTERFACE Ws2_32.lib)
+ endif()
+ endif()
endif()
_CUDAToolkit_find_and_add_import_lib(nvml ALT nvidia-ml nvml)
diff --git a/Modules/FindDoxygen.cmake b/Modules/FindDoxygen.cmake
index ef9801eb24..76f47590c3 100644
--- a/Modules/FindDoxygen.cmake
+++ b/Modules/FindDoxygen.cmake
@@ -76,7 +76,8 @@ Functions
[ALL]
[USE_STAMP_FILE]
[WORKING_DIRECTORY dir]
- [COMMENT comment])
+ [COMMENT comment]
+ [CONFIG_FILE filename])
The function constructs a ``Doxyfile`` and defines a custom target that runs
Doxygen on that generated file. The listed files and directories are used as
@@ -97,6 +98,10 @@ Functions
the :command:`add_custom_target` command used to create the custom target
internally.
+ .. versionadded:: 3.27
+ If ``CONFIG_FILE`` is set, the given file provided with full-path
+ will be used as doxygen configuration file
+
.. versionadded:: 3.12
If ``ALL`` is set, the target will be added to the default build target.
@@ -864,7 +869,7 @@ endfunction()
function(doxygen_add_docs targetName)
set(_options ALL USE_STAMP_FILE)
- set(_one_value_args WORKING_DIRECTORY COMMENT)
+ set(_one_value_args WORKING_DIRECTORY COMMENT CONFIG_FILE)
set(_multi_value_args)
cmake_parse_arguments(_args
"${_options}"
@@ -1166,8 +1171,15 @@ doxygen_add_docs() for target ${targetName}")
# Prepare doxygen configuration file
set(_doxyfile_template "${CMAKE_BINARY_DIR}/CMakeDoxyfile.in")
- set(_target_doxyfile "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile.${targetName}")
- configure_file("${_doxyfile_template}" "${_target_doxyfile}")
+ if(_args_CONFIG_FILE)
+ if(NOT EXISTS "${_args_CONFIG_FILE}")
+ message(FATAL_ERROR "Option CONFIG_FILE specifies file:\n ${_args_CONFIG_FILE}\nbut it does not exist.")
+ endif()
+ set(_target_doxyfile "${_args_CONFIG_FILE}")
+ else()
+ set(_target_doxyfile "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile.${targetName}")
+ configure_file("${_doxyfile_template}" "${_target_doxyfile}")
+ endif()
unset(_all)
if(${_args_ALL})
diff --git a/Modules/FindJNI.cmake b/Modules/FindJNI.cmake
index 64163b008a..27f9b0e199 100644
--- a/Modules/FindJNI.cmake
+++ b/Modules/FindJNI.cmake
@@ -290,6 +290,13 @@ set(_JNI_JAVA_DIRECTORIES_BASE
# Arch Linux specific paths for default JVM
/usr/lib/jvm/default
# Ubuntu specific paths for default JVM
+ /usr/lib/jvm/java-21-openjdk-{libarch} # Ubuntu 23.04
+ /usr/lib/jvm/java-20-openjdk-{libarch} # Ubuntu 22.10
+ /usr/lib/jvm/java-19-openjdk-{libarch} # Ubuntu 22.04 LTS
+ /usr/lib/jvm/java-18-openjdk-{libarch} # Ubuntu 22.04 LTS
+ /usr/lib/jvm/java-17-openjdk-{libarch} # Ubuntu 18.04 LTS
+ /usr/lib/jvm/java-16-openjdk-{libarch} # Ubuntu 20.04 LTS
+ /usr/lib/jvm/java-13-openjdk-{libarch} # Ubuntu 20.04 LTS
/usr/lib/jvm/java-11-openjdk-{libarch} # Ubuntu 18.04 LTS
/usr/lib/jvm/java-8-openjdk-{libarch} # Ubuntu 15.10
/usr/lib/jvm/java-7-openjdk-{libarch} # Ubuntu 15.10
diff --git a/Modules/FindLAPACK.cmake b/Modules/FindLAPACK.cmake
index 17117bd871..4d3ab5a0f3 100644
--- a/Modules/FindLAPACK.cmake
+++ b/Modules/FindLAPACK.cmake
@@ -561,6 +561,29 @@ if(NOT LAPACK_NOT_FOUND_MESSAGE)
endif()
endif()
+ # AOCL? (https://developer.amd.com/amd-aocl/)
+ if(NOT LAPACK_LIBRARIES
+ AND (BLA_VENDOR MATCHES "AOCL" OR BLA_VENDOR STREQUAL "All"))
+ if(_lapack_sizeof_integer EQUAL 8)
+ set(_lapack_aocl_subdir "ILP64")
+ else()
+ set(_lapack_aocl_subdir "LP64")
+ endif()
+
+ check_lapack_libraries(
+ LAPACK_LIBRARIES
+ LAPACK
+ cheev
+ ""
+ "flame"
+ "-fopenmp"
+ ""
+ "${_lapack_aocl_subdir}"
+ "${BLAS_LIBRARIES}"
+ )
+ unset(_lapack_aocl_subdir)
+ endif()
+
# LAPACK in SCSL library? (SGI/Cray Scientific Library)
if(NOT LAPACK_LIBRARIES
AND (BLA_VENDOR MATCHES "SCSL" OR BLA_VENDOR STREQUAL "All"))
diff --git a/Modules/FindPython.cmake b/Modules/FindPython.cmake
index 31ef1c7d53..e6f44e0cad 100644
--- a/Modules/FindPython.cmake
+++ b/Modules/FindPython.cmake
@@ -335,6 +335,8 @@ Hints
constraints is founded.
This is the default if policy :policy:`CMP0094` is set to ``NEW``.
+ See also ``Python_FIND_UNVERSIONED_NAMES``.
+
``Python_FIND_REGISTRY``
.. versionadded:: 3.13
@@ -442,6 +444,8 @@ Hints
This is the default.
* ``NEVER``: The generic name are not searched at all.
+ See also ``Python_FIND_STRATEGY``.
+
Artifacts Specification
^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/Modules/FindPython2.cmake b/Modules/FindPython2.cmake
index 41d9b689ac..0575ea5a45 100644
--- a/Modules/FindPython2.cmake
+++ b/Modules/FindPython2.cmake
@@ -234,6 +234,8 @@ Hints
constraints is founded.
This is the default if policy :policy:`CMP0094` is set to ``NEW``.
+ See also ``Python2_FIND_UNVERSIONED_NAMES``.
+
``Python2_FIND_REGISTRY``
.. versionadded:: 3.13
@@ -341,6 +343,8 @@ Hints
This is the default.
* ``NEVER``: The generic name are not searched at all.
+ See also ``Python2_FIND_STRATEGY``.
+
Artifacts Specification
^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/Modules/FindPython3.cmake b/Modules/FindPython3.cmake
index ae086e8546..18929b2d92 100644
--- a/Modules/FindPython3.cmake
+++ b/Modules/FindPython3.cmake
@@ -333,6 +333,8 @@ Hints
constraints is founded.
This is the default if policy :policy:`CMP0094` is set to ``NEW``.
+ See also ``Python3_FIND_UNVERSIONED_NAMES``.
+
``Python3_FIND_REGISTRY``
.. versionadded:: 3.13
@@ -440,6 +442,8 @@ Hints
This is the default.
* ``NEVER``: The generic name are not searched at all.
+ See also ``Python3_FIND_STRATEGY``.
+
Artifacts Specification
^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/Modules/FindX11.cmake b/Modules/FindX11.cmake
index 6f6483ab73..1047e4fb87 100644
--- a/Modules/FindX11.cmake
+++ b/Modules/FindX11.cmake
@@ -22,55 +22,77 @@ and also the following more fine grained variables and targets:
::
- X11_ICE_INCLUDE_PATH, X11_ICE_LIB, X11_ICE_FOUND, X11::ICE
- X11_SM_INCLUDE_PATH, X11_SM_LIB, X11_SM_FOUND, X11::SM
- X11_X11_INCLUDE_PATH, X11_X11_LIB, X11::X11
+ X11_ICE_INCLUDE_PATH, X11_ICE_LIB, X11_ICE_FOUND, X11::ICE
+ X11_SM_INCLUDE_PATH, X11_SM_LIB, X11_SM_FOUND, X11::SM
+ X11_X11_INCLUDE_PATH, X11_X11_LIB, X11::X11
X11_Xaccessrules_INCLUDE_PATH,
- X11_Xaccessstr_INCLUDE_PATH, X11_Xaccess_FOUND
- X11_Xau_INCLUDE_PATH, X11_Xau_LIB, X11_Xau_FOUND, X11::Xau
- X11_xcb_INCLUDE_PATH, X11_xcb_LIB, X11_xcb_FOUND, X11::xcb
- X11_X11_xcb_INCLUDE_PATH, X11_X11_xcb_LIB, X11_X11_xcb_FOUND, X11::X11_xcb
- X11_xcb_cursor_INCLUDE_PATH, X11_xcb_cursor_LIB, X11_xcb_cursor_FOUND, X11::xcb_cursor
- X11_xcb_icccm_INCLUDE_PATH, X11_xcb_icccm_LIB, X11_xcb_icccm_FOUND, X11::xcb_icccm
- X11_xcb_randr_INCLUDE_PATH, X11_xcb_randr_LIB, X11_xcb_randr_FOUND, X11::xcb_randr
- X11_xcb_shape_INCLUDE_PATH, X11_xcb_shape_LIB, X11_xcb_shape_FOUND, X11::xcb_shape
- X11_xcb_util_INCLUDE_PATH, X11_xcb_util_LIB, X11_xcb_util_FOUND, X11::xcb_util
- X11_xcb_xfixes_INCLUDE_PATH, X11_xcb_xfixes_LIB, X11_xcb_xfixes_FOUND, X11::xcb_xfixes
- X11_xcb_xrm_INCLUDE_PATH, X11_xcb_xrm_LIB, X11_xcb_xrm_FOUND, X11::xcb_xrm
- X11_xcb_xtest_INCLUDE_PATH, X11_xcb_xtest_LIB, X11_xcb_xtest_FOUND, X11::xcb_xtest
- X11_xcb_keysyms_INCLUDE_PATH, X11_xcb_keysyms_LIB,X11_xcb_keysyms_FOUND,X11::xcb_keysyms
- X11_xcb_xkb_INCLUDE_PATH, X11_xcb_xkb_LIB, X11_xcb_xkb_FOUND, X11::xcb_xkb
- X11_Xcomposite_INCLUDE_PATH, X11_Xcomposite_LIB, X11_Xcomposite_FOUND, X11::Xcomposite
- X11_Xcursor_INCLUDE_PATH, X11_Xcursor_LIB, X11_Xcursor_FOUND, X11::Xcursor
- X11_Xdamage_INCLUDE_PATH, X11_Xdamage_LIB, X11_Xdamage_FOUND, X11::Xdamage
- X11_Xdmcp_INCLUDE_PATH, X11_Xdmcp_LIB, X11_Xdmcp_FOUND, X11::Xdmcp
- X11_Xext_INCLUDE_PATH, X11_Xext_LIB, X11_Xext_FOUND, X11::Xext
- X11_Xxf86misc_INCLUDE_PATH, X11_Xxf86misc_LIB, X11_Xxf86misc_FOUND, X11::Xxf86misc
- X11_Xxf86vm_INCLUDE_PATH, X11_Xxf86vm_LIB X11_Xxf86vm_FOUND, X11::Xxf86vm
- X11_Xfixes_INCLUDE_PATH, X11_Xfixes_LIB, X11_Xfixes_FOUND, X11::Xfixes
- X11_Xft_INCLUDE_PATH, X11_Xft_LIB, X11_Xft_FOUND, X11::Xft
- X11_Xi_INCLUDE_PATH, X11_Xi_LIB, X11_Xi_FOUND, X11::Xi
- X11_Xinerama_INCLUDE_PATH, X11_Xinerama_LIB, X11_Xinerama_FOUND, X11::Xinerama
+ X11_Xaccessstr_INCLUDE_PATH, X11_Xaccess_FOUND
+ X11_Xau_INCLUDE_PATH, X11_Xau_LIB, X11_Xau_FOUND, X11::Xau
+ X11_xcb_INCLUDE_PATH, X11_xcb_LIB, X11_xcb_FOUND, X11::xcb
+ X11_X11_xcb_INCLUDE_PATH, X11_X11_xcb_LIB, X11_X11_xcb_FOUND, X11::X11_xcb
+ X11_xcb_composite_INCLUDE_PATH, X11_xcb_composite_LIB, X11_xcb_composite_FOUND, X11::xcb_composite
+ X11_xcb_cursor_INCLUDE_PATH, X11_xcb_cursor_LIB, X11_xcb_cursor_FOUND, X11::xcb_cursor
+ X11_xcb_damage_INCLUDE_PATH, X11_xcb_damage_LIB, X11_xcb_damage_FOUND, X11::xcb_damage
+ X11_xcb_dpms_INCLUDE_PATH, X11_xcb_dpms_LIB, X11_xcb_dpms_FOUND, X11::xcb_dpms
+ X11_xcb_dri2_INCLUDE_PATH, X11_xcb_dri2_LIB, X11_xcb_dri2_FOUND, X11::xcb_dri2
+ X11_xcb_dri3_INCLUDE_PATH, X11_xcb_dri3_LIB, X11_xcb_dri3_FOUND, X11::xcb_dri3
+ X11_xcb_errors_INCLUDE_PATH, X11_xcb_errors_LIB, X11_xcb_errors_FOUND, X11::xcb_errors
+ X11_xcb_ewmh_INCLUDE_PATH, X11_xcb_ewmh_LIB, X11_xcb_ewmh_FOUND, X11::xcb_ewmh
+ X11_xcb_glx_INCLUDE_PATH, X11_xcb_glx_LIB, X11_xcb_glx_FOUND, X11::xcb_glx
+ X11_xcb_icccm_INCLUDE_PATH, X11_xcb_icccm_LIB, X11_xcb_icccm_FOUND, X11::xcb_icccm
+ X11_xcb_image_INCLUDE_PATH, X11_xcb_image_LIB, X11_xcb_image_FOUND, X11::xcb_image
+ X11_xcb_keysyms_INCLUDE_PATH, X11_xcb_keysyms_LIB, X11_xcb_keysyms_FOUND, X11::xcb_keysyms
+ X11_xcb_present_INCLUDE_PATH, X11_xcb_present_LIB, X11_xcb_present_FOUND, X11::xcb_present
+ X11_xcb_randr_INCLUDE_PATH, X11_xcb_randr_LIB, X11_xcb_randr_FOUND, X11::xcb_randr
+ X11_xcb_record_INCLUDE_PATH, X11_xcb_record_LIB, X11_xcb_record_FOUND, X11::xcb_record
+ X11_xcb_render_INCLUDE_PATH, X11_xcb_render_LIB, X11_xcb_render_FOUND, X11::xcb_render
+ X11_xcb_render_util_INCLUDE_PATH,X11_xcb_render_util_LIB,X11_xcb_render_util_FOUND,X11::xcb_render_util
+ X11_xcb_res_INCLUDE_PATH, X11_xcb_res_LIB, X11_xcb_res_FOUND, X11::xcb_res
+ X11_xcb_screensaver_INCLUDE_PATH,X11_xcb_screensaver_LIB,X11_xcb_screensaver_FOUND,X11::xcb_screensaver
+ X11_xcb_shape_INCLUDE_PATH, X11_xcb_shape_LIB, X11_xcb_shape_FOUND, X11::xcb_shape
+ X11_xcb_shm_INCLUDE_PATH, X11_xcb_shm_LIB, X11_xcb_shm_FOUND, X11::xcb_shm
+ X11_xcb_sync_INCLUDE_PATH, X11_xcb_sync_LIB, X11_xcb_sync_FOUND, X11::xcb_sync
+ X11_xcb_util_INCLUDE_PATH, X11_xcb_util_LIB, X11_xcb_util_FOUND, X11::xcb_util
+ X11_xcb_xf86dri_INCLUDE_PATH, X11_xcb_xf86dri_LIB, X11_xcb_xf86dri_FOUND, X11::xcb_xf86dri
+ X11_xcb_xfixes_INCLUDE_PATH, X11_xcb_xfixes_LIB, X11_xcb_xfixes_FOUND, X11::xcb_xfixes
+ X11_xcb_xinerama_INCLUDE_PATH, X11_xcb_xinerama_LIB, X11_xcb_xinerama_FOUND, X11::xcb_xinerama
+ X11_xcb_xinput_INCLUDE_PATH, X11_xcb_xinput_LIB, X11_xcb_xinput_FOUND, X11::xcb_xinput
+ X11_xcb_xkb_INCLUDE_PATH, X11_xcb_xkb_LIB, X11_xcb_xkb_FOUND, X11::xcb_xkb
+ X11_xcb_xrm_INCLUDE_PATH, X11_xcb_xrm_LIB, X11_xcb_xrm_FOUND, X11::xcb_xrm
+ X11_xcb_xtest_INCLUDE_PATH, X11_xcb_xtest_LIB, X11_xcb_xtest_FOUND, X11::xcb_xtest
+ X11_xcb_xvmc_INCLUDE_PATH, X11_xcb_xvmc_LIB, X11_xcb_xvmc_FOUND, X11::xcb_xvmc
+ X11_xcb_xv_INCLUDE_PATH, X11_xcb_xv_LIB, X11_xcb_xv_FOUND X11::xcb_xv
+ X11_Xcomposite_INCLUDE_PATH, X11_Xcomposite_LIB, X11_Xcomposite_FOUND, X11::Xcomposite
+ X11_Xcursor_INCLUDE_PATH, X11_Xcursor_LIB, X11_Xcursor_FOUND, X11::Xcursor
+ X11_Xdamage_INCLUDE_PATH, X11_Xdamage_LIB, X11_Xdamage_FOUND, X11::Xdamage
+ X11_Xdmcp_INCLUDE_PATH, X11_Xdmcp_LIB, X11_Xdmcp_FOUND, X11::Xdmcp
+ X11_Xext_INCLUDE_PATH, X11_Xext_LIB, X11_Xext_FOUND, X11::Xext
+ X11_Xxf86misc_INCLUDE_PATH, X11_Xxf86misc_LIB, X11_Xxf86misc_FOUND, X11::Xxf86misc
+ X11_Xxf86vm_INCLUDE_PATH, X11_Xxf86vm_LIB X11_Xxf86vm_FOUND, X11::Xxf86vm
+ X11_Xfixes_INCLUDE_PATH, X11_Xfixes_LIB, X11_Xfixes_FOUND, X11::Xfixes
+ X11_Xft_INCLUDE_PATH, X11_Xft_LIB, X11_Xft_FOUND, X11::Xft
+ X11_Xi_INCLUDE_PATH, X11_Xi_LIB, X11_Xi_FOUND, X11::Xi
+ X11_Xinerama_INCLUDE_PATH, X11_Xinerama_LIB, X11_Xinerama_FOUND, X11::Xinerama
X11_Xkb_INCLUDE_PATH,
- X11_Xkblib_INCLUDE_PATH, X11_Xkb_FOUND, X11::Xkb
- X11_xkbcommon_INCLUDE_PATH, X11_xkbcommon_LIB, X11_xkbcommon_FOUND, X11::xkbcommon
- X11_xkbcommon_X11_INCLUDE_PATH,X11_xkbcommon_X11_LIB,X11_xkbcommon_X11_FOUND,X11::xkbcommon_X11
- X11_xkbfile_INCLUDE_PATH, X11_xkbfile_LIB, X11_xkbfile_FOUND, X11::xkbfile
- X11_Xmu_INCLUDE_PATH, X11_Xmu_LIB, X11_Xmu_FOUND, X11::Xmu
- X11_Xpm_INCLUDE_PATH, X11_Xpm_LIB, X11_Xpm_FOUND, X11::Xpm
- X11_Xtst_INCLUDE_PATH, X11_Xtst_LIB, X11_Xtst_FOUND, X11::Xtst
- X11_Xrandr_INCLUDE_PATH, X11_Xrandr_LIB, X11_Xrandr_FOUND, X11::Xrandr
- X11_Xrender_INCLUDE_PATH, X11_Xrender_LIB, X11_Xrender_FOUND, X11::Xrender
- X11_XRes_INCLUDE_PATH, X11_XRes_LIB, X11_XRes_FOUND, X11::XRes
- X11_Xss_INCLUDE_PATH, X11_Xss_LIB, X11_Xss_FOUND, X11::Xss
- X11_Xt_INCLUDE_PATH, X11_Xt_LIB, X11_Xt_FOUND, X11::Xt
- X11_Xutil_INCLUDE_PATH, X11_Xutil_FOUND, X11::Xutil
- X11_Xv_INCLUDE_PATH, X11_Xv_LIB, X11_Xv_FOUND, X11::Xv
- X11_dpms_INCLUDE_PATH, (in X11_Xext_LIB), X11_dpms_FOUND
- X11_XShm_INCLUDE_PATH, (in X11_Xext_LIB), X11_XShm_FOUND
- X11_Xshape_INCLUDE_PATH, (in X11_Xext_LIB), X11_Xshape_FOUND
- X11_XSync_INCLUDE_PATH, (in X11_Xext_LIB), X11_XSync_FOUND
- X11_Xaw_INCLUDE_PATH, X11_Xaw_LIB X11_Xaw_FOUND X11::Xaw
+ X11_Xkblib_INCLUDE_PATH, X11_Xkb_FOUND, X11::Xkb
+ X11_xkbcommon_INCLUDE_PATH, X11_xkbcommon_LIB, X11_xkbcommon_FOUND, X11::xkbcommon
+ X11_xkbcommon_X11_INCLUDE_PATH, X11_xkbcommon_X11_LIB, X11_xkbcommon_X11_FOUND, X11::xkbcommon_X11
+ X11_xkbfile_INCLUDE_PATH, X11_xkbfile_LIB, X11_xkbfile_FOUND, X11::xkbfile
+ X11_Xmu_INCLUDE_PATH, X11_Xmu_LIB, X11_Xmu_FOUND, X11::Xmu
+ X11_Xpm_INCLUDE_PATH, X11_Xpm_LIB, X11_Xpm_FOUND, X11::Xpm
+ X11_Xtst_INCLUDE_PATH, X11_Xtst_LIB, X11_Xtst_FOUND, X11::Xtst
+ X11_Xrandr_INCLUDE_PATH, X11_Xrandr_LIB, X11_Xrandr_FOUND, X11::Xrandr
+ X11_Xrender_INCLUDE_PATH, X11_Xrender_LIB, X11_Xrender_FOUND, X11::Xrender
+ X11_XRes_INCLUDE_PATH, X11_XRes_LIB, X11_XRes_FOUND, X11::XRes
+ X11_Xss_INCLUDE_PATH, X11_Xss_LIB, X11_Xss_FOUND, X11::Xss
+ X11_Xt_INCLUDE_PATH, X11_Xt_LIB, X11_Xt_FOUND, X11::Xt
+ X11_Xutil_INCLUDE_PATH, X11_Xutil_FOUND, X11::Xutil
+ X11_Xv_INCLUDE_PATH, X11_Xv_LIB, X11_Xv_FOUND, X11::Xv
+ X11_dpms_INCLUDE_PATH, (in X11_Xext_LIB), X11_dpms_FOUND
+ X11_XShm_INCLUDE_PATH, (in X11_Xext_LIB), X11_XShm_FOUND
+ X11_Xshape_INCLUDE_PATH, (in X11_Xext_LIB), X11_Xshape_FOUND
+ X11_XSync_INCLUDE_PATH, (in X11_Xext_LIB), X11_XSync_FOUND
+ X11_Xaw_INCLUDE_PATH, X11_Xaw_LIB X11_Xaw_FOUND X11::Xaw
.. versionadded:: 3.14
Renamed ``Xxf86misc``, ``X11_Xxf86misc``, ``X11_Xxf86vm``, ``X11_xkbfile``,
@@ -92,7 +114,12 @@ and also the following more fine grained variables and targets:
Added the ``xcb_randr``, ``xcb_xtext``, and ``xcb_keysyms`` libraries.
.. versionadded:: 3.27
- Added the ``xcb_cursor``, ``xcb_shape``, and ``xcb_xrm`` libraries.
+ Added the ``xcb_composite``, ``xcb_cursor``, ``xcb_damage``, ``xcb_dpms``,
+ ``xcb_dri2``, ``xcb_dri3``, ``xcb_errors``, ``xcb_ewmh``, ``xcb_glx``,
+ ``xcb_image``, ``xcb_present``, ``xcb_record``, ``xcb_render``,
+ ``xcb_render_util``, ``xcb_res``, ``xcb_screensaver``, ``xcb_shape``,
+ ``xcb_shm``, ``xcb_sync``, ``xcb_xf86dri``, ``xcb_xinerama``, ``xcb_xinput``,
+ ``xcb_xrm``, ``xcb_xvmc``, and ``xcb_xv`` libraries.
#]=======================================================================]
@@ -135,18 +162,41 @@ if (UNIX)
find_path(X11_Xaccessrules_INCLUDE_PATH X11/extensions/XKBrules.h ${X11_INC_SEARCH_PATH})
find_path(X11_Xaccessstr_INCLUDE_PATH X11/extensions/XKBstr.h ${X11_INC_SEARCH_PATH})
find_path(X11_Xau_INCLUDE_PATH X11/Xauth.h ${X11_INC_SEARCH_PATH})
- find_path(X11_Xaw_INCLUDE_PATH X11/Xaw/Intrinsic.h ${X11_INC_SEARCH_PATH})
+ find_path(X11_Xaw_INCLUDE_PATH X11/Xaw/Box.h ${X11_INC_SEARCH_PATH})
find_path(X11_xcb_INCLUDE_PATH xcb/xcb.h ${X11_INC_SEARCH_PATH})
find_path(X11_X11_xcb_INCLUDE_PATH X11/Xlib-xcb.h ${X11_INC_SEARCH_PATH})
+ find_path(X11_xcb_composite_INCLUDE_PATH xcb/composite.h ${X11_INC_SEARCH_PATH})
find_path(X11_xcb_cursor_INCLUDE_PATH xcb/xcb_cursor.h ${X11_INC_SEARCH_PATH})
+ find_path(X11_xcb_damage_INCLUDE_PATH xcb/damage.h ${X11_INC_SEARCH_PATH})
+ find_path(X11_xcb_dpms_INCLUDE_PATH xcb/dpms.h ${X11_INC_SEARCH_PATH})
+ find_path(X11_xcb_dri2_INCLUDE_PATH xcb/dri2.h ${X11_INC_SEARCH_PATH})
+ find_path(X11_xcb_dri3_INCLUDE_PATH xcb/dri3.h ${X11_INC_SEARCH_PATH})
+ find_path(X11_xcb_errors_INCLUDE_PATH xcb/xcb_errors.h ${X11_INC_SEARCH_PATH})
+ find_path(X11_xcb_ewmh_INCLUDE_PATH xcb/xcb_ewmh.h ${X11_INC_SEARCH_PATH})
+ find_path(X11_xcb_glx_INCLUDE_PATH xcb/glx.h ${X11_INC_SEARCH_PATH})
find_path(X11_xcb_icccm_INCLUDE_PATH xcb/xcb_icccm.h ${X11_INC_SEARCH_PATH})
+ find_path(X11_xcb_image_INCLUDE_PATH xcb/xcb_image.h ${X11_INC_SEARCH_PATH})
+ find_path(X11_xcb_keysyms_INCLUDE_PATH xcb/xcb_keysyms.h ${X11_INC_SEARCH_PATH})
+ find_path(X11_xcb_present_INCLUDE_PATH xcb/present.h ${X11_INC_SEARCH_PATH})
find_path(X11_xcb_randr_INCLUDE_PATH xcb/randr.h ${X11_INC_SEARCH_PATH})
+ find_path(X11_xcb_record_INCLUDE_PATH xcb/record.h ${X11_INC_SEARCH_PATH})
+ find_path(X11_xcb_render_INCLUDE_PATH xcb/render.h ${X11_INC_SEARCH_PATH})
+ find_path(X11_xcb_render_util_INCLUDE_PATH xcb/xcb_renderutil.h ${X11_INC_SEARCH_PATH})
+ find_path(X11_xcb_res_INCLUDE_PATH xcb/res.h ${X11_INC_SEARCH_PATH})
+ find_path(X11_xcb_screensaver_INCLUDE_PATH xcb/screensaver.h ${X11_INC_SEARCH_PATH})
find_path(X11_xcb_shape_INCLUDE_PATH xcb/shape.h ${X11_INC_SEARCH_PATH})
+ find_path(X11_xcb_shm_INCLUDE_PATH xcb/shm.h ${X11_INC_SEARCH_PATH})
+ find_path(X11_xcb_sync_INCLUDE_PATH xcb/sync.h ${X11_INC_SEARCH_PATH})
find_path(X11_xcb_util_INCLUDE_PATH xcb/xcb_aux.h ${X11_INC_SEARCH_PATH})
+ find_path(X11_xcb_xf86dri_INCLUDE_PATH xcb/xf86dri.h ${X11_INC_SEARCH_PATH})
find_path(X11_xcb_xfixes_INCLUDE_PATH xcb/xfixes.h ${X11_INC_SEARCH_PATH})
+ find_path(X11_xcb_xinerama_INCLUDE_PATH xcb/xinerama.h ${X11_INC_SEARCH_PATH})
+ find_path(X11_xcb_xinput_INCLUDE_PATH xcb/xinput.h ${X11_INC_SEARCH_PATH})
+ find_path(X11_xcb_xkb_INCLUDE_PATH xcb/xkb.h ${X11_INC_SEARCH_PATH})
find_path(X11_xcb_xrm_INCLUDE_PATH xcb/xcb_xrm.h ${X11_INC_SEARCH_PATH})
find_path(X11_xcb_xtest_INCLUDE_PATH xcb/xtest.h ${X11_INC_SEARCH_PATH})
- find_path(X11_xcb_keysyms_INCLUDE_PATH xcb/xcb_keysyms.h ${X11_INC_SEARCH_PATH})
+ find_path(X11_xcb_xvmc_INCLUDE_PATH xcb/xvmc.h ${X11_INC_SEARCH_PATH})
+ find_path(X11_xcb_xv_INCLUDE_PATH xcb/xv.h ${X11_INC_SEARCH_PATH})
find_path(X11_Xcomposite_INCLUDE_PATH X11/extensions/Xcomposite.h ${X11_INC_SEARCH_PATH})
find_path(X11_Xcursor_INCLUDE_PATH X11/Xcursor/Xcursor.h ${X11_INC_SEARCH_PATH})
find_path(X11_Xdamage_INCLUDE_PATH X11/extensions/Xdamage.h ${X11_INC_SEARCH_PATH})
@@ -191,45 +241,67 @@ if (UNIX)
find_library(X11_X11_LIB X11 ${X11_LIB_SEARCH_PATH})
# Find additional X libraries. Keep list sorted by library name.
- find_library(X11_ICE_LIB ICE ${X11_LIB_SEARCH_PATH})
- find_library(X11_SM_LIB SM ${X11_LIB_SEARCH_PATH})
- find_library(X11_Xau_LIB Xau ${X11_LIB_SEARCH_PATH})
- find_library(X11_Xaw_LIB Xaw ${X11_LIB_SEARCH_PATH})
- find_library(X11_xcb_LIB xcb ${X11_LIB_SEARCH_PATH})
- find_library(X11_X11_xcb_LIB X11-xcb ${X11_LIB_SEARCH_PATH})
- find_library(X11_xcb_cursor_LIB xcb-cursor ${X11_LIB_SEARCH_PATH})
- find_library(X11_xcb_icccm_LIB xcb-icccm ${X11_LIB_SEARCH_PATH})
- find_library(X11_xcb_randr_LIB xcb-randr ${X11_LIB_SEARCH_PATH})
- find_library(X11_xcb_shape_LIB xcb-shape ${X11_LIB_SEARCH_PATH})
- find_library(X11_xcb_util_LIB xcb-util ${X11_LIB_SEARCH_PATH})
- find_library(X11_xcb_xfixes_LIB xcb-xfixes ${X11_LIB_SEARCH_PATH})
- find_library(X11_xcb_xrm_LIB xcb-xrm ${X11_LIB_SEARCH_PATH})
- find_library(X11_xcb_xtest_LIB xcb-xtest ${X11_LIB_SEARCH_PATH})
- find_library(X11_xcb_keysyms_LIB xcb-keysyms ${X11_LIB_SEARCH_PATH})
- find_library(X11_xcb_xkb_LIB xcb-xkb ${X11_LIB_SEARCH_PATH})
- find_library(X11_Xcomposite_LIB Xcomposite ${X11_LIB_SEARCH_PATH})
- find_library(X11_Xcursor_LIB Xcursor ${X11_LIB_SEARCH_PATH})
- find_library(X11_Xdamage_LIB Xdamage ${X11_LIB_SEARCH_PATH})
- find_library(X11_Xdmcp_LIB Xdmcp ${X11_LIB_SEARCH_PATH})
- find_library(X11_Xext_LIB Xext ${X11_LIB_SEARCH_PATH})
- find_library(X11_Xfixes_LIB Xfixes ${X11_LIB_SEARCH_PATH})
- find_library(X11_Xft_LIB Xft ${X11_LIB_SEARCH_PATH})
- find_library(X11_Xi_LIB Xi ${X11_LIB_SEARCH_PATH})
- find_library(X11_Xinerama_LIB Xinerama ${X11_LIB_SEARCH_PATH})
- find_library(X11_xkbcommon_LIB xkbcommon ${X11_LIB_SEARCH_PATH})
- find_library(X11_xkbcommon_X11_LIB xkbcommon-x11 ${X11_LIB_SEARCH_PATH})
- find_library(X11_xkbfile_LIB xkbfile ${X11_LIB_SEARCH_PATH})
- find_library(X11_Xmu_LIB Xmu ${X11_LIB_SEARCH_PATH})
- find_library(X11_Xpm_LIB Xpm ${X11_LIB_SEARCH_PATH})
- find_library(X11_Xrandr_LIB Xrandr ${X11_LIB_SEARCH_PATH})
- find_library(X11_Xrender_LIB Xrender ${X11_LIB_SEARCH_PATH})
- find_library(X11_XRes_LIB XRes ${X11_LIB_SEARCH_PATH})
- find_library(X11_Xss_LIB Xss ${X11_LIB_SEARCH_PATH})
- find_library(X11_Xt_LIB Xt ${X11_LIB_SEARCH_PATH})
- find_library(X11_Xtst_LIB Xtst ${X11_LIB_SEARCH_PATH})
- find_library(X11_Xv_LIB Xv ${X11_LIB_SEARCH_PATH})
- find_library(X11_Xxf86misc_LIB Xxf86misc ${X11_LIB_SEARCH_PATH})
- find_library(X11_Xxf86vm_LIB Xxf86vm ${X11_LIB_SEARCH_PATH})
+ find_library(X11_ICE_LIB ICE ${X11_LIB_SEARCH_PATH})
+ find_library(X11_SM_LIB SM ${X11_LIB_SEARCH_PATH})
+ find_library(X11_Xau_LIB Xau ${X11_LIB_SEARCH_PATH})
+ find_library(X11_Xaw_LIB Xaw ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_LIB xcb ${X11_LIB_SEARCH_PATH})
+ find_library(X11_X11_xcb_LIB X11-xcb ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_composite_LIB xcb-composite ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_cursor_LIB xcb-cursor ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_damage_LIB xcb-damage ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_dpms_LIB xcb-dpms ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_dri2_LIB xcb-dri2 ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_dri3_LIB xcb-dri3 ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_errors_LIB xcb-errors ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_ewmh_LIB xcb-ewmh ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_glx_LIB xcb-glx ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_icccm_LIB xcb-icccm ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_image_LIB xcb-image ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_keysyms_LIB xcb-keysyms ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_present_LIB xcb-present ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_randr_LIB xcb-randr ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_record_LIB xcb-record ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_render_LIB xcb-render ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_render_util_LIB xcb-render-util ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_res_LIB xcb-res ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_screensaver_LIB xcb-screensaver ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_shape_LIB xcb-shape ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_shm_LIB xcb-shm ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_sync_LIB xcb-sync ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_util_LIB xcb-util ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_xf86dri_LIB xcb-xf86dri ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_xfixes_LIB xcb-xfixes ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_xinerama_LIB xcb-xinerama ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_xinput_LIB xcb-xinput ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_xkb_LIB xcb-xkb ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_xrm_LIB xcb-xrm ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_xtest_LIB xcb-xtest ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_xvmc_LIB xcb-xvmc ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xcb_xv_LIB xcb-xv ${X11_LIB_SEARCH_PATH})
+ find_library(X11_Xcomposite_LIB Xcomposite ${X11_LIB_SEARCH_PATH})
+ find_library(X11_Xcursor_LIB Xcursor ${X11_LIB_SEARCH_PATH})
+ find_library(X11_Xdamage_LIB Xdamage ${X11_LIB_SEARCH_PATH})
+ find_library(X11_Xdmcp_LIB Xdmcp ${X11_LIB_SEARCH_PATH})
+ find_library(X11_Xext_LIB Xext ${X11_LIB_SEARCH_PATH})
+ find_library(X11_Xfixes_LIB Xfixes ${X11_LIB_SEARCH_PATH})
+ find_library(X11_Xft_LIB Xft ${X11_LIB_SEARCH_PATH})
+ find_library(X11_Xi_LIB Xi ${X11_LIB_SEARCH_PATH})
+ find_library(X11_Xinerama_LIB Xinerama ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xkbcommon_LIB xkbcommon ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xkbcommon_X11_LIB xkbcommon-x11 ${X11_LIB_SEARCH_PATH})
+ find_library(X11_xkbfile_LIB xkbfile ${X11_LIB_SEARCH_PATH})
+ find_library(X11_Xmu_LIB Xmu ${X11_LIB_SEARCH_PATH})
+ find_library(X11_Xpm_LIB Xpm ${X11_LIB_SEARCH_PATH})
+ find_library(X11_Xrandr_LIB Xrandr ${X11_LIB_SEARCH_PATH})
+ find_library(X11_Xrender_LIB Xrender ${X11_LIB_SEARCH_PATH})
+ find_library(X11_XRes_LIB XRes ${X11_LIB_SEARCH_PATH})
+ find_library(X11_Xss_LIB Xss ${X11_LIB_SEARCH_PATH})
+ find_library(X11_Xt_LIB Xt ${X11_LIB_SEARCH_PATH})
+ find_library(X11_Xtst_LIB Xtst ${X11_LIB_SEARCH_PATH})
+ find_library(X11_Xv_LIB Xv ${X11_LIB_SEARCH_PATH})
+ find_library(X11_Xxf86misc_LIB Xxf86misc ${X11_LIB_SEARCH_PATH})
+ find_library(X11_Xxf86vm_LIB Xxf86vm ${X11_LIB_SEARCH_PATH})
# Backwards compatibility.
set(X11_Xinput_LIB "${X11_Xi_LIB}")
@@ -301,44 +373,132 @@ if (UNIX)
set(X11_X11_xcb_FOUND TRUE)
endif ()
+ if (X11_xcb_composite_LIB AND X11_xcb_composite_INCLUDE_PATH)
+ set(X11_xcb_composite_FOUND TRUE)
+ endif ()
+
if (X11_xcb_cursor_LIB AND X11_xcb_cursor_INCLUDE_PATH)
set(X11_xcb_cursor_FOUND TRUE)
endif ()
+ if (X11_xcb_damage_LIB AND X11_xcb_damage_INCLUDE_PATH)
+ set(X11_xcb_damage_FOUND TRUE)
+ endif ()
+
+ if (X11_xcb_dpms_LIB AND X11_xcb_dpms_INCLUDE_PATH)
+ set(X11_xcb_dpms_FOUND TRUE)
+ endif ()
+
+ if (X11_xcb_dri2_LIB AND X11_xcb_dri2_INCLUDE_PATH)
+ set(X11_xcb_dri2_FOUND TRUE)
+ endif ()
+
+ if (X11_xcb_dri3_LIB AND X11_xcb_dri3_INCLUDE_PATH)
+ set(X11_xcb_dri3_FOUND TRUE)
+ endif ()
+
+ if (X11_xcb_errors_LIB AND X11_xcb_errors_INCLUDE_PATH)
+ set(X11_xcb_errors_FOUND TRUE)
+ endif ()
+
+ if (X11_xcb_ewmh_LIB AND X11_xcb_ewmh_INCLUDE_PATH)
+ set(X11_xcb_ewmh_FOUND TRUE)
+ endif ()
+
+ if (X11_xcb_glx_LIB AND X11_xcb_glx_INCLUDE_PATH)
+ set(X11_xcb_glx_FOUND TRUE)
+ endif ()
+
if (X11_xcb_icccm_LIB AND X11_xcb_icccm_INCLUDE_PATH)
set(X11_xcb_icccm_FOUND TRUE)
endif ()
+ if (X11_xcb_image_LIB AND X11_xcb_image_INCLUDE_PATH)
+ set(X11_xcb_image_FOUND TRUE)
+ endif ()
+
+ if (X11_xcb_keysyms_LIB AND X11_xcb_keysyms_INCLUDE_PATH)
+ set(X11_xcb_keysyms_FOUND TRUE)
+ endif ()
+
+ if (X11_xcb_present_LIB AND X11_xcb_present_INCLUDE_PATH)
+ set(X11_xcb_present_FOUND TRUE)
+ endif ()
+
if (X11_xcb_randr_LIB AND X11_xcb_randr_INCLUDE_PATH)
set(X11_xcb_randr_FOUND TRUE)
endif ()
+ if (X11_xcb_record_LIB AND X11_xcb_record_INCLUDE_PATH)
+ set(X11_xcb_record_FOUND TRUE)
+ endif ()
+
+ if (X11_xcb_render_LIB AND X11_xcb_render_INCLUDE_PATH)
+ set(X11_xcb_render_FOUND TRUE)
+ endif ()
+
+ if (X11_xcb_render_util_LIB AND X11_xcb_render_util_INCLUDE_PATH)
+ set(X11_xcb_render_util_FOUND TRUE)
+ endif ()
+
+ if (X11_xcb_res_LIB AND X11_xcb_res_INCLUDE_PATH)
+ set(X11_xcb_res_FOUND TRUE)
+ endif ()
+
+ if (X11_xcb_screensaver_LIB AND X11_xcb_screensaver_INCLUDE_PATH)
+ set(X11_xcb_screensaver_FOUND TRUE)
+ endif ()
+
if (X11_xcb_shape_LIB AND X11_xcb_shape_INCLUDE_PATH)
set(X11_xcb_shape_FOUND TRUE)
endif ()
+ if (X11_xcb_shm_LIB AND X11_xcb_shm_INCLUDE_PATH)
+ set(X11_xcb_shm_FOUND TRUE)
+ endif ()
+
+ if (X11_xcb_sync_LIB AND X11_xcb_sync_INCLUDE_PATH)
+ set(X11_xcb_sync_FOUND TRUE)
+ endif ()
+
if (X11_xcb_util_LIB AND X11_xcb_util_INCLUDE_PATH)
set(X11_xcb_util_FOUND TRUE)
endif ()
- if (X11_xcb_xfixes_LIB)
+ if (X11_xcb_xf86dri_LIB AND X11_xcb_xf86dri_INCLUDE_PATH)
+ set(X11_xcb_xf86dri_FOUND TRUE)
+ endif ()
+
+ if (X11_xcb_xfixes_LIB AND X11_xcb_xfixes_INCLUDE_PATH)
set(X11_xcb_xfixes_FOUND TRUE)
endif ()
+ if (X11_xcb_xinerama_LIB AND X11_xcb_xinerama_INCLUDE_PATH)
+ set(X11_xcb_xinerama_FOUND TRUE)
+ endif ()
+
+ if (X11_xcb_xinput_LIB AND X11_xcb_xinput_INCLUDE_PATH)
+ set(X11_xcb_xinput_FOUND TRUE)
+ endif ()
+
+ if (X11_xcb_xkb_LIB AND X11_xcb_xkb_INCLUDE_PATH)
+ set(X11_xcb_xkb_FOUND TRUE)
+ endif ()
+
if (X11_xcb_xrm_LIB AND X11_xcb_xrm_INCLUDE_PATH)
set(X11_xcb_xrm_FOUND TRUE)
endif ()
- if (X11_xcb_xtest_LIB)
+ if (X11_xcb_xtest_LIB AND X11_xcb_xtest_INCLUDE_PATH)
set(X11_xcb_xtest_FOUND TRUE)
endif ()
- if (X11_xcb_keysyms_LIB)
- set(X11_xcb_keysyms_FOUND TRUE)
+ if (X11_xcb_xvmc_LIB AND X11_xcb_xvmc_INCLUDE_PATH)
+ set(X11_xcb_xvmc_FOUND TRUE)
endif ()
- if (X11_xcb_xkb_LIB)
- set(X11_xcb_xkb_FOUND TRUE)
+ if (X11_xcb_xv_LIB AND X11_xcb_xv_INCLUDE_PATH)
+ set(X11_xcb_xv_FOUND TRUE)
endif ()
if (X11_Xdmcp_INCLUDE_PATH AND X11_Xdmcp_LIB)
@@ -641,6 +801,13 @@ if (UNIX)
INTERFACE_LINK_LIBRARIES "X11::xcb;X11::X11")
endif ()
+ if (X11_xcb_composite_FOUND AND NOT TARGET X11::xcb_composite)
+ add_library(X11::xcb_composite UNKNOWN IMPORTED)
+ set_target_properties(X11::xcb_composite PROPERTIES
+ IMPORTED_LOCATION "${X11_xcb_composite_LIB}"
+ INTERFACE_LINK_LIBRARIES "X11::xcb")
+ endif ()
+
if (X11_xcb_cursor_FOUND AND NOT TARGET X11::xcb_cursor)
add_library(X11::xcb_cursor UNKNOWN IMPORTED)
set_target_properties(X11::xcb_cursor PROPERTIES
@@ -648,6 +815,55 @@ if (UNIX)
INTERFACE_LINK_LIBRARIES "X11::xcb")
endif ()
+ if (X11_xcb_damage_FOUND AND NOT TARGET X11::xcb_damage)
+ add_library(X11::xcb_damage UNKNOWN IMPORTED)
+ set_target_properties(X11::xcb_damage PROPERTIES
+ IMPORTED_LOCATION "${X11_xcb_damage_LIB}"
+ INTERFACE_LINK_LIBRARIES "X11::xcb")
+ endif ()
+
+ if (X11_xcb_dpms_FOUND AND NOT TARGET X11::xcb_dpms)
+ add_library(X11::xcb_dpms UNKNOWN IMPORTED)
+ set_target_properties(X11::xcb_dpms PROPERTIES
+ IMPORTED_LOCATION "${X11_xcb_dpms_LIB}"
+ INTERFACE_LINK_LIBRARIES "X11::xcb")
+ endif ()
+
+ if (X11_xcb_dri2_FOUND AND NOT TARGET X11::xcb_dri2)
+ add_library(X11::xcb_dri2 UNKNOWN IMPORTED)
+ set_target_properties(X11::xcb_dri2 PROPERTIES
+ IMPORTED_LOCATION "${X11_xcb_dri2_LIB}"
+ INTERFACE_LINK_LIBRARIES "X11::xcb")
+ endif ()
+
+ if (X11_xcb_dri3_FOUND AND NOT TARGET X11::xcb_dri3)
+ add_library(X11::xcb_dri3 UNKNOWN IMPORTED)
+ set_target_properties(X11::xcb_dri3 PROPERTIES
+ IMPORTED_LOCATION "${X11_xcb_dri3_LIB}"
+ INTERFACE_LINK_LIBRARIES "X11::xcb")
+ endif ()
+
+ if (X11_xcb_errors_FOUND AND NOT TARGET X11::xcb_errors)
+ add_library(X11::xcb_errors UNKNOWN IMPORTED)
+ set_target_properties(X11::xcb_errors PROPERTIES
+ IMPORTED_LOCATION "${X11_xcb_errors_LIB}"
+ INTERFACE_LINK_LIBRARIES "X11::xcb")
+ endif ()
+
+ if (X11_xcb_ewmh_FOUND AND NOT TARGET X11::xcb_ewmh)
+ add_library(X11::xcb_ewmh UNKNOWN IMPORTED)
+ set_target_properties(X11::xcb_ewmh PROPERTIES
+ IMPORTED_LOCATION "${X11_xcb_ewmh_LIB}"
+ INTERFACE_LINK_LIBRARIES "X11::xcb")
+ endif ()
+
+ if (X11_xcb_glx_FOUND AND NOT TARGET X11::xcb_glx)
+ add_library(X11::xcb_glx UNKNOWN IMPORTED)
+ set_target_properties(X11::xcb_glx PROPERTIES
+ IMPORTED_LOCATION "${X11_xcb_glx_LIB}"
+ INTERFACE_LINK_LIBRARIES "X11::xcb")
+ endif ()
+
if (X11_xcb_icccm_FOUND AND NOT TARGET X11::xcb_icccm)
add_library(X11::xcb_icccm UNKNOWN IMPORTED)
set_target_properties(X11::xcb_icccm PROPERTIES
@@ -655,6 +871,27 @@ if (UNIX)
INTERFACE_LINK_LIBRARIES "X11::xcb")
endif ()
+ if (X11_xcb_image_FOUND AND NOT TARGET X11::xcb_image)
+ add_library(X11::xcb_image UNKNOWN IMPORTED)
+ set_target_properties(X11::xcb_image PROPERTIES
+ IMPORTED_LOCATION "${X11_xcb_image_LIB}"
+ INTERFACE_LINK_LIBRARIES "X11::xcb")
+ endif ()
+
+ if (X11_xcb_keysyms_FOUND AND NOT TARGET X11::xcb_keysyms)
+ add_library(X11::xcb_keysyms UNKNOWN IMPORTED)
+ set_target_properties(X11::xcb_keysyms PROPERTIES
+ IMPORTED_LOCATION "${X11_xcb_keysyms_LIB}"
+ INTERFACE_LINK_LIBRARIES "X11::xcb")
+ endif ()
+
+ if (X11_xcb_present_FOUND AND NOT TARGET X11::xcb_present)
+ add_library(X11::xcb_present UNKNOWN IMPORTED)
+ set_target_properties(X11::xcb_present PROPERTIES
+ IMPORTED_LOCATION "${X11_xcb_present_LIB}"
+ INTERFACE_LINK_LIBRARIES "X11::xcb")
+ endif ()
+
if (X11_xcb_randr_FOUND AND NOT TARGET X11::xcb_randr)
add_library(X11::xcb_randr UNKNOWN IMPORTED)
set_target_properties(X11::xcb_randr PROPERTIES
@@ -662,6 +899,41 @@ if (UNIX)
INTERFACE_LINK_LIBRARIES "X11::xcb")
endif ()
+ if (X11_xcb_record_FOUND AND NOT TARGET X11::xcb_record)
+ add_library(X11::xcb_record UNKNOWN IMPORTED)
+ set_target_properties(X11::xcb_record PROPERTIES
+ IMPORTED_LOCATION "${X11_xcb_record_LIB}"
+ INTERFACE_LINK_LIBRARIES "X11::xcb")
+ endif ()
+
+ if (X11_xcb_render_FOUND AND NOT TARGET X11::xcb_render)
+ add_library(X11::xcb_render UNKNOWN IMPORTED)
+ set_target_properties(X11::xcb_render PROPERTIES
+ IMPORTED_LOCATION "${X11_xcb_render_LIB}"
+ INTERFACE_LINK_LIBRARIES "X11::xcb")
+ endif ()
+
+ if (X11_xcb_render_util_FOUND AND NOT TARGET X11::xcb_render_util)
+ add_library(X11::xcb_render_util UNKNOWN IMPORTED)
+ set_target_properties(X11::xcb_render_util PROPERTIES
+ IMPORTED_LOCATION "${X11_xcb_render_util_LIB}"
+ INTERFACE_LINK_LIBRARIES "X11::xcb")
+ endif ()
+
+ if (X11_xcb_res_FOUND AND NOT TARGET X11::xcb_res)
+ add_library(X11::xcb_res UNKNOWN IMPORTED)
+ set_target_properties(X11::xcb_res PROPERTIES
+ IMPORTED_LOCATION "${X11_xcb_res_LIB}"
+ INTERFACE_LINK_LIBRARIES "X11::xcb")
+ endif ()
+
+ if (X11_xcb_screensaver_FOUND AND NOT TARGET X11::xcb_screensaver)
+ add_library(X11::xcb_screensaver UNKNOWN IMPORTED)
+ set_target_properties(X11::xcb_screensaver PROPERTIES
+ IMPORTED_LOCATION "${X11_xcb_screensaver_LIB}"
+ INTERFACE_LINK_LIBRARIES "X11::xcb")
+ endif ()
+
if (X11_xcb_shape_FOUND AND NOT TARGET X11::xcb_shape)
add_library(X11::xcb_shape UNKNOWN IMPORTED)
set_target_properties(X11::xcb_shape PROPERTIES
@@ -669,6 +941,20 @@ if (UNIX)
INTERFACE_LINK_LIBRARIES "X11::xcb")
endif ()
+ if (X11_xcb_shm_FOUND AND NOT TARGET X11::xcb_shm)
+ add_library(X11::xcb_shm UNKNOWN IMPORTED)
+ set_target_properties(X11::xcb_shm PROPERTIES
+ IMPORTED_LOCATION "${X11_xcb_shm_LIB}"
+ INTERFACE_LINK_LIBRARIES "X11::xcb")
+ endif ()
+
+ if (X11_xcb_sync_FOUND AND NOT TARGET X11::xcb_sync)
+ add_library(X11::xcb_sync UNKNOWN IMPORTED)
+ set_target_properties(X11::xcb_sync PROPERTIES
+ IMPORTED_LOCATION "${X11_xcb_sync_LIB}"
+ INTERFACE_LINK_LIBRARIES "X11::xcb")
+ endif ()
+
if (X11_xcb_util_FOUND AND NOT TARGET X11::xcb_util)
add_library(X11::xcb_util UNKNOWN IMPORTED)
set_target_properties(X11::xcb_util PROPERTIES
@@ -676,6 +962,13 @@ if (UNIX)
INTERFACE_LINK_LIBRARIES "X11::xcb")
endif ()
+ if (X11_xcb_xf86dri_FOUND AND NOT TARGET X11::xcb_xf86dri)
+ add_library(X11::xcb_xf86dri UNKNOWN IMPORTED)
+ set_target_properties(X11::xcb_xf86dri PROPERTIES
+ IMPORTED_LOCATION "${X11_xcb_xf86dri_LIB}"
+ INTERFACE_LINK_LIBRARIES "X11::xcb")
+ endif ()
+
if (X11_xcb_xfixes_FOUND AND NOT TARGET X11::xcb_xfixes)
add_library(X11::xcb_xfixes UNKNOWN IMPORTED)
set_target_properties(X11::xcb_xfixes PROPERTIES
@@ -683,6 +976,27 @@ if (UNIX)
INTERFACE_LINK_LIBRARIES "X11::xcb")
endif ()
+ if (X11_xcb_xinerama_FOUND AND NOT TARGET X11::xcb_xinerama)
+ add_library(X11::xcb_xinerama UNKNOWN IMPORTED)
+ set_target_properties(X11::xcb_xinerama PROPERTIES
+ IMPORTED_LOCATION "${X11_xcb_xinerama_LIB}"
+ INTERFACE_LINK_LIBRARIES "X11::xcb")
+ endif ()
+
+ if (X11_xcb_xinput_FOUND AND NOT TARGET X11::xcb_xinput)
+ add_library(X11::xcb_xinput UNKNOWN IMPORTED)
+ set_target_properties(X11::xcb_xinput PROPERTIES
+ IMPORTED_LOCATION "${X11_xcb_xinput_LIB}"
+ INTERFACE_LINK_LIBRARIES "X11::xcb")
+ endif ()
+
+ if (X11_xcb_xkb_FOUND AND NOT TARGET X11::xcb_xkb)
+ add_library(X11::xcb_xkb UNKNOWN IMPORTED)
+ set_target_properties(X11::xcb_xkb PROPERTIES
+ IMPORTED_LOCATION "${X11_xcb_xkb_LIB}"
+ INTERFACE_LINK_LIBRARIES "X11::xcb")
+ endif ()
+
if (X11_xcb_xrm_FOUND AND NOT TARGET X11::xcb_xrm)
add_library(X11::xcb_xrm UNKNOWN IMPORTED)
set_target_properties(X11::xcb_xrm PROPERTIES
@@ -697,17 +1011,17 @@ if (UNIX)
INTERFACE_LINK_LIBRARIES "X11::xcb")
endif ()
- if (X11_xcb_keysyms_FOUND AND NOT TARGET X11::xcb_keysyms)
- add_library(X11::xcb_keysyms UNKNOWN IMPORTED)
- set_target_properties(X11::xcb_keysyms PROPERTIES
- IMPORTED_LOCATION "${X11_xcb_keysyms_LIB}"
+ if (X11_xcb_xvmc_FOUND AND NOT TARGET X11::xcb_xvmc)
+ add_library(X11::xcb_xvmc UNKNOWN IMPORTED)
+ set_target_properties(X11::xcb_xvmc PROPERTIES
+ IMPORTED_LOCATION "${X11_xcb_xvmc_LIB}"
INTERFACE_LINK_LIBRARIES "X11::xcb")
endif ()
- if (X11_xcb_xkb_FOUND AND NOT TARGET X11::xcb_xkb)
- add_library(X11::xcb_xkb UNKNOWN IMPORTED)
- set_target_properties(X11::xcb_xkb PROPERTIES
- IMPORTED_LOCATION "${X11_xcb_xkb_LIB}"
+ if (X11_xcb_xv_FOUND AND NOT TARGET X11::xcb_xv)
+ add_library(X11::xcb_xv UNKNOWN IMPORTED)
+ set_target_properties(X11::xcb_xv PROPERTIES
+ IMPORTED_LOCATION "${X11_xcb_xv_LIB}"
INTERFACE_LINK_LIBRARIES "X11::xcb")
endif ()
@@ -918,26 +1232,70 @@ if (UNIX)
X11_Xau_INCLUDE_PATH
X11_xcb_LIB
X11_xcb_INCLUDE_PATH
+ X11_xcb_composite_LIB
+ X11_xcb_composite_INCLUDE_PATH
X11_xcb_cursor_LIB
X11_xcb_cursor_INCLUDE_PATH
+ X11_xcb_damage_LIB
+ X11_xcb_damage_INCLUDE_PATH
+ X11_xcb_dpms_LIB
+ X11_xcb_dpms_INCLUDE_PATH
+ X11_xcb_dri2_LIB
+ X11_xcb_dri2_INCLUDE_PATH
+ X11_xcb_dri3_LIB
+ X11_xcb_dri3_INCLUDE_PATH
+ X11_xcb_errors_LIB
+ X11_xcb_errors_INCLUDE_PATH
+ X11_xcb_ewmh_LIB
+ X11_xcb_ewmh_INCLUDE_PATH
+ X11_xcb_glx_LIB
+ X11_xcb_glx_INCLUDE_PATH
X11_xcb_icccm_LIB
X11_xcb_icccm_INCLUDE_PATH
+ X11_xcb_image_LIB
+ X11_xcb_image_INCLUDE_PATH
+ X11_xcb_keysyms_LIB
+ X11_xcb_keysyms_INCLUDE_PATH
+ X11_xcb_present_LIB
+ X11_xcb_present_INCLUDE_PATH
X11_xcb_randr_LIB
X11_xcb_randr_INCLUDE_PATH
+ X11_xcb_record_LIB
+ X11_xcb_record_INCLUDE_PATH
+ X11_xcb_render_LIB
+ X11_xcb_render_INCLUDE_PATH
+ X11_xcb_render_util_LIB
+ X11_xcb_render_util_INCLUDE_PATH
+ X11_xcb_res_LIB
+ X11_xcb_res_INCLUDE_PATH
+ X11_xcb_screensaver_LIB
+ X11_xcb_screensaver_INCLUDE_PATH
X11_xcb_shape_LIB
X11_xcb_shape_INCLUDE_PATH
+ X11_xcb_shm_LIB
+ X11_xcb_shm_INCLUDE_PATH
+ X11_xcb_sync_LIB
+ X11_xcb_sync_INCLUDE_PATH
X11_xcb_util_LIB
X11_xcb_util_INCLUDE_PATH
+ X11_xcb_xf86dri_LIB
+ X11_xcb_xf86dri_INCLUDE_PATH
X11_xcb_xfixes_LIB
X11_xcb_xfixes_INCLUDE_PATH
+ X11_xcb_xinerama_LIB
+ X11_xcb_xinerama_INCLUDE_PATH
+ X11_xcb_xinput_LIB
+ X11_xcb_xinput_INCLUDE_PATH
+ X11_xcb_xkb_LIB
+ X11_X11_xcb_LIB
X11_xcb_xrm_LIB
X11_xcb_xrm_INCLUDE_PATH
X11_xcb_xtest_LIB
X11_xcb_xtest_INCLUDE_PATH
- X11_xcb_keysyms_LIB
- X11_xcb_keysyms_INCLUDE_PATH
- X11_xcb_xkb_LIB
- X11_X11_xcb_LIB
+ X11_xcb_xvmc_LIB
+ X11_xcb_xvmc_INCLUDE_PATH
+ X11_xcb_xv_LIB
+ X11_xcb_xv_INCLUDE_PATH
X11_X11_xcb_INCLUDE_PATH
X11_Xlib_INCLUDE_PATH
X11_Xutil_INCLUDE_PATH
diff --git a/Modules/FortranCInterface.cmake b/Modules/FortranCInterface.cmake
index ed8830ebcd..2c85029ed4 100644
--- a/Modules/FortranCInterface.cmake
+++ b/Modules/FortranCInterface.cmake
@@ -373,6 +373,7 @@ function(FortranCInterface_VERIFY)
"-DCMAKE_C_FLAGS_RELEASE:STRING=${CMAKE_C_FLAGS_RELEASE}"
"-DCMAKE_CXX_FLAGS_RELEASE:STRING=${CMAKE_CXX_FLAGS_RELEASE}"
"-DCMAKE_Fortran_FLAGS_RELEASE:STRING=${CMAKE_Fortran_FLAGS_RELEASE}"
+ "-DFortranCInterface_BINARY_DIR=${FortranCInterface_BINARY_DIR}"
${_FortranCInterface_OSX_ARCH}
${_FortranCInterface_EXE_LINKER_FLAGS}
OUTPUT_VARIABLE _output)
diff --git a/Modules/Internal/CPack/ISComponents.pas b/Modules/Internal/CPack/ISComponents.pas
new file mode 100644
index 0000000000..8b5c8b4fc2
--- /dev/null
+++ b/Modules/Internal/CPack/ISComponents.pas
@@ -0,0 +1,88 @@
+{ Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+file Copyright.txt or https://cmake.org/licensing for details. }
+
+function CPackGetCustomInstallationMessage(Param: String): String;
+begin
+ Result := SetupMessage(msgCustomInstallation);
+end;
+
+{ Downloaded components }
+#ifdef CPackDownloadCount
+const
+ NO_PROGRESS_BOX = 4;
+ RESPOND_YES_TO_ALL = 16;
+var
+ CPackDownloadPage: TDownloadWizardPage;
+ CPackShell: Variant;
+
+<event('InitializeWizard')>
+procedure CPackInitializeWizard();
+begin
+ CPackDownloadPage := CreateDownloadPage(SetupMessage(msgWizardPreparing), SetupMessage(msgPreparingDesc), nil);
+ CPackShell := CreateOleObject('Shell.Application');
+end;
+
+<event('NextButtonClick')>
+function CPackNextButtonClick(CurPageID: Integer): Boolean;
+begin
+ if CurPageID = wpReady then
+ begin
+ CPackDownloadPage.Clear;
+ CPackDownloadPage.Show;
+
+#sub AddDownload
+ if WizardIsComponentSelected('{#CPackDownloadComponents[i]}') then
+ #emit "CPackDownloadPage.Add('" + CPackDownloadUrls[i] + "', '" + CPackDownloadArchives[i] + ".zip', '" + CPackDownloadHashes[i] + "');"
+#endsub
+#define i
+#for {i = 0; i < CPackDownloadCount; i++} AddDownload
+#undef i
+
+ try
+ try
+ CPackDownloadPage.Download;
+ Result := True;
+ except
+ if not CPackDownloadPage.AbortedByUser then
+ SuppressibleMsgBox(AddPeriod(GetExceptionMessage), mbCriticalError, MB_OK, IDOK);
+
+ Result := False;
+ end;
+ finally
+ CPackDownloadPage.Hide;
+ end;
+ end else
+ Result := True;
+end;
+
+procedure CPackExtractFile(ArchiveName, FileName: String);
+var
+ ZipFileName: String;
+ ZipFile: Variant;
+ Item: Variant;
+ TargetFolderName: String;
+ TargetFolder: Variant;
+begin
+ TargetFolderName := RemoveBackslashUnlessRoot(ExpandConstant('{tmp}\' + ArchiveName + '\' + ExtractFileDir(FileName)));
+ ZipFileName := ExpandConstant('{tmp}\' + ArchiveName + '.zip');
+
+ if not DirExists(TargetFolderName) then
+ if not ForceDirectories(TargetFolderName) then
+ RaiseException(Format('Target path "%s" cannot be created', [TargetFolderName]));
+
+ ZipFile := CPackShell.NameSpace(ZipFileName);
+ if VarIsClear(ZipFile) then
+ RaiseException(Format('Cannot open ZIP file "%s" or does not exist', [ZipFileName]));
+
+ Item := ZipFile.ParseName(FileName);
+ if VarIsClear(Item) then
+ RaiseException(Format('Cannot find "%s" in "%s" ZIP file', [FileName, ZipFileName]));
+
+ TargetFolder := CPackShell.NameSpace(TargetFolderName);
+ if VarIsClear(TargetFolder) then
+ RaiseException(Format('Target path "%s" does not exist', [TargetFolderName]));
+
+ TargetFolder.CopyHere(Item, NO_PROGRESS_BOX or RESPOND_YES_TO_ALL);
+end;
+
+#endif
diff --git a/Modules/Internal/CPack/ISScript.template.in b/Modules/Internal/CPack/ISScript.template.in
new file mode 100644
index 0000000000..1171058939
--- /dev/null
+++ b/Modules/Internal/CPack/ISScript.template.in
@@ -0,0 +1,34 @@
+; Script generated by the CPack Inno Setup generator.
+; All changes made in this file will be lost when CPack is run again.
+
+@CPACK_INNOSETUP_INCLUDES_INTERNAL@
+
+[Setup]
+@CPACK_INNOSETUP_SETUP_INTERNAL@
+
+[Languages]
+@CPACK_INNOSETUP_LANGUAGES_INTERNAL@
+
+[Dirs]
+@CPACK_INNOSETUP_DIRS_INTERNAL@
+
+[Files]
+@CPACK_INNOSETUP_FILES_INTERNAL@
+
+[Types]
+@CPACK_INNOSETUP_TYPES_INTERNAL@
+
+[Components]
+@CPACK_INNOSETUP_COMPONENTS_INTERNAL@
+
+[Tasks]
+@CPACK_INNOSETUP_TASKS_INTERNAL@
+
+[Icons]
+@CPACK_INNOSETUP_ICONS_INTERNAL@
+
+[Run]
+@CPACK_INNOSETUP_RUN_INTERNAL@
+
+[Code]
+@CPACK_INNOSETUP_CODE_INTERNAL@
diff --git a/Modules/Platform/Android-Determine.cmake b/Modules/Platform/Android-Determine.cmake
index 715f68bb4e..307e4c9a53 100644
--- a/Modules/Platform/Android-Determine.cmake
+++ b/Modules/Platform/Android-Determine.cmake
@@ -34,18 +34,26 @@ cmake_policy(PUSH)
cmake_policy(SET CMP0057 NEW) # if IN_LIST
# If using Android tools for Visual Studio, compile a sample project to get the
-# sysroot.
+# NDK path and set the processor from the generator platform.
if(CMAKE_GENERATOR MATCHES "Visual Studio")
- if(NOT CMAKE_SYSROOT)
- set(vcx_platform ${CMAKE_GENERATOR_PLATFORM})
- if(CMAKE_GENERATOR MATCHES "Visual Studio 1[45]")
- set(vcx_sysroot_var "Sysroot")
+ if(NOT CMAKE_ANDROID_ARCH_ABI AND NOT CMAKE_SYSTEM_PROCESSOR)
+ if(CMAKE_GENERATOR_PLATFORM STREQUAL "ARM")
+ set(CMAKE_SYSTEM_PROCESSOR "armv7-a")
+ elseif(CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64")
+ set(CMAKE_SYSTEM_PROCESSOR "aarch64")
+ elseif(CMAKE_GENERATOR_PLATFORM STREQUAL "x86")
+ set(CMAKE_SYSTEM_PROCESSOR "i686")
+ elseif(CMAKE_GENERATOR_PLATFORM STREQUAL "x64")
+ set(CMAKE_SYSTEM_PROCESSOR "x86_64")
else()
- set(vcx_sysroot_var "SysrootLink")
+ message(FATAL_ERROR "Unhandled generator platform, please choose ARM, ARM64, x86 or x86_64 using -A")
endif()
+ endif()
+ if(NOT CMAKE_ANDROID_NDK)
+ set(vcx_platform ${CMAKE_GENERATOR_PLATFORM})
if(CMAKE_GENERATOR MATCHES "Visual Studio 14")
set(vcx_revision "2.0")
- elseif(CMAKE_GENERATOR MATCHES "Visual Studio 1[56]")
+ elseif(CMAKE_GENERATOR MATCHES "Visual Studio 1[567]")
set(vcx_revision "3.0")
else()
set(vcx_revision "")
@@ -62,16 +70,16 @@ if(CMAKE_GENERATOR MATCHES "Visual Studio")
RESULT_VARIABLE VCXPROJ_INSPECT_RESULT
)
unset(_msbuild)
- if(NOT CMAKE_SYSROOT AND VCXPROJ_INSPECT_OUTPUT MATCHES "CMAKE_SYSROOT=([^%\r\n]+)[\r\n]")
+ if(VCXPROJ_INSPECT_OUTPUT MATCHES "CMAKE_ANDROID_NDK=([^%\r\n]+)[\r\n]")
# Strip VS diagnostic output from the end of the line.
- string(REGEX REPLACE " \\(TaskId:[0-9]*\\)$" "" _sysroot "${CMAKE_MATCH_1}")
- if(EXISTS "${_sysroot}")
- file(TO_CMAKE_PATH "${_sysroot}" CMAKE_SYSROOT)
+ string(REGEX REPLACE " \\(TaskId:[0-9]*\\)$" "" _ndk "${CMAKE_MATCH_1}")
+ if(EXISTS "${_ndk}")
+ file(TO_CMAKE_PATH "${_ndk}" CMAKE_ANDROID_NDK)
endif()
endif()
if(VCXPROJ_INSPECT_RESULT)
message(CONFIGURE_LOG
- "Determining the sysroot for the Android NDK failed.
+ "Determining the Android NDK failed from msbuild failed.
The output was:
${VCXPROJ_INSPECT_RESULT}
${VCXPROJ_INSPECT_OUTPUT}
@@ -79,7 +87,7 @@ ${VCXPROJ_INSPECT_OUTPUT}
")
else()
message(CONFIGURE_LOG
- "Determining the sysroot for the Android NDK succeeded.
+ "Determining the Android NDK succeeded.
The output was:
${VCXPROJ_INSPECT_RESULT}
${VCXPROJ_INSPECT_OUTPUT}
diff --git a/Modules/Platform/Android/VCXProjInspect.vcxproj.in b/Modules/Platform/Android/VCXProjInspect.vcxproj.in
index 6919d2cd85..f87d59bca2 100644
--- a/Modules/Platform/Android/VCXProjInspect.vcxproj.in
+++ b/Modules/Platform/Android/VCXProjInspect.vcxproj.in
@@ -19,6 +19,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|@vcx_platform@'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
+ <AndroidAPILevel>android-21</AndroidAPILevel>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -29,7 +30,7 @@
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|@vcx_platform@'">
<PostBuildEvent>
- <Command>%40echo CMAKE_SYSROOT=$(@vcx_sysroot_var@)</Command>
+ <Command>%40echo CMAKE_ANDROID_NDK=$(VS_NdkRoot)</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 4a7d9bc591..2354f3d999 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -1018,6 +1018,7 @@ add_library(
CPack/cmCPackGeneratorFactory.cxx
CPack/cmCPackGenerator.cxx
CPack/cmCPackLog.cxx
+ CPack/cmCPackInnoSetupGenerator.cxx
CPack/cmCPackNSISGenerator.cxx
CPack/cmCPackNuGetGenerator.cxx
CPack/cmCPackSTGZGenerator.cxx
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 34eb248804..524f706433 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 26)
-set(CMake_VERSION_PATCH 20230411)
+set(CMake_VERSION_PATCH 20230505)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/CPack/IFW/cmCPackIFWCommon.cxx b/Source/CPack/IFW/cmCPackIFWCommon.cxx
index 5d995c335d..4a868ae88f 100644
--- a/Source/CPack/IFW/cmCPackIFWCommon.cxx
+++ b/Source/CPack/IFW/cmCPackIFWCommon.cxx
@@ -5,12 +5,11 @@
#include <cstddef> // IWYU pragma: keep
#include <sstream>
#include <utility>
-#include <vector>
#include "cmCPackGenerator.h"
#include "cmCPackIFWGenerator.h"
#include "cmCPackLog.h" // IWYU pragma: keep
-#include "cmStringAlgorithms.h"
+#include "cmList.h"
#include "cmSystemTools.h"
#include "cmTimestamp.h"
#include "cmVersionConfig.h"
@@ -76,13 +75,13 @@ bool cmCPackIFWCommon::IsVersionEqual(const char* version) const
void cmCPackIFWCommon::ExpandListArgument(
const std::string& arg, std::map<std::string, std::string>& argsOut)
{
- std::vector<std::string> args = cmExpandedList(arg, false);
+ cmList args{ arg };
if (args.empty()) {
return;
}
- std::size_t i = 0;
- std::size_t c = args.size();
+ cmList::size_type i = 0;
+ auto c = args.size();
if (c % 2) {
argsOut[""] = args[i];
++i;
@@ -97,13 +96,13 @@ void cmCPackIFWCommon::ExpandListArgument(
void cmCPackIFWCommon::ExpandListArgument(
const std::string& arg, std::multimap<std::string, std::string>& argsOut)
{
- std::vector<std::string> args = cmExpandedList(arg, false);
+ cmList args{ arg };
if (args.empty()) {
return;
}
- std::size_t i = 0;
- std::size_t c = args.size();
+ cmList::size_type i = 0;
+ auto c = args.size();
if (c % 2) {
argsOut.insert(std::pair<std::string, std::string>("", args[i]));
++i;
diff --git a/Source/CPack/IFW/cmCPackIFWGenerator.cxx b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
index bc14eb40b1..5724175510 100644
--- a/Source/CPack/IFW/cmCPackIFWGenerator.cxx
+++ b/Source/CPack/IFW/cmCPackIFWGenerator.cxx
@@ -14,6 +14,7 @@
#include "cmCPackLog.h" // IWYU pragma: keep
#include "cmDuration.h"
#include "cmGeneratedFileStream.h"
+#include "cmList.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
@@ -409,8 +410,8 @@ int cmCPackIFWGenerator::InitializeInternal()
// Repositories
if (cmValue RepoAllStr = this->GetOption("CPACK_IFW_REPOSITORIES_ALL")) {
- std::vector<std::string> RepoAllVector = cmExpandedList(RepoAllStr);
- for (std::string const& r : RepoAllVector) {
+ cmList RepoAllList{ RepoAllStr };
+ for (std::string const& r : RepoAllList) {
this->GetRepository(r);
}
}
diff --git a/Source/CPack/IFW/cmCPackIFWInstaller.cxx b/Source/CPack/IFW/cmCPackIFWInstaller.cxx
index 69440d9748..a77c22fa81 100644
--- a/Source/CPack/IFW/cmCPackIFWInstaller.cxx
+++ b/Source/CPack/IFW/cmCPackIFWInstaller.cxx
@@ -12,6 +12,7 @@
#include "cmCPackIFWRepository.h"
#include "cmCPackLog.h" // IWYU pragma: keep
#include "cmGeneratedFileStream.h"
+#include "cmList.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
diff --git a/Source/CPack/IFW/cmCPackIFWPackage.cxx b/Source/CPack/IFW/cmCPackIFWPackage.cxx
index 1668fb5d56..083f1ef7b1 100644
--- a/Source/CPack/IFW/cmCPackIFWPackage.cxx
+++ b/Source/CPack/IFW/cmCPackIFWPackage.cxx
@@ -15,6 +15,7 @@
#include "cmCPackIFWInstaller.h"
#include "cmCPackLog.h" // IWYU pragma: keep
#include "cmGeneratedFileStream.h"
+#include "cmList.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTimestamp.h"
@@ -427,16 +428,16 @@ int cmCPackIFWPackage::ConfigureFromPrefix(const std::string& prefix)
}
// QtIFW dependencies
- std::vector<std::string> deps;
+ cmList deps;
option = prefix + "DEPENDS";
if (cmValue value = this->GetOption(option)) {
- cmExpandList(value, deps);
+ deps.assign(value);
}
option = prefix + "DEPENDENCIES";
if (cmValue value = this->GetOption(option)) {
- cmExpandList(value, deps);
+ deps.append(value);
}
- for (std::string const& d : deps) {
+ for (auto const& d : deps) {
DependenceStruct dep(d);
if (this->Generator->Packages.count(dep.Name)) {
cmCPackIFWPackage& depPkg = this->Generator->Packages[dep.Name];
@@ -455,7 +456,7 @@ int cmCPackIFWPackage::ConfigureFromPrefix(const std::string& prefix)
if (this->IsSetToEmpty(option)) {
this->AlienAutoDependOn.clear();
} else if (cmValue value = this->GetOption(option)) {
- std::vector<std::string> depsOn = cmExpandedList(value);
+ cmList depsOn{ value };
for (std::string const& d : depsOn) {
DependenceStruct dep(d);
if (this->Generator->Packages.count(dep.Name)) {
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
index aeb3db3539..1ea78fdc3d 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
@@ -18,6 +18,7 @@
#include "cmCryptoHash.h"
#include "cmGeneratedFileStream.h"
#include "cmInstalledFile.h"
+#include "cmList.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmUuid.h"
@@ -239,7 +240,7 @@ bool cmCPackWIXGenerator::InitializeWiXConfiguration()
cmValue patchFilePath = GetOption("CPACK_WIX_PATCH_FILE");
if (patchFilePath) {
- std::vector<std::string> patchFilePaths = cmExpandedList(patchFilePath);
+ cmList patchFilePaths{ patchFilePath };
for (std::string const& p : patchFilePaths) {
if (!this->Patch->LoadFragments(p)) {
@@ -322,8 +323,7 @@ void cmCPackWIXGenerator::AppendUserSuppliedExtraObjects(std::ostream& stream)
if (!cpackWixExtraObjects)
return;
- std::vector<std::string> expandedExtraObjects =
- cmExpandedList(cpackWixExtraObjects);
+ cmList expandedExtraObjects{ cpackWixExtraObjects };
for (std::string const& obj : expandedExtraObjects) {
stream << " " << QuotePath(obj);
@@ -681,10 +681,10 @@ bool cmCPackWIXGenerator::AddComponentsToFeature(
featureDefinitions.BeginElement("FeatureRef");
featureDefinitions.AddAttribute("Id", featureId);
- std::vector<std::string> cpackPackageExecutablesList;
+ cmList cpackPackageExecutablesList;
cmValue cpackPackageExecutables = GetOption("CPACK_PACKAGE_EXECUTABLES");
if (cpackPackageExecutables) {
- cmExpandList(cpackPackageExecutables, cpackPackageExecutablesList);
+ cpackPackageExecutablesList.assign(cpackPackageExecutables);
if (cpackPackageExecutablesList.size() % 2 != 0) {
cmCPackLogger(
cmCPackLog::LOG_ERROR,
@@ -695,10 +695,10 @@ bool cmCPackWIXGenerator::AddComponentsToFeature(
}
}
- std::vector<std::string> cpackPackageDesktopLinksList;
+ cmList cpackPackageDesktopLinksList;
cmValue cpackPackageDesktopLinks = GetOption("CPACK_CREATE_DESKTOP_LINKS");
if (cpackPackageDesktopLinks) {
- cmExpandList(cpackPackageDesktopLinks, cpackPackageDesktopLinksList);
+ cpackPackageDesktopLinksList.assign(cpackPackageDesktopLinks);
}
AddDirectoryAndFileDefinitions(
@@ -1160,7 +1160,7 @@ void cmCPackWIXGenerator::CollectExtensions(std::string const& variableName,
if (!variableContent)
return;
- std::vector<std::string> list = cmExpandedList(variableContent);
+ cmList list{ variableContent };
extensions.insert(list.begin(), list.end());
}
@@ -1172,7 +1172,7 @@ void cmCPackWIXGenerator::CollectXmlNamespaces(std::string const& variableName,
return;
}
- std::vector<std::string> list = cmExpandedList(variableContent);
+ cmList list{ variableContent };
for (std::string const& str : list) {
auto pos = str.find('=');
if (pos != std::string::npos) {
@@ -1200,7 +1200,7 @@ void cmCPackWIXGenerator::AddCustomFlags(std::string const& variableName,
if (!variableContent)
return;
- std::vector<std::string> list = cmExpandedList(variableContent);
+ cmList list{ variableContent };
for (std::string const& i : list) {
stream << " " << QuotePath(i);
diff --git a/Source/CPack/WiX/cmWIXAccessControlList.cxx b/Source/CPack/WiX/cmWIXAccessControlList.cxx
index 9685a7f495..2261a66e0f 100644
--- a/Source/CPack/WiX/cmWIXAccessControlList.cxx
+++ b/Source/CPack/WiX/cmWIXAccessControlList.cxx
@@ -19,10 +19,9 @@ cmWIXAccessControlList::cmWIXAccessControlList(
bool cmWIXAccessControlList::Apply()
{
- std::vector<std::string> entries;
- this->InstalledFile.GetPropertyAsList("CPACK_WIX_ACL", entries);
+ auto entries = this->InstalledFile.GetPropertyAsList("CPACK_WIX_ACL");
- for (std::string const& entry : entries) {
+ for (auto const& entry : entries) {
this->CreatePermissionElement(entry);
}
diff --git a/Source/CPack/WiX/cmWIXShortcut.cxx b/Source/CPack/WiX/cmWIXShortcut.cxx
index cd1988a1cb..c3eb219a9d 100644
--- a/Source/CPack/WiX/cmWIXShortcut.cxx
+++ b/Source/CPack/WiX/cmWIXShortcut.cxx
@@ -91,10 +91,9 @@ void cmWIXShortcuts::CreateFromProperty(std::string const& propertyName,
std::string const& directoryId,
cmInstalledFile const& installedFile)
{
- std::vector<std::string> list;
- installedFile.GetPropertyAsList(propertyName, list);
+ auto list = installedFile.GetPropertyAsList(propertyName);
- for (std::string const& label : list) {
+ for (auto const& label : list) {
cmWIXShortcut shortcut;
shortcut.label = label;
shortcut.workingDirectoryId = directoryId;
diff --git a/Source/CPack/cmCPackBundleGenerator.cxx b/Source/CPack/cmCPackBundleGenerator.cxx
index b3d425aa51..7e6e4737dd 100644
--- a/Source/CPack/cmCPackBundleGenerator.cxx
+++ b/Source/CPack/cmCPackBundleGenerator.cxx
@@ -6,6 +6,7 @@
#include <vector>
#include "cmCPackLog.h"
+#include "cmList.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
@@ -191,7 +192,7 @@ int cmCPackBundleGenerator::SignBundle(const std::string& src_dir)
cmValue sign_files = this->GetOption("CPACK_BUNDLE_APPLE_CODESIGN_FILES");
- std::vector<std::string> relFiles = cmExpandedList(sign_files);
+ cmList relFiles{ sign_files };
// sign the files supplied by the user, ie. frameworks.
for (auto const& file : relFiles) {
diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx
index 6ba28d166c..34c56c9993 100644
--- a/Source/CPack/cmCPackDebGenerator.cxx
+++ b/Source/CPack/cmCPackDebGenerator.cxx
@@ -20,6 +20,7 @@
#include "cmCPackLog.h"
#include "cmCryptoHash.h"
#include "cmGeneratedFileStream.h"
+#include "cmList.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
@@ -427,8 +428,7 @@ bool DebGenerator::generateControlTar(std::string const& md5Filename) const
// default
control_tar.ClearPermissions();
- std::vector<std::string> controlExtraList =
- cmExpandedList(this->ControlExtra);
+ cmList controlExtraList{ this->ControlExtra };
for (std::string const& i : controlExtraList) {
std::string filenamename = cmsys::SystemTools::GetFilenameName(i);
std::string localcopy = this->WorkDir + "/" + filenamename;
diff --git a/Source/CPack/cmCPackDragNDropGenerator.cxx b/Source/CPack/cmCPackDragNDropGenerator.cxx
index 68e7ba3651..768bfbe08d 100644
--- a/Source/CPack/cmCPackDragNDropGenerator.cxx
+++ b/Source/CPack/cmCPackDragNDropGenerator.cxx
@@ -19,6 +19,7 @@
#include "cmCPackLog.h"
#include "cmDuration.h"
#include "cmGeneratedFileStream.h"
+#include "cmList.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
@@ -128,8 +129,7 @@ int cmCPackDragNDropGenerator::InitializeInternal()
return 0;
}
- std::vector<std::string> languages =
- cmExpandedList(this->GetOption("CPACK_DMG_SLA_LANGUAGES"));
+ cmList languages{ this->GetOption("CPACK_DMG_SLA_LANGUAGES") };
if (languages.empty()) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
"CPACK_DMG_SLA_LANGUAGES set but empty" << std::endl);
@@ -543,9 +543,9 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
std::string sla_xml =
cmStrCat(this->GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/sla.xml");
- std::vector<std::string> languages;
+ cmList languages;
if (!oldStyle) {
- cmExpandList(cpack_dmg_languages, languages);
+ languages.assign(cpack_dmg_languages);
}
std::vector<uint16_t> header_data;
@@ -574,7 +574,7 @@ int cmCPackDragNDropGenerator::CreateDMG(const std::string& src_dir,
header_data.push_back(0);
header_data.push_back(languages.size());
- for (size_t i = 0; i < languages.size(); ++i) {
+ for (cmList::size_type i = 0; i < languages.size(); ++i) {
CFStringRef language_cfstring = CFStringCreateWithCString(
nullptr, languages[i].c_str(), kCFStringEncodingUTF8);
CFStringRef iso_language =
diff --git a/Source/CPack/cmCPackExternalGenerator.cxx b/Source/CPack/cmCPackExternalGenerator.cxx
index 4c92592d03..8ba015c8a6 100644
--- a/Source/CPack/cmCPackExternalGenerator.cxx
+++ b/Source/CPack/cmCPackExternalGenerator.cxx
@@ -15,8 +15,8 @@
#include "cmCPackComponentGroup.h"
#include "cmCPackLog.h"
+#include "cmList.h"
#include "cmMakefile.h"
-#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
@@ -79,7 +79,7 @@ int cmCPackExternalGenerator::PackageFiles()
cmValue builtPackages = this->GetOption("CPACK_EXTERNAL_BUILT_PACKAGES");
if (builtPackages) {
- cmExpandList(builtPackages, this->packageFileNames, false);
+ cmExpandList(builtPackages, this->packageFileNames);
}
}
diff --git a/Source/CPack/cmCPackFreeBSDGenerator.cxx b/Source/CPack/cmCPackFreeBSDGenerator.cxx
index ea7b24b488..0840e33cc8 100644
--- a/Source/CPack/cmCPackFreeBSDGenerator.cxx
+++ b/Source/CPack/cmCPackFreeBSDGenerator.cxx
@@ -2,15 +2,6 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCPackFreeBSDGenerator.h"
-#include "cmArchiveWrite.h"
-#include "cmCPackArchiveGenerator.h"
-#include "cmCPackLog.h"
-#include "cmGeneratedFileStream.h"
-#include "cmStringAlgorithms.h"
-#include "cmSystemTools.h"
-#include "cmWorkingDirectory.h"
-
-// Needed for ::open() and ::stat()
#include <algorithm>
#include <ostream>
#include <utility>
@@ -21,6 +12,15 @@
#include <sys/stat.h>
+#include "cmArchiveWrite.h"
+#include "cmCPackArchiveGenerator.h"
+#include "cmCPackLog.h"
+#include "cmGeneratedFileStream.h"
+#include "cmList.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+#include "cmWorkingDirectory.h"
+
// Suffix used to tell libpkg what compression to use
static const char FreeBSDPackageCompression[] = "txz";
static const char FreeBSDPackageSuffix_17[] = ".pkg";
@@ -292,8 +292,7 @@ void cmCPackFreeBSDGenerator::write_manifest_fields(
manifest << ManifestKeyValue(
"desc", var_lookup("CPACK_FREEBSD_PACKAGE_DESCRIPTION"));
manifest << ManifestKeyValue("www", var_lookup("CPACK_FREEBSD_PACKAGE_WWW"));
- std::vector<std::string> licenses =
- cmExpandedList(var_lookup("CPACK_FREEBSD_PACKAGE_LICENSE"));
+ cmList licenses{ var_lookup("CPACK_FREEBSD_PACKAGE_LICENSE") };
std::string licenselogic("single");
if (licenses.empty()) {
cmSystemTools::SetFatalErrorOccurred();
@@ -302,12 +301,10 @@ void cmCPackFreeBSDGenerator::write_manifest_fields(
}
manifest << ManifestKeyValue("licenselogic", licenselogic);
manifest << (ManifestKeyListValue("licenses") << licenses);
- std::vector<std::string> categories =
- cmExpandedList(var_lookup("CPACK_FREEBSD_PACKAGE_CATEGORIES"));
+ cmList categories{ var_lookup("CPACK_FREEBSD_PACKAGE_CATEGORIES") };
manifest << (ManifestKeyListValue("categories") << categories);
manifest << ManifestKeyValue("prefix", var_lookup("CMAKE_INSTALL_PREFIX"));
- std::vector<std::string> deps =
- cmExpandedList(var_lookup("CPACK_FREEBSD_PACKAGE_DEPS"));
+ cmList deps{ var_lookup("CPACK_FREEBSD_PACKAGE_DEPS") };
if (!deps.empty()) {
manifest << (ManifestKeyDepsValue("deps") << deps);
}
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index 2ac5b3dc77..afd85cda75 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -19,6 +19,7 @@
#include "cmFileTimes.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStateSnapshot.h"
@@ -216,8 +217,7 @@ int cmCPackGenerator::InstallProject()
cmValue default_dir_install_permissions =
this->GetOption("CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS");
if (cmNonempty(default_dir_install_permissions)) {
- std::vector<std::string> items =
- cmExpandedList(default_dir_install_permissions);
+ cmList items{ default_dir_install_permissions };
for (const auto& arg : items) {
if (!cmFSPermissions::stringToModeT(arg, default_dir_mode_v)) {
cmCPackLogger(cmCPackLog::LOG_ERROR,
@@ -266,7 +266,7 @@ int cmCPackGenerator::InstallProject()
// Run pre-build actions
cmValue preBuildScripts = this->GetOption("CPACK_PRE_BUILD_SCRIPTS");
if (preBuildScripts) {
- const auto scripts = cmExpandedList(preBuildScripts, false);
+ const cmList scripts{ preBuildScripts };
for (const auto& script : scripts) {
cmCPackLogger(cmCPackLog::LOG_OUTPUT,
"Executing pre-build script: " << script << std::endl);
@@ -296,8 +296,7 @@ int cmCPackGenerator::InstallProjectViaInstallCommands(
std::string tempInstallDirectoryEnv =
cmStrCat("CMAKE_INSTALL_PREFIX=", tempInstallDirectory);
cmSystemTools::PutEnv(tempInstallDirectoryEnv);
- std::vector<std::string> installCommandsVector =
- cmExpandedList(installCommands);
+ cmList installCommandsVector{ installCommands };
for (std::string const& ic : installCommandsVector) {
cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << ic << std::endl);
std::string output;
@@ -333,8 +332,7 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
std::vector<cmsys::RegularExpression> ignoreFilesRegex;
cmValue cpackIgnoreFiles = this->GetOption("CPACK_IGNORE_FILES");
if (cpackIgnoreFiles) {
- std::vector<std::string> ignoreFilesRegexString =
- cmExpandedList(cpackIgnoreFiles);
+ cmList ignoreFilesRegexString{ cpackIgnoreFiles };
for (std::string const& ifr : ignoreFilesRegexString) {
cmCPackLogger(cmCPackLog::LOG_VERBOSE,
"Create ignore files regex for: " << ifr << std::endl);
@@ -343,9 +341,8 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
}
cmValue installDirectories = this->GetOption("CPACK_INSTALLED_DIRECTORIES");
if (cmNonempty(installDirectories)) {
- std::vector<std::string> installDirectoriesVector =
- cmExpandedList(installDirectories);
- if (installDirectoriesVector.size() % 2 != 0) {
+ cmList installDirectoriesList{ installDirectories };
+ if (installDirectoriesList.size() % 2 != 0) {
cmCPackLogger(
cmCPackLog::LOG_ERROR,
"CPACK_INSTALLED_DIRECTORIES should contain pairs of <directory> "
@@ -355,10 +352,10 @@ int cmCPackGenerator::InstallProjectViaInstalledDirectories(
<< std::endl);
return 0;
}
- std::vector<std::string>::iterator it;
+ cmList::iterator it;
const std::string& tempDir = tempInstallDirectory;
- for (it = installDirectoriesVector.begin();
- it != installDirectoriesVector.end(); ++it) {
+ for (it = installDirectoriesList.begin();
+ it != installDirectoriesList.end(); ++it) {
std::vector<std::pair<std::string, std::string>> symlinkedFiles;
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Find files" << std::endl);
cmsys::Glob gl;
@@ -485,7 +482,7 @@ int cmCPackGenerator::InstallProjectViaInstallScript(
if (cmakeScripts && !cmakeScripts->empty()) {
cmCPackLogger(cmCPackLog::LOG_OUTPUT,
"- Install scripts: " << cmakeScripts << std::endl);
- std::vector<std::string> cmakeScriptsVector = cmExpandedList(cmakeScripts);
+ cmList cmakeScriptsVector{ cmakeScripts };
for (std::string const& installScript : cmakeScriptsVector) {
cmCPackLogger(cmCPackLog::LOG_OUTPUT,
@@ -549,14 +546,12 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
<< std::endl);
return 0;
}
- std::vector<std::string> cmakeProjectsVector =
- cmExpandedList(cmakeProjects);
- std::vector<std::string>::iterator it;
- for (it = cmakeProjectsVector.begin(); it != cmakeProjectsVector.end();
- ++it) {
- if (it + 1 == cmakeProjectsVector.end() ||
- it + 2 == cmakeProjectsVector.end() ||
- it + 3 == cmakeProjectsVector.end()) {
+ cmList cmakeProjectsList{ cmakeProjects };
+ cmList::iterator it;
+ for (it = cmakeProjectsList.begin(); it != cmakeProjectsList.end(); ++it) {
+ if (it + 1 == cmakeProjectsList.end() ||
+ it + 2 == cmakeProjectsList.end() ||
+ it + 3 == cmakeProjectsList.end()) {
cmCPackLogger(
cmCPackLog::LOG_ERROR,
"Not enough items on list: CPACK_INSTALL_CMAKE_PROJECTS. "
@@ -578,7 +573,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
++it;
project.SubDirectory = *it;
- std::vector<std::string> componentsVector;
+ cmList componentsList;
bool componentInstall = false;
/*
@@ -593,10 +588,9 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
std::string installTypesVar = "CPACK_" +
cmSystemTools::UpperCase(project.Component) + "_INSTALL_TYPES";
cmValue installTypes = this->GetOption(installTypesVar);
- if (cmNonempty(installTypes)) {
- std::vector<std::string> installTypesVector =
- cmExpandedList(installTypes);
- for (std::string const& installType : installTypesVector) {
+ if (!installTypes.IsEmpty()) {
+ cmList installTypesList{ installTypes };
+ for (std::string const& installType : installTypesList) {
project.InstallationTypes.push_back(
this->GetInstallationType(project.ProjectName, installType));
}
@@ -606,23 +600,23 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
std::string componentsVar =
"CPACK_COMPONENTS_" + cmSystemTools::UpperCase(project.Component);
cmValue components = this->GetOption(componentsVar);
- if (cmNonempty(components)) {
- cmExpandList(components, componentsVector);
- for (std::string const& comp : componentsVector) {
+ if (!components.IsEmpty()) {
+ componentsList.assign(components);
+ for (auto const& comp : componentsList) {
project.Components.push_back(
this->GetComponent(project.ProjectName, comp));
}
componentInstall = true;
}
}
- if (componentsVector.empty()) {
- componentsVector.push_back(project.Component);
+ if (componentsList.empty()) {
+ componentsList.push_back(project.Component);
}
- std::vector<std::string> buildConfigs;
+ cmList buildConfigs;
// Try get configuration names given via `-C` CLI option
- cmExpandList(this->GetOption("CPACK_BUILD_CONFIG"), buildConfigs);
+ buildConfigs.assign(this->GetOption("CPACK_BUILD_CONFIG"));
// Remove duplicates
std::sort(buildConfigs.begin(), buildConfigs.end());
@@ -661,7 +655,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects(
<< buildConfig << ']'
<< std::endl);
// Run the installation for each component
- for (std::string const& component : componentsVector) {
+ for (std::string const& component : componentsList) {
if (!this->InstallCMakeProject(
setDestDir, project.Directory, baseTempInstallDirectory,
default_dir_mode, component, componentInstall,
@@ -894,9 +888,8 @@ int cmCPackGenerator::InstallCMakeProject(
mf.AddDefinition("CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION", "1");
}
- std::vector<std::string> custom_variables;
- this->MakefileMap->GetDefExpandList("CPACK_CUSTOM_INSTALL_VARIABLES",
- custom_variables);
+ cmList custom_variables{ this->MakefileMap->GetDefinition(
+ "CPACK_CUSTOM_INSTALL_VARIABLES") };
for (auto const& custom_variable : custom_variables) {
std::string value;
@@ -1129,7 +1122,7 @@ int cmCPackGenerator::DoPackage()
this->MakefileMap->AddDefinition("CPACK_PACKAGE_FILES",
cmJoin(this->packageFileNames, ";"));
- const auto scripts = cmExpandedList(postBuildScripts, false);
+ const cmList scripts{ postBuildScripts };
for (const auto& script : scripts) {
cmCPackLogger(cmCPackLog::LOG_OUTPUT,
"Executing post-build script: " << script << std::endl);
@@ -1595,9 +1588,8 @@ cmCPackComponent* cmCPackGenerator::GetComponent(
// Determine the installation types.
cmValue installTypes = this->GetOption(macroPrefix + "_INSTALL_TYPES");
if (cmNonempty(installTypes)) {
- std::vector<std::string> installTypesVector =
- cmExpandedList(installTypes);
- for (std::string const& installType : installTypesVector) {
+ cmList installTypesList{ installTypes };
+ for (auto const& installType : installTypesList) {
component->InstallationTypes.push_back(
this->GetInstallationType(projectName, installType));
}
@@ -1606,8 +1598,8 @@ cmCPackComponent* cmCPackGenerator::GetComponent(
// Determine the component dependencies.
cmValue depends = this->GetOption(macroPrefix + "_DEPENDS");
if (cmNonempty(depends)) {
- std::vector<std::string> dependsVector = cmExpandedList(depends);
- for (std::string const& depend : dependsVector) {
+ cmList dependsList{ depends };
+ for (auto const& depend : dependsList) {
cmCPackComponent* child = this->GetComponent(projectName, depend);
component->Dependencies.push_back(child);
child->ReverseDependencies.push_back(component);
diff --git a/Source/CPack/cmCPackGeneratorFactory.cxx b/Source/CPack/cmCPackGeneratorFactory.cxx
index efb94b9d8f..6ca48bf938 100644
--- a/Source/CPack/cmCPackGeneratorFactory.cxx
+++ b/Source/CPack/cmCPackGeneratorFactory.cxx
@@ -13,6 +13,7 @@
#include "cmCPackDebGenerator.h"
#include "cmCPackExternalGenerator.h"
#include "cmCPackGenerator.h"
+#include "cmCPackInnoSetupGenerator.h"
#include "cmCPackLog.h"
#include "cmCPackNSISGenerator.h"
#include "cmCPackNuGetGenerator.h"
@@ -60,6 +61,10 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory()
this->RegisterGenerator("STGZ", "Self extracting Tar GZip compression",
cmCPackSTGZGenerator::CreateGenerator);
}
+ if (cmCPackInnoSetupGenerator::CanGenerate()) {
+ this->RegisterGenerator("INNOSETUP", "Inno Setup packages",
+ cmCPackInnoSetupGenerator::CreateGenerator);
+ }
if (cmCPackNSISGenerator::CanGenerate()) {
this->RegisterGenerator("NSIS", "Null Soft Installer",
cmCPackNSISGenerator::CreateGenerator);
diff --git a/Source/CPack/cmCPackInnoSetupGenerator.cxx b/Source/CPack/cmCPackInnoSetupGenerator.cxx
new file mode 100644
index 0000000000..d8825d46b5
--- /dev/null
+++ b/Source/CPack/cmCPackInnoSetupGenerator.cxx
@@ -0,0 +1,1159 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmCPackInnoSetupGenerator.h"
+
+#include <algorithm>
+#include <cctype>
+#include <cstdlib>
+#include <ostream>
+#include <stack>
+#include <utility>
+
+#include "cmsys/RegularExpression.hxx"
+
+#include "cmCPackComponentGroup.h"
+#include "cmCPackLog.h"
+#include "cmDuration.h"
+#include "cmGeneratedFileStream.h"
+#include "cmList.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+
+cmCPackInnoSetupGenerator::cmCPackInnoSetupGenerator() = default;
+cmCPackInnoSetupGenerator::~cmCPackInnoSetupGenerator() = default;
+
+bool cmCPackInnoSetupGenerator::CanGenerate()
+{
+ // Inno Setup is only available for Windows
+#ifdef _WIN32
+ return true;
+#else
+ return false;
+#endif
+}
+
+int cmCPackInnoSetupGenerator::InitializeInternal()
+{
+ if (cmIsOn(GetOption("CPACK_INCLUDE_TOPLEVEL_DIRECTORY"))) {
+ cmCPackLogger(cmCPackLog::LOG_WARNING,
+ "Inno Setup Generator cannot work with "
+ "CPACK_INCLUDE_TOPLEVEL_DIRECTORY set. "
+ "This option will be reset to 0 (for this generator only)."
+ << std::endl);
+ SetOption("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", nullptr);
+ }
+
+ std::vector<std::string> path;
+
+#ifdef _WIN32
+ path.push_back("C:\\Program Files (x86)\\Inno Setup 5");
+ path.push_back("C:\\Program Files (x86)\\Inno Setup 6");
+#endif
+
+ SetOptionIfNotSet("CPACK_INNOSETUP_EXECUTABLE", "ISCC");
+ const std::string& isccPath = cmSystemTools::FindProgram(
+ GetOption("CPACK_INNOSETUP_EXECUTABLE"), path, false);
+
+ if (isccPath.empty()) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Cannot find Inno Setup compiler ISCC: "
+ "likely it is not installed, or not in your PATH"
+ << std::endl);
+
+ return 0;
+ }
+
+ const std::string isccCmd = cmStrCat(QuotePath(isccPath), "/?");
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE,
+ "Test Inno Setup version: " << isccCmd << std::endl);
+ std::string output;
+ cmSystemTools::RunSingleCommand(isccCmd, &output, &output, nullptr, nullptr,
+ this->GeneratorVerbose, cmDuration::zero());
+ cmsys::RegularExpression vRex("Inno Setup ([0-9]+)");
+ if (!vRex.find(output)) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Problem checking Inno Setup version with command: "
+ << isccCmd << std::endl
+ << "Have you downloaded Inno Setup from "
+ "https://jrsoftware.org/isinfo.php?"
+ << std::endl);
+ return 0;
+ }
+
+ const int isccVersion = atoi(vRex.match(1).c_str());
+ const int minIsccVersion = 6;
+ cmCPackLogger(cmCPackLog::LOG_DEBUG,
+ "Inno Setup Version: " << isccVersion << std::endl);
+
+ if (isccVersion < minIsccVersion) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "CPack requires Inno Setup Version 6 or greater. "
+ "Inno Setup found on the system was: "
+ << isccVersion << std::endl);
+ return 0;
+ }
+
+ SetOption("CPACK_INSTALLER_PROGRAM", isccPath);
+
+ return this->Superclass::InitializeInternal();
+}
+
+int cmCPackInnoSetupGenerator::PackageFiles()
+{
+ // Includes
+ if (IsSet("CPACK_INNOSETUP_EXTRA_SCRIPTS")) {
+ const cmList extraScripts(GetOption("CPACK_INNOSETUP_EXTRA_SCRIPTS"));
+
+ for (const std::string& i : extraScripts) {
+ includeDirectives.push_back(cmStrCat(
+ "#include ", QuotePath(cmSystemTools::CollapseFullPath(i, toplevel))));
+ }
+ }
+
+ // [Languages] section
+ SetOptionIfNotSet("CPACK_INNOSETUP_LANGUAGES", "english");
+ const cmList languages(GetOption("CPACK_INNOSETUP_LANGUAGES"));
+ for (std::string i : languages) {
+ cmCPackInnoSetupKeyValuePairs params;
+
+ params["Name"] = Quote(i);
+
+ if (cmSystemTools::LowerCase(i) == "english") {
+ params["MessagesFile"] = "\"compiler:Default.isl\"";
+ } else {
+ i[0] = static_cast<char>(std::toupper(i[0]));
+ params["MessagesFile"] = cmStrCat("\"compiler:Languages\\", i, ".isl\"");
+ }
+
+ languageInstructions.push_back(ISKeyValueLine(params));
+ }
+
+ if (!Components.empty() && !ProcessComponents()) {
+ return false;
+ }
+
+ if (!(ProcessSetupSection() && ProcessFiles())) {
+ return false;
+ }
+
+ // [Code] section
+ if (IsSet("CPACK_INNOSETUP_CODE_FILES")) {
+ const cmList codeFiles(GetOption("CPACK_INNOSETUP_CODE_FILES"));
+
+ for (const std::string& i : codeFiles) {
+ codeIncludes.push_back(cmStrCat(
+ "#include ", QuotePath(cmSystemTools::CollapseFullPath(i, toplevel))));
+ }
+ }
+
+ return ConfigureISScript() && Compile();
+}
+
+bool cmCPackInnoSetupGenerator::ProcessSetupSection()
+{
+ if (!RequireOption("CPACK_PACKAGE_INSTALL_REGISTRY_KEY")) {
+ return false;
+ }
+ setupDirectives["AppId"] = GetOption("CPACK_PACKAGE_INSTALL_REGISTRY_KEY");
+
+ if (!RequireOption("CPACK_PACKAGE_NAME")) {
+ return false;
+ }
+ setupDirectives["AppName"] = GetOption("CPACK_PACKAGE_NAME");
+ setupDirectives["UninstallDisplayName"] = GetOption("CPACK_PACKAGE_NAME");
+
+ if (!RequireOption("CPACK_PACKAGE_VERSION")) {
+ return false;
+ }
+ setupDirectives["AppVersion"] = GetOption("CPACK_PACKAGE_VERSION");
+
+ if (!RequireOption("CPACK_PACKAGE_VENDOR")) {
+ return false;
+ }
+ setupDirectives["AppPublisher"] = GetOption("CPACK_PACKAGE_VENDOR");
+
+ if (IsSet("CPACK_PACKAGE_HOMEPAGE_URL")) {
+ setupDirectives["AppPublisherURL"] =
+ GetOption("CPACK_PACKAGE_HOMEPAGE_URL");
+ setupDirectives["AppSupportURL"] = GetOption("CPACK_PACKAGE_HOMEPAGE_URL");
+ setupDirectives["AppUpdatesURL"] = GetOption("CPACK_PACKAGE_HOMEPAGE_URL");
+ }
+
+ SetOptionIfNotSet("CPACK_INNOSETUP_IGNORE_LICENSE_PAGE", "OFF");
+ if (IsSet("CPACK_RESOURCE_FILE_LICENSE") &&
+ !GetOption("CPACK_INNOSETUP_IGNORE_LICENSE_PAGE").IsOn()) {
+ setupDirectives["LicenseFile"] = cmSystemTools::ConvertToWindowsOutputPath(
+ GetOption("CPACK_RESOURCE_FILE_LICENSE"));
+ }
+
+ SetOptionIfNotSet("CPACK_INNOSETUP_IGNORE_README_PAGE", "ON");
+ if (IsSet("CPACK_RESOURCE_FILE_README") &&
+ !GetOption("CPACK_INNOSETUP_IGNORE_README_PAGE").IsOn()) {
+ setupDirectives["InfoBeforeFile"] =
+ cmSystemTools::ConvertToWindowsOutputPath(
+ GetOption("CPACK_RESOURCE_FILE_README"));
+ }
+
+ SetOptionIfNotSet("CPACK_INNOSETUP_USE_MODERN_WIZARD", "OFF");
+ if (GetOption("CPACK_INNOSETUP_USE_MODERN_WIZARD").IsOn()) {
+ setupDirectives["WizardStyle"] = "modern";
+ } else {
+ setupDirectives["WizardStyle"] = "classic";
+ setupDirectives["WizardSmallImageFile"] =
+ "compiler:WizClassicSmallImage.bmp";
+ setupDirectives["WizardImageFile"] = "compiler:WizClassicImage.bmp";
+ setupDirectives["SetupIconFile"] = "compiler:SetupClassicIcon.ico";
+ }
+
+ if (IsSet("CPACK_INNOSETUP_ICON_FILE")) {
+ setupDirectives["SetupIconFile"] =
+ cmSystemTools::ConvertToWindowsOutputPath(
+ GetOption("CPACK_INNOSETUP_ICON_FILE"));
+ }
+
+ if (IsSet("CPACK_PACKAGE_ICON")) {
+ setupDirectives["WizardSmallImageFile"] =
+ cmSystemTools::ConvertToWindowsOutputPath(
+ GetOption("CPACK_PACKAGE_ICON"));
+ }
+
+ if (!RequireOption("CPACK_PACKAGE_INSTALL_DIRECTORY")) {
+ return false;
+ }
+ SetOptionIfNotSet("CPACK_INNOSETUP_INSTALL_ROOT", "{autopf}");
+ setupDirectives["DefaultDirName"] =
+ cmSystemTools::ConvertToWindowsOutputPath(
+ cmStrCat(GetOption("CPACK_INNOSETUP_INSTALL_ROOT"), '\\',
+ GetOption("CPACK_PACKAGE_INSTALL_DIRECTORY")));
+
+ SetOptionIfNotSet("CPACK_INNOSETUP_ALLOW_CUSTOM_DIRECTORY", "ON");
+ if (GetOption("CPACK_INNOSETUP_ALLOW_CUSTOM_DIRECTORY").IsOff()) {
+ setupDirectives["DisableDirPage"] = "yes";
+ }
+
+ SetOptionIfNotSet("CPACK_INNOSETUP_PROGRAM_MENU_FOLDER",
+ GetOption("CPACK_PACKAGE_NAME"));
+ if (GetOption("CPACK_INNOSETUP_PROGRAM_MENU_FOLDER") == ".") {
+ setupDirectives["DisableProgramGroupPage"] = "yes";
+ toplevelProgramFolder = true;
+ } else {
+ setupDirectives["DefaultGroupName"] =
+ GetOption("CPACK_INNOSETUP_PROGRAM_MENU_FOLDER");
+ toplevelProgramFolder = false;
+ }
+
+ if (IsSet("CPACK_INNOSETUP_PASSWORD")) {
+ setupDirectives["Password"] = GetOption("CPACK_INNOSETUP_PASSWORD");
+ setupDirectives["Encryption"] = "yes";
+ }
+
+ /*
+ * These directives can only be modified using the
+ * CPACK_INNOSETUP_SETUP_<directive> variables
+ */
+ setupDirectives["ShowLanguageDialog"] = "auto";
+ setupDirectives["AllowNoIcons"] = "yes";
+ setupDirectives["Compression"] = "lzma";
+ setupDirectives["SolidCompression"] = "yes";
+
+ // Output file and directory
+ if (!RequireOption("CPACK_PACKAGE_FILE_NAME")) {
+ return false;
+ }
+ setupDirectives["OutputBaseFilename"] = GetOption("CPACK_PACKAGE_FILE_NAME");
+
+ if (!RequireOption("CPACK_TOPLEVEL_DIRECTORY")) {
+ return false;
+ }
+ setupDirectives["OutputDir"] = cmSystemTools::ConvertToWindowsOutputPath(
+ GetOption("CPACK_TOPLEVEL_DIRECTORY"));
+
+ setupDirectives["SourceDir"] =
+ cmSystemTools::ConvertToWindowsOutputPath(toplevel);
+
+ // Target architecture
+ if (!RequireOption("CPACK_INNOSETUP_ARCHITECTURE")) {
+ return false;
+ }
+
+ const std::string& architecture = GetOption("CPACK_INNOSETUP_ARCHITECTURE");
+ if (architecture != "x86" && architecture != "x64" &&
+ architecture != "arm64" && architecture != "ia64") {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "CPACK_INNOSETUP_ARCHITECTURE must be either x86, x64, "
+ "arm64 or ia64"
+ << std::endl);
+ return false;
+ }
+
+ // The following directives must not be set to target x86
+ if (architecture != "x86") {
+ setupDirectives["ArchitecturesAllowed"] = architecture;
+ setupDirectives["ArchitecturesInstallIn64BitMode"] = architecture;
+ }
+
+ /*
+ * Handle custom directives (they have higher priority than other variables,
+ * so they have to be processed after all other variables)
+ */
+ for (const std::string& i : GetOptions()) {
+ if (cmHasPrefix(i, "CPACK_INNOSETUP_SETUP_")) {
+ const std::string& directive =
+ i.substr(cmStrLen("CPACK_INNOSETUP_SETUP_"));
+ setupDirectives[directive] = GetOption(i);
+ }
+ }
+
+ return true;
+}
+
+bool cmCPackInnoSetupGenerator::ProcessFiles()
+{
+ std::map<std::string, std::string> customFileInstructions;
+ if (IsSet("CPACK_INNOSETUP_CUSTOM_INSTALL_INSTRUCTIONS")) {
+ const cmList instructions(
+ GetOption("CPACK_INNOSETUP_CUSTOM_INSTALL_INSTRUCTIONS"));
+ if (instructions.size() % 2 != 0) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "CPACK_INNOSETUP_CUSTOM_INSTALL_INSTRUCTIONS should "
+ "contain pairs of <path> and <instruction>"
+ << std::endl);
+ return false;
+ }
+
+ for (auto it = instructions.begin(); it != instructions.end(); ++it) {
+ const std::string& key =
+ QuotePath(cmSystemTools::CollapseFullPath(*it, toplevel));
+ customFileInstructions[key] = *(++it);
+ }
+ }
+
+ const std::string& iconsPrefix =
+ toplevelProgramFolder ? "{autoprograms}\\" : "{group}\\";
+
+ std::map<std::string, std::string> icons;
+ if (IsSet("CPACK_PACKAGE_EXECUTABLES")) {
+ const cmList executables(GetOption("CPACK_PACKAGE_EXECUTABLES"));
+ if (executables.size() % 2 != 0) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "CPACK_PACKAGE_EXECUTABLES should should contain pairs of "
+ "<executable> and <text label>"
+ << std::endl);
+ return false;
+ }
+
+ for (auto it = executables.begin(); it != executables.end(); ++it) {
+ const std::string& key = *it;
+ icons[key] = *(++it);
+ }
+ }
+
+ std::vector<std::string> desktopIcons;
+ if (IsSet("CPACK_CREATE_DESKTOP_LINKS")) {
+ cmExpandList(GetOption("CPACK_CREATE_DESKTOP_LINKS"), desktopIcons);
+ }
+
+ std::vector<std::string> runExecutables;
+ if (IsSet("CPACK_INNOSETUP_RUN_EXECUTABLES")) {
+ cmExpandList(GetOption("CPACK_INNOSETUP_RUN_EXECUTABLES"), runExecutables);
+ }
+
+ for (const std::string& i : files) {
+ cmCPackInnoSetupKeyValuePairs params;
+
+ std::string toplevelDirectory;
+ std::string outputDir;
+ cmCPackComponent* component = nullptr;
+ std::string componentParam;
+ if (!Components.empty()) {
+ const std::string& fileName = cmSystemTools::RelativePath(toplevel, i);
+ const std::string::size_type pos = fileName.find('/');
+
+ // Use the custom component install directory if we have one
+ if (pos != std::string::npos) {
+ const std::string& componentName = fileName.substr(0, pos);
+ component = &Components[componentName];
+
+ toplevelDirectory =
+ cmSystemTools::CollapseFullPath(componentName, toplevel);
+ outputDir = CustomComponentInstallDirectory(component);
+ componentParam =
+ CreateRecursiveComponentPath(component->Group, component->Name);
+
+ if (component->IsHidden && component->IsDisabledByDefault) {
+ continue;
+ }
+
+ if (component->IsHidden) {
+ componentParam.clear();
+ }
+ } else {
+ // Don't install component directories
+ continue;
+ }
+ } else {
+ toplevelDirectory = toplevel;
+ outputDir = "{app}";
+ }
+
+ if (!componentParam.empty()) {
+ params["Components"] = componentParam;
+ }
+
+ if (cmSystemTools::FileIsDirectory(i)) {
+ // Custom instructions replace the automatic generated instructions
+ if (customFileInstructions.count(QuotePath(i))) {
+ dirInstructions.push_back(customFileInstructions[QuotePath(i)]);
+ } else {
+ std::string destDir = cmSystemTools::ConvertToWindowsOutputPath(
+ cmStrCat(outputDir, '\\',
+ cmSystemTools::RelativePath(toplevelDirectory, i)));
+ cmStripSuffixIfExists(destDir, '\\');
+
+ params["Name"] = QuotePath(destDir);
+
+ dirInstructions.push_back(ISKeyValueLine(params));
+ }
+ } else {
+ // Custom instructions replace the automatic generated instructions
+ if (customFileInstructions.count(QuotePath(i))) {
+ fileInstructions.push_back(customFileInstructions[QuotePath(i)]);
+ } else {
+ std::string destDir = cmSystemTools::ConvertToWindowsOutputPath(
+ cmStrCat(outputDir, '\\',
+ cmSystemTools::GetParentDirectory(
+ cmSystemTools::RelativePath(toplevelDirectory, i))));
+ cmStripSuffixIfExists(destDir, '\\');
+
+ params["DestDir"] = QuotePath(destDir);
+
+ if (component != nullptr && component->IsDownloaded) {
+ const std::string& archiveName =
+ cmSystemTools::GetFilenameWithoutLastExtension(
+ component->ArchiveFile);
+ const std::string& relativePath =
+ cmSystemTools::RelativePath(toplevelDirectory, i);
+
+ params["Source"] =
+ QuotePath(cmStrCat("{tmp}\\", archiveName, '\\', relativePath));
+ params["ExternalSize"] =
+ std::to_string(cmSystemTools::FileLength(i));
+ params["Flags"] = "external ignoreversion";
+ params["BeforeInstall"] =
+ cmStrCat("CPackExtractFile('", archiveName, "', '",
+ cmRemoveQuotes(cmSystemTools::ConvertToWindowsOutputPath(
+ relativePath)),
+ "')");
+ } else {
+ params["Source"] = QuotePath(i);
+ params["Flags"] = "ignoreversion";
+ }
+
+ fileInstructions.push_back(ISKeyValueLine(params));
+
+ // Icon
+ const std::string& name =
+ cmSystemTools::GetFilenameWithoutLastExtension(i);
+ const std::string& extension =
+ cmSystemTools::GetFilenameLastExtension(i);
+ if ((extension == ".exe" || extension == ".com") && // only .exe, .com
+ icons.count(name)) {
+ cmCPackInnoSetupKeyValuePairs iconParams;
+
+ iconParams["Name"] = QuotePath(cmStrCat(iconsPrefix, icons[name]));
+ iconParams["Filename"] =
+ QuotePath(cmStrCat(destDir, '\\', name, extension));
+
+ if (!componentParam.empty()) {
+ iconParams["Components"] = componentParam;
+ }
+
+ iconInstructions.push_back(ISKeyValueLine(iconParams));
+
+ // Desktop icon
+ if (std::find(desktopIcons.begin(), desktopIcons.end(), name) !=
+ desktopIcons.end()) {
+ iconParams["Name"] =
+ QuotePath(cmStrCat("{autodesktop}\\", icons[name]));
+ iconParams["Tasks"] = "desktopicon";
+
+ if (!componentParam.empty() &&
+ std::find(desktopIconComponents.begin(),
+ desktopIconComponents.end(),
+ componentParam) == desktopIconComponents.end()) {
+ desktopIconComponents.push_back(componentParam);
+ }
+ iconInstructions.push_back(ISKeyValueLine(iconParams));
+ }
+
+ // [Run] section
+ if (std::find(runExecutables.begin(), runExecutables.end(), name) !=
+ runExecutables.end()) {
+ cmCPackInnoSetupKeyValuePairs runParams;
+
+ runParams["Filename"] = iconParams["Filename"];
+ runParams["Description"] = cmStrCat(
+ "\"{cm:LaunchProgram,", PrepareForConstant(icons[name]), "}\"");
+ runParams["Flags"] = "nowait postinstall skipifsilent";
+
+ if (!componentParam.empty()) {
+ runParams["Components"] = componentParam;
+ }
+
+ runInstructions.push_back(ISKeyValueLine(runParams));
+ }
+ }
+ }
+ }
+ }
+
+ // Additional icons
+ static cmsys::RegularExpression urlRegex(
+ "^(mailto:|(ftps?|https?|news)://).*$");
+
+ if (IsSet("CPACK_INNOSETUP_MENU_LINKS")) {
+ const cmList menuIcons(GetOption("CPACK_INNOSETUP_MENU_LINKS"));
+ if (menuIcons.size() % 2 != 0) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "CPACK_INNOSETUP_MENU_LINKS should "
+ "contain pairs of <shortcut target> and <shortcut label>"
+ << std::endl);
+ return false;
+ }
+
+ for (auto it = menuIcons.begin(); it != menuIcons.end(); ++it) {
+ const std::string& target = *it;
+ const std::string& label = *(++it);
+ cmCPackInnoSetupKeyValuePairs params;
+
+ params["Name"] = QuotePath(cmStrCat(iconsPrefix, label));
+ if (urlRegex.find(target)) {
+ params["Filename"] = Quote(target);
+ } else {
+ std::string dir = "{app}";
+ std::string componentName;
+ for (const auto& i : Components) {
+ if (cmSystemTools::FileExists(cmSystemTools::CollapseFullPath(
+ cmStrCat(i.second.Name, '\\', target), toplevel))) {
+ dir = CustomComponentInstallDirectory(&i.second);
+ componentName =
+ CreateRecursiveComponentPath(i.second.Group, i.second.Name);
+
+ if (i.second.IsHidden && i.second.IsDisabledByDefault) {
+ goto continueOuterLoop;
+ } else if (i.second.IsHidden) {
+ componentName.clear();
+ }
+
+ break;
+ }
+ }
+
+ params["Filename"] = QuotePath(cmStrCat(dir, '\\', target));
+
+ if (!componentName.empty()) {
+ params["Components"] = componentName;
+ }
+ }
+
+ iconInstructions.push_back(ISKeyValueLine(params));
+ continueOuterLoop:;
+ }
+ }
+
+ SetOptionIfNotSet("CPACK_INNOSETUP_CREATE_UNINSTALL_LINK", "OFF");
+ if (GetOption("CPACK_INNOSETUP_CREATE_UNINSTALL_LINK").IsOn()) {
+ cmCPackInnoSetupKeyValuePairs params;
+
+ params["Name"] = QuotePath(
+ cmStrCat(iconsPrefix, "{cm:UninstallProgram,",
+ PrepareForConstant(GetOption("CPACK_PACKAGE_NAME")), '}'));
+ params["Filename"] = "\"{uninstallexe}\"";
+
+ iconInstructions.push_back(ISKeyValueLine(params));
+ }
+
+ return true;
+}
+
+bool cmCPackInnoSetupGenerator::ProcessComponents()
+{
+ codeIncludes.push_back("{ The following lines are required by CPack because "
+ "this script uses components }");
+
+ // Installation types
+ bool noTypes = true;
+ std::vector<cmCPackInstallationType*> types(InstallationTypes.size());
+ for (auto& i : InstallationTypes) {
+ noTypes = false;
+ types[i.second.Index - 1] = &i.second;
+ }
+
+ std::vector<std::string> allTypes; // For required components
+ for (cmCPackInstallationType* i : types) {
+ cmCPackInnoSetupKeyValuePairs params;
+
+ params["Name"] = Quote(i->Name);
+ params["Description"] = Quote(i->DisplayName);
+
+ allTypes.push_back(i->Name);
+ typeInstructions.push_back(ISKeyValueLine(params));
+ }
+
+ if (!noTypes) {
+ // Inno Setup requires the "custom" type
+ cmCPackInnoSetupKeyValuePairs params;
+
+ params["Name"] = "\"custom\"";
+ params["Description"] = "\"{code:CPackGetCustomInstallationMessage}\"";
+ params["Flags"] = "iscustom";
+
+ allTypes.push_back("custom");
+ typeInstructions.push_back(ISKeyValueLine(params));
+ }
+
+ // Components
+ std::vector<cmCPackComponent*> downloadedComponents;
+ std::stack<cmCPackComponentGroup*> groups;
+ for (auto& i : Components) {
+ cmCPackInnoSetupKeyValuePairs params;
+ cmCPackComponent* component = &i.second;
+
+ if (component->IsHidden) {
+ continue;
+ }
+
+ CreateRecursiveComponentGroups(component->Group);
+
+ params["Name"] =
+ Quote(CreateRecursiveComponentPath(component->Group, component->Name));
+ params["Description"] = Quote(component->DisplayName);
+
+ if (component->IsRequired) {
+ params["Types"] = cmJoin(allTypes, " ");
+ params["Flags"] = "fixed";
+ } else if (!component->InstallationTypes.empty()) {
+ std::vector<std::string> installationTypes;
+
+ for (cmCPackInstallationType* j : component->InstallationTypes) {
+ installationTypes.push_back(j->Name);
+ }
+
+ params["Types"] = cmJoin(installationTypes, " ");
+ }
+
+ componentInstructions.push_back(ISKeyValueLine(params));
+
+ if (component->IsDownloaded) {
+ downloadedComponents.push_back(component);
+
+ if (component->ArchiveFile.empty()) {
+ // Compute the name of the archive.
+ if (!RequireOption("CPACK_TEMPORARY_DIRECTORY")) {
+ return false;
+ }
+
+ std::string packagesDir =
+ cmStrCat(GetOption("CPACK_TEMPORARY_DIRECTORY"), ".dummy");
+ component->ArchiveFile =
+ cmStrCat(cmSystemTools::GetFilenameWithoutLastExtension(packagesDir),
+ '-', component->Name, ".zip");
+ } else if (!cmHasSuffix(component->ArchiveFile, ".zip")) {
+ component->ArchiveFile = cmStrCat(component->ArchiveFile, ".zip");
+ }
+ }
+ }
+
+ // Downloaded components
+ if (!downloadedComponents.empty()) {
+ // Create the directory for the upload area
+ cmValue userUploadDirectory = GetOption("CPACK_UPLOAD_DIRECTORY");
+ std::string uploadDirectory;
+ if (cmNonempty(userUploadDirectory)) {
+ uploadDirectory = *userUploadDirectory;
+ } else {
+ if (!RequireOption("CPACK_PACKAGE_DIRECTORY")) {
+ return false;
+ }
+
+ uploadDirectory =
+ cmStrCat(GetOption("CPACK_PACKAGE_DIRECTORY"), "/CPackUploads");
+ }
+
+ if (!cmSystemTools::FileExists(uploadDirectory)) {
+ if (!cmSystemTools::MakeDirectory(uploadDirectory)) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Unable to create Inno Setup upload directory "
+ << uploadDirectory << std::endl);
+ return false;
+ }
+ }
+
+ if (!RequireOption("CPACK_DOWNLOAD_SITE")) {
+ return false;
+ }
+
+ SetOptionIfNotSet("CPACK_INNOSETUP_VERIFY_DOWNLOADS", "ON");
+ const bool verifyDownloads =
+ GetOption("CPACK_INNOSETUP_VERIFY_DOWNLOADS").IsOn();
+
+ const std::string& urlPrefix =
+ cmHasSuffix(GetOption("CPACK_DOWNLOAD_SITE").GetCStr(), '/')
+ ? GetOption("CPACK_DOWNLOAD_SITE")
+ : cmStrCat(GetOption("CPACK_DOWNLOAD_SITE"), '/');
+
+ std::vector<std::string> archiveUrls;
+ std::vector<std::string> archiveFiles;
+ std::vector<std::string> archiveHashes;
+ std::vector<std::string> archiveComponents;
+ for (cmCPackComponent* i : downloadedComponents) {
+ std::string hash;
+ if (!BuildDownloadedComponentArchive(
+ i, uploadDirectory, (verifyDownloads ? &hash : nullptr))) {
+ return false;
+ }
+
+ archiveUrls.push_back(Quote(cmStrCat(urlPrefix, i->ArchiveFile)));
+ archiveFiles.push_back(
+ Quote(cmSystemTools::GetFilenameWithoutLastExtension(i->ArchiveFile)));
+ archiveHashes.push_back(Quote(hash));
+ archiveComponents.push_back(
+ Quote(CreateRecursiveComponentPath(i->Group, i->Name)));
+ }
+
+ SetOption("CPACK_INNOSETUP_DOWNLOAD_COUNT_INTERNAL",
+ std::to_string(archiveFiles.size()));
+ SetOption("CPACK_INNOSETUP_DOWNLOAD_URLS_INTERNAL",
+ cmJoin(archiveUrls, ", "));
+ SetOption("CPACK_INNOSETUP_DOWNLOAD_ARCHIVES_INTERNAL",
+ cmJoin(archiveFiles, ", "));
+ SetOption("CPACK_INNOSETUP_DOWNLOAD_HASHES_INTERNAL",
+ cmJoin(archiveHashes, ", "));
+ SetOption("CPACK_INNOSETUP_DOWNLOAD_COMPONENTS_INTERNAL",
+ cmJoin(archiveComponents, ", "));
+
+ static const std::string& downloadLines =
+ "#define protected CPackDownloadCount "
+ "@CPACK_INNOSETUP_DOWNLOAD_COUNT_INTERNAL@\n"
+ "#dim protected CPackDownloadUrls[CPackDownloadCount] "
+ "{@CPACK_INNOSETUP_DOWNLOAD_URLS_INTERNAL@}\n"
+ "#dim protected CPackDownloadArchives[CPackDownloadCount] "
+ "{@CPACK_INNOSETUP_DOWNLOAD_ARCHIVES_INTERNAL@}\n"
+ "#dim protected CPackDownloadHashes[CPackDownloadCount] "
+ "{@CPACK_INNOSETUP_DOWNLOAD_HASHES_INTERNAL@}\n"
+ "#dim protected CPackDownloadComponents[CPackDownloadCount] "
+ "{@CPACK_INNOSETUP_DOWNLOAD_COMPONENTS_INTERNAL@}";
+
+ std::string output;
+ if (!ConfigureString(downloadLines, output)) {
+ return false;
+ }
+ codeIncludes.push_back(output);
+ }
+
+ // Add the required script
+ const std::string& componentsScriptTemplate =
+ FindTemplate("ISComponents.pas");
+ if (componentsScriptTemplate.empty()) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Could not find additional Inno Setup script file."
+ << std::endl);
+ return false;
+ }
+
+ codeIncludes.push_back("#include " + QuotePath(componentsScriptTemplate) +
+ "\n");
+
+ return true;
+}
+
+bool cmCPackInnoSetupGenerator::ConfigureISScript()
+{
+ const std::string& isScriptTemplate = FindTemplate("ISScript.template.in");
+ const std::string& isScriptFile =
+ cmStrCat(GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/ISScript.iss");
+
+ if (isScriptTemplate.empty()) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Could not find Inno Setup installer template file."
+ << std::endl);
+ return false;
+ }
+
+ // Create internal variables
+ std::vector<std::string> setupSection;
+ for (const auto& i : setupDirectives) {
+ setupSection.push_back(cmStrCat(i.first, '=', TranslateBool(i.second)));
+ }
+
+ // Also create comments if the sections are empty
+ const std::string& defaultMessage =
+ "; CPack didn't find any entries for this section";
+
+ if (IsSet("CPACK_CREATE_DESKTOP_LINKS") &&
+ !GetOption("CPACK_CREATE_DESKTOP_LINKS").Get()->empty()) {
+ cmCPackInnoSetupKeyValuePairs tasks;
+ tasks["Name"] = "\"desktopicon\"";
+ tasks["Description"] = "\"{cm:CreateDesktopIcon}\"";
+ tasks["GroupDescription"] = "\"{cm:AdditionalIcons}\"";
+ tasks["Flags"] = "unchecked";
+
+ if (!desktopIconComponents.empty()) {
+ tasks["Components"] = cmJoin(desktopIconComponents, " ");
+ }
+
+ SetOption("CPACK_INNOSETUP_TASKS_INTERNAL", ISKeyValueLine(tasks));
+ } else {
+ SetOption("CPACK_INNOSETUP_TASKS_INTERNAL", defaultMessage);
+ }
+
+ SetOption("CPACK_INNOSETUP_INCLUDES_INTERNAL",
+ includeDirectives.empty() ? "; No extra script files specified"
+ : cmJoin(includeDirectives, "\n"));
+ SetOption("CPACK_INNOSETUP_SETUP_INTERNAL",
+ setupSection.empty() ? defaultMessage
+ : cmJoin(setupSection, "\n"));
+ SetOption("CPACK_INNOSETUP_LANGUAGES_INTERNAL",
+ languageInstructions.empty() ? defaultMessage
+ : cmJoin(languageInstructions, "\n"));
+ SetOption("CPACK_INNOSETUP_DIRS_INTERNAL",
+ dirInstructions.empty() ? defaultMessage
+ : cmJoin(dirInstructions, "\n"));
+ SetOption("CPACK_INNOSETUP_FILES_INTERNAL",
+ fileInstructions.empty() ? defaultMessage
+ : cmJoin(fileInstructions, "\n"));
+ SetOption("CPACK_INNOSETUP_TYPES_INTERNAL",
+ typeInstructions.empty() ? defaultMessage
+ : cmJoin(typeInstructions, "\n"));
+ SetOption("CPACK_INNOSETUP_COMPONENTS_INTERNAL",
+ componentInstructions.empty()
+ ? defaultMessage
+ : cmJoin(componentInstructions, "\n"));
+ SetOption("CPACK_INNOSETUP_ICONS_INTERNAL",
+ iconInstructions.empty() ? defaultMessage
+ : cmJoin(iconInstructions, "\n"));
+ SetOption("CPACK_INNOSETUP_RUN_INTERNAL",
+ runInstructions.empty() ? defaultMessage
+ : cmJoin(runInstructions, "\n"));
+ SetOption("CPACK_INNOSETUP_CODE_INTERNAL",
+ codeIncludes.empty() ? "{ No extra code files specified }"
+ : cmJoin(codeIncludes, "\n"));
+
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE,
+ "Configure file: " << isScriptTemplate << " to "
+ << isScriptFile << std::endl);
+
+ return ConfigureFile(isScriptTemplate, isScriptFile);
+}
+
+bool cmCPackInnoSetupGenerator::Compile()
+{
+ const std::string& isScriptFile =
+ cmStrCat(GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/ISScript.iss");
+ const std::string& isccLogFile =
+ cmStrCat(GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/ISCCOutput.log");
+
+ std::vector<std::string> isccArgs;
+
+ // Custom defines
+ for (const std::string& i : GetOptions()) {
+ if (cmHasPrefix(i, "CPACK_INNOSETUP_DEFINE_")) {
+ const std::string& name = i.substr(cmStrLen("CPACK_INNOSETUP_DEFINE_"));
+ isccArgs.push_back(
+ cmStrCat("\"/D", name, '=', TranslateBool(GetOption(i)), '"'));
+ }
+ }
+
+ if (IsSet("CPACK_INNOSETUP_EXECUTABLE_ARGUMENTS")) {
+ const cmList args(GetOption("CPACK_INNOSETUP_EXECUTABLE_ARGUMENTS"));
+
+ isccArgs.insert(isccArgs.end(), args.begin(), args.end());
+ }
+
+ const std::string& isccCmd =
+ cmStrCat(QuotePath(GetOption("CPACK_INSTALLER_PROGRAM")), ' ',
+ cmJoin(isccArgs, " "), ' ', QuotePath(isScriptFile));
+
+ cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << isccCmd << std::endl);
+
+ std::string output;
+ int retVal = 1;
+ const bool res = cmSystemTools::RunSingleCommand(
+ isccCmd, &output, &output, &retVal, nullptr, this->GeneratorVerbose,
+ cmDuration::zero());
+
+ if (!res || retVal) {
+ cmGeneratedFileStream ofs(isccLogFile);
+ ofs << "# Run command: " << isccCmd << std::endl
+ << "# Output:" << std::endl
+ << output << std::endl;
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Problem running ISCC. Please check "
+ << isccLogFile << " for errors." << std::endl);
+ return false;
+ }
+
+ return true;
+}
+
+bool cmCPackInnoSetupGenerator::BuildDownloadedComponentArchive(
+ cmCPackComponent* component, const std::string& uploadDirectory,
+ std::string* hash)
+{
+ // Remove the old archive, if one exists
+ const std::string& archiveFile =
+ uploadDirectory + '/' + component->ArchiveFile;
+ cmCPackLogger(cmCPackLog::LOG_OUTPUT,
+ "- Building downloaded component archive: " << archiveFile
+ << std::endl);
+ if (cmSystemTools::FileExists(archiveFile, true)) {
+ if (!cmSystemTools::RemoveFile(archiveFile)) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Unable to remove archive file " << archiveFile
+ << std::endl);
+ return false;
+ }
+ }
+
+ // Find a ZIP program
+ if (!IsSet("ZIP_EXECUTABLE")) {
+ ReadListFile("Internal/CPack/CPackZIP.cmake");
+
+ if (!IsSet("ZIP_EXECUTABLE")) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Unable to find ZIP program" << std::endl);
+ return false;
+ }
+ }
+
+ if (!RequireOption("CPACK_TOPLEVEL_DIRECTORY") ||
+ !RequireOption("CPACK_TEMPORARY_DIRECTORY") ||
+ !RequireOption("CPACK_ZIP_NEED_QUOTES") ||
+ !RequireOption("CPACK_ZIP_COMMAND")) {
+ return false;
+ }
+
+ // The directory where this component's files reside
+ const std::string& dirName =
+ cmStrCat(GetOption("CPACK_TEMPORARY_DIRECTORY"), '/', component->Name);
+
+ // Build the list of files to go into this archive
+ const std::string& zipListFileName =
+ cmStrCat(GetOption("CPACK_TEMPORARY_DIRECTORY"), "/winZip.filelist");
+ const bool needQuotesInFile = cmIsOn(GetOption("CPACK_ZIP_NEED_QUOTES"));
+ { // the scope is needed for cmGeneratedFileStream
+ cmGeneratedFileStream out(zipListFileName);
+ for (const std::string& i : component->Files) {
+ out << (needQuotesInFile ? Quote(i) : i) << std::endl;
+ }
+ }
+
+ // Build the archive in the upload area
+ std::string cmd = GetOption("CPACK_ZIP_COMMAND");
+ cmsys::SystemTools::ReplaceString(cmd, "<ARCHIVE>", archiveFile.c_str());
+ cmsys::SystemTools::ReplaceString(cmd, "<FILELIST>",
+ zipListFileName.c_str());
+ std::string output;
+ int retVal = -1;
+ const bool res = cmSystemTools::RunSingleCommand(
+ cmd, &output, &output, &retVal, dirName.c_str(), this->GeneratorVerbose,
+ cmDuration::zero());
+ if (!res || retVal) {
+ std::string tmpFile =
+ cmStrCat(GetOption("CPACK_TOPLEVEL_DIRECTORY"), "/CompressZip.log");
+ cmGeneratedFileStream ofs(tmpFile);
+ ofs << "# Run command: " << cmd << std::endl
+ << "# Output:" << std::endl
+ << output << std::endl;
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Problem running zip command: " << cmd << std::endl
+ << "Please check " << tmpFile
+ << " for errors"
+ << std::endl);
+ return false;
+ }
+
+ // Try to get the SHA256 hash of the archive file
+ if (hash == nullptr) {
+ return true;
+ }
+
+#ifdef _WIN32
+ const std::string& hashCmd =
+ cmStrCat("certutil -hashfile ", QuotePath(archiveFile), " SHA256");
+
+ std::string hashOutput;
+ int hashRetVal = -1;
+ const bool hashRes = cmSystemTools::RunSingleCommand(
+ hashCmd, &hashOutput, &hashOutput, &hashRetVal, nullptr,
+ this->GeneratorVerbose, cmDuration::zero());
+ if (!hashRes || hashRetVal) {
+ cmCPackLogger(cmCPackLog::LOG_WARNING,
+ "Problem running certutil command: " << hashCmd
+ << std::endl);
+ }
+ *hash = cmTrimWhitespace(cmTokenize(hashOutput, "\n").at(1));
+
+ if (hash->length() != 64) {
+ cmCPackLogger(cmCPackLog::LOG_WARNING,
+ "Problem parsing certutil output of command: " << hashCmd
+ << std::endl);
+ hash->clear();
+ }
+#endif
+
+ return true;
+}
+
+cmValue cmCPackInnoSetupGenerator::RequireOption(const std::string& key)
+{
+ cmValue value = GetOption(key);
+
+ if (!value) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Required variable " << key << " not set" << std::endl);
+ }
+
+ return value;
+}
+
+std::string cmCPackInnoSetupGenerator::CustomComponentInstallDirectory(
+ const cmCPackComponent* component)
+{
+ cmValue outputDir = GetOption(
+ cmStrCat("CPACK_INNOSETUP_", component->Name, "_INSTALL_DIRECTORY"));
+ if (outputDir) {
+ std::string destDir = cmSystemTools::ConvertToWindowsOutputPath(outputDir);
+ cmStripSuffixIfExists(destDir, '\\');
+
+ /*
+ * Add a dir instruction for the custom directory
+ * (only once and not for Inno Setup constants ending with '}')
+ */
+ static std::vector<std::string> customDirectories;
+ if (!cmHasSuffix(destDir, '}') &&
+ std::find(customDirectories.begin(), customDirectories.end(),
+ component->Name) == customDirectories.end()) {
+ cmCPackInnoSetupKeyValuePairs params;
+ params["Name"] = QuotePath(destDir);
+ params["Components"] =
+ CreateRecursiveComponentPath(component->Group, component->Name);
+
+ dirInstructions.push_back(ISKeyValueLine(params));
+ customDirectories.push_back(component->Name);
+ }
+ return destDir;
+ }
+
+ return "{app}";
+}
+
+std::string cmCPackInnoSetupGenerator::TranslateBool(const std::string& value)
+{
+ if (value.empty()) {
+ return value;
+ }
+
+ SetOptionIfNotSet("CPACK_INNOSETUP_USE_CMAKE_BOOL_FORMAT", "ON");
+ if (GetOption("CPACK_INNOSETUP_USE_CMAKE_BOOL_FORMAT").IsOn()) {
+ if (cmIsOn(value)) {
+ return "yes";
+ }
+ if (cmIsOff(value)) {
+ return "no";
+ }
+ }
+
+ return value;
+}
+
+std::string cmCPackInnoSetupGenerator::ISKeyValueLine(
+ const cmCPackInnoSetupKeyValuePairs& params)
+{
+ /*
+ * To simplify readability of the generated code, the keys are sorted.
+ * Unknown keys are ignored to avoid errors during compilation.
+ */
+ static const char* const availableKeys[] = {
+ "Source", "DestDir", "Name", "Filename",
+ "Description", "GroupDescription", "MessagesFile", "Types",
+ "ExternalSize", "BeforeInstall", "Flags", "Components",
+ "Tasks"
+ };
+
+ std::vector<std::string> keys;
+ for (const char* i : availableKeys) {
+ if (params.count(i)) {
+ keys.push_back(cmStrCat(i, ": ", params.at(i)));
+ }
+ }
+
+ return cmJoin(keys, "; ");
+}
+
+std::string cmCPackInnoSetupGenerator::CreateRecursiveComponentPath(
+ cmCPackComponentGroup* group, const std::string& path)
+{
+ if (group == nullptr) {
+ return path;
+ }
+
+ const std::string& newPath =
+ path.empty() ? group->Name : cmStrCat(group->Name, '\\', path);
+ return CreateRecursiveComponentPath(group->ParentGroup, newPath);
+}
+
+void cmCPackInnoSetupGenerator::CreateRecursiveComponentGroups(
+ cmCPackComponentGroup* group)
+{
+ if (group == nullptr) {
+ return;
+ }
+
+ CreateRecursiveComponentGroups(group->ParentGroup);
+
+ static std::vector<cmCPackComponentGroup*> processedGroups;
+ if (std::find(processedGroups.begin(), processedGroups.end(), group) ==
+ processedGroups.end()) {
+ processedGroups.push_back(group);
+
+ cmCPackInnoSetupKeyValuePairs params;
+
+ params["Name"] = Quote(CreateRecursiveComponentPath(group));
+ params["Description"] = Quote(group->DisplayName);
+
+ componentInstructions.push_back(ISKeyValueLine(params));
+ }
+}
+
+std::string cmCPackInnoSetupGenerator::Quote(const std::string& string)
+{
+ if (cmHasPrefix(string, '"') && cmHasSuffix(string, '"')) {
+ return Quote(string.substr(1, string.length() - 2));
+ }
+
+ // Double quote syntax
+ std::string nString = string;
+ cmSystemTools::ReplaceString(nString, "\"", "\"\"");
+ return cmStrCat('"', nString, '"');
+}
+
+std::string cmCPackInnoSetupGenerator::QuotePath(const std::string& path)
+{
+ return Quote(cmSystemTools::ConvertToWindowsOutputPath(path));
+}
+
+std::string cmCPackInnoSetupGenerator::PrepareForConstant(
+ const std::string& string)
+{
+ std::string nString = string;
+
+ cmSystemTools::ReplaceString(nString, "%", "%25"); // First replacement!
+ cmSystemTools::ReplaceString(nString, "\"", "%22");
+ cmSystemTools::ReplaceString(nString, ",", "%2c");
+ cmSystemTools::ReplaceString(nString, "|", "%7c");
+ cmSystemTools::ReplaceString(nString, "}", "%7d");
+
+ return nString;
+}
diff --git a/Source/CPack/cmCPackInnoSetupGenerator.h b/Source/CPack/cmCPackInnoSetupGenerator.h
new file mode 100644
index 0000000000..342f227e00
--- /dev/null
+++ b/Source/CPack/cmCPackInnoSetupGenerator.h
@@ -0,0 +1,116 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+file Copyright.txt or https://cmake.org/licensing for details. */
+
+#pragma once
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "cmCPackGenerator.h"
+#include "cmValue.h"
+
+using cmCPackInnoSetupKeyValuePairs = std::map<std::string, std::string>;
+
+class cmCPackComponentGroup;
+class cmCPackComponent;
+
+/** \class cmCPackInnoSetupGenerator
+ * \brief A generator for Inno Setup
+ *
+ * https://jrsoftware.org/isinfo.php
+ */
+class cmCPackInnoSetupGenerator : public cmCPackGenerator
+{
+public:
+ cmCPackTypeMacro(cmCPackInnoSetupGenerator, cmCPackGenerator);
+
+ /**
+ * Construct generator
+ */
+ cmCPackInnoSetupGenerator();
+ ~cmCPackInnoSetupGenerator() override;
+
+ static bool CanGenerate();
+
+protected:
+ int InitializeInternal() override;
+ int PackageFiles() override;
+
+ inline const char* GetOutputExtension() override { return ".exe"; }
+
+ inline cmCPackGenerator::CPackSetDestdirSupport SupportsSetDestdir()
+ const override
+ {
+ return cmCPackGenerator::SETDESTDIR_UNSUPPORTED;
+ }
+
+ inline bool SupportsAbsoluteDestination() const override { return false; }
+ inline bool SupportsComponentInstallation() const override { return true; }
+
+private:
+ bool ProcessSetupSection();
+ bool ProcessFiles();
+ bool ProcessComponents();
+
+ bool ConfigureISScript();
+ bool Compile();
+
+ bool BuildDownloadedComponentArchive(cmCPackComponent* component,
+ const std::string& uploadDirectory,
+ std::string* hash);
+
+ /**
+ * Returns the option's value or an empty string if the option isn't set.
+ */
+ cmValue RequireOption(const std::string& key);
+
+ std::string CustomComponentInstallDirectory(
+ const cmCPackComponent* component);
+
+ /**
+ * Translates boolean expressions into "yes" or "no", as required in
+ * Inno Setup (only if "CPACK_INNOSETUP_USE_CMAKE_BOOL_FORMAT" is on).
+ */
+ std::string TranslateBool(const std::string& value);
+
+ /**
+ * Creates a typical line of key and value pairs using the given map.
+ *
+ * (e.g.: Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}";
+ * GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked)
+ */
+ std::string ISKeyValueLine(const cmCPackInnoSetupKeyValuePairs& params);
+
+ std::string CreateRecursiveComponentPath(cmCPackComponentGroup* group,
+ const std::string& path = "");
+
+ void CreateRecursiveComponentGroups(cmCPackComponentGroup* group);
+
+ /**
+ * These functions add quotes if the given value hasn't already quotes.
+ * Paths are converted into the format used by Windows before.
+ */
+ std::string Quote(const std::string& string);
+ std::string QuotePath(const std::string& path);
+
+ /**
+ * This function replaces the following 5 characters with their %-encoding:
+ * '|' '}' ',' '%' '"'
+ * Required for Inno Setup constants like {cm:...}
+ */
+ std::string PrepareForConstant(const std::string& string);
+
+ std::vector<std::string> includeDirectives;
+ cmCPackInnoSetupKeyValuePairs setupDirectives;
+ bool toplevelProgramFolder;
+ std::vector<std::string> languageInstructions;
+ std::vector<std::string> fileInstructions;
+ std::vector<std::string> dirInstructions;
+ std::vector<std::string> typeInstructions;
+ std::vector<std::string> componentInstructions;
+ std::vector<std::string> iconInstructions;
+ std::vector<std::string> desktopIconComponents;
+ std::vector<std::string> runInstructions;
+ std::vector<std::string> codeIncludes;
+};
diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx
index d7119c5223..7749b29303 100644
--- a/Source/CPack/cmCPackNSISGenerator.cxx
+++ b/Source/CPack/cmCPackNSISGenerator.cxx
@@ -19,6 +19,7 @@
#include "cmCPackLog.h"
#include "cmDuration.h"
#include "cmGeneratedFileStream.h"
+#include "cmList.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
@@ -245,8 +246,7 @@ int cmCPackNSISGenerator::PackageFiles()
std::string nsisPreArguments;
if (cmValue nsisArguments =
this->GetOption("CPACK_NSIS_EXECUTABLE_PRE_ARGUMENTS")) {
- std::vector<std::string> expandedArguments;
- cmExpandList(nsisArguments, expandedArguments);
+ cmList expandedArguments{ nsisArguments };
for (auto& arg : expandedArguments) {
if (!cmHasPrefix(arg, NSIS_OPT)) {
@@ -259,8 +259,7 @@ int cmCPackNSISGenerator::PackageFiles()
std::string nsisPostArguments;
if (cmValue nsisArguments =
this->GetOption("CPACK_NSIS_EXECUTABLE_POST_ARGUMENTS")) {
- std::vector<std::string> expandedArguments;
- cmExpandList(nsisArguments, expandedArguments);
+ cmList expandedArguments{ nsisArguments };
for (auto& arg : expandedArguments) {
if (!cmHasPrefix(arg, NSIS_OPT)) {
nsisPostArguments = cmStrCat(nsisPostArguments, NSIS_OPT);
@@ -545,14 +544,14 @@ int cmCPackNSISGenerator::InitializeInternal()
this->GetOption("CPACK_CREATE_DESKTOP_LINKS");
cmValue cpackNsisExecutablesDirectory =
this->GetOption("CPACK_NSIS_EXECUTABLES_DIRECTORY");
- std::vector<std::string> cpackPackageDesktopLinksVector;
+ cmList cpackPackageDesktopLinksList;
if (cpackPackageDeskTopLinks) {
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"CPACK_CREATE_DESKTOP_LINKS: " << cpackPackageDeskTopLinks
<< std::endl);
- cmExpandList(cpackPackageDeskTopLinks, cpackPackageDesktopLinksVector);
- for (std::string const& cpdl : cpackPackageDesktopLinksVector) {
+ cpackPackageDesktopLinksList.assign(cpackPackageDeskTopLinks);
+ for (std::string const& cpdl : cpackPackageDesktopLinksList) {
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"CPACK_CREATE_DESKTOP_LINKS: " << cpdl << std::endl);
}
@@ -569,9 +568,8 @@ int cmCPackNSISGenerator::InitializeInternal()
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"The cpackPackageExecutables: " << cpackPackageExecutables
<< "." << std::endl);
- std::vector<std::string> cpackPackageExecutablesVector =
- cmExpandedList(cpackPackageExecutables);
- if (cpackPackageExecutablesVector.size() % 2 != 0) {
+ cmList cpackPackageExecutablesList{ cpackPackageExecutables };
+ if (cpackPackageExecutablesList.size() % 2 != 0) {
cmCPackLogger(
cmCPackLog::LOG_ERROR,
"CPACK_PACKAGE_EXECUTABLES should contain pairs of <executable> and "
@@ -579,9 +577,9 @@ int cmCPackNSISGenerator::InitializeInternal()
<< std::endl);
return 0;
}
- std::vector<std::string>::iterator it;
- for (it = cpackPackageExecutablesVector.begin();
- it != cpackPackageExecutablesVector.end(); ++it) {
+ cmList::iterator it;
+ for (it = cpackPackageExecutablesList.begin();
+ it != cpackPackageExecutablesList.end(); ++it) {
std::string execName = *it;
++it;
std::string linkName = *it;
@@ -592,7 +590,7 @@ int cmCPackNSISGenerator::InitializeInternal()
<< ".lnk\"" << std::endl;
// see if CPACK_CREATE_DESKTOP_LINK_ExeName is on
// if so add a desktop link
- if (cm::contains(cpackPackageDesktopLinksVector, execName)) {
+ if (cm::contains(cpackPackageDesktopLinksList, execName)) {
str << " StrCmp \"$INSTALL_DESKTOP\" \"1\" 0 +2\n";
str << " CreateShortCut \"$DESKTOP\\" << linkName
<< R"(.lnk" "$INSTDIR\)" << cpackNsisExecutablesDirectory << "\\"
@@ -622,9 +620,8 @@ void cmCPackNSISGenerator::CreateMenuLinks(std::ostream& str,
}
cmCPackLogger(cmCPackLog::LOG_DEBUG,
"The cpackMenuLinks: " << cpackMenuLinks << "." << std::endl);
- std::vector<std::string> cpackMenuLinksVector =
- cmExpandedList(cpackMenuLinks);
- if (cpackMenuLinksVector.size() % 2 != 0) {
+ cmList cpackMenuLinksList{ cpackMenuLinks };
+ if (cpackMenuLinksList.size() % 2 != 0) {
cmCPackLogger(
cmCPackLog::LOG_ERROR,
"CPACK_NSIS_MENU_LINKS should contain pairs of <shortcut target> and "
@@ -636,9 +633,8 @@ void cmCPackNSISGenerator::CreateMenuLinks(std::ostream& str,
static cmsys::RegularExpression urlRegex(
"^(mailto:|(ftps?|https?|news)://).*$");
- std::vector<std::string>::iterator it;
- for (it = cpackMenuLinksVector.begin(); it != cpackMenuLinksVector.end();
- ++it) {
+ cmList::iterator it;
+ for (it = cpackMenuLinksList.begin(); it != cpackMenuLinksList.end(); ++it) {
std::string sourceName = *it;
const bool url = urlRegex.find(sourceName);
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index 234bc59352..90716e6e0d 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -29,6 +29,7 @@
#include "cmDocumentationEntry.h"
#include "cmGlobalGenerator.h"
#include "cmJSONState.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStateSnapshot.h"
@@ -509,8 +510,8 @@ int main(int argc, char const* const* argv)
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
"CPack generator not specified\n");
} else {
- std::vector<std::string> generatorsVector = cmExpandedList(*genList);
- for (std::string const& gen : generatorsVector) {
+ cmList generatorsList{ *genList };
+ for (std::string const& gen : generatorsList) {
cmMakefile::ScopePushPop raii(&globalMF);
cmMakefile* mf = &globalMF;
cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE,
diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx
index c6387ab353..882b579fff 100644
--- a/Source/CTest/cmCTestBuildHandler.cxx
+++ b/Source/CTest/cmCTestBuildHandler.cxx
@@ -17,6 +17,7 @@
#include "cmDuration.h"
#include "cmFileTimeCache.h"
#include "cmGeneratedFileStream.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmProcessOutput.h"
#include "cmStringAlgorithms.h"
diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx
index 1f3633de5b..bae1f54011 100644
--- a/Source/CTest/cmCTestConfigureCommand.cxx
+++ b/Source/CTest/cmCTestConfigureCommand.cxx
@@ -4,13 +4,13 @@
#include <cstring>
#include <sstream>
-#include <vector>
#include <cmext/string_view>
#include "cmCTest.h"
#include "cmCTestConfigureHandler.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -25,10 +25,10 @@ void cmCTestConfigureCommand::BindArguments()
cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler()
{
- std::vector<std::string> options;
+ cmList options;
if (!this->Options.empty()) {
- cmExpandList(this->Options, options);
+ options.assign(this->Options);
}
if (this->CTest->GetCTestConfiguration("BuildDirectory").empty()) {
diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx
index b2fb069fd5..a6e7ac52c8 100644
--- a/Source/CTest/cmCTestGIT.cxx
+++ b/Source/CTest/cmCTestGIT.cxx
@@ -14,6 +14,7 @@
#include "cmCTest.h"
#include "cmCTestVC.h"
+#include "cmList.h"
#include "cmProcessOutput.h"
#include "cmProcessTools.h"
#include "cmStringAlgorithms.h"
@@ -215,7 +216,7 @@ bool cmCTestGIT::UpdateByFetchAndReset()
bool cmCTestGIT::UpdateByCustom(std::string const& custom)
{
- std::vector<std::string> git_custom_command = cmExpandedList(custom, true);
+ cmList git_custom_command{ custom, cmList::EmptyElements::Yes };
std::vector<char const*> git_custom;
git_custom.reserve(git_custom_command.size() + 1);
for (std::string const& i : git_custom_command) {
diff --git a/Source/CTest/cmCTestP4.cxx b/Source/CTest/cmCTestP4.cxx
index 0e67c4122e..e22ec4b556 100644
--- a/Source/CTest/cmCTestP4.cxx
+++ b/Source/CTest/cmCTestP4.cxx
@@ -13,9 +13,9 @@
#include "cmCTest.h"
#include "cmCTestVC.h"
+#include "cmList.h"
#include "cmProcessTools.h"
#include "cmRange.h"
-#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
cmCTestP4::cmCTestP4(cmCTest* ct, std::ostream& log)
@@ -460,7 +460,7 @@ bool cmCTestP4::LoadModifications()
bool cmCTestP4::UpdateCustom(const std::string& custom)
{
- std::vector<std::string> p4_custom_command = cmExpandedList(custom, true);
+ cmList p4_custom_command{ custom, cmList::EmptyElements::Yes };
std::vector<char const*> p4_custom;
p4_custom.reserve(p4_custom_command.size() + 1);
diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx
index ee06b29c67..461ad1a947 100644
--- a/Source/CTest/cmCTestScriptHandler.cxx
+++ b/Source/CTest/cmCTestScriptHandler.cxx
@@ -33,6 +33,7 @@
#include "cmDuration.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStateDirectory.h"
@@ -521,7 +522,7 @@ int cmCTestScriptHandler::RunCurrentScript()
// set any environment variables
if (!this->CTestEnv.empty()) {
- std::vector<std::string> envArgs = cmExpandedList(this->CTestEnv);
+ cmList envArgs{ this->CTestEnv };
cmSystemTools::AppendEnv(envArgs);
}
@@ -625,7 +626,7 @@ int cmCTestScriptHandler::PerformExtraUpdates()
// do an initial cvs update as required
command = this->UpdateCmd;
for (std::string const& eu : this->ExtraUpdates) {
- std::vector<std::string> cvsArgs = cmExpandedList(eu);
+ cmList cvsArgs{ eu };
if (cvsArgs.size() == 2) {
std::string fullCommand = cmStrCat(command, " update ", cvsArgs[1]);
output.clear();
@@ -764,7 +765,7 @@ int cmCTestScriptHandler::RunConfigurationDashboard()
}
// run ctest, it may be more than one command in here
- std::vector<std::string> ctestCommands = cmExpandedList(this->CTestCmd);
+ cmList ctestCommands{ this->CTestCmd };
// for each variable/argument do a putenv
for (std::string const& ctestCommand : ctestCommands) {
command = ctestCommand;
diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx
index a1933cccb1..a92f9f28ec 100644
--- a/Source/CTest/cmCTestSubmitCommand.cxx
+++ b/Source/CTest/cmCTestSubmitCommand.cxx
@@ -13,10 +13,10 @@
#include "cmCTest.h"
#include "cmCTestSubmitHandler.h"
#include "cmCommand.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmRange.h"
-#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
@@ -64,14 +64,14 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler()
cmValue notesFilesVariable =
this->Makefile->GetDefinition("CTEST_NOTES_FILES");
if (notesFilesVariable) {
- std::vector<std::string> notesFiles = cmExpandedList(*notesFilesVariable);
+ cmList notesFiles{ *notesFilesVariable };
this->CTest->GenerateNotesFile(notesFiles);
}
cmValue extraFilesVariable =
this->Makefile->GetDefinition("CTEST_EXTRA_SUBMIT_FILES");
if (extraFilesVariable) {
- std::vector<std::string> extraFiles = cmExpandedList(*extraFilesVariable);
+ cmList extraFiles{ *extraFilesVariable };
if (!this->CTest->SubmitExtraFiles(extraFiles)) {
this->SetError("problem submitting extra files.");
return nullptr;
diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx
index 3ff8c8f280..a095e5dc63 100644
--- a/Source/CTest/cmCTestSubmitHandler.cxx
+++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -22,6 +22,7 @@
#include "cmCurl.h"
#include "cmDuration.h"
#include "cmGeneratedFileStream.h"
+#include "cmList.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -160,7 +161,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(
/* In windows, this will init the winsock stuff */
::curl_global_init(CURL_GLOBAL_ALL);
std::string curlopt(this->CTest->GetCTestConfiguration("CurlOptions"));
- std::vector<std::string> args = cmExpandedList(curlopt);
+ cmList args{ curlopt };
bool verifyPeerOff = false;
bool verifyHostOff = false;
for (std::string const& arg : args) {
@@ -499,7 +500,7 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file,
cmCTestCurl curl(this->CTest);
curl.SetQuiet(this->Quiet);
std::string curlopt(this->CTest->GetCTestConfiguration("CurlOptions"));
- std::vector<std::string> args = cmExpandedList(curlopt);
+ cmList args{ curlopt };
curl.SetCurlOptions(args);
auto submitInactivityTimeout = this->GetSubmitInactivityTimeout();
if (submitInactivityTimeout != 0) {
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index f693ace4b5..3a1cb64708 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -38,6 +38,7 @@
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
#include "cmJSONState.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStateSnapshot.h"
@@ -2203,9 +2204,8 @@ bool cmCTestTestHandler::SetTestsProperties(
for (cmCTestTestProperties& rt : this->TestList) {
if (t == rt.Name) {
if (key == "_BACKTRACE_TRIPLES"_s) {
- std::vector<std::string> triples;
// allow empty args in the triples
- cmExpandList(val, triples, true);
+ cmList triples{ val, cmList::EmptyElements::Yes };
// Ensure we have complete triples otherwise the data is corrupt.
if (triples.size() % 3 == 0) {
@@ -2214,7 +2214,7 @@ bool cmCTestTestHandler::SetTestsProperties(
// the first entry represents the top of the trace so we need to
// reconstruct the backtrace in reverse
- for (size_t i = triples.size(); i >= 3; i -= 3) {
+ for (auto i = triples.size(); i >= 3; i -= 3) {
cmListFileContext fc;
fc.FilePath = triples[i - 3];
long line = 0;
@@ -2235,19 +2235,19 @@ bool cmCTestTestHandler::SetTestsProperties(
} else if (key == "ATTACHED_FILES_ON_FAIL"_s) {
cmExpandList(val, rt.AttachOnFail);
} else if (key == "RESOURCE_LOCK"_s) {
- std::vector<std::string> lval = cmExpandedList(val);
+ cmList lval{ val };
rt.LockedResources.insert(lval.begin(), lval.end());
} else if (key == "FIXTURES_SETUP"_s) {
- std::vector<std::string> lval = cmExpandedList(val);
+ cmList lval{ val };
rt.FixturesSetup.insert(lval.begin(), lval.end());
} else if (key == "FIXTURES_CLEANUP"_s) {
- std::vector<std::string> lval = cmExpandedList(val);
+ cmList lval{ val };
rt.FixturesCleanup.insert(lval.begin(), lval.end());
} else if (key == "FIXTURES_REQUIRED"_s) {
- std::vector<std::string> lval = cmExpandedList(val);
+ cmList lval{ val };
rt.FixturesRequired.insert(lval.begin(), lval.end());
} else if (key == "TIMEOUT"_s) {
@@ -2260,12 +2260,12 @@ bool cmCTestTestHandler::SetTestsProperties(
} else if (key == "RUN_SERIAL"_s) {
rt.RunSerial = cmIsOn(val);
} else if (key == "FAIL_REGULAR_EXPRESSION"_s) {
- std::vector<std::string> lval = cmExpandedList(val);
+ cmList lval{ val };
for (std::string const& cr : lval) {
rt.ErrorRegularExpressions.emplace_back(cr, cr);
}
} else if (key == "SKIP_REGULAR_EXPRESSION"_s) {
- std::vector<std::string> lval = cmExpandedList(val);
+ cmList lval{ val };
for (std::string const& cr : lval) {
rt.SkipRegularExpressions.emplace_back(cr, cr);
}
@@ -2292,7 +2292,7 @@ bool cmCTestTestHandler::SetTestsProperties(
} else if (key == "ENVIRONMENT_MODIFICATION"_s) {
cmExpandList(val, rt.EnvironmentModification);
} else if (key == "LABELS"_s) {
- std::vector<std::string> Labels = cmExpandedList(val);
+ cmList Labels{ val };
rt.Labels.insert(rt.Labels.end(), Labels.begin(), Labels.end());
// sort the array
std::sort(rt.Labels.begin(), rt.Labels.end());
@@ -2309,21 +2309,21 @@ bool cmCTestTestHandler::SetTestsProperties(
rt.Measurements[val] = "1";
}
} else if (key == "PASS_REGULAR_EXPRESSION"_s) {
- std::vector<std::string> lval = cmExpandedList(val);
+ cmList lval{ val };
for (std::string const& cr : lval) {
rt.RequiredRegularExpressions.emplace_back(cr, cr);
}
} else if (key == "WORKING_DIRECTORY"_s) {
rt.Directory = val;
} else if (key == "TIMEOUT_AFTER_MATCH"_s) {
- std::vector<std::string> propArgs = cmExpandedList(val);
+ cmList propArgs{ val };
if (propArgs.size() != 2) {
cmCTestLog(this->CTest, WARNING,
"TIMEOUT_AFTER_MATCH expects two arguments, found "
<< propArgs.size() << std::endl);
} else {
rt.AlternateTimeout = cmDuration(atof(propArgs[0].c_str()));
- std::vector<std::string> lval = cmExpandedList(propArgs[1]);
+ cmList lval{ propArgs[1] };
for (std::string const& cr : lval) {
rt.TimeoutRegularExpressions.emplace_back(cr, cr);
}
@@ -2365,7 +2365,7 @@ bool cmCTestTestHandler::SetDirectoryProperties(
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
if (cwd == rt.Directory) {
if (key == "LABELS"_s) {
- std::vector<std::string> DirectoryLabels = cmExpandedList(val);
+ cmList DirectoryLabels{ val };
rt.Labels.insert(rt.Labels.end(), DirectoryLabels.begin(),
DirectoryLabels.end());
diff --git a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
index e9ec09ee28..fc5450ef2b 100644
--- a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
+++ b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
@@ -4,7 +4,6 @@
#include <cassert>
#include <utility>
-#include <vector>
#include <cm/memory>
@@ -15,9 +14,9 @@
#include "cmCursesPathWidget.h"
#include "cmCursesStringWidget.h"
#include "cmCursesWidget.h"
+#include "cmList.h"
#include "cmState.h"
#include "cmStateTypes.h"
-#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
@@ -76,7 +75,7 @@ cmCursesCacheEntryComposite::cmCursesCacheEntryComposite(
if (stringsProp) {
auto ow =
cm::make_unique<cmCursesOptionsWidget>(this->EntryWidth, 1, 1, 1);
- for (std::string const& opt : cmExpandedList(*stringsProp)) {
+ for (auto const& opt : cmList{ *stringsProp }) {
ow->AddOption(opt);
}
ow->SetOption(*value);
diff --git a/Source/Modules/CMakeBuildUtilities.cmake b/Source/Modules/CMakeBuildUtilities.cmake
index 3dc099f7c8..d6e3e884dc 100644
--- a/Source/Modules/CMakeBuildUtilities.cmake
+++ b/Source/Modules/CMakeBuildUtilities.cmake
@@ -279,7 +279,7 @@ else()
set(ENABLE_LIBXML2 OFF)
set(ENABLE_EXPAT OFF)
set(ENABLE_PCREPOSIX OFF)
- set(ENABLE_LibGCC OFF)
+ set(ENABLE_LIBGCC OFF)
set(ENABLE_CNG OFF)
set(ENABLE_TAR OFF)
set(ENABLE_TAR_SHARED OFF)
diff --git a/Source/cmCMakeHostSystemInformationCommand.cxx b/Source/cmCMakeHostSystemInformationCommand.cxx
index 58129a06b6..8bfd7c87c7 100644
--- a/Source/cmCMakeHostSystemInformationCommand.cxx
+++ b/Source/cmCMakeHostSystemInformationCommand.cxx
@@ -21,10 +21,12 @@
#include "cmArgumentParser.h"
#include "cmExecutionStatus.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmRange.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmValue.h"
#include "cmWindowsRegistry.h"
#ifdef _WIN32
@@ -303,7 +305,8 @@ std::map<std::string, std::string> GetOSReleaseVariables(
}
// 2. User provided (append to the CMake prvided)
- makefile.GetDefExpandList("CMAKE_GET_OS_RELEASE_FALLBACK_SCRIPTS", scripts);
+ cmList::append(
+ scripts, makefile.GetDefinition("CMAKE_GET_OS_RELEASE_FALLBACK_SCRIPTS"));
// Filter out files that are not in format `NNN-name.cmake`
auto checkName = [](std::string const& filepath) -> bool {
@@ -330,11 +333,11 @@ std::map<std::string, std::string> GetOSReleaseVariables(
});
// Name of the variable to put the results
- auto const result_variable = "CMAKE_GET_OS_RELEASE_FALLBACK_RESULT"_s;
+ std::string const result_variable{ "CMAKE_GET_OS_RELEASE_FALLBACK_RESULT" };
for (auto const& script : scripts) {
// Unset the result variable
- makefile.RemoveDefinition(result_variable.data());
+ makefile.RemoveDefinition(result_variable);
// include FATAL_ERROR and ERROR in the return status
if (!makefile.ReadListFile(script) ||
@@ -343,8 +346,8 @@ std::map<std::string, std::string> GetOSReleaseVariables(
continue;
}
- std::vector<std::string> variables;
- if (!makefile.GetDefExpandList(result_variable.data(), variables)) {
+ cmList variables{ makefile.GetDefinition(result_variable) };
+ if (variables.empty()) {
// Heh, this script didn't found anything... go try the next one.
continue;
}
@@ -370,7 +373,7 @@ std::map<std::string, std::string> GetOSReleaseVariables(
}
}
- makefile.RemoveDefinition(result_variable.data());
+ makefile.RemoveDefinition(result_variable);
return data;
}
diff --git a/Source/cmCMakePathCommand.cxx b/Source/cmCMakePathCommand.cxx
index 7755082236..0c8f53781a 100644
--- a/Source/cmCMakePathCommand.cxx
+++ b/Source/cmCMakePathCommand.cxx
@@ -18,6 +18,7 @@
#include "cmArgumentParserTypes.h"
#include "cmCMakePath.h"
#include "cmExecutionStatus.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmRange.h"
#include "cmStringAlgorithms.h"
@@ -626,12 +627,12 @@ bool HandleConvertCommand(std::vector<std::string> const& args,
return false;
}
- std::vector<std::string> paths;
+ cmList paths;
if (action == cmakePath) {
paths = cmSystemTools::SplitString(args[1], pathSep.front());
} else {
- cmExpandList(args[1], paths);
+ paths.assign(args[1]);
}
for (auto& path : paths) {
@@ -648,7 +649,7 @@ bool HandleConvertCommand(std::vector<std::string> const& args,
}
}
- auto value = cmJoin(paths, action == cmakePath ? ";"_s : pathSep);
+ auto value = action == cmakePath ? paths.to_string() : paths.join(pathSep);
status.GetMakefile().AddDefinition(args[3], value);
return true;
diff --git a/Source/cmCMakePresetsGraph.cxx b/Source/cmCMakePresetsGraph.cxx
index 13e8bad1f1..13eddbe24f 100644
--- a/Source/cmCMakePresetsGraph.cxx
+++ b/Source/cmCMakePresetsGraph.cxx
@@ -4,7 +4,6 @@
#include <algorithm>
#include <cassert>
-#include <cstdlib>
#include <functional>
#include <iostream>
#include <iterator>
@@ -49,6 +48,7 @@ template <typename T>
using PresetPair = cmCMakePresetsGraph::PresetPair<T>;
using ExpandMacroResult = cmCMakePresetsGraphInternal::ExpandMacroResult;
using MacroExpander = cmCMakePresetsGraphInternal::MacroExpander;
+using cmCMakePresetsGraphInternal::ExpandMacros;
void InheritString(std::string& child, const std::string& parent)
{
@@ -204,14 +204,6 @@ bool IsValidMacroNamespace(const std::string& str)
ExpandMacroResult VisitEnv(std::string& value, CycleStatus& status,
const std::vector<MacroExpander>& macroExpanders,
int version);
-ExpandMacroResult ExpandMacros(
- std::string& out, const std::vector<MacroExpander>& macroExpanders,
- int version);
-ExpandMacroResult ExpandMacro(std::string& out,
- const std::string& macroNamespace,
- const std::string& macroName,
- const std::vector<MacroExpander>& macroExpanders,
- int version);
bool ExpandMacros(const cmCMakePresetsGraph& graph,
const ConfigurePreset& preset,
@@ -448,9 +440,9 @@ bool ExpandMacros(cmCMakePresetsGraph& graph, const T& preset,
if (macroName.empty()) {
return ExpandMacroResult::Error;
}
- const char* value = std::getenv(macroName.c_str());
- if (value) {
- result += value;
+ if (cm::optional<std::string> value =
+ cmSystemTools::GetEnvVar(macroName)) {
+ result += *value;
}
return ExpandMacroResult::Ok;
}
@@ -515,8 +507,9 @@ ExpandMacroResult VisitEnv(std::string& value, CycleStatus& status,
status = CycleStatus::Verified;
return ExpandMacroResult::Ok;
}
+}
-ExpandMacroResult ExpandMacros(
+ExpandMacroResult cmCMakePresetsGraphInternal::ExpandMacros(
std::string& out, const std::vector<MacroExpander>& macroExpanders,
int version)
{
@@ -595,11 +588,10 @@ ExpandMacroResult ExpandMacros(
return ExpandMacroResult::Ok;
}
-ExpandMacroResult ExpandMacro(std::string& out,
- const std::string& macroNamespace,
- const std::string& macroName,
- const std::vector<MacroExpander>& macroExpanders,
- int version)
+ExpandMacroResult cmCMakePresetsGraphInternal::ExpandMacro(
+ std::string& out, const std::string& macroNamespace,
+ const std::string& macroName,
+ const std::vector<MacroExpander>& macroExpanders, int version)
{
for (auto const& macroExpander : macroExpanders) {
auto result = macroExpander(macroNamespace, macroName, out, version);
@@ -615,6 +607,7 @@ ExpandMacroResult ExpandMacro(std::string& out,
return ExpandMacroResult::Error;
}
+namespace {
template <typename T>
bool SetupWorkflowConfigurePreset(const T& preset,
const ConfigurePreset*& configurePreset,
diff --git a/Source/cmCMakePresetsGraphInternal.h b/Source/cmCMakePresetsGraphInternal.h
index db784c341a..f133efb124 100644
--- a/Source/cmCMakePresetsGraphInternal.h
+++ b/Source/cmCMakePresetsGraphInternal.h
@@ -28,6 +28,16 @@ enum class ExpandMacroResult
using MacroExpander = std::function<ExpandMacroResult(
const std::string&, const std::string&, std::string&, int version)>;
+
+ExpandMacroResult ExpandMacros(
+ std::string& out, const std::vector<MacroExpander>& macroExpanders,
+ int version);
+
+ExpandMacroResult ExpandMacro(std::string& out,
+ const std::string& macroNamespace,
+ const std::string& macroName,
+ const std::vector<MacroExpander>& macroExpanders,
+ int version);
}
class cmCMakePresetsGraph::Condition
diff --git a/Source/cmCMakePresetsGraphReadJSON.cxx b/Source/cmCMakePresetsGraphReadJSON.cxx
index bc829f3e44..54fea409c4 100644
--- a/Source/cmCMakePresetsGraphReadJSON.cxx
+++ b/Source/cmCMakePresetsGraphReadJSON.cxx
@@ -33,6 +33,9 @@ using PackagePreset = cmCMakePresetsGraph::PackagePreset;
using WorkflowPreset = cmCMakePresetsGraph::WorkflowPreset;
using ArchToolsetStrategy = cmCMakePresetsGraph::ArchToolsetStrategy;
using JSONHelperBuilder = cmJSONHelperBuilder;
+using ExpandMacroResult = cmCMakePresetsGraphInternal::ExpandMacroResult;
+using MacroExpander = cmCMakePresetsGraphInternal::MacroExpander;
+using cmCMakePresetsGraphInternal::ExpandMacros;
constexpr int MIN_VERSION = 1;
constexpr int MAX_VERSION = 7;
@@ -688,7 +691,39 @@ bool cmCMakePresetsGraph::ReadJSONFile(const std::string& filename,
return true;
};
- for (auto include : presets.Include) {
+ std::vector<MacroExpander> macroExpanders;
+
+ MacroExpander environmentMacroExpander =
+ [](const std::string& macroNamespace, const std::string& macroName,
+ std::string& expanded, int /*version*/) -> ExpandMacroResult {
+ if (macroNamespace == "penv") {
+ if (macroName.empty()) {
+ return ExpandMacroResult::Error;
+ }
+ if (cm::optional<std::string> value =
+ cmSystemTools::GetEnvVar(macroName)) {
+ expanded += *value;
+ }
+ return ExpandMacroResult::Ok;
+ }
+
+ return ExpandMacroResult::Ignore;
+ };
+
+ macroExpanders.push_back(environmentMacroExpander);
+
+ for (Json::ArrayIndex i = 0; i < presets.Include.size(); ++i) {
+ auto include = presets.Include[i];
+
+ // Support for macro expansion in includes added in version 7
+ if (v >= 7) {
+ if (ExpandMacros(include, macroExpanders, v) != ExpandMacroResult::Ok) {
+ cmCMakePresetErrors::INVALID_INCLUDE(&root["include"][i],
+ &this->parseState);
+ return false;
+ }
+ }
+
if (!cmSystemTools::FileIsFullPath(include)) {
auto directory = cmSystemTools::GetFilenamePath(filename);
include = cmStrCat(directory, '/', include);
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index c8eea38b75..a3110413f8 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -55,6 +55,7 @@
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
#include "cmJSONState.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmProcessOutput.h"
#include "cmState.h"
@@ -1468,7 +1469,7 @@ void cmCTest::AddSiteProperties(cmXMLWriter& xml)
ch->GetCMake()->GetState()->GetGlobalProperty("SubProjectLabels");
if (labels) {
xml.StartElement("Labels");
- std::vector<std::string> args = cmExpandedList(*labels);
+ cmList args{ *labels };
for (std::string const& i : args) {
xml.Element("Label", i);
}
@@ -1500,7 +1501,7 @@ std::vector<std::string> cmCTest::GetLabelsForSubprojects()
{
std::string labelsForSubprojects =
this->GetCTestConfiguration("LabelsForSubprojects");
- std::vector<std::string> subprojects = cmExpandedList(labelsForSubprojects);
+ cmList subprojects{ labelsForSubprojects };
// sort the array
std::sort(subprojects.begin(), subprojects.end());
@@ -1508,7 +1509,7 @@ std::vector<std::string> cmCTest::GetLabelsForSubprojects()
auto new_end = std::unique(subprojects.begin(), subprojects.end());
subprojects.erase(new_end, subprojects.end());
- return subprojects;
+ return std::move(subprojects.data());
}
void cmCTest::EndXML(cmXMLWriter& xml)
@@ -3098,8 +3099,7 @@ void cmCTest::PopulateCustomVector(cmMakefile* mf, const std::string& def,
}
cmCTestLog(this, DEBUG, "PopulateCustomVector: " << def << std::endl);
- vec.clear();
- cmExpandList(*dval, vec);
+ cmList::assign(vec, *dval);
for (std::string const& it : vec) {
cmCTestLog(this, DEBUG, " -- " << it << std::endl);
diff --git a/Source/cmCacheManager.cxx b/Source/cmCacheManager.cxx
index b9d1f66d2a..d95dcc44ce 100644
--- a/Source/cmCacheManager.cxx
+++ b/Source/cmCacheManager.cxx
@@ -12,6 +12,7 @@
#include "cmsys/Glob.hxx"
#include "cmGeneratedFileStream.h"
+#include "cmList.h"
#include "cmMessageType.h"
#include "cmMessenger.h"
#include "cmState.h"
@@ -531,15 +532,11 @@ void cmCacheManager::AddCacheEntry(const std::string& key, cmValue value,
// make sure we only use unix style paths
if (type == cmStateEnums::FILEPATH || type == cmStateEnums::PATH) {
if (e.Value.find(';') != std::string::npos) {
- std::vector<std::string> paths = cmExpandedList(e.Value);
- const char* sep = "";
- e.Value = "";
+ cmList paths{ e.Value };
for (std::string& i : paths) {
cmSystemTools::ConvertToUnixSlashes(i);
- e.Value += sep;
- e.Value += i;
- sep = ";";
}
+ e.Value = paths.to_string();
} else {
cmSystemTools::ConvertToUnixSlashes(e.Value);
}
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
index f6fdd48969..1cb62b39d8 100644
--- a/Source/cmCommonTargetGenerator.cxx
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -15,6 +15,7 @@
#include "cmGeneratorTarget.h"
#include "cmGlobalCommonGenerator.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmLocalCommonGenerator.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
@@ -303,8 +304,7 @@ std::string cmCommonTargetGenerator::GetLinkerLauncher(
*launcherProp, this->LocalCommonGenerator, config, this->GeneratorTarget,
&dagChecker, this->GeneratorTarget, lang);
// Convert ;-delimited list to single string
- std::vector<std::string> args =
- cmExpandedList(evaluatedLinklauncher, true);
+ cmList args{ evaluatedLinklauncher, cmList::EmptyElements::Yes };
if (!args.empty()) {
args[0] = this->LocalCommonGenerator->ConvertToOutputFormat(
args[0], cmOutputConverter::SHELL);
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index 5f408d0c65..f51a1c895c 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -20,6 +20,7 @@
#include "cmGeneratorExpressionDAGChecker.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
@@ -627,7 +628,7 @@ void cmComputeLinkDepends::AddVarLinkEntries(size_t depender_index,
// This is called to add the dependencies named by
// <item>_LIB_DEPENDS. The variable contains a semicolon-separated
// list. The list contains link-type;item pairs and just items.
- std::vector<std::string> deplist = cmExpandedList(value);
+ cmList deplist{ value };
// Look for entries meant for this configuration.
std::vector<cmLinkItem> actual_libs;
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index a93477b924..5d44a6ae70 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -15,6 +15,7 @@
#include "cmComputeLinkDepends.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
@@ -858,8 +859,8 @@ bool cmComputeLinkInformation::AddLibraryFeature(std::string const& feature)
return false;
}
- auto items = cmExpandListWithBacktrace(*langFeature,
- this->Target->GetBacktrace(), true);
+ auto items = cmExpandListWithBacktrace(
+ *langFeature, this->Target->GetBacktrace(), cmList::EmptyElements::Yes);
if ((items.size() == 1 && !IsValidFeatureFormat(items.front().Value)) ||
(items.size() == 3 && !IsValidFeatureFormat(items[1].Value))) {
@@ -1016,8 +1017,8 @@ cmComputeLinkInformation::GetGroupFeature(std::string const& feature)
.first->second;
}
- auto items = cmExpandListWithBacktrace(*langFeature,
- this->Target->GetBacktrace(), true);
+ auto items = cmExpandListWithBacktrace(
+ *langFeature, this->Target->GetBacktrace(), cmList::EmptyElements::Yes);
// replace LINKER: pattern
this->Target->ResolveLinkerWrapper(items, this->LinkLanguage, true);
@@ -1072,8 +1073,8 @@ void cmComputeLinkInformation::AddRuntimeLinkLibrary(std::string const& lang)
}
if (cmValue runtimeLinkOptions = this->Makefile->GetDefinition(cmStrCat(
"CMAKE_", lang, "_RUNTIME_LIBRARY_LINK_OPTIONS_", runtimeLibrary))) {
- std::vector<std::string> libsVec = cmExpandedList(*runtimeLinkOptions);
- for (std::string const& i : libsVec) {
+ cmList libs{ *runtimeLinkOptions };
+ for (auto const& i : libs) {
if (!cm::contains(this->ImplicitLinkLibs, i)) {
this->AddItem({ i });
}
@@ -1087,8 +1088,8 @@ void cmComputeLinkInformation::AddImplicitLinkInfo(std::string const& lang)
// linker language.
std::string libVar = cmStrCat("CMAKE_", lang, "_IMPLICIT_LINK_LIBRARIES");
if (cmValue libs = this->Makefile->GetDefinition(libVar)) {
- std::vector<std::string> libsVec = cmExpandedList(*libs);
- for (std::string const& i : libsVec) {
+ cmList libsList{ *libs };
+ for (auto const& i : libsList) {
if (!cm::contains(this->ImplicitLinkLibs, i)) {
this->AddItem({ i });
}
@@ -1099,8 +1100,8 @@ void cmComputeLinkInformation::AddImplicitLinkInfo(std::string const& lang)
// implied by the linker language.
std::string dirVar = cmStrCat("CMAKE_", lang, "_IMPLICIT_LINK_DIRECTORIES");
if (cmValue dirs = this->Makefile->GetDefinition(dirVar)) {
- std::vector<std::string> dirsVec = cmExpandedList(*dirs);
- this->OrderLinkerSearchPath->AddLanguageDirectories(dirsVec);
+ cmList dirsList{ *dirs };
+ this->OrderLinkerSearchPath->AddLanguageDirectories(dirsList);
}
}
@@ -1370,15 +1371,15 @@ void cmComputeLinkInformation::ComputeItemParserInfo()
LinkUnknown);
if (cmValue linkSuffixes =
mf->GetDefinition("CMAKE_EXTRA_LINK_EXTENSIONS")) {
- std::vector<std::string> linkSuffixVec = cmExpandedList(*linkSuffixes);
- for (std::string const& i : linkSuffixVec) {
+ cmList linkSuffixList{ *linkSuffixes };
+ for (auto const& i : linkSuffixList) {
this->AddLinkExtension(i, LinkUnknown);
}
}
if (cmValue sharedSuffixes =
mf->GetDefinition("CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES")) {
- std::vector<std::string> sharedSuffixVec = cmExpandedList(*sharedSuffixes);
- for (std::string const& i : sharedSuffixVec) {
+ cmList sharedSuffixList{ *sharedSuffixes };
+ for (std::string const& i : sharedSuffixList) {
this->AddLinkExtension(i, LinkShared);
}
}
@@ -1916,19 +1917,18 @@ void cmComputeLinkInformation::DropDirectoryItem(BT<std::string> const& item)
void cmComputeLinkInformation::ComputeFrameworkInfo()
{
// Avoid adding implicit framework paths.
- std::vector<std::string> implicitDirVec;
+ cmList implicitDirs;
// Get platform-wide implicit directories.
- this->Makefile->GetDefExpandList(
- "CMAKE_PLATFORM_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES", implicitDirVec);
+ implicitDirs.assign(this->Makefile->GetDefinition(
+ "CMAKE_PLATFORM_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES"));
// Get language-specific implicit directories.
std::string implicitDirVar = cmStrCat(
"CMAKE_", this->LinkLanguage, "_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES");
- this->Makefile->GetDefExpandList(implicitDirVar, implicitDirVec);
+ implicitDirs.append(this->Makefile->GetDefinition(implicitDirVar));
- this->FrameworkPathsEmitted.insert(implicitDirVec.begin(),
- implicitDirVec.end());
+ this->FrameworkPathsEmitted.insert(implicitDirs.begin(), implicitDirs.end());
}
void cmComputeLinkInformation::AddFrameworkPath(std::string const& p)
@@ -2138,17 +2138,15 @@ void cmComputeLinkInformation::PrintLinkPolicyDiagnosis(std::ostream& os)
void cmComputeLinkInformation::LoadImplicitLinkInfo()
{
- std::vector<std::string> implicitDirVec;
-
// Get platform-wide implicit directories.
- this->Makefile->GetDefExpandList("CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES",
- implicitDirVec);
+ cmList implicitDirs{ this->Makefile->GetDefinition(
+ "CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES") };
// Append library architecture to all implicit platform directories
// and add them to the set
if (cmValue libraryArch =
this->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE")) {
- for (std::string const& i : implicitDirVec) {
+ for (auto const& i : implicitDirs) {
this->ImplicitLinkDirs.insert(cmStrCat(i, '/', *libraryArch));
}
}
@@ -2156,19 +2154,18 @@ void cmComputeLinkInformation::LoadImplicitLinkInfo()
// Get language-specific implicit directories.
std::string implicitDirVar =
cmStrCat("CMAKE_", this->LinkLanguage, "_IMPLICIT_LINK_DIRECTORIES");
- this->Makefile->GetDefExpandList(implicitDirVar, implicitDirVec);
+ implicitDirs.append(this->Makefile->GetDefinition(implicitDirVar));
// Store implicit link directories.
- this->ImplicitLinkDirs.insert(implicitDirVec.begin(), implicitDirVec.end());
+ this->ImplicitLinkDirs.insert(implicitDirs.begin(), implicitDirs.end());
// Get language-specific implicit libraries.
- std::vector<std::string> implicitLibVec;
std::string implicitLibVar =
cmStrCat("CMAKE_", this->LinkLanguage, "_IMPLICIT_LINK_LIBRARIES");
- this->Makefile->GetDefExpandList(implicitLibVar, implicitLibVec);
+ cmList implicitLibs{ this->Makefile->GetDefinition(implicitLibVar) };
// Store implicit link libraries.
- for (std::string const& item : implicitLibVec) {
+ for (auto const& item : implicitLibs) {
// Items starting in '-' but not '-l' are flags, not libraries,
// and should not be filtered by this implicit list.
if (item[0] != '-' || item[1] == 'l') {
@@ -2177,8 +2174,8 @@ void cmComputeLinkInformation::LoadImplicitLinkInfo()
}
// Get platform specific rpath link directories
- this->Makefile->GetDefExpandList("CMAKE_PLATFORM_RUNTIME_PATH",
- this->RuntimeLinkDirs);
+ cmList::append(this->RuntimeLinkDirs,
+ this->Makefile->GetDefinition("CMAKE_PLATFORM_RUNTIME_PATH"));
}
std::vector<std::string> const&
@@ -2279,7 +2276,7 @@ static void cmCLI_ExpandListUnique(std::string const& str,
std::vector<std::string>& out,
std::set<std::string>& emitted)
{
- std::vector<std::string> tmp = cmExpandedList(str);
+ cmList tmp{ str };
for (std::string const& i : tmp) {
if (emitted.insert(i).second) {
out.push_back(i);
diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx
index 5de012a7fa..288e107d0a 100644
--- a/Source/cmConditionEvaluator.cxx
+++ b/Source/cmConditionEvaluator.cxx
@@ -18,6 +18,7 @@
#include "cmCMakePath.h"
#include "cmExpandedCommandArgument.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmState.h"
@@ -764,7 +765,9 @@ bool cmConditionEvaluator::HandleLevel2(cmArgumentList& newArgs,
cmValue rhs = this->Makefile.GetDefinition(args.nextnext->GetValue());
newArgs.ReduceTwoArgs(
- rhs && cm::contains(cmExpandedList(*rhs, true), *lhs), args);
+ rhs &&
+ cm::contains(cmList{ *rhs, cmList::EmptyElements::Yes }, *lhs),
+ args);
}
else if (this->Policy57Status == cmPolicies::WARN) {
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index 3149ccfa9c..7d4ab50967 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -20,6 +20,7 @@
#include "cmConfigureLog.h"
#include "cmExportTryCompileFileGenerator.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmOutputConverter.h"
@@ -125,7 +126,7 @@ ArgumentParser::Continue TryCompileLangProp(Arguments& args,
ArgumentParser::Continue TryCompileCompileDefs(Arguments& args,
cm::string_view val)
{
- cmExpandList(val, args.CompileDefs);
+ args.CompileDefs.append(val);
return ArgumentParser::Continue::Yes;
}
@@ -788,7 +789,7 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
if (!arguments.CompileDefs.empty()) {
// Pass using bracket arguments to preserve content.
fprintf(fout, "add_definitions([==[%s]==])\n",
- cmJoin(arguments.CompileDefs, "]==] [==[").c_str());
+ arguments.CompileDefs.join("]==] [==[").c_str());
}
if (!targets.empty()) {
@@ -1024,7 +1025,7 @@ cm::optional<cmTryCompileResult> cmCoreTryCompile::TryCompileCode(
if (cmValue varListStr = this->Makefile->GetDefinition(
kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES)) {
- std::vector<std::string> varList = cmExpandedList(*varListStr);
+ cmList varList{ *varListStr };
vars.insert(varList.begin(), varList.end());
}
diff --git a/Source/cmCoreTryCompile.h b/Source/cmCoreTryCompile.h
index ba38c196b8..c185c68feb 100644
--- a/Source/cmCoreTryCompile.h
+++ b/Source/cmCoreTryCompile.h
@@ -12,6 +12,7 @@
#include "cmArgumentParser.h"
#include "cmArgumentParserTypes.h"
+#include "cmList.h"
#include "cmStateTypes.h"
class cmConfigureLog;
@@ -65,7 +66,7 @@ public:
ArgumentParser::MaybeEmpty<std::vector<std::string>> CMakeFlags{
1, "CMAKE_FLAGS"
}; // fake argv[0]
- std::vector<std::string> CompileDefs;
+ cmList CompileDefs;
cm::optional<ArgumentParser::MaybeEmpty<std::vector<std::string>>>
LinkLibraries;
ArgumentParser::MaybeEmpty<std::vector<std::string>> LinkOptions;
diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx
index 14c22e3a45..7623ccfd18 100644
--- a/Source/cmCustomCommandGenerator.cxx
+++ b/Source/cmCustomCommandGenerator.cxx
@@ -17,6 +17,7 @@
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmStateTypes.h"
@@ -116,7 +117,7 @@ std::vector<std::string> EvaluateDepends(std::vector<std::string> const& paths,
/*outputConfig=*/outputConfig,
/*commandConfig=*/commandConfig,
/*target=*/nullptr);
- cm::append(depends, cmExpandedList(ep));
+ cm::append(depends, cmList{ ep });
}
for (std::string& p : depends) {
if (cmSystemTools::FileIsFullPath(p)) {
@@ -196,7 +197,7 @@ cmCustomCommandGenerator::cmCustomCommandGenerator(
clarg, ge, this->LG, useOutputConfig, this->OutputConfig,
this->CommandConfig, target, &this->Utilities);
if (this->CC->GetCommandExpandLists()) {
- cm::append(argv, cmExpandedList(parsed_arg));
+ cm::append(argv, cmList{ parsed_arg });
} else {
argv.push_back(std::move(parsed_arg));
}
diff --git a/Source/cmDepends.cxx b/Source/cmDepends.cxx
index eca1abdaae..04bccce5e7 100644
--- a/Source/cmDepends.cxx
+++ b/Source/cmDepends.cxx
@@ -9,6 +9,7 @@
#include "cmFileTime.h"
#include "cmFileTimeCache.h"
#include "cmGeneratedFileStream.h"
+#include "cmList.h"
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
@@ -28,11 +29,11 @@ bool cmDepends::Write(std::ostream& makeDepends, std::ostream& internalDepends)
std::map<std::string, std::set<std::string>> dependencies;
{
// Lookup the set of sources to scan.
- std::vector<std::string> pairs;
+ cmList pairs;
{
std::string const srcLang = "CMAKE_DEPENDS_CHECK_" + this->Language;
cmMakefile* mf = this->LocalGenerator->GetMakefile();
- cmExpandList(mf->GetSafeDefinition(srcLang), pairs);
+ pairs.assign(mf->GetSafeDefinition(srcLang));
}
for (auto si = pairs.begin(); si != pairs.end();) {
// Get the source and object file.
diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx
index 25278090a4..408a85b325 100644
--- a/Source/cmDependsC.cxx
+++ b/Source/cmDependsC.cxx
@@ -8,6 +8,7 @@
#include "cmFileTime.h"
#include "cmGlobalUnixMakefileGenerator3.h"
+#include "cmList.h"
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
@@ -393,10 +394,10 @@ void cmDependsC::Scan(std::istream& is, const std::string& directory,
void cmDependsC::SetupTransforms()
{
// Get the transformation rules.
- std::vector<std::string> transformRules;
cmMakefile* mf = this->LocalGenerator->GetMakefile();
- mf->GetDefExpandList("CMAKE_INCLUDE_TRANSFORMS", transformRules, true);
- for (std::string const& tr : transformRules) {
+ cmList transformRules{ mf->GetDefinition("CMAKE_INCLUDE_TRANSFORMS"),
+ cmList::EmptyElements::Yes };
+ for (auto const& tr : transformRules) {
this->ParseTransform(tr);
}
diff --git a/Source/cmDependsCompiler.cxx b/Source/cmDependsCompiler.cxx
index 0cc4946e48..c8061c36ee 100644
--- a/Source/cmDependsCompiler.cxx
+++ b/Source/cmDependsCompiler.cxx
@@ -128,7 +128,7 @@ bool cmDependsCompiler::CheckDependencies(
}
std::string line;
- if (!isValidPath) {
+ if (!isValidPath && !source.empty()) {
// insert source as first dependency
depends.push_back(source);
}
@@ -158,14 +158,16 @@ bool cmDependsCompiler::CheckDependencies(
}
// ensure source file is the first dependency
- if (depends.front() != source) {
- cm::erase(depends, source);
- if (!isValidPath) {
- depends.insert(depends.begin(), source);
+ if (!source.empty()) {
+ if (depends.front() != source) {
+ cm::erase(depends, source);
+ if (!isValidPath) {
+ depends.insert(depends.begin(), source);
+ }
+ } else if (isValidPath) {
+ // remove first dependency because it must not be filtered out
+ depends.erase(depends.begin());
}
- } else if (isValidPath) {
- // remove first dependency because it must not be filtered out
- depends.erase(depends.begin());
}
} else {
// unknown format, ignore it
@@ -174,8 +176,10 @@ bool cmDependsCompiler::CheckDependencies(
if (isValidPath) {
cm::erase_if(depends, isValidPath);
- // insert source as first dependency
- depends.insert(depends.begin(), source);
+ if (!source.empty()) {
+ // insert source as first dependency
+ depends.insert(depends.begin(), source);
+ }
}
dependencies[target] = std::move(depends);
diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx
index 718097f0be..aede3fecff 100644
--- a/Source/cmDependsFortran.cxx
+++ b/Source/cmDependsFortran.cxx
@@ -13,6 +13,7 @@
#include "cmFortranParser.h" /* Interface to parser object. */
#include "cmGeneratedFileStream.h"
#include "cmGlobalUnixMakefileGenerator3.h"
+#include "cmList.h"
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmOutputConverter.h"
@@ -78,9 +79,8 @@ cmDependsFortran::cmDependsFortran(cmLocalUnixMakefileGenerator3* lg)
this->SetIncludePathFromLanguage("Fortran");
// Get the list of definitions.
- std::vector<std::string> definitions;
cmMakefile* mf = this->LocalGenerator->GetMakefile();
- mf->GetDefExpandList("CMAKE_TARGET_DEFINITIONS_Fortran", definitions);
+ cmList definitions{ mf->GetDefinition("CMAKE_TARGET_DEFINITIONS_Fortran") };
// translate i.e. FOO=BAR to FOO and add it to the list of defined
// preprocessor symbols
@@ -244,9 +244,9 @@ bool cmDependsFortran::LocateModules()
// Load information about other targets.
cmMakefile* mf = this->LocalGenerator->GetMakefile();
- std::vector<std::string> infoFiles;
- mf->GetDefExpandList("CMAKE_Fortran_TARGET_LINKED_INFO_FILES", infoFiles);
- for (std::string const& i : infoFiles) {
+ cmList infoFiles{ mf->GetDefinition(
+ "CMAKE_Fortran_TARGET_LINKED_INFO_FILES") };
+ for (auto const& i : infoFiles) {
std::string targetDir = cmSystemTools::GetFilenamePath(i);
std::string fname = targetDir + "/fortran.internal";
cmsys::ifstream fin(fname.c_str());
diff --git a/Source/cmEvaluatedTargetProperty.cxx b/Source/cmEvaluatedTargetProperty.cxx
index 1173690318..b82c29b75c 100644
--- a/Source/cmEvaluatedTargetProperty.cxx
+++ b/Source/cmEvaluatedTargetProperty.cxx
@@ -8,7 +8,7 @@
#include "cmGeneratorExpressionContext.h"
#include "cmGeneratorTarget.h"
#include "cmLinkItem.h"
-#include "cmStringAlgorithms.h"
+#include "cmList.h"
struct cmGeneratorExpressionDAGChecker;
diff --git a/Source/cmExportBuildAndroidMKGenerator.cxx b/Source/cmExportBuildAndroidMKGenerator.cxx
index 5d0b208931..5e7008b957 100644
--- a/Source/cmExportBuildAndroidMKGenerator.cxx
+++ b/Source/cmExportBuildAndroidMKGenerator.cxx
@@ -10,6 +10,7 @@
#include "cmGeneratorTarget.h"
#include "cmLinkItem.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
@@ -148,7 +149,7 @@ void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
}
} else if (property.first == "INTERFACE_INCLUDE_DIRECTORIES") {
std::string includes = property.second;
- std::vector<std::string> includeList = cmExpandedList(includes);
+ cmList includeList{ includes };
os << "LOCAL_EXPORT_C_INCLUDES := ";
std::string end;
for (std::string const& i : includeList) {
@@ -158,9 +159,8 @@ void cmExportBuildAndroidMKGenerator::GenerateInterfaceProperties(
os << "\n";
} else if (property.first == "INTERFACE_LINK_OPTIONS") {
os << "LOCAL_EXPORT_LDFLAGS := ";
- std::vector<std::string> linkFlagsList =
- cmExpandedList(property.second);
- os << cmJoin(linkFlagsList, " ") << "\n";
+ cmList linkFlagsList{ property.second };
+ os << linkFlagsList.join(" ") << "\n";
} else {
os << "# " << property.first << " " << (property.second) << "\n";
}
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index e997158c3e..22276ae508 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -17,6 +17,7 @@
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmLinkItem.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -507,7 +508,7 @@ static void getPropertyContents(cmGeneratorTarget const* tgt,
if (!p) {
return;
}
- std::vector<std::string> content = cmExpandedList(*p);
+ cmList content{ *p };
ifaceProperties.insert(content.begin(), content.end());
}
@@ -1261,7 +1262,7 @@ bool cmExportFileGenerator::PopulateExportProperties(
const auto& targetProperties = gte->Target->GetProperties();
if (cmValue exportProperties =
targetProperties.GetPropertyValue("EXPORT_PROPERTIES")) {
- for (auto& prop : cmExpandedList(*exportProperties)) {
+ for (auto& prop : cmList{ *exportProperties }) {
/* Black list reserved properties */
if (cmHasLiteralPrefix(prop, "IMPORTED_") ||
cmHasLiteralPrefix(prop, "INTERFACE_")) {
@@ -1325,7 +1326,22 @@ void cmExportFileGenerator::GenerateTargetFileSets(cmGeneratorTarget* gte,
<< this->GetFileSetFiles(gte, fileSet, te) << "\n";
}
- os << " )\nendif()\n\n";
+ os << " )\nelse()\n set_property(TARGET " << targetName
+ << "\n APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES";
+ for (auto const& name : interfaceFileSets) {
+ auto* fileSet = gte->Target->GetFileSet(name);
+ if (!fileSet) {
+ gte->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("File set \"", name,
+ "\" is listed in interface file sets of ", gte->GetName(),
+ " but has not been created"));
+ return;
+ }
+
+ os << "\n " << this->GetFileSetDirectories(gte, fileSet, te);
+ }
+ os << "\n )\nendif()\n\n";
}
}
diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx
index c6ebad5c2d..f30c3c3ba4 100644
--- a/Source/cmExportTryCompileFileGenerator.cxx
+++ b/Source/cmExportTryCompileFileGenerator.cxx
@@ -12,6 +12,7 @@
#include "cmGeneratorExpressionDAGChecker.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
@@ -126,7 +127,7 @@ void cmExportTryCompileFileGenerator::PopulateProperties(
std::string evalResult =
this->FindTargets(p, target, std::string(), emitted);
- std::vector<std::string> depends = cmExpandedList(evalResult);
+ cmList depends{ evalResult };
for (std::string const& li : depends) {
cmGeneratorTarget* tgt =
target->GetLocalGenerator()->FindGeneratorTargetToUse(li);
diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index e9e2921316..8d7f33e7ef 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -14,6 +14,7 @@
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmRange.h"
@@ -567,13 +568,13 @@ void cmExtraCodeBlocksGenerator::AppendTarget(
std::string systemIncludeDirs = makefile->GetSafeDefinition(
"CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS");
if (!systemIncludeDirs.empty()) {
- cm::append(allIncludeDirs, cmExpandedList(systemIncludeDirs));
+ cm::append(allIncludeDirs, cmList{ systemIncludeDirs });
}
systemIncludeDirs = makefile->GetSafeDefinition(
"CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS");
if (!systemIncludeDirs.empty()) {
- cm::append(allIncludeDirs, cmExpandedList(systemIncludeDirs));
+ cm::append(allIncludeDirs, cmList{ systemIncludeDirs });
}
auto end = cmRemoveDuplicates(allIncludeDirs);
diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx
index 6201889f22..c7ce5b0676 100644
--- a/Source/cmExtraEclipseCDT4Generator.cxx
+++ b/Source/cmExtraEclipseCDT4Generator.cxx
@@ -16,6 +16,7 @@
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -418,7 +419,7 @@ void cmExtraEclipseCDT4Generator::CreateProjectFile()
if (cmValue extraNaturesProp =
mf->GetState()->GetGlobalProperty("ECLIPSE_EXTRA_NATURES")) {
- std::vector<std::string> extraNatures = cmExpandedList(*extraNaturesProp);
+ cmList extraNatures{ *extraNaturesProp };
for (std::string const& n : extraNatures) {
xml.Element("nature", n);
}
@@ -798,7 +799,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
mf->GetDefinition("CMAKE_EXTRA_GENERATOR_C_SYSTEM_DEFINED_MACROS");
if (this->CEnabled && cDefs) {
// Expand the list.
- std::vector<std::string> defs = cmExpandedList(*cDefs, true);
+ cmList defs{ *cDefs, cmList::EmptyElements::Yes };
// the list must contain only definition-value pairs:
if ((defs.size() % 2) == 0) {
@@ -830,7 +831,7 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
mf->GetDefinition("CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_DEFINED_MACROS");
if (this->CXXEnabled && cxxDefs) {
// Expand the list.
- std::vector<std::string> defs = cmExpandedList(*cxxDefs, true);
+ cmList defs{ *cxxDefs, cmList::EmptyElements::Yes };
// the list must contain only definition-value pairs:
if ((defs.size() % 2) == 0) {
@@ -879,14 +880,14 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const
if (this->CEnabled && !compiler.empty()) {
std::string systemIncludeDirs =
mf->GetSafeDefinition("CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS");
- std::vector<std::string> dirs = cmExpandedList(systemIncludeDirs);
+ cmList dirs{ systemIncludeDirs };
this->AppendIncludeDirectories(xml, dirs, emitted);
}
compiler = mf->GetSafeDefinition("CMAKE_CXX_COMPILER");
if (this->CXXEnabled && !compiler.empty()) {
std::string systemIncludeDirs =
mf->GetSafeDefinition("CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS");
- std::vector<std::string> dirs = cmExpandedList(systemIncludeDirs);
+ cmList dirs{ systemIncludeDirs };
this->AppendIncludeDirectories(xml, dirs, emitted);
}
diff --git a/Source/cmExtraSublimeTextGenerator.cxx b/Source/cmExtraSublimeTextGenerator.cxx
index 33901ac594..205a691f21 100644
--- a/Source/cmExtraSublimeTextGenerator.cxx
+++ b/Source/cmExtraSublimeTextGenerator.cxx
@@ -14,6 +14,7 @@
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -138,7 +139,7 @@ void cmExtraSublimeTextGenerator::CreateNewProjectFile(
// End of build_systems
fout << "\n\t]";
std::string systemName = mf->GetSafeDefinition("CMAKE_SYSTEM_NAME");
- std::vector<std::string> tokens = cmExpandedList(this->EnvSettings);
+ cmList tokens{ this->EnvSettings };
if (!this->EnvSettings.empty()) {
fout << ",";
diff --git a/Source/cmFileAPIToolchains.cxx b/Source/cmFileAPIToolchains.cxx
index fe2972fabf..a51ae2048e 100644
--- a/Source/cmFileAPIToolchains.cxx
+++ b/Source/cmFileAPIToolchains.cxx
@@ -10,6 +10,7 @@
#include "cmFileAPI.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
@@ -124,10 +125,11 @@ void Toolchains::DumpToolchainVariable(cmMakefile const* mf,
cmStrCat("CMAKE_", lang, "_", variable.VariableSuffix);
if (variable.IsList) {
- std::vector<std::string> values;
- if (mf->GetDefExpandList(variableName, values)) {
+ cmValue data = mf->GetDefinition(variableName);
+ if (data) {
+ cmList values(data);
Json::Value jsonArray = Json::arrayValue;
- for (std::string const& value : values) {
+ for (auto const& value : values) {
jsonArray.append(value);
}
object[variable.ObjectKey] = jsonArray;
diff --git a/Source/cmFileCopier.cxx b/Source/cmFileCopier.cxx
index ef55abfd14..663bddcece 100644
--- a/Source/cmFileCopier.cxx
+++ b/Source/cmFileCopier.cxx
@@ -9,6 +9,7 @@
#include "cmExecutionStatus.h"
#include "cmFSPermissions.h"
#include "cmFileTimes.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -169,8 +170,7 @@ bool cmFileCopier::GetDefaultDirectoryPermissions(mode_t** mode)
cmValue default_dir_install_permissions = this->Makefile->GetDefinition(
"CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS");
if (cmNonempty(default_dir_install_permissions)) {
- std::vector<std::string> items =
- cmExpandedList(*default_dir_install_permissions);
+ cmList items{ *default_dir_install_permissions };
for (const auto& arg : items) {
if (!this->CheckPermissions(arg, **mode)) {
this->Status.SetError(
diff --git a/Source/cmFileSet.cxx b/Source/cmFileSet.cxx
index b96ba6e886..48a2570d56 100644
--- a/Source/cmFileSet.cxx
+++ b/Source/cmFileSet.cxx
@@ -12,6 +12,7 @@
#include "cmsys/RegularExpression.hxx"
#include "cmGeneratorExpression.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
@@ -113,7 +114,7 @@ cmFileSet::CompileFileEntries() const
std::vector<std::unique_ptr<cmCompiledGeneratorExpression>> result;
for (auto const& entry : this->FileEntries) {
- for (auto const& ex : cmExpandedList(entry.Value)) {
+ for (auto const& ex : cmList{ entry.Value }) {
cmGeneratorExpression ge(this->CMakeInstance, entry.Backtrace);
auto cge = ge.Parse(ex);
result.push_back(std::move(cge));
@@ -129,7 +130,7 @@ cmFileSet::CompileDirectoryEntries() const
std::vector<std::unique_ptr<cmCompiledGeneratorExpression>> result;
for (auto const& entry : this->DirectoryEntries) {
- for (auto const& ex : cmExpandedList(entry.Value)) {
+ for (auto const& ex : cmList{ entry.Value }) {
cmGeneratorExpression ge(this->CMakeInstance, entry.Backtrace);
auto cge = ge.Parse(ex);
result.push_back(std::move(cge));
@@ -148,7 +149,7 @@ std::vector<std::string> cmFileSet::EvaluateDirectoryEntries(
std::vector<std::string> result;
for (auto const& cge : cges) {
auto entry = cge->Evaluate(lg, config, target, dagChecker);
- auto dirs = cmExpandedList(entry);
+ cmList dirs{ entry };
for (std::string dir : dirs) {
if (!cmSystemTools::FileIsFullPath(dir)) {
dir = cmStrCat(lg->GetCurrentSourceDirectory(), '/', dir);
@@ -184,7 +185,7 @@ void cmFileSet::EvaluateFileEntry(
cmGeneratorExpressionDAGChecker* dagChecker) const
{
auto files = cge->Evaluate(lg, config, target, dagChecker);
- for (std::string file : cmExpandedList(files)) {
+ for (std::string file : cmList{ files }) {
if (!cmSystemTools::FileIsFullPath(file)) {
file = cmStrCat(lg->GetCurrentSourceDirectory(), '/', file);
}
diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx
index 4df81d5773..929c6c1c82 100644
--- a/Source/cmFindBase.cxx
+++ b/Source/cmFindBase.cxx
@@ -15,6 +15,7 @@
#include "cmCMakePath.h"
#include "cmExecutionStatus.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -154,7 +155,7 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
}
// ensure a macro is not specified as validator
const auto& validatorName = args[j];
- auto macros = cmExpandedList(this->Makefile->GetProperty("MACROS"));
+ cmList macros{ this->Makefile->GetProperty("MACROS") };
if (std::find_if(macros.begin(), macros.end(),
[&validatorName](const std::string& item) {
return cmSystemTools::Strucmp(validatorName.c_str(),
@@ -403,7 +404,7 @@ void cmFindBase::FillCMakeSystemVariablePath()
this->Makefile->GetDefinition("CMAKE_SYSTEM_PREFIX_PATH");
// remove entries from CMAKE_SYSTEM_PREFIX_PATH
- std::vector<std::string> expanded = cmExpandedList(*prefix_paths);
+ cmList expanded{ *prefix_paths };
install_entry.remove_self(expanded);
staging_entry.remove_self(expanded);
diff --git a/Source/cmFindCommon.cxx b/Source/cmFindCommon.cxx
index c3fb9077da..bec6369211 100644
--- a/Source/cmFindCommon.cxx
+++ b/Source/cmFindCommon.cxx
@@ -9,6 +9,7 @@
#include <cmext/algorithm>
#include "cmExecutionStatus.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
@@ -238,9 +239,9 @@ void cmFindCommon::RerootPaths(std::vector<std::string>& paths)
}
// Construct the list of path roots with no trailing slashes.
- std::vector<std::string> roots;
+ cmList roots;
if (rootPath) {
- cmExpandList(*rootPath, roots);
+ roots.assign(*rootPath);
}
if (sysrootCompile) {
roots.emplace_back(*sysrootCompile);
@@ -251,14 +252,14 @@ void cmFindCommon::RerootPaths(std::vector<std::string>& paths)
if (sysroot) {
roots.emplace_back(*sysroot);
}
- for (std::string& r : roots) {
+ for (auto& r : roots) {
cmSystemTools::ConvertToUnixSlashes(r);
}
cmValue stagePrefix = this->Makefile->GetDefinition("CMAKE_STAGING_PREFIX");
// Copy the original set of unrooted paths.
- std::vector<std::string> unrootedPaths = paths;
+ auto unrootedPaths = paths;
paths.clear();
auto isSameDirectoryOrSubDirectory = [](std::string const& l,
@@ -267,8 +268,8 @@ void cmFindCommon::RerootPaths(std::vector<std::string>& paths)
cmSystemTools::IsSubDirectory(l, r);
};
- for (std::string const& r : roots) {
- for (std::string const& up : unrootedPaths) {
+ for (auto const& r : roots) {
+ for (auto const& up : unrootedPaths) {
// Place the unrooted path under the current root if it is not
// already inside. Skip the unrooted path if it is relative to
// a user home directory or is empty.
@@ -308,7 +309,7 @@ void cmFindCommon::GetIgnoredPaths(std::vector<std::string>& ignore)
// Construct the list of path roots with no trailing slashes.
for (const char* pathName : paths) {
// Get the list of paths to ignore from the variable.
- this->Makefile->GetDefExpandList(pathName, ignore);
+ cmList::append(ignore, this->Makefile->GetDefinition(pathName));
}
for (std::string& i : ignore) {
@@ -333,7 +334,7 @@ void cmFindCommon::GetIgnoredPrefixPaths(std::vector<std::string>& ignore)
// Construct the list of path roots with no trailing slashes.
for (const char* pathName : paths) {
// Get the list of paths to ignore from the variable.
- this->Makefile->GetDefExpandList(pathName, ignore);
+ cmList::append(ignore, this->Makefile->GetDefinition(pathName));
}
for (std::string& i : ignore) {
diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx
index 6296a60aeb..9eb060357a 100644
--- a/Source/cmFindLibraryCommand.cxx
+++ b/Source/cmFindLibraryCommand.cxx
@@ -11,6 +11,7 @@
#include "cmsys/RegularExpression.hxx"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmStateTypes.h"
@@ -196,8 +197,8 @@ struct cmFindLibraryHelper
cmGlobalGenerator* GG;
// List of valid prefixes and suffixes.
- std::vector<std::string> Prefixes;
- std::vector<std::string> Suffixes;
+ cmList Prefixes;
+ cmList Suffixes;
std::string PrefixRegexStr;
std::string SuffixRegexStr;
@@ -223,7 +224,7 @@ struct cmFindLibraryHelper
std::string TestPath;
void RegexFromLiteral(std::string& out, std::string const& in);
- void RegexFromList(std::string& out, std::vector<std::string> const& in);
+ void RegexFromList(std::string& out, cmList const& in);
size_type GetPrefixIndex(std::string const& prefix)
{
return std::find(this->Prefixes.begin(), this->Prefixes.end(), prefix) -
@@ -307,8 +308,8 @@ cmFindLibraryHelper::cmFindLibraryHelper(std::string debugName, cmMakefile* mf,
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->Prefixes.assign(prefixes_list, cmList::EmptyElements::Yes);
+ this->Suffixes.assign(suffixes_list, cmList::EmptyElements::Yes);
this->RegexFromList(this->PrefixRegexStr, this->Prefixes);
this->RegexFromList(this->SuffixRegexStr, this->Suffixes);
@@ -334,14 +335,13 @@ void cmFindLibraryHelper::RegexFromLiteral(std::string& out,
}
}
-void cmFindLibraryHelper::RegexFromList(std::string& out,
- std::vector<std::string> const& in)
+void cmFindLibraryHelper::RegexFromList(std::string& out, cmList const& in)
{
// Surround the list in parens so the '|' does not apply to anything
// else and the result can be checked after matching.
out += "(";
const char* sep = "";
- for (std::string const& s : in) {
+ for (auto const& s : in) {
// Separate from previous item.
out += sep;
sep = "|";
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index b1029e62c8..98b085cdc0 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -23,6 +23,7 @@
#include "cmAlgorithms.h"
#include "cmDependencyProvider.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -1781,28 +1782,20 @@ bool cmFindPackageCommand::ReadListFile(const std::string& f,
void cmFindPackageCommand::AppendToFoundProperty(const bool found)
{
- std::vector<std::string> foundContents;
+ cmList foundContents;
cmValue foundProp =
this->Makefile->GetState()->GetGlobalProperty("PACKAGES_FOUND");
- if (cmNonempty(foundProp)) {
- cmExpandList(*foundProp, foundContents, false);
- auto nameIt =
- std::find(foundContents.begin(), foundContents.end(), this->Name);
- if (nameIt != foundContents.end()) {
- foundContents.erase(nameIt);
- }
+ if (!foundProp.IsEmpty()) {
+ foundContents.assign(*foundProp);
+ foundContents.remove_items({ this->Name });
}
- std::vector<std::string> notFoundContents;
+ cmList notFoundContents;
cmValue notFoundProp =
this->Makefile->GetState()->GetGlobalProperty("PACKAGES_NOT_FOUND");
- if (cmNonempty(notFoundProp)) {
- cmExpandList(*notFoundProp, notFoundContents, false);
- auto nameIt =
- std::find(notFoundContents.begin(), notFoundContents.end(), this->Name);
- if (nameIt != notFoundContents.end()) {
- notFoundContents.erase(nameIt);
- }
+ if (!notFoundProp.IsEmpty()) {
+ notFoundContents.assign(*notFoundProp);
+ notFoundContents.remove_items({ this->Name });
}
if (found) {
@@ -1811,12 +1804,11 @@ void cmFindPackageCommand::AppendToFoundProperty(const bool found)
notFoundContents.push_back(this->Name);
}
- std::string tmp = cmJoin(foundContents, ";");
- this->Makefile->GetState()->SetGlobalProperty("PACKAGES_FOUND", tmp.c_str());
+ this->Makefile->GetState()->SetGlobalProperty(
+ "PACKAGES_FOUND", foundContents.to_string().c_str());
- tmp = cmJoin(notFoundContents, ";");
- this->Makefile->GetState()->SetGlobalProperty("PACKAGES_NOT_FOUND",
- tmp.c_str());
+ this->Makefile->GetState()->SetGlobalProperty(
+ "PACKAGES_NOT_FOUND", notFoundContents.to_string().c_str());
}
void cmFindPackageCommand::AppendSuccessInformation()
@@ -2338,7 +2330,7 @@ void cmFindPackageCommand::FillPrefixesCMakeSystemVariable()
cmValue prefix_paths =
this->Makefile->GetDefinition("CMAKE_SYSTEM_PREFIX_PATH");
// remove entry from CMAKE_SYSTEM_PREFIX_PATH
- std::vector<std::string> expanded = cmExpandedList(*prefix_paths);
+ cmList expanded{ *prefix_paths };
long count = 0;
for (const auto& path : expanded) {
bool const to_add =
diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx
index 3465c230f8..21a140d02c 100644
--- a/Source/cmForEachCommand.cxx
+++ b/Source/cmForEachCommand.cxx
@@ -23,6 +23,7 @@
#include "cmExecutionStatus.h"
#include "cmFunctionBlocker.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -156,16 +157,16 @@ bool cmForEachFunctionBlocker::ReplayZipLists(
auto& mf = inStatus.GetMakefile();
// Expand the list of list-variables into a list of lists of strings
- std::vector<std::vector<std::string>> values;
+ std::vector<cmList> values;
values.reserve(this->Args.size() - this->IterationVarsCount);
// Also track the longest list size
std::size_t maxItems = 0u;
for (auto const& var :
cmMakeRange(this->Args).advance(this->IterationVarsCount)) {
- std::vector<std::string> items;
+ cmList items;
auto const& value = mf.GetSafeDefinition(var);
if (!value.empty()) {
- cmExpandList(value, items, true);
+ items.assign(value, cmList::EmptyElements::Yes);
}
maxItems = std::max(maxItems, items.size());
values.emplace_back(std::move(items));
@@ -344,7 +345,7 @@ bool HandleInMode(std::vector<std::string> const& args,
} else if (doing == DoingLists) {
auto const& value = makefile.GetSafeDefinition(arg);
if (!value.empty()) {
- cmExpandList(value, fb->Args, true);
+ cmExpandList(value, fb->Args, cmList::EmptyElements::Yes);
}
} else if (doing == DoingItems || doing == DoingZipLists) {
diff --git a/Source/cmGccDepfileLexerHelper.cxx b/Source/cmGccDepfileLexerHelper.cxx
index 34c88248a0..87377de401 100644
--- a/Source/cmGccDepfileLexerHelper.cxx
+++ b/Source/cmGccDepfileLexerHelper.cxx
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGccDepfileLexerHelper.h"
+#include <algorithm>
#include <cstdio>
#include <memory>
#include <string>
@@ -113,6 +114,11 @@ void cmGccDepfileLexerHelper::addToCurrentPath(const char* s)
void cmGccDepfileLexerHelper::sanitizeContent()
{
for (auto it = this->Content.begin(); it != this->Content.end();) {
+ // remove duplicate path entries
+ std::sort(it->paths.begin(), it->paths.end());
+ auto last = std::unique(it->paths.begin(), it->paths.end());
+ it->paths.erase(last, it->paths.end());
+
// Remove empty paths and normalize windows paths
for (auto pit = it->paths.begin(); pit != it->paths.end();) {
if (pit->empty()) {
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index c5ae31bd38..04decd239c 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -14,6 +14,7 @@
#include "cmGeneratorExpressionEvaluator.h"
#include "cmGeneratorExpressionLexer.h"
#include "cmGeneratorExpressionParser.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index ca61f75ffa..bb4fc7e271 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -19,7 +19,6 @@
#include <cm/iterator>
#include <cm/optional>
#include <cm/string_view>
-#include <cm/vector>
#include <cmext/algorithm>
#include <cmext/string_view>
@@ -635,22 +634,48 @@ public:
using Arguments = Range<std::vector<std::string>>;
-bool CheckPathParametersEx(cmGeneratorExpressionContext* ctx,
- const GeneratorExpressionContent* cnt,
- cm::string_view option, std::size_t count,
- int required = 1, bool exactly = true)
+bool CheckGenExParameters(cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ cm::string_view genex, cm::string_view option,
+ std::size_t count, int required = 1,
+ bool exactly = true)
{
if (static_cast<int>(count) < required ||
(exactly && static_cast<int>(count) > required)) {
+ std::string nbParameters;
+ switch (required) {
+ case 1:
+ nbParameters = "one parameter";
+ break;
+ case 2:
+ nbParameters = "two parameters";
+ break;
+ case 3:
+ nbParameters = "three parameters";
+ break;
+ case 4:
+ nbParameters = "four parameters";
+ break;
+ default:
+ nbParameters = cmStrCat(std::to_string(required), " parameters");
+ }
reportError(ctx, cnt->GetOriginalExpression(),
- cmStrCat("$<PATH:", option, "> expression requires ",
- (exactly ? "exactly" : "at least"), ' ',
- (required == 1 ? "one parameter" : "two parameters"),
+ cmStrCat("$<", genex, ':', option, "> expression requires ",
+ (exactly ? "exactly" : "at least"), ' ', nbParameters,
'.'));
return false;
}
return true;
};
+
+bool CheckPathParametersEx(cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ cm::string_view option, std::size_t count,
+ int required = 1, bool exactly = true)
+{
+ return CheckGenExParameters(ctx, cnt, "PATH"_s, option, count, required,
+ exactly);
+}
bool CheckPathParameters(cmGeneratorExpressionContext* ctx,
const GeneratorExpressionContent* cnt,
cm::string_view option, const Arguments& args,
@@ -658,6 +683,7 @@ bool CheckPathParameters(cmGeneratorExpressionContext* ctx,
{
return CheckPathParametersEx(ctx, cnt, option, args.size(), required);
};
+
std::string ToString(bool isTrue)
{
return isTrue ? "1" : "0";
@@ -681,9 +707,9 @@ static const struct PathNode : public cmGeneratorExpressionNode
static auto processList =
[](std::string const& arg,
std::function<void(std::string&)> transform) -> std::string {
- auto list = cmExpandedList(arg);
+ cmList list{ arg };
std::for_each(list.begin(), list.end(), std::move(transform));
- return cmJoin(list, ";");
+ return list.to_string();
};
static std::unordered_map<
@@ -1108,6 +1134,675 @@ static const struct PathEqualNode : public cmGeneratorExpressionNode
}
} pathEqualNode;
+namespace {
+inline bool CheckListParametersEx(cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ cm::string_view option, std::size_t count,
+ int required = 1, bool exactly = true)
+{
+ return CheckGenExParameters(ctx, cnt, "LIST"_s, option, count, required,
+ exactly);
+}
+inline bool CheckListParameters(cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ cm::string_view option, const Arguments& args,
+ int required = 1)
+{
+ return CheckListParametersEx(ctx, cnt, option, args.size(), required);
+};
+
+inline cmList GetList(std::string const& list)
+{
+ return list.empty() ? cmList{} : cmList{ list, cmList::EmptyElements::Yes };
+}
+
+bool GetNumericArgument(const std::string& arg, cmList::index_type& value)
+{
+ try {
+ std::size_t pos;
+
+ if (sizeof(cmList::index_type) == sizeof(long)) {
+ value = std::stol(arg, &pos);
+ } else {
+ value = std::stoll(arg, &pos);
+ }
+
+ if (pos != arg.length()) {
+ // this is not a number
+ return false;
+ }
+ } catch (const std::invalid_argument&) {
+ return false;
+ }
+
+ return true;
+}
+
+bool GetNumericArguments(
+ cmGeneratorExpressionContext* ctx, const GeneratorExpressionContent* cnt,
+ Arguments const& args, std::vector<cmList::index_type>& indexes,
+ cmList::ExpandElements expandElements = cmList::ExpandElements::No)
+{
+ using IndexRange = cmRange<Arguments::const_iterator>;
+ IndexRange arguments(args.begin(), args.end());
+ cmList list;
+ if (expandElements == cmList::ExpandElements::Yes) {
+ list = cmList{ args.begin(), args.end(), expandElements };
+ arguments = IndexRange{ list.begin(), list.end() };
+ }
+
+ for (auto const& value : arguments) {
+ cmList::index_type index;
+ if (!GetNumericArgument(value, index)) {
+ reportError(ctx, cnt->GetOriginalExpression(),
+ cmStrCat("index: \"", value, "\" is not a valid index"));
+ return false;
+ }
+ indexes.push_back(index);
+ }
+ return true;
+}
+}
+
+static const struct ListNode : public cmGeneratorExpressionNode
+{
+ ListNode() {} // NOLINT(modernize-use-equals-default)
+
+ int NumExpectedParameters() const override { return TwoOrMoreParameters; }
+
+ bool AcceptsArbitraryContentParameter() const override { return true; }
+
+ std::string Evaluate(
+ const std::vector<std::string>& parameters,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content,
+ cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
+ {
+ static std::unordered_map<
+ cm::string_view,
+ std::function<std::string(cmGeneratorExpressionContext*,
+ const GeneratorExpressionContent*,
+ Arguments&)>>
+ listCommands{
+ { "LENGTH"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParameters(ctx, cnt, "LENGTH"_s, args)) {
+ return std::to_string(GetList(args.front()).size());
+ }
+ return std::string{};
+ } },
+ { "GET"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParametersEx(ctx, cnt, "GET"_s, args.size(), 2,
+ false)) {
+ auto list = GetList(args.front());
+ if (list.empty()) {
+ reportError(ctx, cnt->GetOriginalExpression(),
+ "given empty list");
+ return std::string{};
+ }
+
+ std::vector<cmList::index_type> indexes;
+ if (!GetNumericArguments(ctx, cnt, args.advance(1), indexes,
+ cmList::ExpandElements::Yes)) {
+ return std::string{};
+ }
+ try {
+ return list.get_items(indexes.begin(), indexes.end())
+ .to_string();
+ } catch (std::out_of_range& e) {
+ reportError(ctx, cnt->GetOriginalExpression(), e.what());
+ return std::string{};
+ }
+ }
+ return std::string{};
+ } },
+ { "JOIN"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParameters(ctx, cnt, "JOIN"_s, args, 2)) {
+ return GetList(args.front()).join(args[1]);
+ }
+ return std::string{};
+ } },
+ { "SUBLIST"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParameters(ctx, cnt, "SUBLIST"_s, args, 3)) {
+ auto list = GetList(args.front());
+ if (!list.empty()) {
+ std::vector<cmList::index_type> indexes;
+ if (!GetNumericArguments(ctx, cnt, args.advance(1), indexes)) {
+ return std::string{};
+ }
+ if (indexes[0] < 0) {
+ reportError(ctx, cnt->GetOriginalExpression(),
+ cmStrCat("begin index: ", indexes[0],
+ " is out of range 0 - ",
+ list.size() - 1));
+ return std::string{};
+ }
+ if (indexes[1] < -1) {
+ reportError(ctx, cnt->GetOriginalExpression(),
+ cmStrCat("length: ", indexes[1],
+ " should be -1 or greater"));
+ return std::string{};
+ }
+ try {
+ return list
+ .sublist(static_cast<cmList::size_type>(indexes[0]),
+ static_cast<cmList::size_type>(indexes[1]))
+ .to_string();
+ } catch (std::out_of_range& e) {
+ reportError(ctx, cnt->GetOriginalExpression(), e.what());
+ return std::string{};
+ }
+ }
+ }
+ return std::string{};
+ } },
+ { "FIND"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParameters(ctx, cnt, "FIND"_s, args, 2)) {
+ auto list = GetList(args.front());
+ auto index = list.find(args[1]);
+ return index == cmList::npos ? "-1" : std::to_string(index);
+ }
+ return std::string{};
+ } },
+ { "APPEND"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParametersEx(ctx, cnt, "APPEND"_s, args.size(), 2,
+ false)) {
+ auto list = args.front();
+ args.advance(1);
+ return cmList::append(list, args.begin(), args.end());
+ }
+ return std::string{};
+ } },
+ { "PREPEND"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParametersEx(ctx, cnt, "PREPEND"_s, args.size(), 2,
+ false)) {
+ auto list = args.front();
+ args.advance(1);
+ return cmList::prepend(list, args.begin(), args.end());
+ }
+ return std::string{};
+ } },
+ { "INSERT"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParametersEx(ctx, cnt, "INSERT"_s, args.size(), 3,
+ false)) {
+ cmList::index_type index;
+ if (!GetNumericArgument(args[1], index)) {
+ reportError(
+ ctx, cnt->GetOriginalExpression(),
+ cmStrCat("index: \"", args[1], "\" is not a valid index"));
+ return std::string{};
+ }
+ try {
+ auto list = GetList(args.front());
+ args.advance(2);
+ list.insert_items(index, args.begin(), args.end());
+ return list.to_string();
+ } catch (std::out_of_range& e) {
+ reportError(ctx, cnt->GetOriginalExpression(), e.what());
+ return std::string{};
+ }
+ }
+ return std::string{};
+ } },
+ { "POP_BACK"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParameters(ctx, cnt, "POP_BACK"_s, args)) {
+ auto list = GetList(args.front());
+ if (!list.empty()) {
+ list.pop_back();
+ return list.to_string();
+ }
+ }
+ return std::string{};
+ } },
+ { "POP_FRONT"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParameters(ctx, cnt, "POP_FRONT"_s, args)) {
+ auto list = GetList(args.front());
+ if (!list.empty()) {
+ list.pop_front();
+ return list.to_string();
+ }
+ }
+ return std::string{};
+ } },
+ { "REMOVE_DUPLICATES"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParameters(ctx, cnt, "REMOVE_DUPLICATES"_s, args)) {
+ return GetList(args.front()).remove_duplicates().to_string();
+ }
+ return std::string{};
+ } },
+ { "REMOVE_ITEM"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParametersEx(ctx, cnt, "REMOVE_ITEM"_s, args.size(),
+ 2, false)) {
+ auto list = GetList(args.front());
+ args.advance(1);
+ cmList items{ args.begin(), args.end(),
+ cmList::ExpandElements::Yes };
+ return list.remove_items(items.begin(), items.end()).to_string();
+ }
+ return std::string{};
+ } },
+ { "REMOVE_AT"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParametersEx(ctx, cnt, "REMOVE_AT"_s, args.size(), 2,
+ false)) {
+ auto list = GetList(args.front());
+ std::vector<cmList::index_type> indexes;
+ if (!GetNumericArguments(ctx, cnt, args.advance(1), indexes,
+ cmList::ExpandElements::Yes)) {
+ return std::string{};
+ }
+ try {
+ return list.remove_items(indexes.begin(), indexes.end())
+ .to_string();
+ } catch (std::out_of_range& e) {
+ reportError(ctx, cnt->GetOriginalExpression(), e.what());
+ return std::string{};
+ }
+ }
+ return std::string{};
+ } },
+ { "FILTER"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParameters(ctx, cnt, "FILTER"_s, args, 3)) {
+ auto const& op = args[1];
+ if (op != "INCLUDE"_s && op != "EXCLUDE"_s) {
+ reportError(
+ ctx, cnt->GetOriginalExpression(),
+ cmStrCat("sub-command FILTER does not recognize operator \"",
+ op, "\". It must be either INCLUDE or EXCLUDE."));
+ return std::string{};
+ }
+ try {
+ return GetList(args.front())
+ .filter(args[2],
+ op == "INCLUDE"_s ? cmList::FilterMode::INCLUDE
+ : cmList::FilterMode::EXCLUDE)
+ .to_string();
+ } catch (std::invalid_argument&) {
+ reportError(
+ ctx, cnt->GetOriginalExpression(),
+ cmStrCat("sub-command FILTER, failed to compile regex \"",
+ args[2], "\"."));
+ return std::string{};
+ }
+ }
+ return std::string{};
+ } },
+ { "TRANSFORM"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParametersEx(ctx, cnt, "TRANSFORM"_s, args.size(), 2,
+ false)) {
+ auto list = GetList(args.front());
+ if (!list.empty()) {
+ struct ActionDescriptor
+ {
+ ActionDescriptor(std::string name)
+ : Name(std::move(name))
+ {
+ }
+ ActionDescriptor(std::string name,
+ cmList::TransformAction action, int arity)
+ : Name(std::move(name))
+ , Action(action)
+ , Arity(arity)
+ {
+ }
+
+ operator const std::string&() const { return this->Name; }
+
+ std::string Name;
+ cmList::TransformAction Action;
+ int Arity = 0;
+ };
+
+ static std::set<
+ ActionDescriptor,
+ std::function<bool(const std::string&, const std::string&)>>
+ descriptors{
+ { { "APPEND", cmList::TransformAction::APPEND, 1 },
+ { "PREPEND", cmList::TransformAction::PREPEND, 1 },
+ { "TOUPPER", cmList::TransformAction::TOUPPER, 0 },
+ { "TOLOWER", cmList::TransformAction::TOLOWER, 0 },
+ { "STRIP", cmList::TransformAction::STRIP, 0 },
+ { "REPLACE", cmList::TransformAction::REPLACE, 2 } },
+ [](const std::string& x, const std::string& y) {
+ return x < y;
+ }
+ };
+
+ auto descriptor = descriptors.find(args.advance(1).front());
+ if (descriptor == descriptors.end()) {
+ reportError(ctx, cnt->GetOriginalExpression(),
+ cmStrCat(" sub-command TRANSFORM, ",
+ args.front(), " invalid action."));
+ return std::string{};
+ }
+
+ // Action arguments
+ args.advance(1);
+ if (args.size() < descriptor->Arity) {
+ reportError(ctx, cnt->GetOriginalExpression(),
+ cmStrCat("sub-command TRANSFORM, action ",
+ descriptor->Name, " expects ",
+ descriptor->Arity, " argument(s)."));
+ return std::string{};
+ }
+ std::vector<std::string> arguments;
+ if (descriptor->Arity > 0) {
+ arguments = std::vector<std::string>(
+ args.begin(), args.begin() + descriptor->Arity);
+ args.advance(descriptor->Arity);
+ }
+
+ const std::string REGEX{ "REGEX" };
+ const std::string AT{ "AT" };
+ const std::string FOR{ "FOR" };
+ std::unique_ptr<cmList::TransformSelector> selector;
+
+ try {
+ // handle optional arguments
+ while (!args.empty()) {
+ if ((args.front() == REGEX || args.front() == AT ||
+ args.front() == FOR) &&
+ selector) {
+ reportError(ctx, cnt->GetOriginalExpression(),
+ cmStrCat("sub-command TRANSFORM, selector "
+ "already specified (",
+ selector->GetTag(), ")."));
+
+ return std::string{};
+ }
+
+ // REGEX selector
+ if (args.front() == REGEX) {
+ if (args.advance(1).empty()) {
+ reportError(
+ ctx, cnt->GetOriginalExpression(),
+ "sub-command TRANSFORM, selector REGEX expects "
+ "'regular expression' argument.");
+ return std::string{};
+ }
+
+ selector = cmList::TransformSelector::New<
+ cmList::TransformSelector::REGEX>(args.front());
+
+ args.advance(1);
+ continue;
+ }
+
+ // AT selector
+ if (args.front() == AT) {
+ args.advance(1);
+ // get all specified indexes
+ std::vector<cmList::index_type> indexes;
+ while (!args.empty()) {
+ cmList indexList{ args.front() };
+ for (auto const& index : indexList) {
+ cmList::index_type value;
+
+ if (!GetNumericArgument(index, value)) {
+ // this is not a number, stop processing
+ reportError(
+ ctx, cnt->GetOriginalExpression(),
+ cmStrCat("sub-command TRANSFORM, selector AT: '",
+ index, "': unexpected argument."));
+ return std::string{};
+ }
+ indexes.push_back(value);
+ }
+ args.advance(1);
+ }
+
+ if (indexes.empty()) {
+ reportError(ctx, cnt->GetOriginalExpression(),
+ "sub-command TRANSFORM, selector AT "
+ "expects at least one "
+ "numeric value.");
+ return std::string{};
+ }
+
+ selector = cmList::TransformSelector::New<
+ cmList::TransformSelector::AT>(std::move(indexes));
+
+ continue;
+ }
+
+ // FOR selector
+ if (args.front() == FOR) {
+ if (args.advance(1).size() < 2) {
+ reportError(ctx, cnt->GetOriginalExpression(),
+ "sub-command TRANSFORM, selector FOR "
+ "expects, at least,"
+ " two arguments.");
+ return std::string{};
+ }
+
+ cmList::index_type start = 0;
+ cmList::index_type stop = 0;
+ cmList::index_type step = 1;
+ bool valid = false;
+
+ if (GetNumericArgument(args.front(), start) &&
+ GetNumericArgument(args.advance(1).front(), stop)) {
+ valid = true;
+ }
+
+ if (!valid) {
+ reportError(
+ ctx, cnt->GetOriginalExpression(),
+ "sub-command TRANSFORM, selector FOR expects, "
+ "at least, two numeric values.");
+ return std::string{};
+ }
+ // try to read a third numeric value for step
+ if (!args.advance(1).empty()) {
+ if (!GetNumericArgument(args.front(), step)) {
+ // this is not a number
+ step = -1;
+ }
+ args.advance(1);
+ }
+
+ if (step <= 0) {
+ reportError(
+ ctx, cnt->GetOriginalExpression(),
+ "sub-command TRANSFORM, selector FOR expects "
+ "positive numeric value for <step>.");
+ return std::string{};
+ }
+
+ selector = cmList::TransformSelector::New<
+ cmList::TransformSelector::FOR>({ start, stop, step });
+ continue;
+ }
+
+ reportError(ctx, cnt->GetOriginalExpression(),
+ cmStrCat("sub-command TRANSFORM, '",
+ cmJoin(args, ", "),
+ "': unexpected argument(s)."));
+ return std::string{};
+ }
+
+ return list
+ .transform(descriptor->Action, arguments,
+ std::move(selector))
+ .to_string();
+ } catch (cmList::transform_error& e) {
+ reportError(ctx, cnt->GetOriginalExpression(), e.what());
+ return std::string{};
+ }
+ }
+ }
+ return std::string{};
+ } },
+ { "REVERSE"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParameters(ctx, cnt, "REVERSE"_s, args)) {
+ return GetList(args.front()).reverse().to_string();
+ }
+ return std::string{};
+ } },
+ { "SORT"_s,
+ [](cmGeneratorExpressionContext* ctx,
+ const GeneratorExpressionContent* cnt,
+ Arguments& args) -> std::string {
+ if (CheckListParametersEx(ctx, cnt, "SORT"_s, args.size(), 1,
+ false)) {
+ auto list = GetList(args.front());
+ args.advance(1);
+ const auto COMPARE = "COMPARE:"_s;
+ const auto CASE = "CASE:"_s;
+ const auto ORDER = "ORDER:"_s;
+ using SortConfig = cmList::SortConfiguration;
+ SortConfig sortConfig;
+ for (auto const& arg : args) {
+ if (cmHasPrefix(arg, COMPARE)) {
+ if (sortConfig.Compare !=
+ SortConfig::CompareMethod::DEFAULT) {
+ reportError(ctx, cnt->GetOriginalExpression(),
+ "sub-command SORT, COMPARE option has been "
+ "specified multiple times.");
+ return std::string{};
+ }
+ auto option =
+ cm::string_view{ arg.c_str() + COMPARE.length() };
+ if (option == "STRING"_s) {
+ sortConfig.Compare = SortConfig::CompareMethod::STRING;
+ continue;
+ }
+ if (option == "FILE_BASENAME"_s) {
+ sortConfig.Compare =
+ SortConfig::CompareMethod::FILE_BASENAME;
+ continue;
+ }
+ if (option == "NATURAL"_s) {
+ sortConfig.Compare = SortConfig::CompareMethod::NATURAL;
+ continue;
+ }
+ reportError(
+ ctx, cnt->GetOriginalExpression(),
+ cmStrCat(
+ "sub-command SORT, an invalid COMPARE option has been "
+ "specified: \"",
+ option, "\"."));
+ return std::string{};
+ }
+ if (cmHasPrefix(arg, CASE)) {
+ if (sortConfig.Case !=
+ SortConfig::CaseSensitivity::DEFAULT) {
+ reportError(ctx, cnt->GetOriginalExpression(),
+ "sub-command SORT, CASE option has been "
+ "specified multiple times.");
+ return std::string{};
+ }
+ auto option = cm::string_view{ arg.c_str() + CASE.length() };
+ if (option == "SENSITIVE"_s) {
+ sortConfig.Case = SortConfig::CaseSensitivity::SENSITIVE;
+ continue;
+ }
+ if (option == "INSENSITIVE"_s) {
+ sortConfig.Case = SortConfig::CaseSensitivity::INSENSITIVE;
+ continue;
+ }
+ reportError(
+ ctx, cnt->GetOriginalExpression(),
+ cmStrCat(
+ "sub-command SORT, an invalid CASE option has been "
+ "specified: \"",
+ option, "\"."));
+ return std::string{};
+ }
+ if (cmHasPrefix(arg, ORDER)) {
+ if (sortConfig.Order != SortConfig::OrderMode::DEFAULT) {
+ reportError(ctx, cnt->GetOriginalExpression(),
+ "sub-command SORT, ORDER option has been "
+ "specified multiple times.");
+ return std::string{};
+ }
+ auto option =
+ cm::string_view{ arg.c_str() + ORDER.length() };
+ if (option == "ASCENDING"_s) {
+ sortConfig.Order = SortConfig::OrderMode::ASCENDING;
+ continue;
+ }
+ if (option == "DESCENDING"_s) {
+ sortConfig.Order = SortConfig::OrderMode::DESCENDING;
+ continue;
+ }
+ reportError(
+ ctx, cnt->GetOriginalExpression(),
+ cmStrCat(
+ "sub-command SORT, an invalid ORDER option has been "
+ "specified: \"",
+ option, "\"."));
+ return std::string{};
+ }
+ reportError(ctx, cnt->GetOriginalExpression(),
+ cmStrCat("sub-command SORT, option \"", arg,
+ "\" is invalid."));
+ return std::string{};
+ }
+
+ return list.sort(sortConfig).to_string();
+ }
+ return std::string{};
+ } }
+ };
+
+ if (cm::contains(listCommands, parameters.front())) {
+ auto args = Arguments{ parameters }.advance(1);
+ return listCommands[parameters.front()](context, content, args);
+ }
+
+ reportError(context, content->GetOriginalExpression(),
+ cmStrCat(parameters.front(), ": invalid option."));
+ return std::string{};
+ }
+} listNode;
+
static const struct MakeCIdentifierNode : public cmGeneratorExpressionNode
{
MakeCIdentifierNode() {} // NOLINT(modernize-use-equals-default)
@@ -1472,11 +2167,11 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
// This imported target has an appropriate location
// for this (possibly mapped) config.
// Check if there is a proper config mapping for the tested config.
- std::vector<std::string> mappedConfigs;
+ cmList mappedConfigs;
std::string mapProp = cmStrCat(
"MAP_IMPORTED_CONFIG_", cmSystemTools::UpperCase(context->Config));
if (cmValue mapValue = context->CurrentTarget->GetProperty(mapProp)) {
- cmExpandList(cmSystemTools::UpperCase(*mapValue), mappedConfigs);
+ mappedConfigs.assign(cmSystemTools::UpperCase(*mapValue));
for (auto const& param : parameters) {
if (cm::contains(mappedConfigs, cmSystemTools::UpperCase(param))) {
@@ -1581,7 +2276,8 @@ static const struct CompileLanguageAndIdNode : public cmGeneratorExpressionNode
// reportError(context, content->GetOriginalExpression(), "");
reportError(
context, content->GetOriginalExpression(),
- "$<COMPILE_LANG_AND_ID:lang,id> may only be used with binary targets "
+ "$<COMPILE_LANG_AND_ID:lang,id> may only be used with binary "
+ "targets "
"to specify include directories, compile definitions, and compile "
"options. It may not be used with the add_custom_command, "
"add_custom_target, or file(GENERATE) commands.");
@@ -1726,7 +2422,8 @@ static const struct LinkLanguageAndIdNode : public cmGeneratorExpressionNode
reportError(
context, content->GetOriginalExpression(),
"$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets "
- "to specify link libraries, link directories, link options, and link "
+ "to specify link libraries, link directories, link options, and "
+ "link "
"depends.");
return std::string();
}
@@ -1785,8 +2482,7 @@ static const struct LinkLibraryNode : public cmGeneratorExpressionNode
return std::string();
}
- std::vector<std::string> list;
- cmExpandLists(parameters.begin(), parameters.end(), list);
+ cmList list{ parameters.begin(), parameters.end() };
if (list.empty()) {
reportError(
context, content->GetOriginalExpression(),
@@ -1871,8 +2567,7 @@ static const struct LinkGroupNode : public cmGeneratorExpressionNode
return std::string();
}
- std::vector<std::string> list;
- cmExpandLists(parameters.begin(), parameters.end(), list);
+ cmList list{ parameters.begin(), parameters.end() };
if (list.empty()) {
reportError(
context, content->GetOriginalExpression(),
@@ -1962,8 +2657,7 @@ static const struct DeviceLinkNode : public cmGeneratorExpressionNode
}
if (context->HeadTarget->IsDeviceLink()) {
- std::vector<std::string> list;
- cmExpandLists(parameters.begin(), parameters.end(), list);
+ cmList list{ parameters.begin(), parameters.end() };
const auto DL_BEGIN = "<DEVICE_LINK>"_s;
const auto DL_END = "</DEVICE_LINK>"_s;
cm::erase_if(list, [&](const std::string& item) {
@@ -2108,7 +2802,8 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
reportError(
context, content->GetOriginalExpression(),
"$<TARGET_PROPERTY:prop> may only be used with binary targets. "
- "It may not be used with add_custom_command or add_custom_target. "
+ "It may not be used with add_custom_command or add_custom_target. "
+ " "
" "
"Specify the target to read a property from using the "
"$<TARGET_PROPERTY:tgt,prop> signature instead.");
@@ -2373,14 +3068,14 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
}
}
- std::vector<std::string> objects;
+ cmList objects;
if (gt->IsImported()) {
cmValue loc = nullptr;
cmValue imp = nullptr;
std::string suffix;
if (gt->Target->GetMappedConfig(context->Config, loc, imp, suffix)) {
- cmExpandList(*loc, objects);
+ objects.assign(*loc);
}
context->HadContextSensitiveCondition = true;
} else {
@@ -2398,7 +3093,7 @@ static const struct TargetObjectsNode : public cmGeneratorExpressionNode
context->HadContextSensitiveCondition = true;
}
- for (std::string& o : objects) {
+ for (auto& o : objects) {
o = cmStrCat(obj_dir, o);
}
}
@@ -2518,7 +3213,7 @@ static const struct CompileFeaturesNode : public cmGeneratorExpressionNode
}
context->HadHeadSensitiveCondition = true;
- using LangMap = std::map<std::string, std::vector<std::string>>;
+ using LangMap = std::map<std::string, cmList>;
static LangMap availableFeatures;
LangMap testedFeatures;
@@ -2540,7 +3235,7 @@ static const struct CompileFeaturesNode : public cmGeneratorExpressionNode
reportError(context, content->GetOriginalExpression(), error);
return std::string();
}
- cmExpandList(featuresKnown, availableFeatures[lang]);
+ availableFeatures[lang].assign(featuresKnown);
}
}
@@ -3691,7 +4386,7 @@ static const struct ShellPathNode : public cmGeneratorExpressionNode
const GeneratorExpressionContent* content,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
{
- std::vector<std::string> listIn = cmExpandedList(parameters.front());
+ cmList listIn{ parameters.front() };
if (listIn.empty()) {
reportError(context, content->GetOriginalExpression(),
"\"\" is not an absolute path.");
@@ -3802,6 +4497,7 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
{ "IN_LIST", &inListNode },
{ "FILTER", &filterNode },
{ "REMOVE_DUPLICATES", &removeDuplicatesNode },
+ { "LIST", &listNode },
{ "LOWER_CASE", &lowerCaseNode },
{ "UPPER_CASE", &upperCaseNode },
{ "PATH", &pathNode },
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 7e5ef0a7cb..28ba60f4ed 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -36,6 +36,7 @@
#include "cmGeneratorExpressionDAGChecker.h"
#include "cmGeneratorExpressionNode.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -730,6 +731,29 @@ void cmGeneratorTarget::AddIncludeDirectory(const std::string& src,
BT<std::string>(src, this->Makefile->GetBacktrace()), true));
}
+void cmGeneratorTarget::AddSystemIncludeDirectory(std::string const& inc,
+ std::string const& lang)
+{
+ std::string config_upper;
+ auto const& configs =
+ this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
+
+ for (auto const& config : configs) {
+ std::string inc_with_config = inc;
+ if (!config.empty()) {
+ cmSystemTools::ReplaceString(inc_with_config, "$<CONFIG>", config);
+ config_upper = cmSystemTools::UpperCase(config);
+ }
+ auto const& key = cmStrCat(config_upper, "/", lang);
+ this->Target->AddSystemIncludeDirectories({ inc_with_config });
+ this->SystemIncludesCache[key].emplace_back(inc_with_config);
+
+ // SystemIncludesCache should be sorted so that binary search can be used
+ std::sort(this->SystemIncludesCache[key].begin(),
+ this->SystemIncludesCache[key].end());
+ }
+}
+
std::vector<cmSourceFile*> const* cmGeneratorTarget::GetSourceDepends(
cmSourceFile const* sf) const
{
@@ -746,14 +770,13 @@ void handleSystemIncludesDep(cmLocalGenerator* lg,
const std::string& config,
cmGeneratorTarget const* headTarget,
cmGeneratorExpressionDAGChecker* dagChecker,
- std::vector<std::string>& result,
- bool excludeImported, std::string const& language)
+ cmList& result, bool excludeImported,
+ std::string const& language)
{
if (cmValue dirs =
depTgt->GetProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES")) {
- cmExpandList(cmGeneratorExpression::Evaluate(*dirs, lg, config, headTarget,
- dagChecker, depTgt, language),
- result);
+ result.append(cmGeneratorExpression::Evaluate(
+ *dirs, lg, config, headTarget, dagChecker, depTgt, language));
}
if (!depTgt->GetPropertyAsBool("SYSTEM")) {
return;
@@ -768,9 +791,8 @@ void handleSystemIncludesDep(cmLocalGenerator* lg,
}
if (cmValue dirs = depTgt->GetProperty("INTERFACE_INCLUDE_DIRECTORIES")) {
- cmExpandList(cmGeneratorExpression::Evaluate(*dirs, lg, config, headTarget,
- dagChecker, depTgt, language),
- result);
+ result.append(cmGeneratorExpression::Evaluate(
+ *dirs, lg, config, headTarget, dagChecker, depTgt, language));
}
}
}
@@ -1264,12 +1286,11 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(
bool excludeImported = this->GetPropertyAsBool("NO_SYSTEM_FROM_IMPORTED");
- std::vector<std::string> result;
+ cmList result;
for (std::string const& it : this->Target->GetSystemIncludeDirectories()) {
- cmExpandList(cmGeneratorExpression::Evaluate(it, this->LocalGenerator,
- config, this, &dagChecker,
- nullptr, language),
- result);
+ result.append(cmGeneratorExpression::Evaluate(it, this->LocalGenerator,
+ config, this, &dagChecker,
+ nullptr, language));
}
std::vector<cmGeneratorTarget const*> const& deps =
@@ -1634,20 +1655,20 @@ void AddFileSetEntries(cmGeneratorTarget const* headTarget,
EvaluatedTargetPropertyEntries& entries)
{
for (auto const& entry : headTarget->Target->GetHeaderSetsEntries()) {
- for (auto const& name : cmExpandedList(entry.Value)) {
+ for (auto const& name : cmList{ entry.Value }) {
auto const* headerSet = headTarget->Target->GetFileSet(name);
addFileSetEntry(headTarget, config, dagChecker, headerSet, entries);
}
}
for (auto const& entry : headTarget->Target->GetCxxModuleSetsEntries()) {
- for (auto const& name : cmExpandedList(entry.Value)) {
+ for (auto const& name : cmList{ entry.Value }) {
auto const* cxxModuleSet = headTarget->Target->GetFileSet(name);
addFileSetEntry(headTarget, config, dagChecker, cxxModuleSet, entries);
}
}
for (auto const& entry :
headTarget->Target->GetCxxModuleHeaderSetsEntries()) {
- for (auto const& name : cmExpandedList(entry.Value)) {
+ for (auto const& name : cmList{ entry.Value }) {
auto const* cxxModuleHeaderSet = headTarget->Target->GetFileSet(name);
addFileSetEntry(headTarget, config, dagChecker, cxxModuleHeaderSet,
entries);
@@ -1740,8 +1761,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
cmBTStringRange sourceEntries = this->Target->GetSourceEntries();
for (auto const& entry : sourceEntries) {
- std::vector<std::string> items = cmExpandedList(entry.Value);
- for (std::string const& item : items) {
+ cmList items{ entry.Value };
+ for (auto const& item : items) {
if (cmHasLiteralPrefix(item, "$<TARGET_OBJECTS:") &&
item.back() == '>') {
continue;
@@ -1752,10 +1773,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
return files;
}
- std::vector<std::string> debugProperties;
- this->Makefile->GetDefExpandList("CMAKE_DEBUG_TARGET_PROPERTIES",
- debugProperties);
-
+ cmList debugProperties{ this->Makefile->GetDefinition(
+ "CMAKE_DEBUG_TARGET_PROPERTIES") };
bool debugSources =
!this->DebugSourcesDone && cm::contains(debugProperties, "SOURCES");
@@ -3105,8 +3124,8 @@ void cmTargetTraceDependencies::Trace()
// Queue dependencies added explicitly by the user.
if (cmValue additionalDeps = sf->GetProperty("OBJECT_DEPENDS")) {
- std::vector<std::string> objDeps = cmExpandedList(*additionalDeps);
- for (std::string& objDep : objDeps) {
+ cmList objDeps{ *additionalDeps };
+ for (auto& objDep : objDeps) {
if (cmSystemTools::FileIsFullPath(objDep)) {
objDep = cmSystemTools::CollapseFullPath(objDep);
}
@@ -3299,9 +3318,9 @@ std::string cmGeneratorTarget::GetCompilePDBDirectory(
std::vector<std::string> cmGeneratorTarget::GetAppleArchs(
std::string const& config, cm::optional<std::string> lang) const
{
- std::vector<std::string> archVec;
+ cmList archList;
if (!this->IsApple()) {
- return archVec;
+ return std::move(archList.data());
}
cmValue archs = nullptr;
if (!config.empty()) {
@@ -3313,17 +3332,18 @@ std::vector<std::string> cmGeneratorTarget::GetAppleArchs(
archs = this->GetProperty("OSX_ARCHITECTURES");
}
if (archs) {
- cmExpandList(*archs, archVec);
+ archList.assign(*archs);
}
- if (archVec.empty() &&
+ if (archList.empty() &&
// Fall back to a default architecture if no compiler target is set.
(!lang ||
this->Makefile
->GetDefinition(cmStrCat("CMAKE_", *lang, "_COMPILER_TARGET"))
.IsEmpty())) {
- this->Makefile->GetDefExpandList("_CMAKE_APPLE_ARCHS_DEFAULT", archVec);
+ archList.assign(
+ this->Makefile->GetDefinition("_CMAKE_APPLE_ARCHS_DEFAULT"));
}
- return archVec;
+ return std::move(archList.data());
}
void cmGeneratorTarget::AddExplicitLanguageFlags(std::string& flags,
@@ -3432,10 +3452,9 @@ void cmGeneratorTarget::AddCUDAArchitectureFlags(cmBuildStep compileOrLink,
std::vector<CudaArchitecture> architectures;
{
- std::vector<std::string> options;
- cmExpandList(property, options);
+ cmList options(property);
- for (std::string& option : options) {
+ for (auto& option : options) {
CudaArchitecture architecture;
// Architecture name is up to the first specifier.
@@ -3526,8 +3545,7 @@ void cmGeneratorTarget::AddISPCTargetFlags(std::string& flags) const
this->Makefile->GetSafeDefinition("CMAKE_ISPC_COMPILER_ID");
if (compiler == "Intel") {
- std::vector<std::string> targets;
- cmExpandList(property, targets);
+ cmList targets(property);
if (!targets.empty()) {
flags += cmStrCat(" --target=", cmWrap("", targets, "", ","));
}
@@ -3549,8 +3567,7 @@ void cmGeneratorTarget::AddHIPArchitectureFlags(std::string& flags) const
return;
}
- std::vector<std::string> options;
- cmExpandList(property, options);
+ cmList options(property);
for (std::string& option : options) {
flags += " --offload-arch=" + option;
@@ -3762,10 +3779,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
cmGeneratorExpressionDAGChecker dagChecker(this, "INCLUDE_DIRECTORIES",
nullptr, nullptr);
- std::vector<std::string> debugProperties;
- this->Makefile->GetDefExpandList("CMAKE_DEBUG_TARGET_PROPERTIES",
- debugProperties);
-
+ cmList debugProperties{ this->Makefile->GetDefinition(
+ "CMAKE_DEBUG_TARGET_PROPERTIES") };
bool debugIncludes = !this->DebugIncludesDone &&
cm::contains(debugProperties, "INCLUDE_DIRECTORIES");
@@ -4021,10 +4036,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileOptions(
cmGeneratorExpressionDAGChecker dagChecker(this, "COMPILE_OPTIONS", nullptr,
nullptr);
- std::vector<std::string> debugProperties;
- this->Makefile->GetDefExpandList("CMAKE_DEBUG_TARGET_PROPERTIES",
- debugProperties);
-
+ cmList debugProperties{ this->Makefile->GetDefinition(
+ "CMAKE_DEBUG_TARGET_PROPERTIES") };
bool debugOptions = !this->DebugCompileOptionsDone &&
cm::contains(debugProperties, "COMPILE_OPTIONS");
@@ -4064,10 +4077,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileFeatures(
cmGeneratorExpressionDAGChecker dagChecker(this, "COMPILE_FEATURES", nullptr,
nullptr);
- std::vector<std::string> debugProperties;
- this->Makefile->GetDefExpandList("CMAKE_DEBUG_TARGET_PROPERTIES",
- debugProperties);
-
+ cmList debugProperties{ this->Makefile->GetDefinition(
+ "CMAKE_DEBUG_TARGET_PROPERTIES") };
bool debugFeatures = !this->DebugCompileFeaturesDone &&
cm::contains(debugProperties, "COMPILE_FEATURES");
@@ -4116,10 +4127,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions(
cmGeneratorExpressionDAGChecker dagChecker(this, "COMPILE_DEFINITIONS",
nullptr, nullptr);
- std::vector<std::string> debugProperties;
- this->Makefile->GetDefExpandList("CMAKE_DEBUG_TARGET_PROPERTIES",
- debugProperties);
-
+ cmList debugProperties{ this->Makefile->GetDefinition(
+ "CMAKE_DEBUG_TARGET_PROPERTIES") };
bool debugDefines = !this->DebugCompileDefinitionsDone &&
cm::contains(debugProperties, "COMPILE_DEFINITIONS");
@@ -4182,10 +4191,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetPrecompileHeaders(
cmGeneratorExpressionDAGChecker dagChecker(this, "PRECOMPILE_HEADERS",
nullptr, nullptr);
- std::vector<std::string> debugProperties;
- this->Makefile->GetDefExpandList("CMAKE_DEBUG_TARGET_PROPERTIES",
- debugProperties);
-
+ cmList debugProperties{ this->Makefile->GetDefinition(
+ "CMAKE_DEBUG_TARGET_PROPERTIES") };
bool debugDefines = !this->DebugPrecompileHeadersDone &&
std::find(debugProperties.begin(), debugProperties.end(),
"PRECOMPILE_HEADERS") != debugProperties.end();
@@ -4579,10 +4586,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions(
cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_OPTIONS", nullptr,
nullptr);
- std::vector<std::string> debugProperties;
- this->Makefile->GetDefExpandList("CMAKE_DEBUG_TARGET_PROPERTIES",
- debugProperties);
-
+ cmList debugProperties{ this->Makefile->GetDefinition(
+ "CMAKE_DEBUG_TARGET_PROPERTIES") };
bool debugOptions = !this->DebugLinkOptionsDone &&
cm::contains(debugProperties, "LINK_OPTIONS");
@@ -4606,7 +4611,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions(
// wrap host link options
const std::string wrapper(this->Makefile->GetSafeDefinition(
"CMAKE_" + language + "_DEVICE_COMPILER_WRAPPER_FLAG"));
- std::vector<std::string> wrapperFlag = cmExpandedList(wrapper);
+ cmList wrapperFlag{ wrapper };
const std::string wrapperSep(this->Makefile->GetSafeDefinition(
"CMAKE_" + language + "_DEVICE_COMPILER_WRAPPER_FLAG_SEP"));
bool concatFlagAndArgs = true;
@@ -4665,7 +4670,7 @@ std::vector<BT<std::string>>& cmGeneratorTarget::ResolveLinkerWrapper(
"CMAKE_" + language +
(this->IsDeviceLink() ? "_DEVICE_LINKER_WRAPPER_FLAG"
: "_LINKER_WRAPPER_FLAG")));
- std::vector<std::string> wrapperFlag = cmExpandedList(wrapper);
+ cmList wrapperFlag{ wrapper };
const std::string wrapperSep(this->Makefile->GetSafeDefinition(
"CMAKE_" + language +
(this->IsDeviceLink() ? "_DEVICE_LINKER_WRAPPER_FLAG_SEP"
@@ -4863,10 +4868,8 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDirectories(
cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_DIRECTORIES", nullptr,
nullptr);
- std::vector<std::string> debugProperties;
- this->Makefile->GetDefExpandList("CMAKE_DEBUG_TARGET_PROPERTIES",
- debugProperties);
-
+ cmList debugProperties{ this->Makefile->GetDefinition(
+ "CMAKE_DEBUG_TARGET_PROPERTIES") };
bool debugDirectories = !this->DebugLinkDirectoriesDone &&
cm::contains(debugProperties, "LINK_DIRECTORIES");
@@ -4911,7 +4914,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDepends(
EvaluatedTargetPropertyEntries entries;
if (cmValue linkDepends = this->GetProperty("LINK_DEPENDS")) {
- std::vector<std::string> depends = cmExpandedList(*linkDepends);
+ cmList depends{ *linkDepends };
for (const auto& depend : depends) {
std::unique_ptr<TargetPropertyEntry> entry = CreateTargetPropertyEntry(
*this->LocalGenerator->GetCMakeInstance(), depend);
@@ -5590,8 +5593,8 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const
// Process public headers to mark the source files.
if (cmValue files = this->GetProperty("PUBLIC_HEADER")) {
- std::vector<std::string> relFiles = cmExpandedList(*files);
- for (std::string const& relFile : relFiles) {
+ cmList relFiles{ *files };
+ for (auto const& relFile : relFiles) {
if (cmSourceFile* sf = this->Makefile->GetSource(relFile)) {
SourceFileFlags& flags = this->SourceFlagsMap[sf];
flags.MacFolder = "Headers";
@@ -5603,8 +5606,8 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const
// Process private headers after public headers so that they take
// precedence if a file is listed in both.
if (cmValue files = this->GetProperty("PRIVATE_HEADER")) {
- std::vector<std::string> relFiles = cmExpandedList(*files);
- for (std::string const& relFile : relFiles) {
+ cmList relFiles{ *files };
+ for (auto const& relFile : relFiles) {
if (cmSourceFile* sf = this->Makefile->GetSource(relFile)) {
SourceFileFlags& flags = this->SourceFlagsMap[sf];
flags.MacFolder = "PrivateHeaders";
@@ -5615,8 +5618,8 @@ void cmGeneratorTarget::ConstructSourceFileFlags() const
// Mark sources listed as resources.
if (cmValue files = this->GetProperty("RESOURCE")) {
- std::vector<std::string> relFiles = cmExpandedList(*files);
- for (std::string const& relFile : relFiles) {
+ cmList relFiles{ *files };
+ for (auto const& relFile : relFiles) {
if (cmSourceFile* sf = this->Makefile->GetSource(relFile)) {
SourceFileFlags& flags = this->SourceFlagsMap[sf];
flags.MacFolder = "";
@@ -5643,8 +5646,7 @@ cmGeneratorTarget::GetCompatibleInterfaces(std::string const& config) const
for (cmGeneratorTarget const* li : deps) {
#define CM_READ_COMPATIBLE_INTERFACE(X, x) \
if (cmValue prop = li->GetProperty("COMPATIBLE_INTERFACE_" #X)) { \
- std::vector<std::string> props; \
- cmExpandList(*prop, props); \
+ cmList props(*prop); \
compat.Props##x.insert(props.begin(), props.end()); \
}
CM_READ_COMPATIBLE_INTERFACE(BOOL, Bool)
@@ -5757,7 +5759,7 @@ void checkPropertyConsistency(cmGeneratorTarget const* depender,
return;
}
- std::vector<std::string> props = cmExpandedList(*prop);
+ cmList props{ *prop };
std::string pdir =
cmStrCat(cmSystemTools::GetCMakeRoot(), "/Help/prop_tgt/");
@@ -6718,10 +6720,8 @@ void cmGeneratorTarget::ReportPropertyOrigin(
const std::string& p, const std::string& result, const std::string& report,
const std::string& compatibilityType) const
{
- std::vector<std::string> debugProperties;
- this->Target->GetMakefile()->GetDefExpandList(
- "CMAKE_DEBUG_TARGET_PROPERTIES", debugProperties);
-
+ cmList debugProperties{ this->Target->GetMakefile()->GetDefinition(
+ "CMAKE_DEBUG_TARGET_PROPERTIES") };
bool debugOrigin = !this->DebugCompatiblePropertiesDone[p] &&
cm::contains(debugProperties, p);
@@ -6800,10 +6800,10 @@ void cmGeneratorTarget::ExpandLinkItems(
entry.Backtrace);
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(entry.Value);
cge->SetEvaluateForBuildsystem(true);
- std::vector<std::string> libs = cmExpandedList(
- cge->Evaluate(this->LocalGenerator, config, headTarget, &dagChecker,
- this, headTarget->LinkerLanguage));
- for (std::string const& lib : libs) {
+ cmList libs{ cge->Evaluate(this->LocalGenerator, config, headTarget,
+ &dagChecker, this,
+ headTarget->LinkerLanguage) };
+ for (auto const& lib : libs) {
if (cm::optional<cmLinkItem> maybeItem = this->LookupLinkItem(
lib, cge->GetBacktrace(), &scope,
field == LinkInterfaceField::Libraries ? LookupSelf::No
@@ -7467,10 +7467,10 @@ std::vector<ValueType> computeImplicitLanguageTargets(
currentTarget->GetRuntimeLinkLibrary(lang, config);
if (cmValue runtimeLinkOptions = currentTarget->Makefile->GetDefinition(
"CMAKE_" + lang + "_RUNTIME_LIBRARIES_" + runtimeLibrary)) {
- std::vector<std::string> libsVec = cmExpandedList(*runtimeLinkOptions);
- result.reserve(libsVec.size());
+ cmList libsList{ *runtimeLinkOptions };
+ result.reserve(libsList.size());
- for (std::string const& i : libsVec) {
+ for (auto const& i : libsList) {
cmGeneratorTarget::TargetOrString resolved =
currentTarget->ResolveTargetReference(i, lg);
if (resolved.Target) {
@@ -7551,9 +7551,9 @@ const cmLinkInterface* cmGeneratorTarget::GetImportLinkInterface(
this->ExpandLinkItems(info->LibrariesProp, cmMakeRange(info->Libraries),
config, headTarget, interfaceFor,
LinkInterfaceField::Libraries, iface);
- std::vector<std::string> deps = cmExpandedList(info->SharedDeps);
+ cmList deps{ info->SharedDeps };
LookupLinkItemScope scope{ this->LocalGenerator };
- for (std::string const& dep : deps) {
+ for (auto const& dep : deps) {
if (cm::optional<cmLinkItem> maybeItem = this->LookupLinkItem(
dep, cmListFileBacktrace(), &scope, LookupSelf::No)) {
iface.SharedDeps.emplace_back(std::move(*maybeItem));
@@ -7874,8 +7874,8 @@ void cmGeneratorTarget::GetObjectLibrariesCMP0026(
// behavior of CMP0024 and CMP0026 only.
cmBTStringRange rng = this->Target->GetSourceEntries();
for (auto const& entry : rng) {
- std::vector<std::string> files = cmExpandedList(entry.Value);
- for (std::string const& li : files) {
+ cmList files{ entry.Value };
+ for (auto const& li : files) {
if (cmHasLiteralPrefix(li, "$<TARGET_OBJECTS:") && li.back() == '>') {
std::string objLibName = li.substr(17, li.size() - 18);
@@ -8223,7 +8223,6 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
cmBTStringRange entryRange = this->Target->GetLinkImplementationEntries();
// Collect libraries directly linked in this configuration.
for (auto const& entry : entryRange) {
- std::vector<std::string> llibs;
// Keep this logic in sync with ExpandLinkItems.
cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_LIBRARIES", nullptr,
nullptr);
@@ -8251,7 +8250,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
cge->Evaluate(this->LocalGenerator, config, head, &dagChecker, nullptr,
this->LinkerLanguage);
bool const checkCMP0027 = evaluated != entry.Value;
- cmExpandList(evaluated, llibs);
+ cmList llibs(evaluated);
if (cge->GetHadHeadSensitiveCondition()) {
impl.HadHeadSensitiveCondition = true;
}
@@ -8262,7 +8261,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
impl.HadLinkLanguageSensitiveCondition = true;
}
- for (std::string const& lib : llibs) {
+ for (auto const& lib : llibs) {
if (this->IsLinkLookupScope(lib, lg)) {
continue;
}
@@ -8430,16 +8429,16 @@ bool cmGeneratorTarget::HasPackageReferences() const
std::vector<std::string> cmGeneratorTarget::GetPackageReferences() const
{
- std::vector<std::string> packageReferences;
+ cmList packageReferences;
if (this->IsInBuildSystem()) {
if (cmValue vsPackageReferences =
this->GetProperty("VS_PACKAGE_REFERENCES")) {
- cmExpandList(*vsPackageReferences, packageReferences);
+ packageReferences.assign(*vsPackageReferences);
}
}
- return packageReferences;
+ return std::move(packageReferences.data());
}
std::string cmGeneratorTarget::GetPDBDirectory(const std::string& config) const
@@ -8544,6 +8543,30 @@ bool cmGeneratorTarget::IsLinkable() const
this->IsExecutableWithExports());
}
+bool cmGeneratorTarget::HasLinkDependencyFile(std::string const& config) const
+{
+ if (this->GetType() != cmStateEnums::EXECUTABLE &&
+ this->GetType() != cmStateEnums::SHARED_LIBRARY &&
+ this->GetType() != cmStateEnums::MODULE_LIBRARY) {
+ return false;
+ }
+
+ if (this->Target->GetProperty("LINK_DEPENDS_NO_SHARED").IsOn()) {
+ // Do not use the linker dependency file because it includes shared
+ // libraries as well
+ return false;
+ }
+
+ const std::string depsUseLinker{ "CMAKE_LINK_DEPENDS_USE_LINKER" };
+ auto linkLanguage = this->GetLinkerLanguage(config);
+ const std::string langDepsUseLinker{ cmStrCat("CMAKE_", linkLanguage,
+ "_LINK_DEPENDS_USE_LINKER") };
+
+ return (!this->Makefile->IsDefinitionSet(depsUseLinker) ||
+ this->Makefile->IsOn(depsUseLinker)) &&
+ this->Makefile->IsOn(langDepsUseLinker);
+}
+
bool cmGeneratorTarget::IsFrameworkOnApple() const
{
return this->Target->IsFrameworkOnApple();
@@ -8638,7 +8661,7 @@ bool cmGeneratorTarget::AddHeaderSetVerification()
const bool all = verifyValue.IsEmpty();
std::set<std::string> verifySet;
if (!all) {
- auto verifyList = cmExpandedList(verifyValue);
+ cmList verifyList{ verifyValue };
verifySet.insert(verifyList.begin(), verifyList.end());
}
@@ -8651,7 +8674,7 @@ bool cmGeneratorTarget::AddHeaderSetVerification()
std::set<cmFileSet*> fileSets;
for (auto const& entry : interfaceFileSetEntries) {
- for (auto const& name : cmExpandedList(entry.Value)) {
+ for (auto const& name : cmList{ entry.Value }) {
if (all || verifySet.count(name)) {
fileSets.insert(this->Target->GetFileSet(name));
verifySet.erase(name);
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 87227fd29c..78945c3fa9 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -805,6 +805,9 @@ public:
/** Return whether this target may be used to link another target. */
bool IsLinkable() const;
+ /** Return whether the link step generates a dependency file. */
+ bool HasLinkDependencyFile(std::string const& config) const;
+
/** Return whether this target is a shared library Framework on
Apple. */
bool IsFrameworkOnApple() const;
@@ -912,6 +915,8 @@ public:
std::vector<std::string> GetGeneratedISPCObjects(
std::string const& config) const;
+ void AddSystemIncludeDirectory(std::string const& inc,
+ std::string const& lang);
bool AddHeaderSetVerification();
std::string GenerateHeaderSetVerificationFile(
cmSourceFile& source, const std::string& dir,
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
index 8471dfe615..a1e0650d20 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -17,6 +17,7 @@
#include "cmGeneratorTarget.h"
#include "cmGlobalGhsMultiGenerator.h"
#include "cmLinkLineComputer.h" // IWYU pragma: keep
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmLocalGhsMultiGenerator.h"
#include "cmMakefile.h"
@@ -484,7 +485,7 @@ void cmGhsMultiTargetGenerator::WriteSourceProperty(
{
cmValue prop = sf->GetProperty(propName);
if (prop) {
- std::vector<std::string> list = cmExpandedList(*prop);
+ cmList list{ *prop };
for (const std::string& p : list) {
fout << " " << propFlag << p << '\n';
}
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 3563a1a17d..040f500519 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -42,6 +42,7 @@
#include "cmInstallGenerator.h"
#include "cmInstallRuntimeDependencySet.h"
#include "cmLinkLineComputer.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmMSVC60LinkLineComputer.h"
#include "cmMakefile.h"
@@ -238,10 +239,10 @@ void cmGlobalGenerator::ResolveLanguageCompiler(const std::string& lang,
this->GetCMakeInstance()->GetState()->GetInitializedCacheValue(langComp);
// Split compiler from arguments
- std::vector<std::string> cnameArgVec;
+ cmList cnameArgList;
if (cname && !cname->empty()) {
- cmExpandList(*cname, cnameArgVec);
- cname = cmValue(cnameArgVec.front());
+ cnameArgList.assign(*cname);
+ cname = cmValue(cnameArgList.front());
}
std::string changeVars;
@@ -670,7 +671,7 @@ void cmGlobalGenerator::EnableLanguage(
mf->GetState()->SetInTopLevelIncludes(true);
std::string includes =
mf->GetSafeDefinition("CMAKE_PROJECT_TOP_LEVEL_INCLUDES");
- std::vector<std::string> includesList = cmExpandedList(includes);
+ cmList includesList{ includes };
for (std::string const& setupFile : includesList) {
std::string absSetupFile = cmSystemTools::CollapseFullPath(
setupFile, mf->GetCurrentSourceDirectory());
@@ -1234,7 +1235,7 @@ void cmGlobalGenerator::SetLanguageEnabledMaps(const std::string& l,
std::string ignoreExtensionsVar =
std::string("CMAKE_") + std::string(l) + std::string("_IGNORE_EXTENSIONS");
std::string ignoreExts = mf->GetSafeDefinition(ignoreExtensionsVar);
- std::vector<std::string> extensionList = cmExpandedList(ignoreExts);
+ cmList extensionList{ ignoreExts };
for (std::string const& i : extensionList) {
this->IgnoreExtensions[i] = true;
}
@@ -1246,7 +1247,7 @@ void cmGlobalGenerator::FillExtensionToLanguageMap(const std::string& l,
std::string extensionsVar = std::string("CMAKE_") + std::string(l) +
std::string("_SOURCE_FILE_EXTENSIONS");
const std::string& exts = mf->GetSafeDefinition(extensionsVar);
- std::vector<std::string> extensionList = cmExpandedList(exts);
+ cmList extensionList{ exts };
for (std::string const& i : extensionList) {
this->ExtensionToLanguage[i] = l;
}
@@ -1887,10 +1888,9 @@ void cmGlobalGenerator::FinalizeTargetConfiguration()
"CMAKE_" + li + "_STANDARD_INCLUDE_DIRECTORIES";
std::string const& standardIncludesStr =
mf->GetSafeDefinition(standardIncludesVar);
- std::vector<std::string> standardIncludesVec =
- cmExpandedList(standardIncludesStr);
- standardIncludesSet.insert(standardIncludesVec.begin(),
- standardIncludesVec.end());
+ cmList standardIncludesList{ standardIncludesStr };
+ standardIncludesSet.insert(standardIncludesList.begin(),
+ standardIncludesList.end());
}
mf->AddSystemIncludeDirectories(standardIncludesSet);
}
@@ -1985,7 +1985,6 @@ void cmGlobalGenerator::CheckTargetProperties()
notFoundMap[varName] = text;
}
}
- std::vector<std::string> incs;
cmValue incDirProp = target.second.GetProperty("INCLUDE_DIRECTORIES");
if (!incDirProp) {
continue;
@@ -1994,7 +1993,7 @@ void cmGlobalGenerator::CheckTargetProperties()
std::string incDirs = cmGeneratorExpression::Preprocess(
*incDirProp, cmGeneratorExpression::StripAllGeneratorExpressions);
- cmExpandList(incDirs, incs);
+ cmList incs(incDirs);
for (std::string const& incDir : incs) {
if (incDir.size() > 9 && cmIsNOTFOUND(incDir)) {
@@ -2789,11 +2788,9 @@ void cmGlobalGenerator::AddGlobalTarget_Test(
cmCustomCommandLine singleLine;
singleLine.push_back(cmSystemTools::GetCTestCommand());
singleLine.push_back("--force-new-ctest-process");
- std::vector<std::string> args;
- if (mf->GetDefExpandList("CMAKE_CTEST_ARGUMENTS", args)) {
- for (auto const& arg : args) {
- singleLine.push_back(arg);
- }
+ cmList args(mf->GetDefinition("CMAKE_CTEST_ARGUMENTS"));
+ for (auto const& arg : args) {
+ singleLine.push_back(arg);
}
if (cmNonempty(cmakeCfgIntDir) && cmakeCfgIntDir[0] != '.') {
singleLine.push_back("-C");
@@ -3348,12 +3345,12 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target)
cmSystemTools::MakeDirectory(dir);
cmGeneratedFileStream fout(file);
- std::vector<std::string> labels;
+ cmList labels;
// List the target-wide labels. All sources in the target get
// these labels.
if (targetLabels) {
- cmExpandList(*targetLabels, labels);
+ labels.assign(*targetLabels);
if (!labels.empty()) {
fout << "# Target labels\n";
for (std::string const& l : labels) {
@@ -3364,27 +3361,27 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target)
}
// List directory labels
- std::vector<std::string> directoryLabelsList;
- std::vector<std::string> cmakeDirectoryLabelsList;
+ cmList directoryLabelsList;
+ cmList cmakeDirectoryLabelsList;
if (directoryLabels) {
- cmExpandList(*directoryLabels, directoryLabelsList);
+ directoryLabelsList.assign(*directoryLabels);
}
if (cmakeDirectoryLabels) {
- cmExpandList(*cmakeDirectoryLabels, cmakeDirectoryLabelsList);
+ cmakeDirectoryLabelsList.assign(*cmakeDirectoryLabels);
}
if (!directoryLabelsList.empty() || !cmakeDirectoryLabelsList.empty()) {
fout << "# Directory labels\n";
}
- for (std::string const& li : directoryLabelsList) {
+ for (auto const& li : directoryLabelsList) {
fout << " " << li << "\n";
lj_target_labels.append(li);
}
- for (std::string const& li : cmakeDirectoryLabelsList) {
+ for (auto const& li : cmakeDirectoryLabelsList) {
fout << " " << li << "\n";
lj_target_labels.append(li);
}
@@ -3405,10 +3402,9 @@ void cmGlobalGenerator::WriteSummary(cmGeneratorTarget* target)
fout << sfp << "\n";
lj_source["file"] = sfp;
if (cmValue svalue = sf->GetProperty("LABELS")) {
- labels.clear();
Json::Value& lj_source_labels = lj_source["labels"] = Json::arrayValue;
- cmExpandList(*svalue, labels);
- for (std::string const& label : labels) {
+ labels.assign(*svalue);
+ for (auto const& label : labels) {
fout << " " << label << "\n";
lj_source_labels.append(label);
}
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index dde364886e..79fe52c193 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -546,6 +546,8 @@ public:
return cm::nullopt;
}
+ virtual bool SupportsLinkerDependencyFile() const { return false; }
+
std::string GetSharedLibFlagsForLanguage(std::string const& lang) const;
/** Generate an <output>.rule file path for a given command output. */
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
index b1f2b4a393..578e805332 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -18,6 +18,7 @@
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGhsMultiGpj.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmLocalGhsMultiGenerator.h"
#include "cmMakefile.h"
@@ -531,7 +532,7 @@ void cmGlobalGhsMultiGenerator::WriteMacros(std::ostream& fout,
fout << "macro PROJ_NAME=" << root->GetProjectName() << '\n';
cmValue ghsGpjMacros = root->GetMakefile()->GetDefinition("GHS_GPJ_MACROS");
if (ghsGpjMacros) {
- std::vector<std::string> expandedList = cmExpandedList(*ghsGpjMacros);
+ cmList expandedList{ *ghsGpjMacros };
for (std::string const& arg : expandedList) {
fout << "macro " << arg << '\n';
}
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 0c28776a82..84c85e07e6 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -32,6 +32,7 @@
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmLinkLineComputer.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmLocalNinjaGenerator.h"
@@ -3031,19 +3032,17 @@ void cmGlobalNinjaMultiGenerator::GetQtAutoGenConfigs(
bool cmGlobalNinjaMultiGenerator::InspectConfigTypeVariables()
{
- std::vector<std::string> configsVec;
- cmExpandList(
- this->Makefiles.front()->GetSafeDefinition("CMAKE_CONFIGURATION_TYPES"),
- configsVec);
- if (configsVec.empty()) {
- configsVec.emplace_back();
+ cmList configsList{ this->Makefiles.front()->GetDefinition(
+ "CMAKE_CONFIGURATION_TYPES") };
+ if (configsList.empty()) {
+ configsList.emplace_back();
}
- std::set<std::string> configs(configsVec.cbegin(), configsVec.cend());
+ std::set<std::string> configs(configsList.cbegin(), configsList.cend());
this->DefaultFileConfig =
this->Makefiles.front()->GetSafeDefinition("CMAKE_DEFAULT_BUILD_TYPE");
if (this->DefaultFileConfig.empty()) {
- this->DefaultFileConfig = configsVec.front();
+ this->DefaultFileConfig = configsList.front();
}
if (!configs.count(this->DefaultFileConfig)) {
std::ostringstream msg;
@@ -3055,11 +3054,9 @@ bool cmGlobalNinjaMultiGenerator::InspectConfigTypeVariables()
return false;
}
- std::vector<std::string> crossConfigsVec;
- cmExpandList(
- this->Makefiles.front()->GetSafeDefinition("CMAKE_CROSS_CONFIGS"),
- crossConfigsVec);
- auto crossConfigs = ListSubsetWithAll(configs, configs, crossConfigsVec);
+ cmList crossConfigsList{ this->Makefiles.front()->GetSafeDefinition(
+ "CMAKE_CROSS_CONFIGS") };
+ auto crossConfigs = ListSubsetWithAll(configs, configs, crossConfigsList);
if (!crossConfigs) {
std::ostringstream msg;
msg << "CMAKE_CROSS_CONFIGS is not a subset of "
@@ -3086,12 +3083,11 @@ bool cmGlobalNinjaMultiGenerator::InspectConfigTypeVariables()
return false;
}
- std::vector<std::string> defaultConfigsVec;
- cmExpandList(defaultConfigsString, defaultConfigsVec);
+ cmList defaultConfigsList(defaultConfigsString);
if (!this->DefaultFileConfig.empty()) {
auto defaultConfigs =
ListSubsetWithAll(this->GetCrossConfigs(this->DefaultFileConfig),
- this->CrossConfigs, defaultConfigsVec);
+ this->CrossConfigs, defaultConfigsList);
if (!defaultConfigs) {
std::ostringstream msg;
msg << "CMAKE_DEFAULT_CONFIGS is not a subset of CMAKE_CROSS_CONFIGS";
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index bd541685c9..bfbe57f22b 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -236,6 +236,8 @@ public:
return cmDepfileFormat::GccDepfile;
}
+ bool SupportsLinkerDependencyFile() const override { return true; }
+
virtual cmGeneratedFileStream* GetImplFileStream(
const std::string& /*config*/) const
{
diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h
index 214ba2af51..760679a051 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.h
+++ b/Source/cmGlobalUnixMakefileGenerator3.h
@@ -99,6 +99,12 @@ public:
*/
bool SupportsCustomCommandDepfile() const override { return true; }
+ /**
+ * Utilized to determine if this generator
+ * supports linker dependency file.
+ */
+ bool SupportsLinkerDependencyFile() const override { return true; }
+
/** Get the documentation entry for this generator. */
static cmDocumentationEntry GetDocumentation();
diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx
index de139241ed..bcb26cc1cb 100644
--- a/Source/cmGlobalVisualStudio71Generator.cxx
+++ b/Source/cmGlobalVisualStudio71Generator.cxx
@@ -8,6 +8,7 @@
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmGlobalVisualStudioGenerator.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
@@ -205,12 +206,12 @@ void cmGlobalVisualStudio71Generator::WriteProjectConfigurations(
!platformMapping.empty() ? platformMapping : this->GetPlatformName();
std::string guid = this->GetGUID(name);
for (std::string const& i : configs) {
- std::vector<std::string> mapConfig;
+ cmList mapConfig;
const char* dstConfig = i.c_str();
if (target.GetProperty("EXTERNAL_MSPROJECT")) {
if (cmValue m = target.GetProperty("MAP_IMPORTED_CONFIG_" +
cmSystemTools::UpperCase(i))) {
- cmExpandList(*m, mapConfig);
+ mapConfig.assign(*m);
if (!mapConfig.empty()) {
dstConfig = mapConfig[0].c_str();
}
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index 5de3a55939..694698e559 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -17,6 +17,7 @@
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmLocalVisualStudio7Generator.h"
#include "cmMakefile.h"
@@ -580,7 +581,7 @@ void cmGlobalVisualStudio7Generator::WriteSLNGlobalSections(
}
fout << "\tGlobalSection(" << name << ") = " << sectionType << "\n";
cmValue p = root->GetMakefile()->GetProperty(it);
- std::vector<std::string> keyValuePairs = cmExpandedList(p ? *p : "");
+ cmList keyValuePairs{ *p };
for (std::string const& itPair : keyValuePairs) {
const std::string::size_type posEqual = itPair.find('=');
if (posEqual != std::string::npos) {
diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx
index 2aba46fe2c..819bb09b1a 100644
--- a/Source/cmGlobalVisualStudio8Generator.cxx
+++ b/Source/cmGlobalVisualStudio8Generator.cxx
@@ -20,6 +20,7 @@
#include "cmGlobalGenerator.h"
#include "cmGlobalVisualStudio7Generator.h"
#include "cmGlobalVisualStudioGenerator.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmLocalVisualStudio7Generator.h"
@@ -262,6 +263,33 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
cmTarget* tgt = lg.AddUtilityCommand(CMAKE_CHECK_BUILD_SYSTEM_TARGET, false,
std::move(cc));
+ // Collect the input files used to generate all targets in this
+ // project.
+ std::vector<std::string> listFiles;
+ for (const auto& gen : generators) {
+ cm::append(listFiles, gen->GetMakefile()->GetListFiles());
+ }
+ // Sort the list of input files and remove duplicates.
+ std::sort(listFiles.begin(), listFiles.end(), std::less<std::string>());
+ auto new_end = std::unique(listFiles.begin(), listFiles.end());
+ listFiles.erase(new_end, listFiles.end());
+
+ // Add all cmake input files which are used by the project
+ // so Visual Studio does not close them when reloading it.
+ for (const std::string& listFile : listFiles) {
+ if (listFile.find("/CMakeFiles/") != std::string::npos) {
+ continue;
+ }
+ if (!cmSystemTools::IsSubDirectory(listFile,
+ lg.GetMakefile()->GetHomeDirectory()) &&
+ !cmSystemTools::IsSubDirectory(
+ listFile, lg.GetMakefile()->GetHomeOutputDirectory())) {
+ continue;
+ }
+
+ tgt->AddSource(listFile);
+ }
+
auto ptr = cm::make_unique<cmGeneratorTarget>(tgt, &lg);
auto* gt = ptr.get();
lg.AddGeneratorTarget(std::move(ptr));
@@ -295,13 +323,6 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
// The custom rule runs cmake so set UTF-8 pipes.
bool stdPipesUTF8 = true;
- // Collect the input files used to generate all targets in this
- // project.
- std::vector<std::string> listFiles;
- for (const auto& gen : generators) {
- cm::append(listFiles, gen->GetMakefile()->GetListFiles());
- }
-
// Add a custom prebuild target to run the VerifyGlobs script.
cmake* cm = this->GetCMakeInstance();
if (cm->DoWriteGlobVerifyTarget()) {
@@ -325,11 +346,6 @@ bool cmGlobalVisualStudio8Generator::AddCheckTarget()
listFiles.push_back(cm->GetGlobVerifyStamp());
}
- // Sort the list of input files and remove duplicates.
- std::sort(listFiles.begin(), listFiles.end(), std::less<std::string>());
- auto new_end = std::unique(listFiles.begin(), listFiles.end());
- listFiles.erase(new_end, listFiles.end());
-
// Create a rule to re-run CMake.
std::string argS = cmStrCat("-S", lg.GetSourceDirectory());
std::string argB = cmStrCat("-B", lg.GetBinaryDirectory());
@@ -396,12 +412,12 @@ void cmGlobalVisualStudio8Generator::WriteProjectConfigurations(
{
std::string guid = this->GetGUID(name);
for (std::string const& i : configs) {
- std::vector<std::string> mapConfig;
+ cmList mapConfig;
const char* dstConfig = i.c_str();
if (target.GetProperty("EXTERNAL_MSPROJECT")) {
if (cmValue m = target.GetProperty("MAP_IMPORTED_CONFIG_" +
cmSystemTools::UpperCase(i))) {
- cmExpandList(*m, mapConfig);
+ mapConfig.assign(*m);
if (!mapConfig.empty()) {
dstConfig = mapConfig[0].c_str();
}
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 139635797f..60f46e5aca 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -30,6 +30,7 @@
#include "cmGeneratorTarget.h"
#include "cmGlobalGeneratorFactory.h"
#include "cmLinkItem.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmLocalXCodeGenerator.h"
@@ -1027,7 +1028,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
cmValue extraFileAttributes = sf->GetProperty("XCODE_FILE_ATTRIBUTES");
if (extraFileAttributes) {
// Expand the list of attributes.
- std::vector<std::string> attributes = cmExpandedList(*extraFileAttributes);
+ cmList attributes{ *extraFileAttributes };
// Store the attributes.
for (const auto& attribute : attributes) {
@@ -1171,7 +1172,7 @@ template <class T>
std::string GetTargetObjectDirArch(T const& target,
const std::string& defaultVal)
{
- auto archs = cmExpandedList(target.GetSafeProperty("OSX_ARCHITECTURES"));
+ cmList archs{ target.GetSafeProperty("OSX_ARCHITECTURES") };
if (archs.size() > 1) {
return "$(CURRENT_ARCH)";
} else if (archs.size() == 1) {
@@ -3127,8 +3128,8 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateUtilityTarget(
std::string cmGlobalXCodeGenerator::AddConfigurations(cmXCodeObject* target,
cmGeneratorTarget* gtgt)
{
- std::vector<std::string> const configVector = cmExpandedList(
- this->CurrentMakefile->GetRequiredDefinition("CMAKE_CONFIGURATION_TYPES"));
+ cmList const configList{ this->CurrentMakefile->GetRequiredDefinition(
+ "CMAKE_CONFIGURATION_TYPES") };
cmXCodeObject* configlist =
this->CreateObject(cmXCodeObject::XCConfigurationList);
cmXCodeObject* buildConfigurations =
@@ -3140,7 +3141,7 @@ std::string cmGlobalXCodeGenerator::AddConfigurations(cmXCodeObject* target,
configlist->SetComment(comment);
target->AddAttribute("buildConfigurationList",
this->CreateObjectReference(configlist));
- for (auto const& i : configVector) {
+ for (auto const& i : configList) {
cmXCodeObject* config =
this->CreateObject(cmXCodeObject::XCBuildConfiguration);
buildConfigurations->AddObject(config);
@@ -3153,12 +3154,12 @@ std::string cmGlobalXCodeGenerator::AddConfigurations(cmXCodeObject* target,
this->CreateTargetXCConfigSettings(gtgt, config, i);
}
- if (!configVector.empty()) {
+ if (!configList.empty()) {
configlist->AddAttribute("defaultConfigurationName",
- this->CreateString(configVector[0]));
+ this->CreateString(configList[0]));
configlist->AddAttribute("defaultConfigurationIsVisible",
this->CreateString("0"));
- return configVector[0];
+ return configList[0];
}
return "";
}
@@ -4029,7 +4030,7 @@ void cmGlobalXCodeGenerator::AddEmbeddedObjects(
this->CreateString("0"));
cmXCodeObject* buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST);
// Collect all embedded frameworks and dylibs and add them to build phase
- std::vector<std::string> relFiles = cmExpandedList(*files);
+ cmList relFiles{ *files };
for (std::string const& relFile : relFiles) {
cmXCodeObject* buildFile{ nullptr };
std::string filePath = relFile;
@@ -4599,13 +4600,12 @@ std::string cmGlobalXCodeGenerator::GetTargetTempDir(
void cmGlobalXCodeGenerator::ComputeArchitectures(cmMakefile* mf)
{
this->Architectures.clear();
- cmValue sysroot = mf->GetDefinition("CMAKE_OSX_SYSROOT");
- if (sysroot) {
- mf->GetDefExpandList("CMAKE_OSX_ARCHITECTURES", this->Architectures);
- }
+ cmList::append(this->Architectures,
+ mf->GetDefinition("CMAKE_OSX_ARCHITECTURES"));
if (this->Architectures.empty()) {
- mf->GetDefExpandList("_CMAKE_APPLE_ARCHS_DEFAULT", this->Architectures);
+ cmList::append(this->Architectures,
+ mf->GetDefinition("_CMAKE_APPLE_ARCHS_DEFAULT"));
}
if (this->Architectures.empty()) {
@@ -5008,7 +5008,7 @@ void cmGlobalXCodeGenerator::AppendDefines(BuildObjectListOrString& defs,
}
// Expand the list of definitions.
- std::vector<std::string> defines = cmExpandedList(defines_list);
+ cmList defines{ defines_list };
// Store the definitions in the string.
this->AppendDefines(defs, defines, dflag);
diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx
index 2bb438d7d4..a8a7abb087 100644
--- a/Source/cmGraphVizWriter.cxx
+++ b/Source/cmGraphVizWriter.cxx
@@ -15,6 +15,7 @@
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmLinkItem.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmState.h"
@@ -255,9 +256,8 @@ void cmGraphVizWriter::ReadSettings(
this->TargetsToIgnoreRegex.clear();
if (!ignoreTargetsRegexes.empty()) {
- std::vector<std::string> ignoreTargetsRegExVector =
- cmExpandedList(ignoreTargetsRegexes);
- for (std::string const& currentRegexString : ignoreTargetsRegExVector) {
+ cmList ignoreTargetsRegExList{ ignoreTargetsRegexes };
+ for (std::string const& currentRegexString : ignoreTargetsRegExList) {
cmsys::RegularExpression currentRegex;
if (!currentRegex.compile(currentRegexString)) {
std::cerr << "Could not compile bad regex \"" << currentRegexString
diff --git a/Source/cmIDEOptions.cxx b/Source/cmIDEOptions.cxx
index 9468d4abdb..f94faf88b8 100644
--- a/Source/cmIDEOptions.cxx
+++ b/Source/cmIDEOptions.cxx
@@ -12,6 +12,7 @@
#include "cmsys/String.h"
#include "cmIDEFlagTable.h"
+#include "cmList.h"
#include "cmStringAlgorithms.h"
cmIDEOptions::cmIDEOptions()
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index 40230d9fb6..7f5f15b3c9 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -39,6 +39,7 @@
#include "cmInstallRuntimeDependencySetGenerator.h"
#include "cmInstallScriptGenerator.h"
#include "cmInstallTargetGenerator.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
@@ -1079,7 +1080,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
if (createInstallGeneratorsForTargetFileSets && !namelinkOnly) {
cmValue files = target.GetProperty("PRIVATE_HEADER");
if (cmNonempty(files)) {
- std::vector<std::string> relFiles = cmExpandedList(*files);
+ cmList relFiles{ *files };
std::vector<std::string> absFiles;
if (!helper.MakeFilesFullPath("PRIVATE_HEADER", relFiles, absFiles)) {
return false;
@@ -1101,7 +1102,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
files = target.GetProperty("PUBLIC_HEADER");
if (cmNonempty(files)) {
- std::vector<std::string> relFiles = cmExpandedList(*files);
+ cmList relFiles{ *files };
std::vector<std::string> absFiles;
if (!helper.MakeFilesFullPath("PUBLIC_HEADER", relFiles, absFiles)) {
return false;
@@ -1123,7 +1124,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
files = target.GetProperty("RESOURCE");
if (cmNonempty(files)) {
- std::vector<std::string> relFiles = cmExpandedList(*files);
+ cmList relFiles{ *files };
std::vector<std::string> absFiles;
if (!helper.MakeFilesFullPath("RESOURCE", relFiles, absFiles)) {
return false;
@@ -1145,8 +1146,8 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
if (!namelinkOnly) {
for (std::size_t i = 0; i < fileSetArgs.size(); i++) {
if (auto* fileSet = target.GetFileSet(fileSetArgs[i].GetFileSet())) {
- auto interfaceFileSetEntries = cmExpandedList(target.GetSafeProperty(
- cmTarget::GetInterfaceFileSetsPropertyName(fileSet->GetType())));
+ cmList interfaceFileSetEntries{ target.GetSafeProperty(
+ cmTarget::GetInterfaceFileSetsPropertyName(fileSet->GetType())) };
if (std::find(interfaceFileSetEntries.begin(),
interfaceFileSetEntries.end(),
fileSetArgs[i].GetFileSet()) !=
diff --git a/Source/cmInstallDirectoryGenerator.cxx b/Source/cmInstallDirectoryGenerator.cxx
index d358763c71..6aa99102bd 100644
--- a/Source/cmInstallDirectoryGenerator.cxx
+++ b/Source/cmInstallDirectoryGenerator.cxx
@@ -6,6 +6,7 @@
#include "cmGeneratorExpression.h"
#include "cmInstallType.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
@@ -53,17 +54,16 @@ bool cmInstallDirectoryGenerator::Compute(cmLocalGenerator* lg)
std::vector<std::string> cmInstallDirectoryGenerator::GetDirectories(
std::string const& config) const
{
- std::vector<std::string> directories;
+ cmList directories;
if (this->ActionsPerConfig) {
for (std::string const& f : this->Directories) {
- cmExpandList(
- cmGeneratorExpression::Evaluate(f, this->LocalGenerator, config),
- directories);
+ directories.append(
+ cmGeneratorExpression::Evaluate(f, this->LocalGenerator, config));
}
} else {
directories = this->Directories;
}
- return directories;
+ return std::move(directories.data());
}
void cmInstallDirectoryGenerator::GenerateScriptActions(std::ostream& os,
diff --git a/Source/cmInstallFilesGenerator.cxx b/Source/cmInstallFilesGenerator.cxx
index 18a852b210..43dc656a75 100644
--- a/Source/cmInstallFilesGenerator.cxx
+++ b/Source/cmInstallFilesGenerator.cxx
@@ -6,8 +6,8 @@
#include "cmGeneratorExpression.h"
#include "cmInstallType.h"
+#include "cmList.h"
#include "cmListFileCache.h"
-#include "cmStringAlgorithms.h"
class cmLocalGenerator;
@@ -69,17 +69,15 @@ std::string cmInstallFilesGenerator::GetRename(std::string const& config) const
std::vector<std::string> cmInstallFilesGenerator::GetFiles(
std::string const& config) const
{
- std::vector<std::string> files;
if (this->ActionsPerConfig) {
+ cmList files;
for (std::string const& f : this->Files) {
- cmExpandList(
- cmGeneratorExpression::Evaluate(f, this->LocalGenerator, config),
- files);
+ files.append(
+ cmGeneratorExpression::Evaluate(f, this->LocalGenerator, config));
}
- } else {
- files = this->Files;
+ return std::move(files.data());
}
- return files;
+ return this->Files;
}
void cmInstallFilesGenerator::AddFilesInstallRule(
diff --git a/Source/cmInstalledFile.cxx b/Source/cmInstalledFile.cxx
index 5bf8320bbb..381c91bac1 100644
--- a/Source/cmInstalledFile.cxx
+++ b/Source/cmInstalledFile.cxx
@@ -5,9 +5,9 @@
#include <utility>
#include "cmGeneratorExpression.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
-#include "cmStringAlgorithms.h"
#include "cmValue.h"
cmInstalledFile::cmInstalledFile() = default;
@@ -97,12 +97,11 @@ bool cmInstalledFile::GetPropertyAsBool(const std::string& prop) const
return isSet && cmIsOn(value);
}
-void cmInstalledFile::GetPropertyAsList(const std::string& prop,
- std::vector<std::string>& list) const
+std::vector<std::string> cmInstalledFile::GetPropertyAsList(
+ const std::string& prop) const
{
std::string value;
this->GetProperty(prop, value);
- list.clear();
- cmExpandList(value, list);
+ return std::move(cmList(value).data());
}
diff --git a/Source/cmInstalledFile.h b/Source/cmInstalledFile.h
index 82474f5203..373c34938a 100644
--- a/Source/cmInstalledFile.h
+++ b/Source/cmInstalledFile.h
@@ -59,8 +59,7 @@ public:
bool GetPropertyAsBool(const std::string& prop) const;
- void GetPropertyAsList(const std::string& prop,
- std::vector<std::string>& list) const;
+ std::vector<std::string> GetPropertyAsList(const std::string& prop) const;
void SetName(cmMakefile* mf, const std::string& name);
diff --git a/Source/cmLDConfigLDConfigTool.cxx b/Source/cmLDConfigLDConfigTool.cxx
index cce6178dae..0752b3353d 100644
--- a/Source/cmLDConfigLDConfigTool.cxx
+++ b/Source/cmLDConfigLDConfigTool.cxx
@@ -9,9 +9,9 @@
#include "cmsys/RegularExpression.hxx"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmRuntimeDependencyArchive.h"
-#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmUVProcessChain.h"
@@ -34,7 +34,7 @@ bool cmLDConfigLDConfigTool::GetLDConfigPaths(std::vector<std::string>& paths)
}
}
- std::vector<std::string> ldConfigCommand = cmExpandedList(ldConfigPath);
+ cmList ldConfigCommand{ ldConfigPath };
ldConfigCommand.emplace_back("-v");
ldConfigCommand.emplace_back("-N"); // Don't rebuild the cache.
ldConfigCommand.emplace_back("-X"); // Don't update links.
diff --git a/Source/cmList.cxx b/Source/cmList.cxx
index bf5a65459a..022fcd2b4c 100644
--- a/Source/cmList.cxx
+++ b/Source/cmList.cxx
@@ -287,18 +287,20 @@ protected:
: TransformSelector(std::move(tag))
{
}
- TransformSelectorIndexes(std::string&& tag, std::vector<int> const& indexes)
+ TransformSelectorIndexes(std::string&& tag,
+ std::vector<index_type> const& indexes)
: TransformSelector(std::move(tag))
, Indexes(indexes)
{
}
- TransformSelectorIndexes(std::string&& tag, std::vector<int>&& indexes)
+ TransformSelectorIndexes(std::string&& tag,
+ std::vector<index_type>&& indexes)
: TransformSelector(std::move(tag))
, Indexes(indexes)
{
}
- int NormalizeIndex(index_type index, std::size_t count)
+ index_type NormalizeIndex(index_type index, std::size_t count)
{
if (index < 0) {
index = static_cast<index_type>(count) + index;
@@ -338,7 +340,7 @@ public:
class TransformSelectorFor : public TransformSelectorIndexes
{
public:
- TransformSelectorFor(int start, int stop, int step)
+ TransformSelectorFor(index_type start, index_type stop, index_type step)
: TransformSelectorIndexes("FOR")
, Start(start)
, Stop(stop)
@@ -369,7 +371,7 @@ public:
auto start = this->Start;
auto step = this->Step;
std::generate(this->Indexes.begin(), this->Indexes.end(),
- [&start, step]() -> int {
+ [&start, step]() -> index_type {
auto r = start;
start += step;
return r;
@@ -805,7 +807,7 @@ std::string cmList::join(cm::string_view glue) const
return cmJoin(this->Values, glue);
}
-std::string& cmList::append(cm::string_view value, std::string& list)
+std::string& cmList::append(std::string& list, cm::string_view value)
{
if (list.empty()) {
list = std::string(value);
@@ -816,7 +818,7 @@ std::string& cmList::append(cm::string_view value, std::string& list)
return list;
}
-std::string& cmList::prepend(cm::string_view value, std::string& list)
+std::string& cmList::prepend(std::string& list, cm::string_view value)
{
if (list.empty()) {
list = std::string(value);
@@ -835,18 +837,19 @@ cmList::size_type cmList::ComputeIndex(index_type pos, bool boundCheck) const
cmStrCat("index: ", pos, " out of range (0, 0)"));
}
+ auto index = pos;
if (!this->Values.empty()) {
auto length = this->Values.size();
- if (pos < 0) {
- pos = static_cast<index_type>(length) + pos;
+ if (index < 0) {
+ index = static_cast<index_type>(length) + index;
}
- if (pos < 0 || length <= static_cast<size_type>(pos)) {
+ if (index < 0 || length <= static_cast<size_type>(index)) {
throw std::out_of_range(cmStrCat("index: ", pos, " out of range (-",
this->Values.size(), ", ",
this->Values.size() - 1, ")"));
}
}
- return pos;
+ return index;
}
return pos < 0 ? this->Values.size() + pos : pos;
@@ -860,18 +863,19 @@ cmList::size_type cmList::ComputeInsertIndex(index_type pos,
cmStrCat("index: ", pos, " out of range (0, 0)"));
}
+ auto index = pos;
if (!this->Values.empty()) {
auto length = this->Values.size();
- if (pos < 0) {
- pos = static_cast<index_type>(length) + pos;
+ if (index < 0) {
+ index = static_cast<index_type>(length) + index;
}
- if (pos < 0 || length < static_cast<size_type>(pos)) {
+ if (index < 0 || length < static_cast<size_type>(index)) {
throw std::out_of_range(cmStrCat("index: ", pos, " out of range (-",
this->Values.size(), ", ",
this->Values.size(), ")"));
}
}
- return pos;
+ return index;
}
return pos < 0 ? this->Values.size() + pos : pos;
@@ -882,7 +886,7 @@ cmList cmList::GetItems(std::vector<index_type>&& indexes) const
cmList listItems;
for (auto index : indexes) {
- listItems.emplace_back(this->at(index));
+ listItems.emplace_back(this->get_item(index));
}
return listItems;
@@ -896,9 +900,10 @@ cmList& cmList::RemoveItems(std::vector<index_type>&& indexes)
// compute all indexes
std::vector<size_type> idx(indexes.size());
- std::transform(
- indexes.cbegin(), indexes.cend(), idx.begin(),
- [this](const index_type& index) { return this->ComputeIndex(index); });
+ std::transform(indexes.cbegin(), indexes.cend(), idx.begin(),
+ [this](const index_type& index) -> size_type {
+ return this->ComputeIndex(index);
+ });
std::sort(idx.begin(), idx.end(),
[](size_type l, size_type r) { return l > r; });
@@ -925,8 +930,8 @@ cmList& cmList::RemoveItems(std::vector<std::string>&& items)
}
cmList::container_type::iterator cmList::Insert(
- container_type::const_iterator pos, std::string&& value,
- container_type& container, ExpandElements expandElements,
+ container_type& container, container_type::const_iterator pos,
+ std::string&& value, ExpandElements expandElements,
EmptyElements emptyElements)
{
auto delta = std::distance(container.cbegin(), pos);
diff --git a/Source/cmList.h b/Source/cmList.h
index d994ad3890..d9ce9510c6 100644
--- a/Source/cmList.h
+++ b/Source/cmList.h
@@ -6,6 +6,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <algorithm>
+#include <cstdint>
#include <initializer_list>
#include <iterator>
#include <memory>
@@ -16,19 +17,25 @@
#include <vector>
#include <cm/string_view>
+#include <cm/type_traits>
+#include <cmext/iterator>
#include "cmValue.h"
/**
* CMake lists management
+ * A CMake list is a string where list elements are separated by the ';'
+ * character.
*
* For all operations, input arguments (single value like cm::string_view or
* multiple values specified through pair of iterators) are, by default,
* expanded. The expansion can be controlled by the cmList::ExpandElements
* option.
*
- * There is an exception to this rule. The following methods do not expand
- * their argument: cmList::push_back, cmList::emplace and cmList::emplace_back.
+ * There ate some exceptions to this rule:
+ * * When the input argument is a cmList instance, the value is not expanded.
+ * * The following methods do not expand their argument: cmList::push_back,
+ * cmList::emplace and cmList::emplace_back.
*/
class cmList
@@ -38,7 +45,7 @@ public:
using value_type = container_type::value_type;
using allocator_type = container_type::allocator_type;
- using index_type = int;
+ using index_type = std::intptr_t;
using size_type = container_type::size_type;
using difference_type = container_type::difference_type;
using reference = container_type::reference;
@@ -74,8 +81,18 @@ public:
this->assign(value, expandElements, emptyElements);
}
cmList(cm::string_view value, EmptyElements emptyElements)
+ : cmList(value, ExpandElements::Yes, emptyElements)
+ {
+ }
+ cmList(std::string const& value,
+ ExpandElements expandElements = ExpandElements::Yes,
+ EmptyElements emptyElements = EmptyElements::No)
+ {
+ this->assign(value, expandElements, emptyElements);
+ }
+ cmList(std::string const& value, EmptyElements emptyElements)
+ : cmList(value, ExpandElements::Yes, emptyElements)
{
- this->assign(value, ExpandElements::Yes, emptyElements);
}
cmList(cmValue list, ExpandElements expandElements = ExpandElements::Yes,
EmptyElements emptyElements = EmptyElements::No)
@@ -135,6 +152,11 @@ public:
this->assign(value);
return *this;
}
+ cmList& operator=(std::string const& value)
+ {
+ this->assign(value);
+ return *this;
+ }
cmList& operator=(cmValue value)
{
if (value) {
@@ -175,6 +197,17 @@ public:
{
this->assign(value, ExpandElements::Yes, emptyElements);
}
+ void assign(std::string const& value,
+ ExpandElements expandElements = ExpandElements::Yes,
+ EmptyElements emptyElements = EmptyElements::No)
+ {
+ this->clear();
+ this->append(value, expandElements, emptyElements);
+ }
+ void assign(std::string const& value, EmptyElements emptyElements)
+ {
+ this->assign(value, ExpandElements::Yes, emptyElements);
+ }
void assign(cmValue value,
ExpandElements expandElements = ExpandElements::Yes,
EmptyElements emptyElements = EmptyElements::No)
@@ -204,17 +237,17 @@ public:
this->assign(first, last, ExpandElements::Yes, emptyElements);
}
void assign(const cmList& init,
- ExpandElements expandElements = ExpandElements::Yes,
+ ExpandElements expandElements = ExpandElements::No,
EmptyElements emptyElements = EmptyElements::No)
{
this->assign(init.begin(), init.end(), expandElements, emptyElements);
}
void assign(const cmList& init, EmptyElements emptyElements)
{
- this->assign(init, ExpandElements::Yes, emptyElements);
+ this->assign(init, ExpandElements::No, emptyElements);
}
void assign(cmList&& init,
- ExpandElements expandElements = ExpandElements::Yes,
+ ExpandElements expandElements = ExpandElements::No,
EmptyElements emptyElements = EmptyElements::No)
{
this->assign(std::make_move_iterator(init.begin()),
@@ -224,7 +257,7 @@ public:
}
void assign(cmList&& init, EmptyElements emptyElements)
{
- this->assign(std::move(init), ExpandElements::Yes, emptyElements);
+ this->assign(std::move(init), ExpandElements::No, emptyElements);
}
void assign(const container_type& init,
ExpandElements expandElements = ExpandElements::Yes,
@@ -265,24 +298,21 @@ public:
operator container_type&&() && noexcept { return std::move(this->Values); }
// Element access
- reference at(index_type pos)
+ reference at(size_type pos) { return this->Values.at(pos); }
+ const_reference at(size_type pos) const { return this->Values.at(pos); }
+
+ reference operator[](size_type pos) { return this->Values[pos]; }
+ const_reference operator[](size_type pos) const { return this->Values[pos]; }
+
+ reference get_item(index_type pos)
{
return this->Values.at(this->ComputeIndex(pos));
}
- const_reference at(index_type pos) const
+ const_reference get_item(index_type pos) const
{
return this->Values.at(this->ComputeIndex(pos));
}
- reference operator[](index_type pos)
- {
- return this->Values[this->ComputeIndex(pos, false)];
- }
- const_reference operator[](index_type pos) const
- {
- return this->Values[this->ComputeIndex(pos, false)];
- }
-
reference front() { return this->Values.front(); }
const_reference front() const { return this->Values.front(); }
@@ -361,7 +391,7 @@ public:
ExpandElements expandElements = ExpandElements::Yes,
EmptyElements emptyElements = EmptyElements::No)
{
- return cmList::Insert(pos, std::string(value), this->Values,
+ return cmList::Insert(this->Values, pos, std::string(value),
expandElements, emptyElements);
}
iterator insert(const_iterator pos, cm::string_view value,
@@ -369,6 +399,18 @@ public:
{
return this->insert(pos, value, ExpandElements::Yes, emptyElements);
}
+ iterator insert(const_iterator pos, std::string const& value,
+ ExpandElements expandElements = ExpandElements::Yes,
+ EmptyElements emptyElements = EmptyElements::No)
+ {
+ return cmList::Insert(this->Values, pos, value, expandElements,
+ emptyElements);
+ }
+ iterator insert(const_iterator pos, std::string const& value,
+ EmptyElements emptyElements)
+ {
+ return this->insert(pos, value, ExpandElements::Yes, emptyElements);
+ }
iterator insert(const_iterator pos, cmValue value,
ExpandElements expandElements = ExpandElements::Yes,
EmptyElements emptyElements = EmptyElements::No)
@@ -390,7 +432,7 @@ public:
ExpandElements expandElements = ExpandElements::Yes,
EmptyElements emptyElements = EmptyElements::No)
{
- return cmList::Insert(pos, first, last, this->Values, expandElements,
+ return cmList::Insert(this->Values, pos, first, last, expandElements,
emptyElements);
}
template <typename InputIterator>
@@ -400,7 +442,7 @@ public:
return this->insert(pos, first, last, ExpandElements::Yes, emptyElements);
}
iterator insert(const_iterator pos, const cmList& values,
- ExpandElements expandElements = ExpandElements::Yes,
+ ExpandElements expandElements = ExpandElements::No,
EmptyElements emptyElements = EmptyElements::No)
{
return this->insert(pos, values.begin(), values.end(), expandElements,
@@ -409,10 +451,10 @@ public:
iterator insert(const_iterator pos, const cmList& values,
EmptyElements emptyElements)
{
- return this->insert(pos, values, ExpandElements::Yes, emptyElements);
+ return this->insert(pos, values, ExpandElements::No, emptyElements);
}
iterator insert(const_iterator pos, cmList&& values,
- ExpandElements expandElements = ExpandElements::Yes,
+ ExpandElements expandElements = ExpandElements::No,
EmptyElements emptyElements = EmptyElements::No)
{
auto result = this->insert(pos, std::make_move_iterator(values.begin()),
@@ -425,7 +467,7 @@ public:
iterator insert(const_iterator pos, cmList&& values,
EmptyElements emptyElements)
{
- return this->insert(pos, std::move(values), ExpandElements::Yes,
+ return this->insert(pos, std::move(values), ExpandElements::No,
emptyElements);
}
iterator insert(const_iterator pos, const container_type& values,
@@ -472,6 +514,16 @@ public:
{
return this->append(value, ExpandElements::Yes, emptyElements);
}
+ iterator append(std::string const& value,
+ ExpandElements expandElements = ExpandElements::Yes,
+ EmptyElements emptyElements = EmptyElements::No)
+ {
+ return this->insert(this->cend(), value, expandElements, emptyElements);
+ }
+ iterator append(std::string const& value, EmptyElements emptyElements)
+ {
+ return this->append(value, ExpandElements::Yes, emptyElements);
+ }
iterator append(cmValue value,
ExpandElements expandElements = ExpandElements::Yes,
EmptyElements emptyElements = EmptyElements::No)
@@ -501,7 +553,7 @@ public:
return this->append(first, last, ExpandElements::Yes, emptyElements);
}
iterator append(const cmList& values,
- ExpandElements expandElements = ExpandElements::Yes,
+ ExpandElements expandElements = ExpandElements::No,
EmptyElements emptyElements = EmptyElements::No)
{
return this->append(values.begin(), values.end(), expandElements,
@@ -509,10 +561,10 @@ public:
}
iterator append(const cmList& values, EmptyElements emptyElements)
{
- return this->append(values, ExpandElements::Yes, emptyElements);
+ return this->append(values, ExpandElements::No, emptyElements);
}
iterator append(cmList&& values,
- ExpandElements expandElements = ExpandElements::Yes,
+ ExpandElements expandElements = ExpandElements::No,
EmptyElements emptyElements = EmptyElements::No)
{
auto result = this->append(std::make_move_iterator(values.begin()),
@@ -524,7 +576,7 @@ public:
}
iterator append(cmList&& values, EmptyElements emptyElements)
{
- return this->append(std::move(values), ExpandElements::Yes, emptyElements);
+ return this->append(std::move(values), ExpandElements::No, emptyElements);
}
iterator append(const container_type& values,
ExpandElements expandElements = ExpandElements::Yes,
@@ -567,6 +619,16 @@ public:
{
return this->prepend(value, ExpandElements::Yes, emptyElements);
}
+ iterator prepend(std::string const& value,
+ ExpandElements expandElements = ExpandElements::Yes,
+ EmptyElements emptyElements = EmptyElements::No)
+ {
+ return this->insert(this->cbegin(), value, expandElements, emptyElements);
+ }
+ iterator prepend(std::string const& value, EmptyElements emptyElements)
+ {
+ return this->prepend(value, ExpandElements::Yes, emptyElements);
+ }
iterator prepend(cmValue value,
ExpandElements expandElements = ExpandElements::Yes,
EmptyElements emptyElements = EmptyElements::No)
@@ -596,7 +658,7 @@ public:
return this->prepend(first, last, ExpandElements::Yes, emptyElements);
}
iterator prepend(const cmList& values,
- ExpandElements expandElements = ExpandElements::Yes,
+ ExpandElements expandElements = ExpandElements::No,
EmptyElements emptyElements = EmptyElements::No)
{
return this->prepend(values.begin(), values.end(), expandElements,
@@ -604,10 +666,10 @@ public:
}
iterator prepend(const cmList& values, EmptyElements emptyElements)
{
- return this->prepend(values, ExpandElements::Yes, emptyElements);
+ return this->prepend(values, ExpandElements::No, emptyElements);
}
iterator prepend(cmList&& values,
- ExpandElements expandElements = ExpandElements::Yes,
+ ExpandElements expandElements = ExpandElements::No,
EmptyElements emptyElements = EmptyElements::No)
{
auto result = this->prepend(std::make_move_iterator(values.begin()),
@@ -619,8 +681,7 @@ public:
}
iterator prepend(cmList&& values, EmptyElements emptyElements)
{
- return this->prepend(std::move(values), ExpandElements::Yes,
- emptyElements);
+ return this->prepend(std::move(values), ExpandElements::No, emptyElements);
}
iterator prepend(const container_type& values,
ExpandElements expandElements = ExpandElements::Yes,
@@ -654,6 +715,7 @@ public:
return this->insert(this->cbegin(), ilist);
}
+ void push_back(std::string const& value) { this->Values.push_back(value); }
void push_back(cm::string_view value)
{
this->Values.push_back(std::string{ value });
@@ -733,6 +795,8 @@ public:
cmList& remove_duplicates();
+ void resize(size_type count) { this->Values.resize(count); }
+
enum class FilterMode
{
INCLUDE,
@@ -880,46 +944,61 @@ public:
// ==============
// these methods can be used to store CMake list expansion directly in a
// std::vector.
- static void assign(cm::string_view value,
- std::vector<std::string>& container,
+ static void assign(std::vector<std::string>& container,
+ cm::string_view value,
+ EmptyElements emptyElements = EmptyElements::No)
+ {
+ container.clear();
+ cmList::append(container, value, emptyElements);
+ }
+ static void assign(std::vector<std::string>& container,
+ std::string const& value,
EmptyElements emptyElements = EmptyElements::No)
{
container.clear();
- cmList::append(value, container, emptyElements);
+ cmList::append(container, value, emptyElements);
}
- static void assign(cmValue value, std::vector<std::string>& container,
+ static void assign(std::vector<std::string>& container, cmValue value,
EmptyElements emptyElements = EmptyElements::No)
{
if (value) {
- cmList::assign(*value, container, emptyElements);
+ cmList::assign(container, *value, emptyElements);
} else {
container.clear();
}
}
template <typename InputIterator>
- static void assign(InputIterator first, InputIterator last,
- std::vector<std::string>& container,
+ static void assign(std::vector<std::string>& container, InputIterator first,
+ InputIterator last,
EmptyElements emptyElements = EmptyElements::No)
{
container.clear();
- cmList::append(first, last, container, emptyElements);
+ cmList::append(container, first, last, emptyElements);
}
static std::vector<std::string>::iterator insert(
- std::vector<std::string>::const_iterator pos, cm::string_view value,
std::vector<std::string>& container,
+ std::vector<std::string>::const_iterator pos, cm::string_view value,
EmptyElements emptyElements = EmptyElements::No)
{
- return cmList::Insert(pos, std::string(value), container,
+ return cmList::Insert(container, pos, std::string(value),
ExpandElements::Yes, emptyElements);
}
static std::vector<std::string>::iterator insert(
- std::vector<std::string>::const_iterator pos, cmValue value,
std::vector<std::string>& container,
+ std::vector<std::string>::const_iterator pos, std::string const& value,
+ EmptyElements emptyElements = EmptyElements::No)
+ {
+ return cmList::Insert(container, pos, value, ExpandElements::Yes,
+ emptyElements);
+ }
+ static std::vector<std::string>::iterator insert(
+ std::vector<std::string>& container,
+ std::vector<std::string>::const_iterator pos, cmValue value,
EmptyElements emptyElements = EmptyElements::No)
{
if (value) {
- return cmList::insert(pos, *value, container, emptyElements);
+ return cmList::insert(container, pos, *value, emptyElements);
}
auto delta = std::distance(container.cbegin(), pos);
@@ -927,63 +1006,73 @@ public:
}
template <typename InputIterator>
static std::vector<std::string>::iterator insert(
+ std::vector<std::string>& container,
std::vector<std::string>::const_iterator pos, InputIterator first,
- InputIterator last, std::vector<std::string>& container,
- EmptyElements emptyElements = EmptyElements::No)
+ InputIterator last, EmptyElements emptyElements = EmptyElements::No)
{
- return cmList::Insert(pos, first, last, container, ExpandElements::Yes,
+ return cmList::Insert(container, pos, first, last, ExpandElements::Yes,
emptyElements);
}
static std::vector<std::string>::iterator append(
- cm::string_view value, std::vector<std::string>& container,
+ std::vector<std::string>& container, cm::string_view value,
EmptyElements emptyElements = EmptyElements::No)
{
- return cmList::insert(container.cend(), value, container, emptyElements);
+ return cmList::insert(container, container.cend(), value, emptyElements);
}
static std::vector<std::string>::iterator append(
- cmValue value, std::vector<std::string>& container,
+ std::vector<std::string>& container, std::string const& value,
+ EmptyElements emptyElements = EmptyElements::No)
+ {
+ return cmList::insert(container, container.cend(), value, emptyElements);
+ }
+ static std::vector<std::string>::iterator append(
+ std::vector<std::string>& container, cmValue value,
EmptyElements emptyElements = EmptyElements::No)
{
if (value) {
- return cmList::append(*value, container, emptyElements);
+ return cmList::append(container, *value, emptyElements);
}
return container.end();
}
template <typename InputIterator>
static std::vector<std::string>::iterator append(
- InputIterator first, InputIterator last,
- std::vector<std::string>& container,
- EmptyElements emptyElements = EmptyElements::No)
+ std::vector<std::string>& container, InputIterator first,
+ InputIterator last, EmptyElements emptyElements = EmptyElements::No)
{
- return cmList::insert(container.cend(), first, last, container,
+ return cmList::insert(container, container.cend(), first, last,
emptyElements);
}
static std::vector<std::string>::iterator prepend(
- cm::string_view value, std::vector<std::string>& container,
+ std::vector<std::string>& container, cm::string_view value,
+ EmptyElements emptyElements = EmptyElements::No)
+ {
+ return cmList::insert(container, container.cbegin(), value, emptyElements);
+ }
+ static std::vector<std::string>::iterator prepend(
+ std::vector<std::string>& container, std::string const& value,
EmptyElements emptyElements = EmptyElements::No)
{
- return cmList::insert(container.cbegin(), value, container, emptyElements);
+ return cmList::insert(container, container.cbegin(), value, emptyElements);
}
static std::vector<std::string>::iterator prepend(
- cmValue value, std::vector<std::string>& container,
+ std::vector<std::string>& container, cmValue value,
EmptyElements emptyElements = EmptyElements::No)
{
if (value) {
- return cmList::prepend(*value, container, emptyElements);
+ return cmList::prepend(container, *value, emptyElements);
}
return container.begin();
}
template <typename InputIterator>
static std::vector<std::string>::iterator prepend(
- InputIterator first, InputIterator last,
- std::vector<std::string>& container,
- EmptyElements emptyElements = EmptyElements::No)
+ std::vector<std::string>& container, InputIterator first,
+ InputIterator last, EmptyElements emptyElements = EmptyElements::No)
{
- return cmList::insert(container.cbegin(), first, last, container,
+ return cmList::insert(container, container.cbegin(), first, last,
emptyElements);
}
@@ -991,40 +1080,40 @@ public:
// but without any intermediate expansion. So the operation is simply a
// string concatenation with special handling for the CMake list item
// separator
- static std::string& append(cm::string_view value, std::string& list);
+ static std::string& append(std::string& list, cm::string_view value);
template <typename InputIterator>
- static std::string& append(InputIterator first, InputIterator last,
- std::string& list)
+ static std::string& append(std::string& list, InputIterator first,
+ InputIterator last)
{
if (first == last) {
return list;
}
- return cmList::append(cm::string_view{ std::accumulate(
+ return cmList::append(list,
+ cm::string_view{ std::accumulate(
std::next(first), last, *first,
[](std::string a, const std::string& b) {
return std::move(a) +
std::string(cmList::element_separator) + b;
- }) },
- list);
+ }) });
}
- static std::string& prepend(cm::string_view value, std::string& list);
+ static std::string& prepend(std::string& list, cm::string_view value);
template <typename InputIterator>
- static std::string& prepend(InputIterator first, InputIterator last,
- std::string& list)
+ static std::string& prepend(std::string& list, InputIterator first,
+ InputIterator last)
{
if (first == last) {
return list;
}
- return cmList::prepend(cm::string_view{ std::accumulate(
+ return cmList::prepend(list,
+ cm::string_view{ std::accumulate(
std::next(first), last, *first,
[](std::string a, const std::string& b) {
return std::move(a) +
std::string(cmList::element_separator) + b;
- }) },
- list);
+ }) });
}
// Non-members
@@ -1047,26 +1136,26 @@ private:
cmList& RemoveItems(std::vector<index_type>&& indexes);
cmList& RemoveItems(std::vector<std::string>&& items);
- static container_type::iterator Insert(container_type::const_iterator pos,
+ static container_type::iterator Insert(container_type& container,
+ container_type::const_iterator pos,
std::string&& value,
- container_type& container,
ExpandElements expandElements,
EmptyElements emptyElements);
- static container_type::iterator Insert(container_type::const_iterator pos,
+ static container_type::iterator Insert(container_type& container,
+ container_type::const_iterator pos,
const std::string& value,
- container_type& container,
ExpandElements expandElements,
EmptyElements emptyElements)
{
auto tmp = value;
- return cmList::Insert(pos, std::move(tmp), container, expandElements,
+ return cmList::Insert(container, pos, std::move(tmp), expandElements,
emptyElements);
}
template <typename InputIterator>
- static container_type::iterator Insert(container_type::const_iterator pos,
+ static container_type::iterator Insert(container_type& container,
+ container_type::const_iterator pos,
InputIterator first,
InputIterator last,
- container_type& container,
ExpandElements expandElements,
EmptyElements emptyElements)
{
@@ -1080,7 +1169,7 @@ private:
if (expandElements == ExpandElements::Yes) {
for (; first != last; ++first) {
auto size = container.size();
- insertPos = cmList::Insert(insertPos, *first, container,
+ insertPos = cmList::Insert(container, insertPos, *first,
expandElements, emptyElements);
insertPos += container.size() - size;
}
@@ -1177,6 +1266,13 @@ inline std::vector<std::string>& operator+=(std::vector<std::string>& l,
return l;
}
+namespace std {
+inline void swap(cmList& lhs, cmList& rhs) noexcept
+{
+ lhs.swap(rhs);
+}
+} // namespace std
+
namespace cm {
inline void erase(cmList& list, const std::string& value)
{
@@ -1188,11 +1284,69 @@ inline void erase_if(cmList& list, Predicate pred)
{
list.erase(std::remove_if(list.begin(), list.end(), pred), list.end());
}
+
+//
+// Provide a special implementation of cm::append because, in this case,
+// expansion must not be applied to the inserted elements
+//
+#if defined(__SUNPRO_CC) && defined(__sparc)
+// Oracle DeveloperStudio C++ compiler on Solaris/Sparc fails to compile
+// templates with constraints.
+// So, on this platform, use only simple templates.
+template <typename InputIt,
+ cm::enable_if_t<cm::is_input_iterator<InputIt>::value, int> = 0>
+void append(cmList& v, InputIt first, InputIt last)
+{
+ v.append(first, last, cmList::ExpandElements::No);
}
-namespace srd {
-inline void swap(cmList& lhs, cmList& rhs) noexcept
+template <typename Range,
+ cm::enable_if_t<cm::is_input_range<Range>::value, int> = 0>
+void append(cmList& v, Range const& r)
{
- lhs.swap(rhs);
+ v.append(r.begin(), r.end(), cmList::ExpandElements::No);
+}
+
+#else
+
+template <
+ typename InputIt,
+ cm::enable_if_t<
+ cm::is_input_iterator<InputIt>::value &&
+ std::is_convertible<typename std::iterator_traits<InputIt>::value_type,
+ cmList::value_type>::value,
+ int> = 0>
+void append(cmList& v, InputIt first, InputIt last)
+{
+ v.append(first, last, cmList::ExpandElements::No);
+}
+
+template <typename Range,
+ cm::enable_if_t<cm::is_input_range<Range>::value &&
+ std::is_convertible<typename Range::value_type,
+ cmList::value_type>::value,
+ int> = 0>
+void append(cmList& v, Range const& r)
+{
+ v.append(r.begin(), r.end(), cmList::ExpandElements::No);
}
+#endif
+
+} // namespace cm
+
+/**
+ * Helper functions for legacy support. Use preferably cmList class directly
+ * or the static methods of the class.
+ */
+inline void cmExpandList(
+ cm::string_view arg, std::vector<std::string>& argsOut,
+ cmList::EmptyElements emptyElements = cmList::EmptyElements::No)
+{
+ cmList::append(argsOut, arg, emptyElements);
+}
+inline void cmExpandList(
+ cmValue arg, std::vector<std::string>& argsOut,
+ cmList::EmptyElements emptyElements = cmList::EmptyElements::No)
+{
+ cmList::append(argsOut, arg, emptyElements);
}
diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx
index 40be0ceeb5..acffa2ec81 100644
--- a/Source/cmListCommand.cxx
+++ b/Source/cmListCommand.cxx
@@ -205,7 +205,7 @@ bool HandleAppendCommand(std::vector<std::string> const& args,
GetListString(listString, listName, makefile);
makefile.AddDefinition(
- listName, cmList::append(args.begin() + 2, args.end(), listString));
+ listName, cmList::append(listString, args.begin() + 2, args.end()));
return true;
}
@@ -226,7 +226,7 @@ bool HandlePrependCommand(std::vector<std::string> const& args,
GetListString(listString, listName, makefile);
makefile.AddDefinition(
- listName, cmList::prepend(args.begin() + 2, args.end(), listString));
+ listName, cmList::prepend(listString, args.begin() + 2, args.end()));
return true;
}
diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx
index 6270c825f2..97f5de9697 100644
--- a/Source/cmListFileCache.cxx
+++ b/Source/cmListFileCache.cxx
@@ -11,10 +11,10 @@
# include <cmsys/Encoding.hxx>
#endif
+#include "cmList.h"
#include "cmListFileLexer.h"
#include "cmMessageType.h"
#include "cmMessenger.h"
-#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
struct cmListFileParser
@@ -496,10 +496,11 @@ std::ostream& operator<<(std::ostream& os, BT<std::string> const& s)
}
std::vector<BT<std::string>> cmExpandListWithBacktrace(
- std::string const& list, cmListFileBacktrace const& bt, bool emptyArgs)
+ std::string const& list, cmListFileBacktrace const& bt,
+ cmList::EmptyElements emptyArgs)
{
std::vector<BT<std::string>> result;
- std::vector<std::string> tmp = cmExpandedList(list, emptyArgs);
+ cmList tmp{ list, emptyArgs };
result.reserve(tmp.size());
for (std::string& i : tmp) {
result.emplace_back(std::move(i), bt);
diff --git a/Source/cmListFileCache.h b/Source/cmListFileCache.h
index 05539892c9..e4e6eb37ed 100644
--- a/Source/cmListFileCache.h
+++ b/Source/cmListFileCache.h
@@ -13,6 +13,7 @@
#include <cm/optional>
#include "cmConstStack.h"
+#include "cmList.h"
#include "cmSystemTools.h"
/** \class cmListFileCache
@@ -232,7 +233,7 @@ public:
std::vector<BT<std::string>> cmExpandListWithBacktrace(
std::string const& list,
cmListFileBacktrace const& bt = cmListFileBacktrace(),
- bool emptyArgs = false);
+ cmList::EmptyElements emptyArgs = cmList::EmptyElements::No);
struct cmListFile
{
diff --git a/Source/cmLocalCommonGenerator.cxx b/Source/cmLocalCommonGenerator.cxx
index eca7a9eb6e..aa953f469d 100644
--- a/Source/cmLocalCommonGenerator.cxx
+++ b/Source/cmLocalCommonGenerator.cxx
@@ -8,7 +8,6 @@
#include "cmGeneratorTarget.h"
#include "cmMakefile.h"
#include "cmOutputConverter.h"
-#include "cmState.h"
#include "cmStateDirectory.h"
#include "cmStateSnapshot.h"
#include "cmStringAlgorithms.h"
@@ -17,9 +16,8 @@
class cmGlobalGenerator;
cmLocalCommonGenerator::cmLocalCommonGenerator(cmGlobalGenerator* gg,
- cmMakefile* mf, WorkDir wd)
+ cmMakefile* mf)
: cmLocalGenerator(gg, mf)
- , WorkingDirectory(wd)
{
this->ConfigNames =
this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
@@ -29,21 +27,9 @@ cmLocalCommonGenerator::~cmLocalCommonGenerator() = default;
std::string const& cmLocalCommonGenerator::GetWorkingDirectory() const
{
- if (this->WorkingDirectory == WorkDir::TopBin) {
- return this->GetState()->GetBinaryDirectory();
- }
return this->StateSnapshot.GetDirectory().GetCurrentBinary();
}
-std::string cmLocalCommonGenerator::MaybeRelativeToWorkDir(
- std::string const& path) const
-{
- if (this->WorkingDirectory == WorkDir::TopBin) {
- return this->MaybeRelativeToTopBinDir(path);
- }
- return this->MaybeRelativeToCurBinDir(path);
-}
-
std::string cmLocalCommonGenerator::GetTargetFortranFlags(
cmGeneratorTarget const* target, std::string const& config)
{
diff --git a/Source/cmLocalCommonGenerator.h b/Source/cmLocalCommonGenerator.h
index 0505c138d1..52f7a9e5e6 100644
--- a/Source/cmLocalCommonGenerator.h
+++ b/Source/cmLocalCommonGenerator.h
@@ -20,15 +20,8 @@ class cmSourceFile;
*/
class cmLocalCommonGenerator : public cmLocalGenerator
{
-protected:
- enum class WorkDir
- {
- TopBin,
- CurBin,
- };
-
public:
- cmLocalCommonGenerator(cmGlobalGenerator* gg, cmMakefile* mf, WorkDir wd);
+ cmLocalCommonGenerator(cmGlobalGenerator* gg, cmMakefile* mf);
~cmLocalCommonGenerator() override;
std::vector<std::string> const& GetConfigNames() const
@@ -36,9 +29,7 @@ public:
return this->ConfigNames;
}
- std::string const& GetWorkingDirectory() const;
-
- std::string MaybeRelativeToWorkDir(std::string const& path) const;
+ virtual std::string const& GetWorkingDirectory() const;
std::string GetTargetFortranFlags(cmGeneratorTarget const* target,
std::string const& config) override;
@@ -48,8 +39,6 @@ public:
cmGeneratorTarget const* gt = nullptr) override;
protected:
- WorkDir WorkingDirectory;
-
std::vector<std::string> ConfigNames;
friend class cmCommonTargetGenerator;
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 01e4241360..4089fd440b 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -38,6 +38,7 @@
#include "cmInstallTargetGenerator.h"
#include "cmLinkLineComputer.h"
#include "cmLinkLineDeviceComputer.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmRange.h"
#include "cmRulePlaceholderExpander.h"
@@ -146,12 +147,10 @@ cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile)
this->Makefile->GetDefinition("CMAKE_APPLE_ARCH_SYSROOTS")) {
std::string const& appleArchs =
this->Makefile->GetSafeDefinition("CMAKE_OSX_ARCHITECTURES");
- std::vector<std::string> archs;
- std::vector<std::string> sysroots;
- cmExpandList(appleArchs, archs);
- cmExpandList(*appleArchSysroots, sysroots, true);
+ cmList archs(appleArchs);
+ cmList sysroots{ appleArchSysroots, cmList::EmptyElements::Yes };
if (archs.size() == sysroots.size()) {
- for (size_t i = 0; i < archs.size(); ++i) {
+ for (cmList::size_type i = 0; i < archs.size(); ++i) {
this->AppleArchSysroots[archs[i]] = sysroots[i];
}
} else {
@@ -208,12 +207,12 @@ cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile)
}
}
-cmRulePlaceholderExpander* cmLocalGenerator::CreateRulePlaceholderExpander()
- const
+std::unique_ptr<cmRulePlaceholderExpander>
+cmLocalGenerator::CreateRulePlaceholderExpander() const
{
- return new cmRulePlaceholderExpander(this->Compilers, this->VariableMappings,
- this->CompilerSysroot,
- this->LinkerSysroot);
+ return cm::make_unique<cmRulePlaceholderExpander>(
+ this->Compilers, this->VariableMappings, this->CompilerSysroot,
+ this->LinkerSysroot);
}
cmLocalGenerator::~cmLocalGenerator() = default;
@@ -347,7 +346,7 @@ void cmLocalGenerator::GenerateTestFiles()
cmValue testIncludeFiles = this->Makefile->GetProperty("TEST_INCLUDE_FILES");
if (testIncludeFiles) {
- std::vector<std::string> includesList = cmExpandedList(*testIncludeFiles);
+ cmList includesList{ *testIncludeFiles };
for (std::string const& i : includesList) {
fout << "include(\"" << i << "\")\n";
}
@@ -1064,9 +1063,9 @@ void cmLocalGenerator::AddCompileOptions(std::vector<BT<std::string>>& flags,
std::string isJMCEnabled =
cmGeneratorExpression::Evaluate(*jmcExprGen, this, config);
if (cmIsOn(isJMCEnabled)) {
- std::vector<std::string> optVec = cmExpandedList(*jmc);
+ cmList optList{ *jmc };
std::string jmcFlags;
- this->AppendCompileOptions(jmcFlags, optVec);
+ this->AppendCompileOptions(jmcFlags, optList);
if (!jmcFlags.empty()) {
flags.emplace_back(std::move(jmcFlags));
}
@@ -1168,11 +1167,11 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit(
// Standard include directories to be added unconditionally at the end.
// These are intended to simulate additional implicit include directories.
- std::vector<std::string> userStandardDirs;
+ cmList userStandardDirs;
{
std::string const value = this->Makefile->GetSafeDefinition(
cmStrCat("CMAKE_", lang, "_STANDARD_INCLUDE_DIRECTORIES"));
- cmExpandList(value, userStandardDirs);
+ userStandardDirs.assign(value);
for (std::string& usd : userStandardDirs) {
cmSystemTools::ConvertToUnixSlashes(usd);
}
@@ -1195,13 +1194,12 @@ std::vector<BT<std::string>> cmLocalGenerator::GetIncludeDirectoriesImplicit(
// directories for modules ('.mod' files).
if (lang != "Fortran") {
size_t const impDirVecOldSize = impDirVec.size();
- if (this->Makefile->GetDefExpandList(
- cmStrCat("CMAKE_", lang, "_IMPLICIT_INCLUDE_DIRECTORIES"),
- impDirVec)) {
- // FIXME: Use cmRange with 'advance()' when it supports non-const.
- for (size_t i = impDirVecOldSize; i < impDirVec.size(); ++i) {
- cmSystemTools::ConvertToUnixSlashes(impDirVec[i]);
- }
+ cmList::append(impDirVec,
+ this->Makefile->GetDefinition(cmStrCat(
+ "CMAKE_", lang, "_IMPLICIT_INCLUDE_DIRECTORIES")));
+ // FIXME: Use cmRange with 'advance()' when it supports non-const.
+ for (size_t i = impDirVecOldSize; i < impDirVec.size(); ++i) {
+ cmSystemTools::ConvertToUnixSlashes(impDirVec[i]);
}
}
@@ -1588,6 +1586,8 @@ void cmLocalGenerator::GetTargetFlags(
this->AppendPositionIndependentLinkerFlags(extraLinkFlags, target, config,
linkLanguage);
this->AppendIPOLinkerFlags(extraLinkFlags, target, config, linkLanguage);
+ this->AppendDependencyInfoLinkerFlags(extraLinkFlags, target, config,
+ linkLanguage);
this->AppendModuleDefinitionFlag(extraLinkFlags, target, linkLineComputer,
config);
@@ -1954,8 +1954,8 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags,
cmValue opt =
target->Target->GetMakefile()->GetDefinition(optionFlagDef);
if (opt) {
- std::vector<std::string> optVec = cmExpandedList(*opt);
- for (std::string const& i : optVec) {
+ cmList optList{ *opt };
+ for (std::string const& i : optList) {
this->AppendFlagEscape(flags, i);
}
}
@@ -2426,7 +2426,7 @@ void cmLocalGenerator::AddPositionIndependentFlags(std::string& flags,
cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_PIC"));
}
if (!picFlags.empty()) {
- std::vector<std::string> options = cmExpandedList(picFlags);
+ cmList options{ picFlags };
for (std::string const& o : options) {
this->AppendFlagEscape(flags, o);
}
@@ -2447,10 +2447,9 @@ void cmLocalGenerator::AddColorDiagnosticsFlags(std::string& flags,
cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_COLOR_DIAGNOSTICS_OFF");
}
- std::vector<std::string> options;
- this->Makefile->GetDefExpandList(colorFlagName, options);
+ cmList options{ this->Makefile->GetDefinition(colorFlagName) };
- for (std::string const& option : options) {
+ for (auto const& option : options) {
this->AppendFlagEscape(flags, option);
}
}
@@ -2973,6 +2972,7 @@ void cmLocalGenerator::WriteUnitySourceInclude(
unity_file << *beforeInclude << "\n";
}
+ unity_file << "// NOLINTNEXTLINE(bugprone-suspicious-include)\n";
unity_file << "#include \"" << sf_full_path << "\"\n";
if (afterInclude) {
@@ -3163,7 +3163,7 @@ void cmLocalGenerator::AppendIPOLinkerFlags(std::string& flags,
return;
}
- std::vector<std::string> flagsList = cmExpandedList(*rawFlagsList);
+ cmList flagsList{ *rawFlagsList };
for (std::string const& o : flagsList) {
this->AppendFlagEscape(flags, o);
}
@@ -3198,12 +3198,47 @@ void cmLocalGenerator::AppendPositionIndependentLinkerFlags(
return;
}
- std::vector<std::string> flagsList = cmExpandedList(pieFlags);
+ cmList flagsList{ pieFlags };
for (const auto& flag : flagsList) {
this->AppendFlagEscape(flags, flag);
}
}
+void cmLocalGenerator::AppendDependencyInfoLinkerFlags(
+ std::string& flags, cmGeneratorTarget* target, const std::string& config,
+ const std::string& linkLanguage)
+{
+ if (!this->GetGlobalGenerator()->SupportsLinkerDependencyFile() ||
+ !target->HasLinkDependencyFile(config)) {
+ return;
+ }
+
+ auto depFlag = *this->Makefile->GetDefinition(
+ cmStrCat("CMAKE_", linkLanguage, "_LINKER_DEPFILE_FLAGS"));
+ if (depFlag.empty()) {
+ return;
+ }
+
+ auto depFile = this->ConvertToOutputFormat(
+ this->MaybeRelativeToWorkDir(this->GetLinkDependencyFile(target, config)),
+ cmOutputConverter::SHELL);
+ auto rulePlaceholderExpander = this->CreateRulePlaceholderExpander();
+ cmRulePlaceholderExpander::RuleVariables linkDepsVariables;
+ linkDepsVariables.DependencyFile = depFile.c_str();
+ rulePlaceholderExpander->ExpandRuleVariables(this, depFlag,
+ linkDepsVariables);
+ auto depFlags = cmExpandListWithBacktrace(depFlag);
+ target->ResolveLinkerWrapper(depFlags, linkLanguage);
+
+ this->AppendFlags(flags, depFlags);
+}
+
+std::string cmLocalGenerator::GetLinkDependencyFile(
+ cmGeneratorTarget* /*target*/, const std::string& /*config*/) const
+{
+ return "link.d";
+}
+
void cmLocalGenerator::AppendModuleDefinitionFlag(
std::string& flags, cmGeneratorTarget const* target,
cmLinkLineComputer* linkLineComputer, std::string const& config)
@@ -3264,7 +3299,7 @@ void cmLocalGenerator::AppendCompileOptions(std::string& options,
}
// Expand the list of options.
- std::vector<std::string> options_vec = cmExpandedList(options_list);
+ cmList options_vec{ options_list };
this->AppendCompileOptions(options, options_vec, regex);
}
@@ -3322,7 +3357,7 @@ void cmLocalGenerator::AppendIncludeDirectories(
}
// Expand the list of includes.
- std::vector<std::string> includes_vec = cmExpandedList(includes_list);
+ cmList includes_vec{ includes_list };
this->AppendIncludeDirectories(includes, includes_vec, sourceFile);
}
@@ -3454,7 +3489,7 @@ void cmLocalGenerator::AppendFeatureOptions(std::string& flags,
cmValue optionList = this->Makefile->GetDefinition(
cmStrCat("CMAKE_", lang, "_COMPILE_OPTIONS_", feature));
if (optionList) {
- std::vector<std::string> options = cmExpandedList(*optionList);
+ cmList options{ *optionList };
for (std::string const& o : options) {
this->AppendFlagEscape(flags, o);
}
@@ -4385,12 +4420,11 @@ void AddUtilityCommand(cmLocalGenerator& lg, cmCommandOrigin origin,
std::vector<std::string> ComputeISPCObjectSuffixes(cmGeneratorTarget* target)
{
- const std::string& targetProperty =
- target->GetSafeProperty("ISPC_INSTRUCTION_SETS");
- std::vector<std::string> ispcTargets;
+ const cmValue targetProperty = target->GetProperty("ISPC_INSTRUCTION_SETS");
+ cmList ispcTargets;
- if (!cmIsOff(targetProperty)) {
- cmExpandList(targetProperty, ispcTargets);
+ if (!targetProperty.IsOff()) {
+ ispcTargets.assign(targetProperty);
for (auto& ispcTarget : ispcTargets) {
// transform targets into the suffixes
auto pos = ispcTarget.find('-');
@@ -4402,7 +4436,7 @@ std::vector<std::string> ComputeISPCObjectSuffixes(cmGeneratorTarget* target)
ispcTarget = target_suffix;
}
}
- return ispcTargets;
+ return std::move(ispcTargets.data());
}
std::vector<std::string> ComputeISPCExtraObjects(
@@ -4500,11 +4534,11 @@ cmLocalGenerator::MakeCustomCommandGenerators(cmCustomCommand const& cc,
std::vector<std::string> cmLocalGenerator::ExpandCustomCommandOutputPaths(
cmCompiledGeneratorExpression const& cge, std::string const& config)
{
- std::vector<std::string> paths = cmExpandedList(cge.Evaluate(this, config));
+ cmList paths{ cge.Evaluate(this, config) };
for (std::string& p : paths) {
p = cmSystemTools::CollapseFullPath(p, this->GetCurrentBinaryDirectory());
}
- return paths;
+ return std::move(paths.data());
}
std::vector<std::string> cmLocalGenerator::ExpandCustomCommandOutputGenex(
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index bda82bce00..c811408138 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -89,7 +89,7 @@ class cmLocalGenerator : public cmOutputConverter
{
public:
cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile);
- virtual ~cmLocalGenerator();
+ ~cmLocalGenerator() override;
/**
* Generate the makefile for this directory.
@@ -137,7 +137,8 @@ public:
return this->GlobalGenerator;
}
- virtual cmRulePlaceholderExpander* CreateRulePlaceholderExpander() const;
+ virtual std::unique_ptr<cmRulePlaceholderExpander>
+ CreateRulePlaceholderExpander() const;
std::string GetLinkLibsCMP0065(std::string const& linkLanguage,
cmGeneratorTarget& tgt) const;
@@ -183,6 +184,12 @@ public:
cmGeneratorTarget* target,
const std::string& config,
const std::string& lang);
+ void AppendDependencyInfoLinkerFlags(std::string& flags,
+ cmGeneratorTarget* target,
+ const std::string& config,
+ const std::string& lang);
+ virtual std::string GetLinkDependencyFile(cmGeneratorTarget* target,
+ const std::string& config) const;
void AppendModuleDefinitionFlag(std::string& flags,
cmGeneratorTarget const* target,
cmLinkLineComputer* linkLineComputer,
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index d0bd3758f4..4b0604c55e 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -22,6 +22,7 @@
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmGlobalNinjaGenerator.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -40,19 +41,18 @@
cmLocalNinjaGenerator::cmLocalNinjaGenerator(cmGlobalGenerator* gg,
cmMakefile* mf)
- : cmLocalCommonGenerator(gg, mf, WorkDir::TopBin)
+ : cmLocalCommonGenerator(gg, mf)
{
}
// Virtual public methods.
-cmRulePlaceholderExpander*
+std::unique_ptr<cmRulePlaceholderExpander>
cmLocalNinjaGenerator::CreateRulePlaceholderExpander() const
{
- cmRulePlaceholderExpander* ret =
- this->cmLocalGenerator::CreateRulePlaceholderExpander();
+ auto ret = this->cmLocalGenerator::CreateRulePlaceholderExpander();
ret->SetTargetImpLib("$TARGET_IMPLIB");
- return ret;
+ return std::unique_ptr<cmRulePlaceholderExpander>(std::move(ret));
}
cmLocalNinjaGenerator::~cmLocalNinjaGenerator() = default;
@@ -187,6 +187,26 @@ cmGlobalNinjaGenerator* cmLocalNinjaGenerator::GetGlobalNinjaGenerator()
return static_cast<cmGlobalNinjaGenerator*>(this->GetGlobalGenerator());
}
+std::string const& cmLocalNinjaGenerator::GetWorkingDirectory() const
+{
+ return this->GetState()->GetBinaryDirectory();
+}
+
+std::string cmLocalNinjaGenerator::MaybeRelativeToWorkDir(
+ std::string const& path) const
+{
+ return this->GetGlobalNinjaGenerator()->NinjaOutputPath(
+ this->MaybeRelativeToTopBinDir(path));
+}
+
+std::string cmLocalNinjaGenerator::GetLinkDependencyFile(
+ cmGeneratorTarget* target, std::string const& config) const
+{
+ return cmStrCat(target->GetSupportDirectory(),
+ this->GetGlobalNinjaGenerator()->ConfigDirectory(config),
+ "/link.d");
+}
+
// Virtual protected methods.
std::string cmLocalNinjaGenerator::ConvertToIncludeReference(
@@ -301,7 +321,7 @@ void cmLocalNinjaGenerator::WritePools(std::ostream& os)
if (jobpools) {
cmGlobalNinjaGenerator::WriteComment(
os, "Pools defined by global property JOB_POOLS");
- std::vector<std::string> pools = cmExpandedList(*jobpools);
+ cmList pools{ *jobpools };
for (std::string const& pool : pools) {
const std::string::size_type eq = pool.find('=');
unsigned int jobs;
@@ -892,8 +912,7 @@ std::string cmLocalNinjaGenerator::MakeCustomLauncher(
}
vars.Output = output.c_str();
- std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
- this->CreateRulePlaceholderExpander());
+ auto rulePlaceholderExpander = this->CreateRulePlaceholderExpander();
std::string launcher = *property_value;
rulePlaceholderExpander->ExpandRuleVariables(this, launcher, vars);
@@ -908,14 +927,11 @@ void cmLocalNinjaGenerator::AdditionalCleanFiles(const std::string& config)
{
if (cmValue prop_value =
this->Makefile->GetProperty("ADDITIONAL_CLEAN_FILES")) {
- std::vector<std::string> cleanFiles;
- {
- cmExpandList(cmGeneratorExpression::Evaluate(*prop_value, this, config),
- cleanFiles);
- }
+ cmList cleanFiles{ cmGeneratorExpression::Evaluate(*prop_value, this,
+ config) };
std::string const& binaryDir = this->GetCurrentBinaryDirectory();
cmGlobalNinjaGenerator* gg = this->GetGlobalNinjaGenerator();
- for (std::string const& cleanFile : cleanFiles) {
+ for (auto const& cleanFile : cleanFiles) {
// Support relative paths
gg->AddAdditionalCleanFile(
cmSystemTools::CollapseFullPath(cleanFile, binaryDir), config);
diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h
index 4d393d9c3a..74b8b3b3f8 100644
--- a/Source/cmLocalNinjaGenerator.h
+++ b/Source/cmLocalNinjaGenerator.h
@@ -6,6 +6,7 @@
#include <iosfwd>
#include <map>
+#include <memory>
#include <set>
#include <string>
#include <vector>
@@ -41,7 +42,8 @@ public:
void Generate() override;
- cmRulePlaceholderExpander* CreateRulePlaceholderExpander() const override;
+ std::unique_ptr<cmRulePlaceholderExpander> CreateRulePlaceholderExpander()
+ const override;
std::string GetTargetDirectory(
cmGeneratorTarget const* target) const override;
@@ -52,6 +54,10 @@ public:
const cmake* GetCMakeInstance() const;
cmake* GetCMakeInstance();
+ std::string const& GetWorkingDirectory() const override;
+
+ std::string MaybeRelativeToWorkDir(std::string const& path) const override;
+
/// @returns the relative path between the HomeOutputDirectory and this
/// local generators StartOutputDirectory.
std::string GetHomeRelativeOutputPath() const
@@ -90,6 +96,9 @@ public:
bool HasUniqueByproducts(std::vector<std::string> const& byproducts,
cmListFileBacktrace const& bt);
+ std::string GetLinkDependencyFile(cmGeneratorTarget* target,
+ std::string const& config) const override;
+
protected:
std::string ConvertToIncludeReference(
std::string const& path, cmOutputConverter::OutputFormat format) override;
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 56a41b1a98..cfe4eb629d 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -29,6 +29,7 @@
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmGlobalUnixMakefileGenerator3.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
@@ -110,7 +111,7 @@ private:
cmLocalUnixMakefileGenerator3::cmLocalUnixMakefileGenerator3(
cmGlobalGenerator* gg, cmMakefile* mf)
- : cmLocalCommonGenerator(gg, mf, WorkDir::CurBin)
+ : cmLocalCommonGenerator(gg, mf)
{
this->MakefileVariableSize = 0;
this->ColorMakefile = false;
@@ -238,6 +239,12 @@ void cmLocalUnixMakefileGenerator3::GetIndividualFileTargets(
}
}
+std::string cmLocalUnixMakefileGenerator3::GetLinkDependencyFile(
+ cmGeneratorTarget* target, std::string const& /*config*/) const
+{
+ return cmStrCat(target->GetSupportDirectory(), "/link.d");
+}
+
void cmLocalUnixMakefileGenerator3::WriteLocalMakefile()
{
// generate the includes
@@ -962,8 +969,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand(
*content << dir;
}
- std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
- this->CreateRulePlaceholderExpander());
+ auto rulePlaceholderExpander = this->CreateRulePlaceholderExpander();
// Add each command line to the set of commands.
std::vector<std::string> commands1;
@@ -1129,14 +1135,13 @@ void cmLocalUnixMakefileGenerator3::AppendCleanCommand(
void cmLocalUnixMakefileGenerator3::AppendDirectoryCleanCommand(
std::vector<std::string>& commands)
{
- std::vector<std::string> cleanFiles;
+ cmList cleanFiles;
// Look for additional files registered for cleaning in this directory.
if (cmValue prop_value =
this->Makefile->GetProperty("ADDITIONAL_CLEAN_FILES")) {
- cmExpandList(cmGeneratorExpression::Evaluate(
- *prop_value, this,
- this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")),
- cleanFiles);
+ cleanFiles.assign(cmGeneratorExpression::Evaluate(
+ *prop_value, this,
+ this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")));
}
if (cleanFiles.empty()) {
return;
@@ -1434,7 +1439,7 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(
this->Makefile->GetSafeDefinition("CMAKE_DEPENDS_DEPENDENCY_FILES");
if (!depends.empty()) {
// dependencies are managed by compiler
- auto depFiles = cmExpandedList(depends, true);
+ cmList depFiles{ depends, cmList::EmptyElements::Yes };
std::string const internalDepFile =
targetDir + "/compiler_depend.internal";
std::string const depFile = targetDir + "/compiler_depend.make";
@@ -1556,8 +1561,7 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies(
this->WriteDisclaimer(internalRuleFileStream);
// for each language we need to scan, scan it
- std::vector<std::string> langs =
- cmExpandedList(mf->GetSafeDefinition("CMAKE_DEPENDS_LANGUAGES"));
+ cmList langs{ mf->GetSafeDefinition("CMAKE_DEPENDS_LANGUAGES") };
for (std::string const& lang : langs) {
// construct the checker
// Create the scanner for this language
@@ -1602,7 +1606,7 @@ void cmLocalUnixMakefileGenerator3::CheckMultipleOutputs(bool verbose)
}
// Convert the string to a list and preserve empty entries.
- std::vector<std::string> pairs = cmExpandedList(*pairs_string, true);
+ cmList pairs{ *pairs_string, cmList::EmptyElements::Yes };
for (auto i = pairs.begin(); i != pairs.end() && (i + 1) != pairs.end();) {
const std::string& depender = *i++;
const std::string& dependee = *i++;
@@ -1822,7 +1826,7 @@ void cmLocalUnixMakefileGenerator3::ClearDependencies(cmMakefile* mf,
if (!infoDef) {
return;
}
- std::vector<std::string> files = cmExpandedList(*infoDef);
+ cmList files{ *infoDef };
// Each depend information file corresponds to a target. Clear the
// dependencies for that target.
@@ -1863,7 +1867,7 @@ void cmLocalUnixMakefileGenerator3::ClearDependencies(cmMakefile* mf,
cmSystemTools::Touch(DepTimestamp.GenericString(), true);
// clear the dependencies files generated by the compiler
- std::vector<std::string> dependencies = cmExpandedList(depsFiles, true);
+ cmList dependencies{ depsFiles, cmList::EmptyElements::Yes };
cmDependsCompiler depsManager;
depsManager.SetVerbose(verbose);
depsManager.ClearDependencies(dependencies);
@@ -1973,14 +1977,14 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo(
// Store include transform rule properties. Write the directory
// rules first because they may be overridden by later target rules.
- std::vector<std::string> transformRules;
+ cmList transformRules;
if (cmValue xform =
this->Makefile->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) {
- cmExpandList(*xform, transformRules);
+ transformRules.assign(*xform);
}
if (cmValue xform =
target->GetProperty("IMPLICIT_DEPENDS_INCLUDE_TRANSFORM")) {
- cmExpandList(*xform, transformRules);
+ transformRules.append(*xform);
}
if (!transformRules.empty()) {
cmakefileStream << "\nset(CMAKE_INCLUDE_TRANSFORMS\n";
@@ -2009,6 +2013,18 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo(
<< this->MaybeRelativeToTopBinDir(src) << "\"\n";
}
}
+ } else if (compilerLang.first == "LINK"_s) {
+ auto depFormat = this->Makefile->GetDefinition(
+ cmStrCat("CMAKE_", target->GetLinkerLanguage(this->GetConfigName()),
+ "_LINKER_DEPFILE_FORMAT"));
+ for (auto const& compilerPair : compilerPairs) {
+ for (auto const& src : compilerPair.second) {
+ cmakefileStream << R"( "" ")"
+ << this->MaybeRelativeToTopBinDir(compilerPair.first)
+ << "\" \"" << depFormat << "\" \""
+ << this->MaybeRelativeToTopBinDir(src) << "\"\n";
+ }
+ }
} else {
auto depFormat = this->Makefile->GetSafeDefinition(
cmStrCat("CMAKE_", compilerLang.first, "_DEPFILE_FORMAT"));
diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h
index 78aa7f9c2f..7d5a9224b4 100644
--- a/Source/cmLocalUnixMakefileGenerator3.h
+++ b/Source/cmLocalUnixMakefileGenerator3.h
@@ -191,6 +191,9 @@ public:
// Eclipse generator.
void GetIndividualFileTargets(std::vector<std::string>& targets);
+ std::string GetLinkDependencyFile(cmGeneratorTarget* target,
+ std::string const& config) const override;
+
protected:
void WriteLocalMakefile();
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 239748db67..a7ea0dff2c 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -29,6 +29,7 @@
#include "cmGlobalGenerator.h"
#include "cmGlobalVisualStudio7Generator.h"
#include "cmGlobalVisualStudioGenerator.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmOutputConverter.h"
@@ -1576,12 +1577,12 @@ cmLocalVisualStudio7GeneratorFCInfo::cmLocalVisualStudio7GeneratorFCInfo(
// Check for extra object-file dependencies.
if (cmValue deps = sf.GetProperty("OBJECT_DEPENDS")) {
- std::vector<std::string> depends = cmExpandedList(*deps);
- const char* sep = "";
- for (const std::string& d : depends) {
- fc.AdditionalDeps += sep;
- fc.AdditionalDeps += lg->ConvertToXMLOutputPath(d);
- sep = ";";
+ cmList depends{ *deps };
+ if (!depends.empty()) {
+ for (std::string& d : depends) {
+ d = lg->ConvertToXMLOutputPath(d);
+ }
+ fc.AdditionalDeps += depends.to_string();
needfc = true;
}
}
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 3a69b2eeed..01afc44f28 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -43,6 +43,7 @@
#include "cmGlobalGenerator.h"
#include "cmInstallGenerator.h" // IWYU pragma: keep
#include "cmInstallSubdirectoryGenerator.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMessageType.h"
@@ -1448,15 +1449,13 @@ bool cmMakefile::ParseDefineFlag(std::string const& def, bool remove)
if (remove) {
if (cmValue cdefs = this->GetProperty("COMPILE_DEFINITIONS")) {
// Expand the list.
- std::vector<std::string> defs = cmExpandedList(*cdefs);
+ cmList defs{ *cdefs };
// Recompose the list without the definition.
- auto defEnd = std::remove(defs.begin(), defs.end(), define);
- auto defBegin = defs.begin();
- std::string ndefs = cmJoin(cmMakeRange(defBegin, defEnd), ";");
+ defs.remove_items({ define });
// Store the new list.
- this->SetProperty("COMPILE_DEFINITIONS", ndefs);
+ this->SetProperty("COMPILE_DEFINITIONS", defs.to_string());
}
} else {
// Append the definition to the directory property.
@@ -1958,21 +1957,15 @@ void cmMakefile::AddCacheDefinition(const std::string& name, const char* value,
value = existingValue->c_str();
}
if (type == cmStateEnums::PATH || type == cmStateEnums::FILEPATH) {
- std::vector<std::string>::size_type cc;
- std::vector<std::string> files;
nvalue = value ? value : "";
- cmExpandList(nvalue, files);
- nvalue.clear();
- for (cc = 0; cc < files.size(); cc++) {
- if (!cmIsOff(files[cc])) {
- files[cc] = cmSystemTools::CollapseFullPath(files[cc]);
+ cmList files(nvalue);
+ for (auto& file : files) {
+ if (!cmIsOff(file)) {
+ file = cmSystemTools::CollapseFullPath(file);
}
- if (cc > 0) {
- nvalue += ";";
- }
- nvalue += files[cc];
}
+ nvalue = files.to_string();
this->GetCMakeInstance()->AddCacheEntry(name, nvalue, doc, type);
nvalue = *this->GetState()->GetInitializedCacheValue(name);
@@ -2064,7 +2057,7 @@ void cmMakefile::AddGlobalLinkInformation(cmTarget& target)
}
if (cmValue linkLibsProp = this->GetProperty("LINK_LIBRARIES")) {
- std::vector<std::string> linkLibs = cmExpandedList(*linkLibsProp);
+ cmList linkLibs{ *linkLibsProp };
for (auto j = linkLibs.begin(); j != linkLibs.end(); ++j) {
std::string libraryName = *j;
@@ -2378,7 +2371,7 @@ void cmMakefile::ExpandVariablesCMP0019()
}
if (cmValue linkLibsProp = this->GetProperty("LINK_LIBRARIES")) {
- std::vector<std::string> linkLibs = cmExpandedList(*linkLibsProp);
+ cmList linkLibs{ *linkLibsProp };
for (auto l = linkLibs.begin(); l != linkLibs.end(); ++l) {
std::string libName = *l;
@@ -2614,18 +2607,6 @@ const std::string& cmMakefile::GetSafeDefinition(const std::string& name) const
return this->GetDefinition(name);
}
-bool cmMakefile::GetDefExpandList(const std::string& name,
- std::vector<std::string>& out,
- bool emptyArgs) const
-{
- cmValue def = this->GetDefinition(name);
- if (!def) {
- return false;
- }
- cmExpandList(*def, out, emptyArgs);
- return true;
-}
-
std::vector<std::string> cmMakefile::GetDefinitions() const
{
std::vector<std::string> res = this->StateSnapshot.ClosureKeys();
@@ -3266,9 +3247,9 @@ std::string cmMakefile::GetDefaultConfiguration() const
std::vector<std::string> cmMakefile::GetGeneratorConfigs(
GeneratorConfigQuery mode) const
{
- std::vector<std::string> configs;
+ cmList configs;
if (this->GetGlobalGenerator()->IsMultiConfig()) {
- this->GetDefExpandList("CMAKE_CONFIGURATION_TYPES", configs);
+ configs.assign(this->GetDefinition("CMAKE_CONFIGURATION_TYPES"));
} else if (mode != cmMakefile::OnlyMultiConfig) {
const std::string& buildType = this->GetSafeDefinition("CMAKE_BUILD_TYPE");
if (!buildType.empty()) {
@@ -3278,7 +3259,7 @@ std::vector<std::string> cmMakefile::GetGeneratorConfigs(
if (mode == cmMakefile::IncludeEmptyConfig && configs.empty()) {
configs.emplace_back();
}
- return configs;
+ return std::move(configs.data());
}
bool cmMakefile::IsFunctionBlocked(const cmListFileFunction& lff,
@@ -3406,7 +3387,7 @@ bool cmMakefile::ExpandArguments(
if (i.Delim == cmListFileArgument::Quoted) {
outArgs.emplace_back(value, true);
} else {
- std::vector<std::string> stringArgs = cmExpandedList(value);
+ cmList stringArgs{ value };
for (std::string const& stringArg : stringArgs) {
outArgs.emplace_back(stringArg, false);
}
@@ -3812,7 +3793,7 @@ std::string cmMakefile::GetModulesFile(const std::string& filename,
// Always search in CMAKE_MODULE_PATH:
cmValue cmakeModulePath = this->GetDefinition("CMAKE_MODULE_PATH");
if (cmakeModulePath) {
- std::vector<std::string> modulePath = cmExpandedList(*cmakeModulePath);
+ cmList modulePath{ *cmakeModulePath };
// Look through the possible module directories.
for (std::string itempl : modulePath) {
@@ -4155,11 +4136,11 @@ void cmMakefile::GetTests(const std::string& config,
void cmMakefile::AddCMakeDependFilesFromUser()
{
- std::vector<std::string> deps;
+ cmList deps;
if (cmValue deps_str = this->GetProperty("CMAKE_CONFIGURE_DEPENDS")) {
- cmExpandList(*deps_str, deps);
+ deps.assign(*deps_str);
}
- for (std::string const& dep : deps) {
+ for (auto const& dep : deps) {
if (cmSystemTools::FileIsFullPath(dep)) {
this->AddCMakeDependFile(dep);
} else {
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index a43ff41f9c..d1f5be53a0 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -518,8 +518,6 @@ public:
const std::string& GetRequiredDefinition(const std::string& name) const;
bool IsDefinitionSet(const std::string&) const;
bool IsNormalDefinitionSet(const std::string&) const;
- bool GetDefExpandList(const std::string& name, std::vector<std::string>& out,
- bool emptyArgs = false) const;
/**
* Get the list of all variables in the current space. If argument
* cacheonly is specified and is greater than 0, then only cache
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 196007328e..4a2b9e8996 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -16,6 +16,7 @@
#include "cmGlobalUnixMakefileGenerator3.h"
#include "cmLinkLineComputer.h"
#include "cmLinkLineDeviceComputer.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
@@ -69,6 +70,8 @@ void cmMakefileExecutableTargetGenerator::WriteRuleFiles()
this->WriteExecutableRule(true);
}
+ this->WriteTargetLinkDependRules();
+
// Write clean target
this->WriteTargetCleanRules();
@@ -151,11 +154,10 @@ void cmMakefileExecutableTargetGenerator::WriteNvidiaDeviceExecutableRule(
bool useLinkScript = this->GlobalGenerator->GetUseLinkScript();
// Construct the main link rule.
- std::vector<std::string> real_link_commands;
const std::string linkRuleVar = "CMAKE_CUDA_DEVICE_LINK_EXECUTABLE";
const std::string linkRule = this->GetLinkRule(linkRuleVar);
std::vector<std::string> commands1;
- cmExpandList(linkRule, real_link_commands);
+ cmList real_link_commands(linkRule);
bool useResponseFileForObjects =
this->CheckUseResponseFileForObjects(linkLanguage);
@@ -230,12 +232,12 @@ void cmMakefileExecutableTargetGenerator::WriteNvidiaDeviceExecutableRule(
launcher = cmStrCat(val, ' ');
}
- std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
- this->LocalGenerator->CreateRulePlaceholderExpander());
+ auto rulePlaceholderExpander =
+ this->LocalGenerator->CreateRulePlaceholderExpander();
// Expand placeholders in the commands.
rulePlaceholderExpander->SetTargetImpLib(targetOutput);
- for (std::string& real_link_command : real_link_commands) {
+ for (auto& real_link_command : real_link_commands) {
real_link_command = cmStrCat(launcher, real_link_command);
rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
real_link_command, vars);
@@ -466,18 +468,18 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
bool useLinkScript = this->GlobalGenerator->GetUseLinkScript();
// Construct the main link rule.
- std::vector<std::string> real_link_commands;
std::string linkRuleVar = this->GeneratorTarget->GetCreateRuleVariable(
linkLanguage, this->GetConfigName());
std::string linkRule = this->GetLinkRule(linkRuleVar);
std::vector<std::string> commands1;
- cmExpandList(linkRule, real_link_commands);
+ cmList real_link_commands(linkRule);
+
if (this->GeneratorTarget->IsExecutableWithExports()) {
// If a separate rule for creating an import library is specified
// add it now.
std::string implibRuleVar =
cmStrCat("CMAKE_", linkLanguage, "_CREATE_IMPORT_LIBRARY");
- this->Makefile->GetDefExpandList(implibRuleVar, real_link_commands);
+ real_link_commands.append(this->Makefile->GetDefinition(implibRuleVar));
}
bool useResponseFileForObjects =
@@ -596,12 +598,12 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink)
launcher = cmStrCat(val, ' ');
}
- std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
- this->LocalGenerator->CreateRulePlaceholderExpander());
+ auto rulePlaceholderExpander =
+ this->LocalGenerator->CreateRulePlaceholderExpander();
// Expand placeholders in the commands.
rulePlaceholderExpander->SetTargetImpLib(targetOutPathImport);
- for (std::string& real_link_command : real_link_commands) {
+ for (auto& real_link_command : real_link_commands) {
real_link_command = cmStrCat(launcher, real_link_command);
rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
real_link_command, vars);
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index 3e4a08ee27..b07a74b568 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -16,6 +16,7 @@
#include "cmGlobalUnixMakefileGenerator3.h"
#include "cmLinkLineComputer.h"
#include "cmLinkLineDeviceComputer.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
@@ -61,6 +62,9 @@ void cmMakefileLibraryTargetGenerator::WriteRuleFiles()
// write in rules for object files and custom commands
this->WriteTargetBuildRules();
+ // Write in the rules for the link dependency file
+ this->WriteTargetLinkDependRules();
+
// write the link rules
// Write the rule for this target type.
switch (this->GeneratorTarget->GetType()) {
@@ -304,7 +308,7 @@ void cmMakefileLibraryTargetGenerator::WriteNvidiaDeviceLibraryRules(
vars.Language = linkLanguage.c_str();
// Expand the rule variables.
- std::vector<std::string> real_link_commands;
+ cmList real_link_commands;
{
// Set path conversion for link script shells.
this->LocalGenerator->SetLinkScriptShell(useLinkScript);
@@ -369,16 +373,16 @@ void cmMakefileLibraryTargetGenerator::WriteNvidiaDeviceLibraryRules(
launcher = cmStrCat(val, ' ');
}
- std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
- this->LocalGenerator->CreateRulePlaceholderExpander());
+ auto rulePlaceholderExpander =
+ this->LocalGenerator->CreateRulePlaceholderExpander();
// Construct the main link rule and expand placeholders.
rulePlaceholderExpander->SetTargetImpLib(targetOutput);
std::string linkRule = this->GetLinkRule(linkRuleVar);
- cmExpandList(linkRule, real_link_commands);
+ real_link_commands.append(linkRule);
// Expand placeholders.
- for (std::string& real_link_command : real_link_commands) {
+ for (auto& real_link_command : real_link_commands) {
real_link_command = cmStrCat(launcher, real_link_command);
rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
real_link_command, vars);
@@ -640,9 +644,9 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
// For static libraries there might be archiving rules.
bool haveStaticLibraryRule = false;
- std::vector<std::string> archiveCreateCommands;
- std::vector<std::string> archiveAppendCommands;
- std::vector<std::string> archiveFinishCommands;
+ cmList archiveCreateCommands;
+ cmList archiveAppendCommands;
+ cmList archiveFinishCommands;
std::string::size_type archiveCommandLimit = std::string::npos;
if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY) {
haveStaticLibraryRule = this->Makefile->IsDefinitionSet(linkRuleVar);
@@ -652,21 +656,23 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
arCreateVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
arCreateVar, linkLanguage, this->GetConfigName());
- this->Makefile->GetDefExpandList(arCreateVar, archiveCreateCommands);
+ archiveCreateCommands.assign(this->Makefile->GetDefinition(arCreateVar));
+
std::string arAppendVar =
cmStrCat("CMAKE_", linkLanguage, "_ARCHIVE_APPEND");
arAppendVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
arAppendVar, linkLanguage, this->GetConfigName());
- this->Makefile->GetDefExpandList(arAppendVar, archiveAppendCommands);
+ archiveAppendCommands.assign(this->Makefile->GetDefinition(arAppendVar));
+
std::string arFinishVar =
cmStrCat("CMAKE_", linkLanguage, "_ARCHIVE_FINISH");
arFinishVar = this->GeneratorTarget->GetFeatureSpecificLinkRuleVariable(
arFinishVar, linkLanguage, this->GetConfigName());
- this->Makefile->GetDefExpandList(arFinishVar, archiveFinishCommands);
+ archiveFinishCommands.assign(this->Makefile->GetDefinition(arFinishVar));
}
// Decide whether to use archiving rules.
@@ -690,11 +696,11 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
}
// Expand the rule variables.
- std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
- this->LocalGenerator->CreateRulePlaceholderExpander());
+ auto rulePlaceholderExpander =
+ this->LocalGenerator->CreateRulePlaceholderExpander();
bool useWatcomQuote =
this->Makefile->IsOn(linkRuleVar + "_USE_WATCOM_QUOTE");
- std::vector<std::string> real_link_commands;
+ cmList real_link_commands;
{
// Set path conversion for link script shells.
this->LocalGenerator->SetLinkScriptShell(useLinkScript);
@@ -879,7 +885,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
} else {
// Get the set of commands.
std::string linkRule = this->GetLinkRule(linkRuleVar);
- cmExpandList(linkRule, real_link_commands);
+ real_link_commands.append(linkRule);
if (this->UseLWYU) {
cmValue lwyuCheck =
this->Makefile->GetDefinition("CMAKE_LINK_WHAT_YOU_USE_CHECK");
@@ -895,7 +901,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
}
// Expand placeholders.
- for (std::string& real_link_command : real_link_commands) {
+ for (auto& real_link_command : real_link_commands) {
real_link_command = cmStrCat(launcher, real_link_command);
rulePlaceholderExpander->ExpandRuleVariables(this->LocalGenerator,
real_link_command, vars);
@@ -965,7 +971,7 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules(
this->GeneratorTarget->HasImportLibrary(this->GetConfigName())) {
auto genStubsRule =
this->Makefile->GetDefinition("CMAKE_CREATE_TEXT_STUBS");
- auto genStubs_commands = cmExpandedList(genStubsRule);
+ cmList genStubs_commands{ genStubsRule };
std::string TBDFullPath =
cmStrCat(outpathImp, this->TargetNames.ImportOutput);
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 3112acd578..02cdf57275 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -29,6 +29,7 @@
#include "cmGlobalCommonGenerator.h"
#include "cmGlobalUnixMakefileGenerator3.h"
#include "cmLinkLineComputer.h" // IWYU pragma: keep
+#include "cmList.h"
#include "cmLocalCommonGenerator.h"
#include "cmLocalGenerator.h"
#include "cmLocalUnixMakefileGenerator3.h"
@@ -149,6 +150,8 @@ void cmMakefileTargetGenerator::GetTargetLinkFlags(
this->LocalGenerator->AppendPositionIndependentLinkerFlags(
flags, this->GeneratorTarget, this->GetConfigName(), linkLanguage);
+ this->LocalGenerator->AppendDependencyInfoLinkerFlags(
+ flags, this->GeneratorTarget, this->GetConfigName(), linkLanguage);
}
void cmMakefileTargetGenerator::CreateRuleFile()
@@ -207,27 +210,24 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
// -- Write the custom commands for this target
// Evaluates generator expressions and expands prop_value
- auto evaluatedFiles =
- [this](const std::string& prop_value) -> std::vector<std::string> {
- std::vector<std::string> files;
- cmExpandList(cmGeneratorExpression::Evaluate(
- prop_value, this->LocalGenerator, this->GetConfigName(),
- this->GeneratorTarget),
- files);
+ auto evaluatedFiles = [this](const std::string& prop_value) -> cmList {
+ cmList files{ cmGeneratorExpression::Evaluate(
+ prop_value, this->LocalGenerator, this->GetConfigName(),
+ this->GeneratorTarget) };
return files;
};
// Look for additional files registered for cleaning in this directory.
if (cmValue prop_value =
this->Makefile->GetProperty("ADDITIONAL_MAKE_CLEAN_FILES")) {
- std::vector<std::string> const files = evaluatedFiles(*prop_value);
+ auto const files = evaluatedFiles(*prop_value);
this->CleanFiles.insert(files.begin(), files.end());
}
// Look for additional files registered for cleaning in this target.
if (cmValue prop_value =
this->GeneratorTarget->GetProperty("ADDITIONAL_CLEAN_FILES")) {
- std::vector<std::string> const files = evaluatedFiles(*prop_value);
+ auto const files = evaluatedFiles(*prop_value);
// For relative path support
std::string const& binaryDir =
this->LocalGenerator->GetCurrentBinaryDirectory();
@@ -416,8 +416,10 @@ void cmMakefileTargetGenerator::WriteCommonCodeRules()
this->GlobalGenerator->SupportsCompilerDependencies() &&
(!this->Makefile->IsDefinitionSet(depsUseCompiler) ||
this->Makefile->IsOn(depsUseCompiler));
+ bool linkerGenerateDeps =
+ this->GeneratorTarget->HasLinkDependencyFile(this->GetConfigName());
- if (compilerGenerateDeps || ccGenerateDeps) {
+ if (compilerGenerateDeps || linkerGenerateDeps || ccGenerateDeps) {
std::string compilerDependFile =
cmStrCat(this->TargetBuildDirectoryFull, "/compiler_depend.make");
*this->BuildFileStream << "# Include any dependencies generated by the "
@@ -965,8 +967,8 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
bool const lang_has_assembly = lang_has_preprocessor;
bool const lang_can_export_cmds = lang_has_preprocessor;
- std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
- this->LocalGenerator->CreateRulePlaceholderExpander());
+ auto rulePlaceholderExpander =
+ this->LocalGenerator->CreateRulePlaceholderExpander();
// Construct the compile rules.
{
@@ -1002,10 +1004,10 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
vars.CudaCompileMode = cudaCompileMode.c_str();
}
- std::vector<std::string> compileCommands;
+ cmList compileCommands;
const std::string& compileRule = this->Makefile->GetRequiredDefinition(
"CMAKE_" + lang + "_COMPILE_OBJECT");
- cmExpandList(compileRule, compileCommands);
+ compileCommands.assign(compileRule);
if (this->GeneratorTarget->GetPropertyAsBool("EXPORT_COMPILE_COMMANDS") &&
lang_can_export_cmds && compileCommands.size() == 1) {
@@ -1200,7 +1202,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
// If compiler launcher was specified and not consumed above, it
// goes to the beginning of the command line.
if (!compileCommands.empty() && !compilerLauncher.empty()) {
- std::vector<std::string> args = cmExpandedList(compilerLauncher, true);
+ cmList args{ compilerLauncher, cmList::EmptyElements::Yes };
if (!args.empty()) {
args[0] = this->LocalGenerator->ConvertToOutputFormat(
args[0], cmOutputConverter::SHELL);
@@ -1208,7 +1210,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
i = this->LocalGenerator->EscapeForShell(i);
}
}
- compileCommands.front().insert(0, cmJoin(args, " ") + " ");
+ compileCommands.front().insert(0, args.join(" ") + " ");
}
std::string launcher;
@@ -1240,9 +1242,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
const auto& extraCommands = this->Makefile->GetSafeDefinition(
cmStrCat("CMAKE_", lang, "_DEPENDS_EXTRA_COMMANDS"));
if (!extraCommands.empty()) {
- auto commandList = cmExpandedList(extraCommands);
- compileCommands.insert(compileCommands.end(), commandList.cbegin(),
- commandList.cend());
+ compileCommands.append(extraCommands);
}
const auto& depFormat = this->Makefile->GetRequiredDefinition(
@@ -1283,14 +1283,15 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
}
// Check for extra outputs created by the compilation.
- std::vector<std::string> outputs(1, relativeObj);
+ cmList outputs;
+ outputs.emplace_back(relativeObj);
if (cmValue extra_outputs_str = source.GetProperty("OBJECT_OUTPUTS")) {
std::string evaluated_outputs = cmGeneratorExpression::Evaluate(
*extra_outputs_str, this->LocalGenerator, config);
if (!evaluated_outputs.empty()) {
// Register these as extra files to clean.
- cmExpandList(evaluated_outputs, outputs);
+ outputs.append(evaluated_outputs);
}
}
if (!ispcHeaderRelative.empty()) {
@@ -1341,8 +1342,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
cmStrCat("CMAKE_", lang, "_CREATE_PREPROCESSED_SOURCE");
if (cmValue preprocessRule =
this->Makefile->GetDefinition(preprocessRuleVar)) {
- std::vector<std::string> preprocessCommands =
- cmExpandedList(*preprocessRule);
+ cmList preprocessCommands{ *preprocessRule };
std::string shellObjI = this->LocalGenerator->ConvertToOutputFormat(
objI, cmOutputConverter::SHELL);
@@ -1386,8 +1386,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
cmStrCat("CMAKE_", lang, "_CREATE_ASSEMBLY_SOURCE");
if (cmValue assemblyRule =
this->Makefile->GetDefinition(assemblyRuleVar)) {
- std::vector<std::string> assemblyCommands =
- cmExpandedList(*assemblyRule);
+ cmList assemblyCommands{ *assemblyRule };
std::string shellObjS = this->LocalGenerator->ConvertToOutputFormat(
objS, cmOutputConverter::SHELL);
@@ -1504,6 +1503,21 @@ bool cmMakefileTargetGenerator::WriteMakeRule(
return symbolic;
}
+void cmMakefileTargetGenerator::WriteTargetLinkDependRules()
+{
+ if (!this->GeneratorTarget->HasLinkDependencyFile(this->GetConfigName())) {
+ return;
+ }
+
+ auto depFile = this->LocalGenerator->GetLinkDependencyFile(
+ this->GeneratorTarget, this->GetConfigName());
+ this->CleanFiles.insert(depFile);
+ this->LocalGenerator->AddImplicitDepends(
+ this->GeneratorTarget, "LINK",
+ this->GeneratorTarget->GetFullPath(this->GetConfigName()), depFile,
+ cmDependencyScannerKind::Compiler);
+}
+
void cmMakefileTargetGenerator::WriteTargetDependRules()
{
// must write the targets depend info file
@@ -1674,7 +1688,7 @@ void cmMakefileTargetGenerator::WriteDeviceLinkRule(
}
cmLocalUnixMakefileGenerator3* localGen{ this->LocalGenerator };
- std::vector<std::string> architectures = cmExpandedList(architecturesStr);
+ cmList architectures{ architecturesStr };
std::string const& relPath = localGen->GetHomeRelativeOutputPath();
// Ensure there are no duplicates.
@@ -1775,8 +1789,7 @@ void cmMakefileTargetGenerator::WriteDeviceLinkRule(
vars.Flags = flags.c_str();
std::string compileCmd = this->GetLinkRule("CMAKE_CUDA_DEVICE_LINK_COMPILE");
- std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
- localGen->CreateRulePlaceholderExpander());
+ auto rulePlaceholderExpander = localGen->CreateRulePlaceholderExpander();
rulePlaceholderExpander->ExpandRuleVariables(localGen, compileCmd, vars);
commands.emplace_back(compileCmd);
@@ -2057,8 +2070,14 @@ void cmMakefileTargetGenerator::AppendTargetDepends(
return;
}
- // Loop over all library dependencies.
const std::string& cfg = this->GetConfigName();
+
+ if (this->GeneratorTarget->HasLinkDependencyFile(cfg)) {
+ depends.push_back(
+ cmStrCat(this->TargetBuildDirectoryFull, "/compiler_depend.ts"));
+ }
+
+ // Loop over all library dependencies.
if (cmComputeLinkInformation* cli =
this->GeneratorTarget->GetLinkInformation(cfg)) {
cm::append(depends, cli->GetDepends());
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index 98c3a0e8db..ef7a60fa62 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -77,6 +77,8 @@ protected:
// write the clean rules for this target
void WriteTargetCleanRules();
+ // write the linker depend rules for this target
+ void WriteTargetLinkDependRules();
// write the depend rules for this target
void WriteTargetDependRules();
diff --git a/Source/cmMessageCommand.cxx b/Source/cmMessageCommand.cxx
index 52373f3160..baf40f8258 100644
--- a/Source/cmMessageCommand.cxx
+++ b/Source/cmMessageCommand.cxx
@@ -10,6 +10,7 @@
#include "cmConfigureLog.h"
#include "cmExecutionStatus.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmMessenger.h"
@@ -31,13 +32,13 @@ enum class CheckingType
std::string IndentText(std::string text, cmMakefile& mf)
{
auto indent =
- cmJoin(cmExpandedList(mf.GetSafeDefinition("CMAKE_MESSAGE_INDENT")), "");
+ cmList{ mf.GetSafeDefinition("CMAKE_MESSAGE_INDENT") }.join("");
const auto showContext = mf.GetCMakeInstance()->GetShowLogContext() ||
mf.IsOn("CMAKE_MESSAGE_CONTEXT_SHOW");
if (showContext) {
- auto context = cmJoin(
- cmExpandedList(mf.GetSafeDefinition("CMAKE_MESSAGE_CONTEXT")), ".");
+ auto context =
+ cmList{ mf.GetSafeDefinition("CMAKE_MESSAGE_CONTEXT") }.join(".");
if (!context.empty()) {
indent.insert(0u, cmStrCat("["_s, context, "] "_s));
}
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 4d68460521..063ca6ba6a 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -23,6 +23,7 @@
#include "cmGlobalNinjaGenerator.h"
#include "cmLinkLineComputer.h"
#include "cmLinkLineDeviceComputer.h"
+#include "cmList.h"
#include "cmLocalCommonGenerator.h"
#include "cmLocalGenerator.h"
#include "cmLocalNinjaGenerator.h"
@@ -213,6 +214,22 @@ std::string cmNinjaNormalTargetGenerator::TextStubsGeneratorRule(
'_', config);
}
+bool cmNinjaNormalTargetGenerator::CheckUseResponseFileForLibraries(
+ const std::string& l) const
+{
+ // Check for an explicit setting one way or the other.
+ std::string const responseVar =
+ "CMAKE_" + l + "_USE_RESPONSE_FILE_FOR_LIBRARIES";
+
+ // If the option is defined, read it's value
+ if (cmValue val = this->Makefile->GetDefinition(responseVar)) {
+ return val.IsOn();
+ }
+
+ // Default to true
+ return true;
+}
+
struct cmNinjaRemoveNoOpCommands
{
bool operator()(std::string const& cmd)
@@ -251,9 +268,16 @@ void cmNinjaNormalTargetGenerator::WriteNvidiaDeviceLinkRule(
} else {
rule.RspContent = "$in_newline";
}
- rule.RspContent += " $LINK_LIBRARIES";
+
+ // add the link command in the file if necessary
+ if (this->CheckUseResponseFileForLibraries("CUDA")) {
+ rule.RspContent += " $LINK_LIBRARIES";
+ vars.LinkLibraries = "";
+ } else {
+ vars.LinkLibraries = "$LINK_PATH $LINK_LIBRARIES";
+ }
+
vars.Objects = responseFlag.c_str();
- vars.LinkLibraries = "";
}
vars.ObjectDir = "$OBJECT_DIR";
@@ -278,8 +302,8 @@ void cmNinjaNormalTargetGenerator::WriteNvidiaDeviceLinkRule(
launcher = cmStrCat(val, ' ');
}
- std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
- this->GetLocalGenerator()->CreateRulePlaceholderExpander());
+ auto rulePlaceholderExpander =
+ this->GetLocalGenerator()->CreateRulePlaceholderExpander();
// Rule for linking library/executable.
std::vector<std::string> linkCmds = this->ComputeDeviceLinkCmd();
@@ -338,8 +362,8 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRules(
std::string compileCmd = this->GetMakefile()->GetRequiredDefinition(
"CMAKE_CUDA_DEVICE_LINK_COMPILE");
- std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
- this->GetLocalGenerator()->CreateRulePlaceholderExpander());
+ auto rulePlaceholderExpander =
+ this->GetLocalGenerator()->CreateRulePlaceholderExpander();
rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(),
compileCmd, vars);
@@ -393,6 +417,13 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile,
std::string cmakeVarLang =
cmStrCat("CMAKE_", this->TargetLinkLanguage(config));
+ if (this->GeneratorTarget->HasLinkDependencyFile(config)) {
+ auto DepFileFormat = this->GetMakefile()->GetDefinition(
+ cmStrCat(cmakeVarLang, "_LINKER_DEPFILE_FORMAT"));
+ rule.DepType = DepFileFormat;
+ rule.DepFile = "$DEP_FILE";
+ }
+
// build response file name
std::string cmakeLinkVar = cmakeVarLang + "_RESPONSE_FILE_LINK_FLAG";
cmValue flag = this->GetMakefile()->GetDefinition(cmakeLinkVar);
@@ -416,13 +447,20 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile,
} else {
rule.RspContent = "$in_newline";
}
- rule.RspContent += " $LINK_PATH $LINK_LIBRARIES";
+
+ // If libraries in rsp is enable
+ if (this->CheckUseResponseFileForLibraries(lang)) {
+ rule.RspContent += " $LINK_PATH $LINK_LIBRARIES";
+ vars.LinkLibraries = "";
+ } else {
+ vars.LinkLibraries = "$LINK_PATH $LINK_LIBRARIES";
+ }
+
if (this->TargetLinkLanguage(config) == "Swift") {
vars.SwiftSources = responseFlag.c_str();
} else {
vars.Objects = responseFlag.c_str();
}
- vars.LinkLibraries = "";
}
vars.ObjectDir = "$OBJECT_DIR";
@@ -473,8 +511,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile,
launcher = cmStrCat(val, ' ');
}
- std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
- this->GetLocalGenerator()->CreateRulePlaceholderExpander());
+ auto rulePlaceholderExpander =
+ this->GetLocalGenerator()->CreateRulePlaceholderExpander();
// Rule for linking library/executable.
std::vector<std::string> linkCmds = this->ComputeLinkCmd(config);
@@ -546,8 +584,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile,
std::string cmd =
this->GetMakefile()->GetDefinition("CMAKE_CREATE_TEXT_STUBS");
- std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
- this->GetLocalGenerator()->CreateRulePlaceholderExpander());
+ auto rulePlaceholderExpander =
+ this->GetLocalGenerator()->CreateRulePlaceholderExpander();
cmRulePlaceholderExpander::RuleVariables vars;
vars.Target = "$in";
rulePlaceholderExpander->SetTargetImpLib("$out");
@@ -579,7 +617,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile,
std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeDeviceLinkCmd()
{
- std::vector<std::string> linkCmds;
+ cmList linkCmds;
// this target requires separable cuda compilation
// now build the correct command depending on if the target is
@@ -588,23 +626,23 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeDeviceLinkCmd()
case cmStateEnums::STATIC_LIBRARY:
case cmStateEnums::SHARED_LIBRARY:
case cmStateEnums::MODULE_LIBRARY: {
- this->GetMakefile()->GetDefExpandList("CMAKE_CUDA_DEVICE_LINK_LIBRARY",
- linkCmds);
+ linkCmds.assign(
+ this->GetMakefile()->GetDefinition("CMAKE_CUDA_DEVICE_LINK_LIBRARY"));
} break;
case cmStateEnums::EXECUTABLE: {
- this->GetMakefile()->GetDefExpandList(
- "CMAKE_CUDA_DEVICE_LINK_EXECUTABLE", linkCmds);
+ linkCmds.assign(this->GetMakefile()->GetDefinition(
+ "CMAKE_CUDA_DEVICE_LINK_EXECUTABLE"));
} break;
default:
break;
}
- return linkCmds;
+ return std::move(linkCmds.data());
}
std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd(
const std::string& config)
{
- std::vector<std::string> linkCmds;
+ cmList linkCmds;
cmMakefile* mf = this->GetMakefile();
{
// If we have a rule variable prefer it. In the case of static libraries
@@ -623,7 +661,7 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd(
linkCmdStr += *rule;
}
}
- cmExpandList(linkCmdStr, linkCmds);
+ linkCmds.assign(linkCmdStr);
if (this->UseLWYU) {
cmValue lwyuCheck = mf->GetDefinition("CMAKE_LINK_WHAT_YOU_USE_CHECK");
if (lwyuCheck) {
@@ -642,7 +680,7 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd(
linkCmds.push_back(std::move(cmakeCommand));
}
}
- return linkCmds;
+ return std::move(linkCmds.data());
}
}
switch (this->GetGeneratorTarget()->GetType()) {
@@ -663,7 +701,7 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd(
linkCmdVar, this->TargetLinkLanguage(config), config);
std::string const& linkCmd = mf->GetRequiredDefinition(linkCmdVar);
- cmExpandList(linkCmd, linkCmds);
+ linkCmds.append(linkCmd);
}
{
std::string linkCmdVar = cmStrCat(
@@ -673,7 +711,7 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd(
linkCmdVar, this->TargetLinkLanguage(config), config);
std::string const& linkCmd = mf->GetRequiredDefinition(linkCmdVar);
- cmExpandList(linkCmd, linkCmds);
+ linkCmds.append(linkCmd);
}
#ifdef __APPLE__
// On macOS ranlib truncates the fractional part of the static archive
@@ -697,7 +735,7 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeLinkCmd(
default:
assert(false && "Unexpected target type");
}
- return linkCmds;
+ return std::move(linkCmds.data());
}
void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement(
@@ -754,7 +792,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement(
}
this->WriteDeviceLinkRules(config);
- this->WriteDeviceLinkStatements(config, cmExpandedList(architecturesStr),
+ this->WriteDeviceLinkStatements(config, cmList{ architecturesStr },
targetOutputReal);
} else {
this->WriteNvidiaDeviceLinkStatement(config, fileConfig, targetOutputDir,
@@ -1103,6 +1141,14 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement(
cmNinjaBuild linkBuild(this->LanguageLinkerRule(config));
cmNinjaVars& vars = linkBuild.Variables;
+ if (this->GeneratorTarget->HasLinkDependencyFile(config)) {
+ vars["DEP_FILE"] = this->GetLocalGenerator()->ConvertToOutputFormat(
+ this->ConvertToNinjaPath(
+ this->GetLocalGenerator()->GetLinkDependencyFile(this->GeneratorTarget,
+ config)),
+ cmOutputConverter::SHELL);
+ }
+
// Compute the comment.
linkBuild.Comment =
cmStrCat("Link the ", this->GetVisibleTypeName(), ' ', targetOutputReal);
diff --git a/Source/cmNinjaNormalTargetGenerator.h b/Source/cmNinjaNormalTargetGenerator.h
index 85f42a4487..187ea4627a 100644
--- a/Source/cmNinjaNormalTargetGenerator.h
+++ b/Source/cmNinjaNormalTargetGenerator.h
@@ -26,7 +26,7 @@ private:
const std::string& config) const;
std::string LanguageLinkerCudaFatbinaryRule(const std::string& config) const;
std::string TextStubsGeneratorRule(const std::string& config) const;
-
+ bool CheckUseResponseFileForLibraries(const std::string& config) const;
const char* GetVisibleTypeName() const;
void WriteLanguagesRules(const std::string& config);
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 5dbc283fac..4ed491d33c 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -9,6 +9,7 @@
#include <iterator>
#include <map>
#include <ostream>
+#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
@@ -21,8 +22,6 @@
#include <cm3p/json/value.h>
#include <cm3p/json/writer.h>
-#include "cmsys/RegularExpression.hxx"
-
#include "cmComputeLinkInformation.h"
#include "cmCustomCommandGenerator.h"
#include "cmDyndepCollation.h"
@@ -32,6 +31,7 @@
#include "cmGeneratorTarget.h"
#include "cmGlobalCommonGenerator.h"
#include "cmGlobalNinjaGenerator.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmLocalNinjaGenerator.h"
#include "cmMakefile.h"
@@ -665,8 +665,8 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
std::string const modmapFormat =
this->Makefile->GetSafeDefinition(modmapFormatVar);
- std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
- this->GetLocalGenerator()->CreateRulePlaceholderExpander());
+ auto rulePlaceholderExpander =
+ this->GetLocalGenerator()->CreateRulePlaceholderExpander();
std::string const tdi = this->GetLocalGenerator()->ConvertToOutputFormat(
this->ConvertToNinjaPath(this->GetTargetDependInfoPath(lang, config)),
@@ -689,7 +689,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
// Rule to scan dependencies of sources that need preprocessing.
{
- std::vector<std::string> scanCommands;
+ cmList scanCommands;
std::string scanRuleName;
std::string ppFileName;
if (compilationPreprocesses) {
@@ -697,8 +697,8 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
ppFileName = "$PREPROCESSED_OUTPUT_FILE";
std::string const& scanCommand = mf->GetRequiredDefinition(
cmStrCat("CMAKE_EXPERIMENTAL_", lang, "_SCANDEP_SOURCE"));
- cmExpandList(scanCommand, scanCommands);
- for (std::string& i : scanCommands) {
+ scanCommands.assign(scanCommand);
+ for (auto& i : scanCommands) {
i = cmStrCat(launcher, i);
}
} else {
@@ -706,8 +706,8 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
ppFileName = "$out";
std::string const& ppCommmand = mf->GetRequiredDefinition(
cmStrCat("CMAKE_", lang, "_PREPROCESS_SOURCE"));
- cmExpandList(ppCommmand, scanCommands);
- for (std::string& i : scanCommands) {
+ scanCommands.assign(ppCommmand);
+ for (auto& i : scanCommands) {
i = cmStrCat(launcher, i);
}
scanCommands.emplace_back(GetScanCommand(cmakeCmd, tdi, lang, "$out",
@@ -886,10 +886,9 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
}
// Rule for compiling object file.
- std::vector<std::string> compileCmds;
const std::string cmdVar = cmStrCat("CMAKE_", lang, "_COMPILE_OBJECT");
const std::string& compileCmd = mf->GetRequiredDefinition(cmdVar);
- cmExpandList(compileCmd, compileCmds);
+ cmList compileCmds(compileCmd);
// See if we need to use a compiler launcher like ccache or distcc
std::string compilerLauncher;
@@ -1038,7 +1037,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
// If compiler launcher was specified and not consumed above, it
// goes to the beginning of the command line.
if (!compileCmds.empty() && !compilerLauncher.empty()) {
- std::vector<std::string> args = cmExpandedList(compilerLauncher, true);
+ cmList args{ compilerLauncher, cmList::EmptyElements::Yes };
if (!args.empty()) {
args[0] = this->LocalGenerator->ConvertToOutputFormat(
args[0], cmOutputConverter::SHELL);
@@ -1046,7 +1045,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
i = this->LocalGenerator->EscapeForShell(i);
}
}
- compileCmds.front().insert(0, cmStrCat(cmJoin(args, " "), ' '));
+ compileCmds.front().insert(0, cmStrCat(args.join(" "), ' '));
}
if (!compileCmds.empty()) {
@@ -1056,12 +1055,10 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
const auto& extraCommands = this->GetMakefile()->GetSafeDefinition(
cmStrCat("CMAKE_", lang, "_DEPENDS_EXTRA_COMMANDS"));
if (!extraCommands.empty()) {
- auto commandList = cmExpandedList(extraCommands);
- compileCmds.insert(compileCmds.end(), commandList.cbegin(),
- commandList.cend());
+ compileCmds.append(extraCommands);
}
- for (std::string& i : compileCmds) {
+ for (auto& i : compileCmds) {
i = cmStrCat(launcher, i);
rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(), i,
vars);
@@ -1261,7 +1258,6 @@ namespace {
cmNinjaBuild GetScanBuildStatement(const std::string& ruleName,
const std::string& ppFileName,
bool compilePP, bool compilePPWithDefines,
- cmValue ppExcludeFlagsRegex,
cmNinjaBuild& objBuild, cmNinjaVars& vars,
const std::string& objectFileName,
cmLocalGenerator* lg)
@@ -1290,20 +1286,6 @@ cmNinjaBuild GetScanBuildStatement(const std::string& ruleName,
// Scanning and compilation generally use the same flags.
scanBuild.Variables["FLAGS"] = vars["FLAGS"];
- // Exclude flags not valid during preprocessing.
- if (compilePP && !ppExcludeFlagsRegex.IsEmpty()) {
- std::string in = std::move(scanBuild.Variables["FLAGS"]);
- std::string out;
- cmsys::RegularExpression regex(*ppExcludeFlagsRegex);
- std::string::size_type pos = 0;
- while (regex.find(in.c_str() + pos)) {
- out = cmStrCat(out, in.substr(pos, regex.start()), ' ');
- pos += regex.end();
- }
- out = cmStrCat(out, in.substr(pos));
- scanBuild.Variables["FLAGS"] = std::move(out);
- }
-
if (compilePP && !compilePPWithDefines) {
// Move preprocessor definitions to the scan/preprocessor build statement.
std::swap(scanBuild.Variables["DEFINES"], vars["DEFINES"]);
@@ -1468,7 +1450,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
}
if (cmValue objectDeps = source->GetProperty("OBJECT_DEPENDS")) {
- std::vector<std::string> objDepList = cmExpandedList(*objectDeps);
+ cmList objDepList{ *objectDeps };
std::copy(objDepList.begin(), objDepList.end(),
std::back_inserter(depList));
}
@@ -1528,22 +1510,18 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
std::string scanRuleName;
std::string ppFileName;
- cmValue ppExcludeFlagsRegex;
if (compilePP) {
scanRuleName = this->LanguagePreprocessAndScanRule(language, config);
ppFileName = this->ConvertToNinjaPath(
this->GetPreprocessedFilePath(source, config));
- ppExcludeFlagsRegex = this->Makefile->GetDefinition(cmStrCat(
- "CMAKE_", language, "_PREPROCESS_SOURCE_EXCLUDE_FLAGS_REGEX"));
} else {
scanRuleName = this->LanguageScanRule(language, config);
ppFileName = cmStrCat(objectFileName, ".ddi.i");
}
cmNinjaBuild ppBuild = GetScanBuildStatement(
- scanRuleName, ppFileName, compilePP, compilePPWithDefines,
- ppExcludeFlagsRegex, objBuild, vars, objectFileName,
- this->LocalGenerator);
+ scanRuleName, ppFileName, compilePP, compilePPWithDefines, objBuild,
+ vars, objectFileName, this->LocalGenerator);
if (compilePP) {
// In case compilation requires flags that are incompatible with
@@ -1688,7 +1666,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
if (!evaluatedObjectOutputs.empty()) {
cmNinjaBuild build("phony");
build.Comment = "Additional output files.";
- build.Outputs = cmExpandedList(evaluatedObjectOutputs);
+ build.Outputs = cmList{ evaluatedObjectOutputs }.data();
std::transform(build.Outputs.begin(), build.Outputs.end(),
build.Outputs.begin(), this->MapToNinjaPath());
build.ExplicitDeps = objBuild.Outputs;
@@ -1882,16 +1860,15 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand(
compileObjectVars.CudaCompileMode = cudaCompileMode.c_str();
}
- std::vector<std::string> compileCmds;
const std::string cmdVar = cmStrCat("CMAKE_", language, "_COMPILE_OBJECT");
const std::string& compileCmd =
this->Makefile->GetRequiredDefinition(cmdVar);
- cmExpandList(compileCmd, compileCmds);
+ cmList compileCmds(compileCmd);
- std::unique_ptr<cmRulePlaceholderExpander> rulePlaceholderExpander(
- this->GetLocalGenerator()->CreateRulePlaceholderExpander());
+ auto rulePlaceholderExpander =
+ this->GetLocalGenerator()->CreateRulePlaceholderExpander();
- for (std::string& i : compileCmds) {
+ for (auto& i : compileCmds) {
// no launcher for CMAKE_EXPORT_COMPILE_COMMANDS
rulePlaceholderExpander->ExpandRuleVariables(this->GetLocalGenerator(), i,
compileObjectVars);
@@ -1909,13 +1886,11 @@ void cmNinjaTargetGenerator::AdditionalCleanFiles(const std::string& config)
if (cmValue prop_value =
this->GeneratorTarget->GetProperty("ADDITIONAL_CLEAN_FILES")) {
cmLocalNinjaGenerator* lg = this->LocalGenerator;
- std::vector<std::string> cleanFiles;
- cmExpandList(cmGeneratorExpression::Evaluate(*prop_value, lg, config,
- this->GeneratorTarget),
- cleanFiles);
+ cmList cleanFiles(cmGeneratorExpression::Evaluate(*prop_value, lg, config,
+ this->GeneratorTarget));
std::string const& binaryDir = lg->GetCurrentBinaryDirectory();
cmGlobalNinjaGenerator* gg = lg->GetGlobalNinjaGenerator();
- for (std::string const& cleanFile : cleanFiles) {
+ for (auto const& cleanFile : cleanFiles) {
// Support relative paths
gg->AddAdditionalCleanFile(
cmSystemTools::CollapseFullPath(cleanFile, binaryDir), config);
diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx
index 6c54e01e3d..53cb21e59d 100644
--- a/Source/cmOutputConverter.cxx
+++ b/Source/cmOutputConverter.cxx
@@ -6,16 +6,15 @@
#include <cassert>
#include <cctype>
#include <set>
-#include <vector>
#ifdef _WIN32
# include <unordered_map>
# include <utility>
#endif
+#include "cmList.h"
#include "cmState.h"
#include "cmStateDirectory.h"
-#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
@@ -176,7 +175,12 @@ std::string cmOutputConverter::ConvertToOutputForExisting(
}
std::string tmp{};
- cmSystemTools::GetShortPath(remote, tmp);
+ cmsys::Status status = cmSystemTools::GetShortPath(remote, tmp);
+ if (!status) {
+ // Fallback for cases when Windows refuses to resolve the short path,
+ // like for C:\Program Files\WindowsApps\...
+ tmp = remote;
+ }
shortPathCache[remote] = tmp;
return tmp;
}();
@@ -319,7 +323,7 @@ cmOutputConverter::FortranFormat cmOutputConverter::GetFortranFormat(
{
FortranFormat format = FortranFormatNone;
if (!value.empty()) {
- for (std::string const& fi : cmExpandedList(value)) {
+ for (std::string const& fi : cmList(value)) {
if (fi == "FIXED") {
format = FortranFormatFixed;
}
diff --git a/Source/cmOutputConverter.h b/Source/cmOutputConverter.h
index 2717bdd1c2..625d89768c 100644
--- a/Source/cmOutputConverter.h
+++ b/Source/cmOutputConverter.h
@@ -16,6 +16,7 @@ class cmOutputConverter
{
public:
cmOutputConverter(cmStateSnapshot const& snapshot);
+ virtual ~cmOutputConverter() = default;
/**
* Convert the given remote path to a relative path with respect to
@@ -27,6 +28,15 @@ public:
std::string MaybeRelativeToTopBinDir(std::string const& path) const;
std::string MaybeRelativeToCurBinDir(std::string const& path) const;
+ /**
+ * The effective working directory can be different for each generator.
+ * By default, equivalent to the current binary directory.
+ */
+ virtual std::string MaybeRelativeToWorkDir(std::string const& path) const
+ {
+ return this->MaybeRelativeToCurBinDir(path);
+ }
+
std::string const& GetRelativePathTopSource() const;
std::string const& GetRelativePathTopBinary() const;
void SetRelativePathTop(std::string const& topSource,
diff --git a/Source/cmOutputRequiredFilesCommand.cxx b/Source/cmOutputRequiredFilesCommand.cxx
index ad276d2f70..f147ed22de 100644
--- a/Source/cmOutputRequiredFilesCommand.cxx
+++ b/Source/cmOutputRequiredFilesCommand.cxx
@@ -14,6 +14,7 @@
#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
#include "cmStringAlgorithms.h"
@@ -126,9 +127,9 @@ public:
std::string incDirs = cmGeneratorExpression::Preprocess(
*incDirProp, cmGeneratorExpression::StripAllGeneratorExpressions);
- std::vector<std::string> includes = cmExpandedList(incDirs);
+ cmList includes{ incDirs };
- for (std::string& path : includes) {
+ for (auto& path : includes) {
this->Makefile->ExpandVariablesInString(path);
if (uniqueIncludes.insert(path).second) {
orderedAndUniqueIncludes.push_back(path);
diff --git a/Source/cmParseArgumentsCommand.cxx b/Source/cmParseArgumentsCommand.cxx
index 7e195664e2..b0462f056a 100644
--- a/Source/cmParseArgumentsCommand.cxx
+++ b/Source/cmParseArgumentsCommand.cxx
@@ -12,6 +12,7 @@
#include "cmArgumentParser.h"
#include "cmArgumentParserTypes.h"
#include "cmExecutionStatus.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmRange.h"
@@ -169,17 +170,15 @@ bool cmParseArgumentsCommand(std::vector<std::string> const& args,
};
// the second argument is a (cmake) list of options without argument
- std::vector<std::string> list = cmExpandedList(*argIter++);
+ cmList list{ *argIter++ };
parser.Bind(list, options, duplicateKey);
// the third argument is a (cmake) list of single argument options
- list.clear();
- cmExpandList(*argIter++, list);
+ list.assign(*argIter++);
parser.Bind(list, singleValArgs, duplicateKey);
// the fourth argument is a (cmake) list of multi argument options
- list.clear();
- cmExpandList(*argIter++, list);
+ list.assign(*argIter++);
parser.Bind(list, multiValArgs, duplicateKey);
list.clear();
@@ -187,7 +186,7 @@ bool cmParseArgumentsCommand(std::vector<std::string> const& args,
// Flatten ;-lists in the arguments into a single list as was done
// by the original function(CMAKE_PARSE_ARGUMENTS).
for (; argIter != argEnd; ++argIter) {
- cmExpandList(*argIter, list);
+ list.append(*argIter);
}
} else {
// in the PARSE_ARGV move read the arguments from ARGC and ARGV#
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index fe883826aa..a0030d3dc1 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -450,7 +450,16 @@ class cmMakefile;
27, 0, cmPolicies::WARN) \
SELECT(POLICY, CMP0149, \
"Visual Studio generators select latest Windows SDK by default.", 3, \
- 27, 0, cmPolicies::WARN)
+ 27, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0150, \
+ "ExternalProject_Add and FetchContent_Declare commands " \
+ "treat relative GIT_REPOSITORY paths as being relative " \
+ "to the parent project's remote.", \
+ 3, 27, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0151, \
+ "AUTOMOC include directory is a system include directory by " \
+ "default.", \
+ 3, 27, 0, cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index 782c154653..d897f0e5be 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -35,6 +35,7 @@
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmLinkItem.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
@@ -507,7 +508,7 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
std::string const& deps =
this->GenTarget->GetSafeProperty("AUTOGEN_TARGET_DEPENDS");
if (!deps.empty()) {
- for (std::string const& depName : cmExpandedList(deps)) {
+ for (auto const& depName : cmList{ deps }) {
// Allow target and file dependencies
auto* depTarget = this->Makefile->FindTargetToUse(depName);
if (depTarget) {
@@ -545,8 +546,8 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
this->Moc.MacroNames.erase(cmRemoveDuplicates(this->Moc.MacroNames),
this->Moc.MacroNames.end());
{
- auto filterList = cmExpandedList(
- this->GenTarget->GetSafeProperty("AUTOMOC_DEPEND_FILTERS"));
+ cmList filterList = { this->GenTarget->GetSafeProperty(
+ "AUTOMOC_DEPEND_FILTERS") };
if ((filterList.size() % 2) != 0) {
cmSystemTools::Error(
cmStrCat("AutoMoc: AUTOMOC_DEPEND_FILTERS predefs size ",
@@ -558,7 +559,7 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
"Q_PLUGIN_METADATA",
"[\n][ \t]*Q_PLUGIN_METADATA[ \t]*\\("
"[^\\)]*FILE[ \t]*\"([^\"]+)\"");
- for (std::size_t ii = 0; ii != filterList.size(); ii += 2) {
+ for (cmList::size_type ii = 0; ii != filterList.size(); ii += 2) {
this->Moc.DependFilters.emplace_back(filterList[ii],
filterList[ii + 1]);
}
@@ -573,7 +574,31 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
// Add autogen include directory to the origin target INCLUDE_DIRECTORIES
if (this->MocOrUicEnabled() || (this->Rcc.Enabled && this->MultiConfig)) {
- this->GenTarget->AddIncludeDirectory(this->Dir.IncludeGenExp, true);
+ auto addBefore = false;
+ auto const& value =
+ this->GenTarget->GetProperty("AUTOGEN_USE_SYSTEM_INCLUDE");
+ if (value.IsSet()) {
+ if (cmIsOn(value)) {
+ this->GenTarget->AddSystemIncludeDirectory(this->Dir.IncludeGenExp,
+ "CXX");
+ } else {
+ addBefore = true;
+ }
+ } else {
+ switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0151)) {
+ case cmPolicies::WARN:
+ case cmPolicies::OLD:
+ addBefore = true;
+ break;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::NEW:
+ this->GenTarget->AddSystemIncludeDirectory(this->Dir.IncludeGenExp,
+ "CXX");
+ break;
+ }
+ }
+ this->GenTarget->AddIncludeDirectory(this->Dir.IncludeGenExp, addBefore);
}
// Scan files
@@ -613,8 +638,9 @@ bool cmQtAutoGenInitializer::InitMoc()
if (this->GenTarget->GetPropertyAsBool("AUTOMOC_COMPILER_PREDEFINES") &&
(this->QtVersion >= IntegerVersion(5, 8))) {
// Command
- this->Makefile->GetDefExpandList("CMAKE_CXX_COMPILER_PREDEFINES_COMMAND",
- this->Moc.PredefsCmd);
+ cmList::assign(
+ this->Moc.PredefsCmd,
+ this->Makefile->GetDefinition("CMAKE_CXX_COMPILER_PREDEFINES_COMMAND"));
// Header
if (!this->Moc.PredefsCmd.empty()) {
this->ConfigFileNames(this->Moc.PredefsFile,
@@ -701,7 +727,7 @@ bool cmQtAutoGenInitializer::InitUic()
this->GenTarget->GetSafeProperty("AUTOUIC_SEARCH_PATHS");
if (!usp.empty()) {
this->Uic.SearchPaths =
- SearchPathSanitizer(this->Makefile)(cmExpandedList(usp));
+ SearchPathSanitizer(this->Makefile)(cmList{ usp });
}
}
// Uic target options
@@ -961,8 +987,8 @@ bool cmQtAutoGenInitializer::InitScanFiles()
if (uicOpts.empty()) {
this->Uic.UiFilesNoOptions.emplace_back(fullPath);
} else {
- this->Uic.UiFilesWithOptions.emplace_back(fullPath,
- cmExpandedList(uicOpts));
+ this->Uic.UiFilesWithOptions.emplace_back(
+ fullPath, std::move(cmList{ uicOpts }.data()));
}
auto uiHeaderRelativePath = cmSystemTools::RelativePath(
@@ -1063,8 +1089,8 @@ bool cmQtAutoGenInitializer::InitScanFiles()
if (!this->Rcc.Qrcs.empty()) {
const bool modernQt = (this->QtVersion.Major >= 5);
// Target rcc options
- std::vector<std::string> optionsTarget =
- cmExpandedList(this->GenTarget->GetSafeProperty(kw.AUTORCC_OPTIONS));
+ cmList optionsTarget{ this->GenTarget->GetSafeProperty(
+ kw.AUTORCC_OPTIONS) };
// Check if file name is unique
for (Qrc& qrc : this->Rcc.Qrcs) {
diff --git a/Source/cmRemoveCommand.cxx b/Source/cmRemoveCommand.cxx
index 8af13ae2b4..65a2268bc8 100644
--- a/Source/cmRemoveCommand.cxx
+++ b/Source/cmRemoveCommand.cxx
@@ -3,8 +3,8 @@
#include "cmRemoveCommand.h"
#include "cmExecutionStatus.h"
+#include "cmList.h"
#include "cmMakefile.h"
-#include "cmStringAlgorithms.h"
#include "cmValue.h"
// cmRemoveCommand
@@ -25,12 +25,11 @@ bool cmRemoveCommand(std::vector<std::string> const& args,
}
// expand the variable
- std::vector<std::string> const varArgsExpanded = cmExpandedList(*cacheValue);
+ cmList const varArgsExpanded{ *cacheValue };
// expand the args
// check for REMOVE(VAR v1 v2 ... vn)
- std::vector<std::string> const argsExpanded =
- cmExpandedLists(args.begin() + 1, args.end());
+ cmList const argsExpanded{ args.begin() + 1, args.end() };
// now create the new value
std::string value;
diff --git a/Source/cmRuntimeDependencyArchive.cxx b/Source/cmRuntimeDependencyArchive.cxx
index 4dfdfae4f9..2fbf2fa04c 100644
--- a/Source/cmRuntimeDependencyArchive.cxx
+++ b/Source/cmRuntimeDependencyArchive.cxx
@@ -3,13 +3,21 @@
#include "cmRuntimeDependencyArchive.h"
+#include <algorithm>
+#include <sstream>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <cm/memory>
+
#include "cmBinUtilsLinuxELFLinker.h"
#include "cmBinUtilsMacOSMachOLinker.h"
#include "cmBinUtilsWindowsPELinker.h"
#include "cmExecutionStatus.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmStateTypes.h"
-#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#if defined(_WIN32)
@@ -22,14 +30,6 @@
# include "cmVSSetupHelper.h"
#endif
-#include <algorithm>
-#include <sstream>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include <cm/memory>
-
#if defined(_WIN32)
static void AddVisualStudioPath(std::vector<std::string>& paths,
const std::string& prefix,
diff --git a/Source/cmSearchPath.cxx b/Source/cmSearchPath.cxx
index d5f6f0dc21..2b992ef285 100644
--- a/Source/cmSearchPath.cxx
+++ b/Source/cmSearchPath.cxx
@@ -9,6 +9,7 @@
#include <cm/optional>
#include "cmFindCommon.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -71,7 +72,7 @@ void cmSearchPath::AddCMakePath(const std::string& variable)
// Get a path from a CMake variable.
if (cmValue value = this->FC->Makefile->GetDefinition(variable)) {
- std::vector<std::string> expanded = cmExpandedList(*value);
+ cmList expanded{ *value };
for (std::string const& p : expanded) {
this->AddPathInternal(
@@ -95,7 +96,7 @@ void cmSearchPath::AddCMakePrefixPath(const std::string& variable)
// Get a path from a CMake variable.
if (cmValue value = this->FC->Makefile->GetDefinition(variable)) {
- std::vector<std::string> expanded = cmExpandedList(*value);
+ cmList expanded{ *value };
this->AddPrefixPaths(
expanded, this->FC->Makefile->GetCurrentSourceDirectory().c_str());
diff --git a/Source/cmStandardLevelResolver.cxx b/Source/cmStandardLevelResolver.cxx
index d2eac0cd7b..f6e8bc6f34 100644
--- a/Source/cmStandardLevelResolver.cxx
+++ b/Source/cmStandardLevelResolver.cxx
@@ -18,6 +18,7 @@
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -349,7 +350,7 @@ struct StandardLevelComputer
for (size_t i = 0; i < this->Levels.size(); ++i) {
if (cmValue prop = makefile->GetDefinition(
cmStrCat(prefix, this->LevelsAsStrings[i], "_COMPILE_FEATURES"))) {
- std::vector<std::string> props = cmExpandedList(*prop);
+ cmList props{ *prop };
if (cm::contains(props, feature)) {
maxLevel = { static_cast<int>(i), this->Levels[i] };
}
@@ -468,7 +469,7 @@ bool cmStandardLevelResolver::CheckCompileFeaturesAvailable(
return false;
}
- std::vector<std::string> availableFeatures = cmExpandedList(features);
+ cmList availableFeatures{ features };
if (!cm::contains(availableFeatures, feature)) {
std::ostringstream e;
e << "The compiler feature \"" << feature << "\" is not known to " << lang
diff --git a/Source/cmStringAlgorithms.cxx b/Source/cmStringAlgorithms.cxx
index 66bf383941..e352d8dd22 100644
--- a/Source/cmStringAlgorithms.cxx
+++ b/Source/cmStringAlgorithms.cxx
@@ -80,77 +80,6 @@ std::vector<std::string> cmTokenize(cm::string_view str, cm::string_view sep)
return tokens;
}
-void cmExpandList(cm::string_view arg, std::vector<std::string>& argsOut,
- bool emptyArgs)
-{
- // If argument is empty, it is an empty list.
- if (!emptyArgs && arg.empty()) {
- return;
- }
-
- // if there are no ; in the name then just copy the current string
- if (arg.find(';') == cm::string_view::npos) {
- argsOut.emplace_back(arg);
- return;
- }
-
- std::string newArg;
- // Break the string at non-escaped semicolons not nested in [].
- int squareNesting = 0;
- cm::string_view::iterator last = arg.begin();
- cm::string_view::iterator const cend = arg.end();
- for (cm::string_view::iterator c = last; c != cend; ++c) {
- switch (*c) {
- case '\\': {
- // We only want to allow escaping of semicolons. Other
- // escapes should not be processed here.
- cm::string_view::iterator cnext = c + 1;
- if ((cnext != cend) && *cnext == ';') {
- newArg.append(last, c);
- // Skip over the escape character
- last = cnext;
- c = cnext;
- }
- } break;
- case '[': {
- ++squareNesting;
- } break;
- case ']': {
- --squareNesting;
- } break;
- case ';': {
- // Break the string here if we are not nested inside square
- // brackets.
- if (squareNesting == 0) {
- newArg.append(last, c);
- // Skip over the semicolon
- last = c + 1;
- if (!newArg.empty() || emptyArgs) {
- // Add the last argument if the string is not empty.
- argsOut.push_back(newArg);
- newArg.clear();
- }
- }
- } break;
- default: {
- // Just append this character.
- } break;
- }
- }
- newArg.append(last, cend);
- if (!newArg.empty() || emptyArgs) {
- // Add the last argument if the string is not empty.
- argsOut.push_back(std::move(newArg));
- }
-}
-
-std::vector<std::string> cmExpandedList(cm::string_view arg, bool emptyArgs)
-{
- std::vector<std::string> argsOut;
- cmExpandList(arg, argsOut, emptyArgs);
- return argsOut;
-}
-
namespace {
template <std::size_t N, typename T>
inline void MakeDigits(cm::string_view& view, char (&digits)[N],
diff --git a/Source/cmStringAlgorithms.h b/Source/cmStringAlgorithms.h
index 9ea74919f6..4a9840b166 100644
--- a/Source/cmStringAlgorithms.h
+++ b/Source/cmStringAlgorithms.h
@@ -88,63 +88,6 @@ std::string cmJoin(cmStringRange const& rng, cm::string_view separator,
/** Extract tokens that are separated by any of the characters in @a sep. */
std::vector<std::string> cmTokenize(cm::string_view str, cm::string_view sep);
-/**
- * Expand the ; separated string @a arg into multiple arguments.
- * All found arguments are appended to @a argsOut.
- */
-void cmExpandList(cm::string_view arg, std::vector<std::string>& argsOut,
- bool emptyArgs = false);
-inline void cmExpandList(cmValue arg, std::vector<std::string>& argsOut,
- bool emptyArgs = false)
-{
- if (arg) {
- cmExpandList(*arg, argsOut, emptyArgs);
- }
-}
-
-/**
- * Expand out any arguments in the string range [@a first, @a last) that have
- * ; separated strings into multiple arguments. All found arguments are
- * appended to @a argsOut.
- */
-template <class InputIt>
-void cmExpandLists(InputIt first, InputIt last,
- std::vector<std::string>& argsOut)
-{
- for (; first != last; ++first) {
- cmExpandList(*first, argsOut);
- }
-}
-
-/**
- * Same as cmExpandList but a new vector is created containing
- * the expanded arguments from the string @a arg.
- */
-std::vector<std::string> cmExpandedList(cm::string_view arg,
- bool emptyArgs = false);
-inline std::vector<std::string> cmExpandedList(cmValue arg,
- bool emptyArgs = false)
-{
- if (!arg) {
- return {};
- }
- return cmExpandedList(*arg, emptyArgs);
-}
-
-/**
- * Same as cmExpandList but a new vector is created containing the expanded
- * versions of all arguments in the string range [@a first, @a last).
- */
-template <class InputIt>
-std::vector<std::string> cmExpandedLists(InputIt first, InputIt last)
-{
- std::vector<std::string> argsOut;
- for (; first != last; ++first) {
- cmExpandList(*first, argsOut);
- }
- return argsOut;
-}
-
/** Concatenate string pieces into a single string. */
std::string cmCatViews(
std::initializer_list<std::pair<cm::string_view, std::string*>> views);
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 5e558714e2..0fbe430140 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -23,6 +23,7 @@
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -92,7 +93,7 @@ cmValue cmTargetPropertyComputer::GetSources<cmTarget>(cmTarget const* tgt,
std::ostringstream ss;
const char* sep = "";
for (auto const& entry : entries) {
- std::vector<std::string> files = cmExpandedList(entry.Value);
+ cmList files{ entry.Value };
for (std::string const& file : files) {
if (cmHasLiteralPrefix(file, "$<TARGET_OBJECTS:") &&
file.back() == '>') {
@@ -396,6 +397,10 @@ TargetProperty const StaticTargetProperties[] = {
{ "MSVC_DEBUG_INFORMATION_FORMAT"_s, IC::CanCompileSources },
{ "MSVC_RUNTIME_LIBRARY"_s, IC::CanCompileSources },
{ "VS_JUST_MY_CODE_DEBUGGING"_s, IC::CanCompileSources },
+ { "VS_DEBUGGER_COMMAND"_s, IC::ExecutableTarget },
+ { "VS_DEBUGGER_COMMAND_ARGUMENTS"_s, IC::ExecutableTarget },
+ { "VS_DEBUGGER_ENVIRONMENT"_s, IC::ExecutableTarget },
+ { "VS_DEBUGGER_WORKING_DIRECTORY"_s, IC::ExecutableTarget },
// ---- OpenWatcom
{ "WATCOM_RUNTIME_LIBRARY"_s, IC::CanCompileSources },
// -- Language
@@ -545,6 +550,7 @@ TargetProperty const StaticTargetProperties[] = {
// -- Autogen
{ "AUTOGEN_ORIGIN_DEPENDS"_s, IC::CanCompileSources },
{ "AUTOGEN_PARALLEL"_s, IC::CanCompileSources },
+ { "AUTOGEN_USE_SYSTEM_INCLUDE"_s, IC::CanCompileSources },
// -- moc
{ "AUTOMOC_DEPEND_FILTERS"_s, IC::CanCompileSources },
// -- C++
@@ -1115,7 +1121,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
if (globals) {
const std::string genName = mf->GetGlobalGenerator()->GetName();
if (cmHasLiteralPrefix(genName, "Visual Studio")) {
- std::vector<std::string> props = cmExpandedList(*globals);
+ cmList props{ *globals };
const std::string vsGlobal = "VS_GLOBAL_";
for (const std::string& i : props) {
// split NAME=VALUE
@@ -1428,7 +1434,7 @@ public:
bool operator()(BT<std::string> const& entry)
{
- std::vector<std::string> files = cmExpandedList(entry.Value);
+ cmList files{ entry.Value };
std::vector<cmSourceFileLocation> locations;
locations.reserve(files.size());
std::transform(files.begin(), files.end(), std::back_inserter(locations),
@@ -2967,7 +2973,7 @@ std::vector<std::string> cmTarget::GetAllInterfaceFileSets() const
auto appendEntries = [=](const std::vector<BT<std::string>>& entries) {
for (auto const& entry : entries) {
- auto expanded = cmExpandedList(entry.Value);
+ cmList expanded{ entry.Value };
std::copy(expanded.begin(), expanded.end(), inserter);
}
};
@@ -3029,11 +3035,11 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config, cmValue& loc,
// Track the configuration-specific property suffix.
suffix = cmStrCat('_', config_upper);
- std::vector<std::string> mappedConfigs;
+ cmList mappedConfigs;
{
std::string mapProp = cmStrCat("MAP_IMPORTED_CONFIG_", config_upper);
if (cmValue mapValue = this->GetProperty(mapProp)) {
- cmExpandList(*mapValue, mappedConfigs, true);
+ mappedConfigs.assign(*mapValue, cmList::EmptyElements::Yes);
}
}
@@ -3115,9 +3121,9 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config, cmValue& loc,
// If we have not yet found it then the project is willing to try
// any available configuration.
if (!loc && !imp) {
- std::vector<std::string> availableConfigs;
+ cmList availableConfigs;
if (cmValue iconfigs = this->GetProperty("IMPORTED_CONFIGURATIONS")) {
- cmExpandList(*iconfigs, availableConfigs);
+ availableConfigs.assign(*iconfigs);
}
for (auto aci = availableConfigs.begin();
!loc && !imp && aci != availableConfigs.end(); ++aci) {
diff --git a/Source/cmTargetSourcesCommand.cxx b/Source/cmTargetSourcesCommand.cxx
index 53e25b5d3f..cd7ff7419d 100644
--- a/Source/cmTargetSourcesCommand.cxx
+++ b/Source/cmTargetSourcesCommand.cxx
@@ -13,6 +13,7 @@
#include "cmExperimental.h"
#include "cmFileSet.h"
#include "cmGeneratorExpression.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -320,7 +321,7 @@ bool TargetSourcesImpl::HandleOneFileSet(
fileSet.first->AddDirectoryEntry(
BT<std::string>(baseDirectories, this->Makefile->GetBacktrace()));
if (type == "HEADERS"_s || type == "CXX_MODULE_HEADER_UNITS"_s) {
- for (auto const& dir : cmExpandedList(baseDirectories)) {
+ for (auto const& dir : cmList{ baseDirectories }) {
auto interfaceDirectoriesGenex =
cmStrCat("$<BUILD_INTERFACE:", dir, ">");
if (cmFileSetVisibilityIsForSelf(visibility)) {
diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx
index 5e325dd221..c4a2bc220d 100644
--- a/Source/cmTestGenerator.cxx
+++ b/Source/cmTestGenerator.cxx
@@ -13,6 +13,7 @@
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
@@ -147,16 +148,15 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
}
// Evaluate command line arguments
- std::vector<std::string> argv =
- this->EvaluateCommandLineArguments(this->Test->GetCommand(), ge, config);
-
- // Expand arguments if COMMAND_EXPAND_LISTS is set
- if (this->Test->GetCommandExpandLists()) {
- argv = cmExpandedLists(argv.begin(), argv.end());
- // Expanding lists on an empty command may have left it empty
- if (argv.empty()) {
- argv.emplace_back();
- }
+ cmList argv{
+ this->EvaluateCommandLineArguments(this->Test->GetCommand(), ge, config),
+ // Expand arguments if COMMAND_EXPAND_LISTS is set
+ this->Test->GetCommandExpandLists() ? cmList::ExpandElements::Yes
+ : cmList::ExpandElements::No
+ };
+ // Expanding lists on an empty command may have left it empty
+ if (argv.empty()) {
+ argv.emplace_back();
}
// Check whether the command executable is a target whose name is to
@@ -170,7 +170,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os,
// Prepend with the emulator when cross compiling if required.
cmValue emulator = target->GetProperty("CROSSCOMPILING_EMULATOR");
if (cmNonempty(emulator)) {
- std::vector<std::string> emulatorWithArgs = cmExpandedList(*emulator);
+ cmList emulatorWithArgs{ *emulator };
std::string emulatorExe(emulatorWithArgs[0]);
cmSystemTools::ConvertToUnixSlashes(emulatorExe);
os << cmOutputConverter::EscapeForCMake(emulatorExe) << " ";
diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx
index b648d9b94f..368155c346 100644
--- a/Source/cmTryRunCommand.cxx
+++ b/Source/cmTryRunCommand.cxx
@@ -15,6 +15,7 @@
#include "cmCoreTryCompile.h"
#include "cmDuration.h"
#include "cmExecutionStatus.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmRange.h"
@@ -271,7 +272,7 @@ void TryRunCommandImpl::RunExecutable(const std::string& runArgs,
const std::string& emulator =
this->Makefile->GetSafeDefinition("CMAKE_CROSSCOMPILING_EMULATOR");
if (!emulator.empty()) {
- std::vector<std::string> emulatorWithArgs = cmExpandedList(emulator);
+ cmList emulatorWithArgs{ emulator };
finalCommand +=
cmSystemTools::ConvertToRunCommandPath(emulatorWithArgs[0]);
finalCommand += " ";
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 8926f9ed15..7360bf5d75 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -9,6 +9,7 @@
#include <set>
#include <sstream>
+#include <cm/filesystem>
#include <cm/memory>
#include <cm/optional>
#include <cm/string_view>
@@ -31,6 +32,7 @@
#include "cmGlobalVisualStudio7Generator.h"
#include "cmGlobalVisualStudioGenerator.h"
#include "cmLinkLineDeviceComputer.h"
+#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmLocalVisualStudio10Generator.h"
@@ -50,6 +52,8 @@
#include "cmValue.h"
#include "cmVisualStudioGeneratorOptions.h"
+const std::string kBuildSystemSources = "Buildsystem Input Files";
+
struct cmIDEFlagTable;
static void ConvertToWindowsSlash(std::string& s);
@@ -1090,10 +1094,10 @@ void cmVisualStudio10TargetGenerator::WritePackageReferences(Elem& e0)
void cmVisualStudio10TargetGenerator::WriteDotNetReferences(Elem& e0)
{
- std::vector<std::string> references;
+ cmList references;
if (cmValue vsDotNetReferences =
this->GeneratorTarget->GetProperty("VS_DOTNET_REFERENCES")) {
- cmExpandList(*vsDotNetReferences, references);
+ references.assign(*vsDotNetReferences);
}
cmPropertyMap const& props = this->GeneratorTarget->Target->GetProperties();
for (auto const& i : props.GetList()) {
@@ -1110,7 +1114,7 @@ void cmVisualStudio10TargetGenerator::WriteDotNetReferences(Elem& e0)
}
if (!references.empty() || !this->DotNetHintReferences.empty()) {
Elem e1(e0, "ItemGroup");
- for (std::string const& ri : references) {
+ for (auto const& ri : references) {
// if the entry from VS_DOTNET_REFERENCES is an existing file, generate
// a new hint-reference and name it from the filename
if (cmsys::SystemTools::FileExists(ri, true)) {
@@ -1167,7 +1171,7 @@ void cmVisualStudio10TargetGenerator::WriteImports(Elem& e0)
cmValue imports =
this->GeneratorTarget->Target->GetProperty("VS_PROJECT_IMPORT");
if (imports) {
- std::vector<std::string> argsSplit = cmExpandedList(*imports, false);
+ cmList argsSplit{ *imports };
for (auto& path : argsSplit) {
if (!cmsys::SystemTools::FileIsFullPath(path)) {
path = this->Makefile->GetCurrentSourceDirectory() + "/" + path;
@@ -1365,20 +1369,20 @@ void cmVisualStudio10TargetGenerator::WriteTargetsFileReferences(Elem& e1)
void cmVisualStudio10TargetGenerator::WriteWinRTReferences(Elem& e0)
{
- std::vector<std::string> references;
+ cmList references;
if (cmValue vsWinRTReferences =
this->GeneratorTarget->GetProperty("VS_WINRT_REFERENCES")) {
- cmExpandList(*vsWinRTReferences, references);
+ references.assign(*vsWinRTReferences);
}
if (this->GlobalGenerator->TargetsWindowsPhone() &&
this->GlobalGenerator->GetSystemVersion() == "8.0" &&
references.empty()) {
- references.push_back("platform.winmd");
+ references.push_back(std::string{ "platform.winmd" });
}
if (!references.empty()) {
Elem e1(e0, "ItemGroup");
- for (std::string const& ri : references) {
+ for (auto const& ri : references) {
Elem e2(e1, "Reference");
e2.Attribute("Include", ri);
e2.Element("IsWinMDFile", "true");
@@ -1949,7 +1953,13 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
"http://schemas.microsoft.com/developer/msbuild/2003");
for (auto const& ti : this->Tools) {
- this->WriteGroupSources(e0, ti.first, ti.second, sourceGroups);
+ if ((this->GeneratorTarget->GetName() ==
+ CMAKE_CHECK_BUILD_SYSTEM_TARGET) &&
+ (ti.first == "None")) {
+ this->WriteBuildSystemSources(e0, ti.first, ti.second);
+ } else {
+ this->WriteGroupSources(e0, ti.first, ti.second, sourceGroups);
+ }
}
// Added files are images and the manifest.
@@ -2020,6 +2030,18 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
"rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;"
"gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms");
}
+
+ if (this->GeneratorTarget->GetName() ==
+ CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
+ for (const std::string& filter : this->BuildSystemSourcesFilters) {
+ std::string guidName = "SG_Filter_";
+ guidName += filter;
+ std::string guid = this->GlobalGenerator->GetGUID(guidName);
+ Elem e2(e1, "Filter");
+ e2.Attribute("Include", filter);
+ e2.Element("UniqueIdentifier", "{" + guid + "}");
+ }
+ }
}
}
fout << '\n';
@@ -2086,6 +2108,39 @@ void cmVisualStudio10TargetGenerator::WriteGroupSources(
}
}
+void cmVisualStudio10TargetGenerator::WriteBuildSystemSources(
+ Elem& e0, std::string const& name, ToolSources const& sources)
+{
+ const std::string srcDir = this->Makefile->GetCurrentSourceDirectory();
+ const std::string::size_type srcDirLength = srcDir.length();
+
+ Elem e1(e0, "ItemGroup");
+ e1.SetHasElements();
+ for (ToolSource const& s : sources) {
+ cmSourceFile const* sf = s.SourceFile;
+ std::string const& source = sf->GetFullPath();
+
+ cm::filesystem::path sourcePath(source);
+ bool isInSrcDir = cmHasPrefix(source, srcDir);
+
+ std::string filter = kBuildSystemSources;
+ if (isInSrcDir) {
+ std::string parentPath = sourcePath.parent_path().string();
+ if (srcDir != parentPath) {
+ filter += parentPath.substr(srcDirLength);
+ }
+ ConvertToWindowsSlash(filter);
+ this->BuildSystemSourcesFilters.insert(filter);
+ }
+
+ std::string path = this->ConvertPath(source, s.RelativePath);
+ ConvertToWindowsSlash(path);
+ Elem e2(e1, name);
+ e2.Attribute("Include", path);
+ e2.Element("Filter", filter);
+ }
+}
+
void cmVisualStudio10TargetGenerator::WriteHeaderSource(
Elem& e1, cmSourceFile const* sf, ConfigToSettings const& toolSettings)
{
@@ -2113,8 +2168,8 @@ void cmVisualStudio10TargetGenerator::ParseSettingsProperty(
for (const std::string& config : this->Configurations) {
std::string evaluated = cge->Evaluate(this->LocalGenerator, config);
- std::vector<std::string> settings = cmExpandedList(evaluated);
- for (const std::string& setting : settings) {
+ cmList settings{ evaluated };
+ for (const auto& setting : settings) {
const std::string::size_type assignment = setting.find('=');
if (assignment != std::string::npos) {
const std::string propName = setting.substr(0, assignment);
@@ -2714,16 +2769,11 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
if (lang == "ASM_NASM") {
if (cmValue objectDeps = sf.GetProperty("OBJECT_DEPENDS")) {
- std::string dependencies;
- std::vector<std::string> depends = cmExpandedList(*objectDeps);
- const char* sep = "";
- for (std::string& d : depends) {
+ cmList depends{ *objectDeps };
+ for (auto& d : depends) {
ConvertToWindowsSlash(d);
- dependencies += sep;
- dependencies += d;
- sep = ";";
}
- e2.Element("AdditionalDependencies", dependencies);
+ e2.Element("AdditionalDependencies", depends.join(";"));
}
}
@@ -4767,13 +4817,13 @@ void cmVisualStudio10TargetGenerator::WriteSinglePlatformExtension(
void cmVisualStudio10TargetGenerator::WriteSDKReferences(Elem& e0)
{
- std::vector<std::string> sdkReferences;
+ cmList sdkReferences;
std::unique_ptr<Elem> spe1;
if (cmValue vsSDKReferences =
this->GeneratorTarget->GetProperty("VS_SDK_REFERENCES")) {
- cmExpandList(*vsSDKReferences, sdkReferences);
+ sdkReferences.assign(*vsSDKReferences);
spe1 = cm::make_unique<Elem>(e0, "ItemGroup");
- for (std::string const& ri : sdkReferences) {
+ for (auto const& ri : sdkReferences) {
Elem(*spe1, "SDKReference").Attribute("Include", ri);
}
}
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index 97ae69fc37..a87cb01b7e 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -193,6 +193,9 @@ private:
void WriteGroupSources(Elem& e0, std::string const& name,
ToolSources const& sources,
std::vector<cmSourceGroup>&);
+ void WriteBuildSystemSources(Elem& e0, std::string const& name,
+ ToolSources const& sources);
+
void AddMissingSourceGroups(std::set<cmSourceGroup const*>& groupsUsed,
const std::vector<cmSourceGroup>& allGroups);
bool IsResxHeader(const std::string& headerFile);
@@ -243,6 +246,7 @@ private:
std::set<std::string> ASanEnabledConfigurations;
std::set<std::string> FuzzerEnabledConfigurations;
std::map<std::string, std::string> SpectreMitigation;
+ std::set<std::string> BuildSystemSourcesFilters;
cmGlobalVisualStudio10Generator* const GlobalGenerator;
cmLocalVisualStudio10Generator* const LocalGenerator;
std::set<std::string> CSharpCustomCommandNames;
diff --git a/Source/cmXCodeScheme.cxx b/Source/cmXCodeScheme.cxx
index e727d22141..7f26fd8b23 100644
--- a/Source/cmXCodeScheme.cxx
+++ b/Source/cmXCodeScheme.cxx
@@ -13,6 +13,7 @@
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
+#include "cmList.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -270,7 +271,7 @@ void cmXCodeScheme::WriteLaunchAction(cmXMLWriter& xout,
if (cmValue argList =
this->Target->GetTarget()->GetProperty("XCODE_SCHEME_ARGUMENTS")) {
- std::vector<std::string> arguments = cmExpandedList(*argList);
+ cmList arguments{ *argList };
if (!arguments.empty()) {
xout.StartElement("CommandLineArguments");
@@ -290,7 +291,7 @@ void cmXCodeScheme::WriteLaunchAction(cmXMLWriter& xout,
if (cmValue envList =
this->Target->GetTarget()->GetProperty("XCODE_SCHEME_ENVIRONMENT")) {
- std::vector<std::string> envs = cmExpandedList(*envList);
+ cmList envs{ *envList };
if (!envs.empty()) {
xout.StartElement("EnvironmentVariables");
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 8dee5cc13c..0fd7461339 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -53,6 +53,7 @@
# include "cmMakefileProfilingData.h"
#endif
#include "cmJSONState.h"
+#include "cmList.h"
#include "cmMessenger.h"
#include "cmState.h"
#include "cmStateDirectory.h"
@@ -813,7 +814,7 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
}
} else if (mode == "COMPILE"_s) {
std::string includes = mf->GetSafeDefinition("PACKAGE_INCLUDE_DIRS");
- std::vector<std::string> includeDirs = cmExpandedList(includes);
+ cmList includeDirs{ includes };
this->GlobalGenerator->CreateGenerationObjects();
const auto& lg = this->GlobalGenerator->LocalGenerators[0];
@@ -829,7 +830,7 @@ bool cmake::FindPackage(const std::vector<std::string>& args)
tgt->SetProperty("LINKER_LANGUAGE", language);
std::string libs = mf->GetSafeDefinition("PACKAGE_LIBRARIES");
- std::vector<std::string> libList = cmExpandedList(libs);
+ cmList libList{ libs };
for (std::string const& lib : libList) {
tgt->AddLinkLibrary(*mf, lib, GENERAL_LibraryType);
}
@@ -1026,7 +1027,7 @@ void cmake::SetArgs(const std::vector<std::string>& args)
CommandArgument{ "--check-build-system", CommandArgument::Values::Two,
[](std::string const& value, cmake* state) -> bool {
- std::vector<std::string> values = cmExpandedList(value);
+ cmList values{ value };
state->CheckBuildSystemArgument = values[0];
state->ClearBuildSystem = (atoi(values[1].c_str()) > 0);
return true;
@@ -2163,7 +2164,7 @@ struct SaveCacheEntry
int cmake::HandleDeleteCacheVariables(const std::string& var)
{
- std::vector<std::string> argsSplit = cmExpandedList(var, true);
+ cmList argsSplit{ var, cmList::EmptyElements::Yes };
// erase the property to avoid infinite recursion
this->State->SetGlobalProperty("__CMAKE_DELETE_CACHE_CHANGE_VARS_", "");
if (this->GetIsInTryCompile()) {
@@ -3140,9 +3141,8 @@ int cmake::CheckBuildSystem()
}
// If any byproduct of makefile generation is missing we must re-run.
- std::vector<std::string> products;
- mf.GetDefExpandList("CMAKE_MAKEFILE_PRODUCTS", products);
- for (std::string const& p : products) {
+ cmList products{ mf.GetDefinition("CMAKE_MAKEFILE_PRODUCTS") };
+ for (auto const& p : products) {
if (!(cmSystemTools::FileExists(p) || cmSystemTools::FileIsSymlink(p))) {
if (verbose) {
cmSystemTools::Stdout(
@@ -3153,10 +3153,10 @@ int cmake::CheckBuildSystem()
}
// Get the set of dependencies and outputs.
- std::vector<std::string> depends;
- std::vector<std::string> outputs;
- if (mf.GetDefExpandList("CMAKE_MAKEFILE_DEPENDS", depends)) {
- mf.GetDefExpandList("CMAKE_MAKEFILE_OUTPUTS", outputs);
+ cmList depends{ mf.GetDefinition("CMAKE_MAKEFILE_DEPENDS") };
+ cmList outputs;
+ if (!depends.empty()) {
+ outputs.assign(mf.GetDefinition("CMAKE_MAKEFILE_OUTPUTS"));
}
if (depends.empty() || outputs.empty()) {
// Not enough information was provided to do the test. Just rerun.
@@ -3432,19 +3432,18 @@ void cmake::IssueMessage(MessageType t, std::string const& text,
std::vector<std::string> cmake::GetDebugConfigs()
{
- std::vector<std::string> configs;
+ cmList configs;
if (cmValue config_list =
this->State->GetGlobalProperty("DEBUG_CONFIGURATIONS")) {
// Expand the specified list and convert to upper-case.
- cmExpandList(*config_list, configs);
- std::transform(configs.begin(), configs.end(), configs.begin(),
- cmSystemTools::UpperCase);
+ configs.assign(*config_list);
+ configs.transform(cmList::TransformAction::TOUPPER);
}
// If no configurations were specified, use a default list.
if (configs.empty()) {
configs.emplace_back("DEBUG");
}
- return configs;
+ return std::move(configs.data());
}
int cmake::Build(int jobs, std::string dir, std::vector<std::string> targets,
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index f4e602bf02..ad27443596 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -26,6 +26,7 @@
#include "cmConsoleBuf.h"
#include "cmDocumentationEntry.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmMakefile.h"
#include "cmMessageMetadata.h"
#include "cmState.h"
@@ -457,7 +458,7 @@ int do_build(int ac, char const* const* av)
};
auto targetLambda = [&](std::string const& value) -> bool {
if (!value.empty()) {
- std::vector<std::string> values = cmExpandedList(value);
+ cmList values{ value };
for (auto const& v : values) {
targets.emplace_back(v);
if (v == "clean") {
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index a2a9e09cfc..9929e85905 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -3,6 +3,7 @@
#include "cmcmd.h"
#include <functional>
+#include <iterator>
#include <cm/optional>
#include <cmext/algorithm>
@@ -14,6 +15,7 @@
#include "cmConsoleBuf.h"
#include "cmDuration.h"
#include "cmGlobalGenerator.h"
+#include "cmList.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmQtAutoMocUic.h"
@@ -342,10 +344,9 @@ int HandleIWYU(const std::string& runCmd, const std::string& /* sourceFile */,
{
// Construct the iwyu command line by taking what was given
// and adding all the arguments we give to the compiler.
- std::vector<std::string> iwyu_cmd = cmExpandedList(runCmd, true);
+ cmList iwyu_cmd{ runCmd, cmList::EmptyElements::Yes };
cm::append(iwyu_cmd, orig_cmd.begin() + 1, orig_cmd.end());
// Run the iwyu command line. Capture its stderr and hide its stdout.
- // Ignore its return code because the tool always returns non-zero.
std::string stdErr;
int ret;
if (!cmSystemTools::RunSingleCommand(iwyu_cmd, nullptr, &stdErr, &ret,
@@ -359,14 +360,21 @@ int HandleIWYU(const std::string& runCmd, const std::string& /* sourceFile */,
std::cerr << "Warning: include-what-you-use reported diagnostics:\n"
<< stdErr << "\n";
}
- // always return 0 we don't want to break the compile
- return 0;
+ // Older versions of iwyu always returned a non-zero exit code,
+ // so ignore it unless the user has enabled errors.
+ auto has_error_opt = std::find_if(
+ iwyu_cmd.cbegin(), iwyu_cmd.cend(),
+ [](std::string const& opt) { return cmHasLiteralPrefix(opt, "--error"); });
+ bool errors_enabled = has_error_opt != iwyu_cmd.cend() &&
+ has_error_opt != iwyu_cmd.cbegin() &&
+ *std::prev(has_error_opt) == "-Xiwyu";
+ return errors_enabled ? ret : 0;
}
int HandleTidy(const std::string& runCmd, const std::string& sourceFile,
const std::vector<std::string>& orig_cmd)
{
- std::vector<std::string> tidy_cmd = cmExpandedList(runCmd, true);
+ cmList tidy_cmd{ runCmd, cmList::EmptyElements::Yes };
tidy_cmd.push_back(sourceFile);
for (auto const& arg : tidy_cmd) {
@@ -416,7 +424,7 @@ int HandleLWYU(const std::string& runCmd, const std::string& sourceFile,
{
// Construct the ldd -r -u (link what you use lwyu) command line
// ldd -u -r lwuy target
- std::vector<std::string> lwyu_cmd = cmExpandedList(runCmd, true);
+ cmList lwyu_cmd{ runCmd, cmList::EmptyElements::Yes };
lwyu_cmd.push_back(sourceFile);
// Run the lwyu check command line, currently ldd is expected.
@@ -444,7 +452,7 @@ int HandleCppLint(const std::string& runCmd, const std::string& sourceFile,
const std::vector<std::string>&)
{
// Construct the cpplint command line.
- std::vector<std::string> cpplint_cmd = cmExpandedList(runCmd, true);
+ cmList cpplint_cmd{ runCmd, cmList::EmptyElements::Yes };
cpplint_cmd.push_back(sourceFile);
// Run the cpplint command line. Capture its output.
@@ -471,7 +479,7 @@ int HandleCppCheck(const std::string& runCmd, const std::string& sourceFile,
const std::vector<std::string>& orig_cmd)
{
// Construct the cpplint command line.
- std::vector<std::string> cppcheck_cmd = cmExpandedList(runCmd, true);
+ cmList cppcheck_cmd{ runCmd, cmList::EmptyElements::Yes };
// extract all the -D, -U, and -I options from the compile line
for (auto const& opt : orig_cmd) {
if (opt.size() > 2) {
@@ -551,8 +559,8 @@ struct CoCompileJob
int cmcmd::HandleCoCompileCommands(std::vector<std::string> const& args)
{
std::vector<CoCompileJob> jobs;
- std::string sourceFile; // store --source=
- std::vector<std::string> launchers; // store --launcher=
+ std::string sourceFile; // store --source=
+ cmList launchers; // store --launcher=
// Default is to run the original command found after -- if the option
// does not need to do that, it should be specified here, currently only
@@ -585,7 +593,7 @@ int cmcmd::HandleCoCompileCommands(std::vector<std::string> const& args)
if (cmHasLiteralPrefix(arg, "--source=")) {
sourceFile = arg.substr(9);
} else if (cmHasLiteralPrefix(arg, "--launcher=")) {
- cmExpandList(arg.substr(11), launchers, true);
+ launchers.append(arg.substr(11), cmList::EmptyElements::Yes);
} else {
// if it was not a co-compiler or --source/--launcher then error
std::cerr << "__run_co_compile given unknown argument: " << arg
diff --git a/Templates/TestDriver.cxx.in b/Templates/TestDriver.cxx.in
index c47266a75e..3bb2fd6b39 100644
--- a/Templates/TestDriver.cxx.in
+++ b/Templates/TestDriver.cxx.in
@@ -20,11 +20,19 @@
# else
# define CM_NULL NULL
# endif
+# define CM_NAMESPACE_BEGIN namespace {
+# define CM_NAMESPACE_END }
+# define CM_LOCAL
#else
# define CM_CAST(TYPE, EXPR) (TYPE)(EXPR)
# define CM_NULL NULL
+# define CM_NAMESPACE_BEGIN
+# define CM_NAMESPACE_END
+# define CM_LOCAL static
#endif
+CM_NAMESPACE_BEGIN
+
/* Create map. */
typedef int (*MainFuncPointer)(int, char* []); /* NOLINT */
@@ -34,17 +42,17 @@ typedef struct /* NOLINT */
MainFuncPointer func;
} functionMapEntry;
-static functionMapEntry cmakeGeneratedFunctionMapEntries[] = {
+CM_LOCAL const functionMapEntry cmakeGeneratedFunctionMapEntries[] = {
@CMAKE_FUNCTION_TABLE_ENTRIES@
{ CM_NULL, CM_NULL } /* NOLINT */
};
-static const int NumTests = CM_CAST(int,
+CM_LOCAL const int NumTests = CM_CAST(int,
sizeof(cmakeGeneratedFunctionMapEntries) / sizeof(functionMapEntry)) - 1;
/* Allocate and create a lowercased copy of string
(note that it has to be free'd manually) */
-static char* lowercase(const char* string)
+CM_LOCAL char* lowercase(const char* string)
{
char *new_string;
char *p;
@@ -63,7 +71,7 @@ static char* lowercase(const char* string)
return new_string;
}
-static int isTestSkipped(const char *name, int n_skipped_tests, char *skipped_tests[]) {
+CM_LOCAL int isTestSkipped(const char *name, int n_skipped_tests, char *skipped_tests[]) {
int i;
for (i = 0; i < n_skipped_tests; i++) {
if (strcmp(name, skipped_tests[i]) == 0) {
@@ -74,6 +82,8 @@ static int isTestSkipped(const char *name, int n_skipped_tests, char *skipped_te
return 0;
}
+CM_NAMESPACE_END
+
int main(int ac, char* av[])
{
int i;
diff --git a/Tests/CMakeLib/testGccDepfileReader_data/deps1.txt b/Tests/CMakeLib/testGccDepfileReader_data/deps1.txt
index fd2679f41a..4207b58139 100644
--- a/Tests/CMakeLib/testGccDepfileReader_data/deps1.txt
+++ b/Tests/CMakeLib/testGccDepfileReader_data/deps1.txt
@@ -1,26 +1,26 @@
--RULES--
main.o
--DEPENDENCIES--
-main.cpp
+/usr/include/features.h
/usr/include/stdc-predef.h
/usr/include/stdio.h
/usr/include/x86_64-linux-gnu/bits/libc-header-start.h
-/usr/include/features.h
-/usr/include/x86_64-linux-gnu/sys/cdefs.h
-/usr/include/x86_64-linux-gnu/bits/wordsize.h
/usr/include/x86_64-linux-gnu/bits/long-double.h
-/usr/include/x86_64-linux-gnu/gnu/stubs.h
-/usr/include/x86_64-linux-gnu/gnu/stubs-64.h
-/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h
-/usr/lib/gcc/x86_64-linux-gnu/8/include/stdarg.h
+/usr/include/x86_64-linux-gnu/bits/stdio_lim.h
+/usr/include/x86_64-linux-gnu/bits/sys_errlist.h
/usr/include/x86_64-linux-gnu/bits/types.h
-/usr/include/x86_64-linux-gnu/bits/typesizes.h
+/usr/include/x86_64-linux-gnu/bits/types/FILE.h
+/usr/include/x86_64-linux-gnu/bits/types/__FILE.h
+/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h
/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h
/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h
-/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h
-/usr/include/x86_64-linux-gnu/bits/types/__FILE.h
-/usr/include/x86_64-linux-gnu/bits/types/FILE.h
-/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h
/usr/include/x86_64-linux-gnu/bits/types/cookie_io_functions_t.h
-/usr/include/x86_64-linux-gnu/bits/stdio_lim.h
-/usr/include/x86_64-linux-gnu/bits/sys_errlist.h
+/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h
+/usr/include/x86_64-linux-gnu/bits/typesizes.h
+/usr/include/x86_64-linux-gnu/bits/wordsize.h
+/usr/include/x86_64-linux-gnu/gnu/stubs-64.h
+/usr/include/x86_64-linux-gnu/gnu/stubs.h
+/usr/include/x86_64-linux-gnu/sys/cdefs.h
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stdarg.h
+/usr/lib/gcc/x86_64-linux-gnu/8/include/stddef.h
+main.cpp
diff --git a/Tests/CMakeLib/testGccDepfileReader_data/deps3.txt b/Tests/CMakeLib/testGccDepfileReader_data/deps3.txt
index 448f69c1e5..8d82c60d44 100644
--- a/Tests/CMakeLib/testGccDepfileReader_data/deps3.txt
+++ b/Tests/CMakeLib/testGccDepfileReader_data/deps3.txt
@@ -1,11 +1,11 @@
--RULES--
main.o
--DEPENDENCIES--
-main.cpp
-foo#bar.h
-foo\#bar.h
foo bar.h
+foo#bar.h
+foo$bar.h
foo\ bar.h
+foo\#bar.h
foo\\ bar.h
foo\\\\
-foo$bar.h
+main.cpp
diff --git a/Tests/CMakeLib/testList.cxx b/Tests/CMakeLib/testList.cxx
index 7294be0b31..f6ec7208ea 100644
--- a/Tests/CMakeLib/testList.cxx
+++ b/Tests/CMakeLib/testList.cxx
@@ -8,7 +8,7 @@
#include <utility>
#include <vector>
-#include <cm/string_view>
+#include <cmext/string_view>
#include "cmList.h"
@@ -42,7 +42,7 @@ bool testConstructors()
}
{
cmList list1{ "aa", "bb" };
- cmList list2("aa;bb");
+ cmList list2("aa;bb"_s);
if (list1.size() != 2 || list2.size() != 2 || list1 != list2) {
result = false;
@@ -174,7 +174,7 @@ bool testAssign()
{
cmList list{ "cc", "dd" };
- list = "aa;bb";
+ list = "aa;bb"_s;
if (list.size() != 2) {
result = false;
}
@@ -195,7 +195,7 @@ bool testConversions()
bool result = true;
{
- cmList list("a;b;c");
+ cmList list("a;b;c"_s);
std::string s = list.to_string();
if (s != "a;b;c") {
@@ -203,7 +203,7 @@ bool testConversions()
}
}
{
- cmList list("a;b;c");
+ cmList list("a;b;c"_s);
std::vector<std::string> v = list;
if (list.size() != 3 || v.size() != 3) {
@@ -211,7 +211,7 @@ bool testConversions()
}
}
{
- cmList list("a;b;c");
+ cmList list("a;b;c"_s);
std::vector<std::string> v = std::move(list);
// Microsoft compiler is not able to handle correctly the move semantics
@@ -221,7 +221,7 @@ bool testConversions()
}
}
{
- cmList list("a;b;c");
+ cmList list("a;b;c"_s);
std::vector<std::string> v;
// compiler is not able to select the cmList conversion operator
@@ -247,20 +247,20 @@ bool testAccess()
{
cmList list{ "a", "b", "c" };
- if (list.at(1) != "b") {
+ if (list.get_item(1) != "b") {
result = false;
}
}
{
cmList list{ "a", "b", "c" };
- if (list.at(-3) != "a") {
+ if (list.get_item(-3) != "a") {
result = false;
}
}
{
try {
cmList list{ "a", "b", "c" };
- if (list.at(4) != "a") {
+ if (list.get_item(4) != "a") {
result = false;
}
} catch (std::out_of_range&) {
@@ -269,7 +269,7 @@ bool testAccess()
{
try {
cmList list{ "a", "b", "c" };
- if (list.at(-4) != "a") {
+ if (list.get_item(-4) != "a") {
result = false;
}
} catch (std::out_of_range&) {
@@ -342,7 +342,7 @@ bool testModifiers()
{
cmList list{ "1;2;3;4;5" };
- auto it = list.insert(list.begin() + 2, "6;7;8");
+ auto it = list.insert(list.begin() + 2, "6;7;8"_s);
if (list.size() != 8 || list.to_string() != "1;2;6;7;8;3;4;5") {
result = false;
}
@@ -354,7 +354,7 @@ bool testModifiers()
cmList list{ "1;2;3;4;5" };
auto it =
- list.insert(list.begin() + 2, "6;7;8", cmList::ExpandElements::No);
+ list.insert(list.begin() + 2, "6;7;8"_s, cmList::ExpandElements::No);
if (list.size() != 6 || list.to_string() != "1;2;6;7;8;3;4;5") {
result = false;
}
@@ -479,7 +479,7 @@ bool testRemoveItems()
bool result = true;
{
- cmList list("a;b;c;d;e;f;g;h");
+ cmList list("a;b;c;d;e;f;g;h"_s);
list.remove_items({ 1, 3, 5 });
@@ -488,7 +488,7 @@ bool testRemoveItems()
}
}
{
- cmList list("a;b;c;b;a;d;e;f");
+ cmList list("a;b;c;b;a;d;e;f"_s);
list.remove_items({ "a", "b", "h" });
@@ -497,7 +497,7 @@ bool testRemoveItems()
}
}
{
- cmList list("a;b;c;d;e;f;g;h");
+ cmList list("a;b;c;d;e;f;g;h"_s);
std::vector<cmList::index_type> remove{ 1, 3, 5 };
list.remove_items(remove.begin(), remove.end());
@@ -507,7 +507,7 @@ bool testRemoveItems()
}
}
{
- cmList list("a;b;c;b;a;d;e;f");
+ cmList list("a;b;c;b;a;d;e;f"_s);
std::vector<std::string> remove{ "b", "a", "h" };
list.remove_items(remove.begin(), remove.end());
@@ -529,7 +529,7 @@ bool testRemoveDuplicates()
bool result = true;
{
- cmList list("b;c;b;a;a;c;b;a;c;b");
+ cmList list("b;c;b;a;a;c;b;a;c;b"_s);
list.remove_duplicates();
@@ -803,7 +803,7 @@ bool testStaticModifiers()
{
std::vector<std::string> v{ "a", "b", "c" };
- cmList::assign("d;e", v);
+ cmList::assign(v, "d;e"_s);
if (v.size() != 2 || v[0] != "d" || v[1] != "e") {
result = false;
@@ -811,7 +811,7 @@ bool testStaticModifiers()
}
{
std::vector<std::string> v{ "a", "b", "c" };
- cmList::append("d;;e", v);
+ cmList::append(v, "d;;e"_s);
if (v.size() != 5 || v[3] != "d" || v[4] != "e") {
result = false;
@@ -819,7 +819,7 @@ bool testStaticModifiers()
}
{
std::vector<std::string> v{ "a", "b", "c" };
- cmList::append("d;;e", v, cmList::EmptyElements::Yes);
+ cmList::append(v, "d;;e"_s, cmList::EmptyElements::Yes);
if (v.size() != 6 || v[3] != "d" || !v[4].empty() || v[5] != "e") {
result = false;
@@ -827,7 +827,7 @@ bool testStaticModifiers()
}
{
std::vector<std::string> v{ "a", "b", "c" };
- cmList::prepend("d;e", v);
+ cmList::prepend(v, "d;e"_s);
if (v.size() != 5 || v[0] != "d" || v[1] != "e") {
result = false;
@@ -835,7 +835,7 @@ bool testStaticModifiers()
}
{
std::vector<std::string> v{ "a", "b", "c" };
- cmList::prepend("d;;e", v, cmList::EmptyElements::Yes);
+ cmList::prepend(v, "d;;e"_s, cmList::EmptyElements::Yes);
if (v.size() != 6 || v[0] != "d" || !v[1].empty() || v[2] != "e") {
result = false;
@@ -843,7 +843,7 @@ bool testStaticModifiers()
}
{
std::string list{ "a;b;c" };
- cmList::append("d;e", list);
+ cmList::append(list, "d;e"_s);
if (list != "a;b;c;d;e") {
result = false;
@@ -851,7 +851,7 @@ bool testStaticModifiers()
}
{
std::string list;
- cmList::append("d;e", list);
+ cmList::append(list, "d;e"_s);
if (list != "d;e") {
result = false;
@@ -859,7 +859,7 @@ bool testStaticModifiers()
}
{
std::string list{ "a;b;c" };
- cmList::append("", list);
+ cmList::append(list, "");
if (list != "a;b;c;") {
result = false;
@@ -868,7 +868,7 @@ bool testStaticModifiers()
{
std::string list{ "a;b;c" };
std::vector<std::string> v{ "d", "e" };
- cmList::append(v.begin(), v.end(), list);
+ cmList::append(list, v.begin(), v.end());
if (list != "a;b;c;d;e") {
result = false;
@@ -877,7 +877,7 @@ bool testStaticModifiers()
{
std::string list{ "a;b;c" };
std::vector<std::string> v;
- cmList::append(v.begin(), v.end(), list);
+ cmList::append(list, v.begin(), v.end());
if (list != "a;b;c") {
result = false;
@@ -886,7 +886,7 @@ bool testStaticModifiers()
{
std::string list;
std::vector<std::string> v{ "d", "e" };
- cmList::append(v.begin(), v.end(), list);
+ cmList::append(list, v.begin(), v.end());
if (list != "d;e") {
result = false;
@@ -894,7 +894,7 @@ bool testStaticModifiers()
}
{
std::string list{ "a;b;c" };
- cmList::prepend("d;e", list);
+ cmList::prepend(list, "d;e");
if (list != "d;e;a;b;c") {
result = false;
@@ -902,7 +902,7 @@ bool testStaticModifiers()
}
{
std::string list;
- cmList::prepend("d;e", list);
+ cmList::prepend(list, "d;e");
if (list != "d;e") {
result = false;
@@ -910,7 +910,7 @@ bool testStaticModifiers()
}
{
std::string list{ "a;b;c" };
- cmList::prepend("", list);
+ cmList::prepend(list, "");
if (list != ";a;b;c") {
result = false;
@@ -919,7 +919,7 @@ bool testStaticModifiers()
{
std::string list{ "a;b;c" };
std::vector<std::string> v{ "d", "e" };
- cmList::prepend(v.begin(), v.end(), list);
+ cmList::prepend(list, v.begin(), v.end());
if (list != "d;e;a;b;c") {
result = false;
@@ -928,7 +928,7 @@ bool testStaticModifiers()
{
std::string list{ "a;b;c" };
std::vector<std::string> v;
- cmList::prepend(v.begin(), v.end(), list);
+ cmList::prepend(list, v.begin(), v.end());
if (list != "a;b;c") {
result = false;
@@ -937,7 +937,7 @@ bool testStaticModifiers()
{
std::string list;
std::vector<std::string> v{ "d", "e" };
- cmList::prepend(v.begin(), v.end(), list);
+ cmList::prepend(list, v.begin(), v.end());
if (list != "d;e") {
result = false;
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index e92d1c1c09..e3b5ec41d8 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -986,6 +986,30 @@ if(BUILD_TESTING)
endif()
endif()
+ # On Windows run the CPackInnoSetupGenerator test
+ if(WIN32 AND CMake_TEST_CPACK_INNOSETUP)
+ add_test(CPackInnoSetupGenerator ${CMAKE_CTEST_COMMAND}
+ -C \${CTEST_CONFIGURATION_TYPE}
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/CPackInnoSetupGenerator"
+ "${CMake_BINARY_DIR}/Tests/CPackInnoSetupGenerator"
+ ${build_generator_args}
+ --build-project CPackInnoSetupGenerator
+ --build-options
+ --test-command ${CMAKE_CMAKE_COMMAND}
+ "-DCPackInnoSetupGenerator_BINARY_DIR:PATH=${CMake_BINARY_DIR}/Tests/CPackInnoSetupGenerator"
+ "-Dconfig=\${CTEST_CONFIGURATION_TYPE}"
+ -P "${CMake_SOURCE_DIR}/Tests/CPackInnoSetupGenerator/RunCPackVerifyResult.cmake")
+
+ set_property(TEST CPackInnoSetupGenerator PROPERTY
+ ATTACHED_FILES_ON_FAIL
+ "${CMake_BINARY_DIR}/Tests/CPackInnoSetupGenerator/_CPack_Packages/win32/INNOSETUP/ISCCOutput.log")
+
+ set_property(TEST CPackInnoSetupGenerator PROPERTY
+ ATTACHED_FILES
+ "${CMake_BINARY_DIR}/Tests/CPackInnoSetupGenerator/_CPack_Packages/win32/INNOSETUP/ISScript.iss")
+ endif()
+
# On Windows run the CPackNSISGenerator test
# if the nsis is available
if(WIN32 AND NSIS_MAKENSIS_EXECUTABLE)
diff --git a/Tests/CPackInnoSetupGenerator/CMakeLists.txt b/Tests/CPackInnoSetupGenerator/CMakeLists.txt
new file mode 100644
index 0000000000..bca0ad6cd7
--- /dev/null
+++ b/Tests/CPackInnoSetupGenerator/CMakeLists.txt
@@ -0,0 +1,55 @@
+cmake_minimum_required(VERSION 3.13)
+
+project(CPackInnoSetupGenerator VERSION 42.0 HOMEPAGE_URL "https://www.example.com")
+
+add_executable(hello main.c)
+file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/empty)
+
+install(TARGETS hello DESTINATION / COMPONENT application)
+install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/empty DESTINATION / COMPONENT extras)
+install(FILES my_bitmap.bmp DESTINATION awesome COMPONENT extras)
+install(FILES my_file.txt DESTINATION / COMPONENT hidden_component)
+install(FILES my_file.txt DESTINATION / COMPONENT hidden_component2)
+
+set(CPACK_GENERATOR "INNOSETUP")
+
+set(CPACK_PACKAGE_NAME "Hello, World!") # Test constant escape (like {cm:...}, see code documentation)
+set(CPACK_PACKAGE_VENDOR "Sheldon Cooper")
+set(CPACK_PACKAGE_INSTALL_DIRECTORY "hello_world")
+set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "hello_world")
+set(CPACK_PACKAGE_FILE_NAME "hello_world_setup")
+set(CPACK_SYSTEM_NAME "win32")
+set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/my_bitmap.bmp")
+set(CPACK_VERBATIM_VARIABLES ON)
+set(CPACK_PACKAGE_EXECUTABLES "hello" "Hello, World!")
+set(CPACK_CREATE_DESKTOP_LINKS hello)
+
+set(CPACK_INNOSETUP_INSTALL_ROOT "{autopf}\\Sheldon Cooper")
+set(CPACK_INNOSETUP_PROGRAM_MENU_FOLDER ".")
+set(CPACK_INNOSETUP_IGNORE_LICENSE_PAGE ON)
+set(CPACK_INNOSETUP_IGNORE_README_PAGE OFF) # Test if only readme page is shown
+set(CPACK_INNOSETUP_SETUP_AppComments ON) # Test if CPACK_INNOSETUP_USE_CMAKE_BOOL_FORMAT works
+set(CPACK_INNOSETUP_CUSTOM_INSTALL_INSTRUCTIONS "extras/empty"
+ "Name: \"{userdocs}\\empty\"\; Check: ReturnTrue\; Components: accessories\\extras")
+set(CPACK_INNOSETUP_MENU_LINKS "https://www.example.com" "Web"
+ "my_file.txt" "Text")
+set(CPACK_INNOSETUP_RUN_EXECUTABLES hello)
+set(CPACK_INNOSETUP_CREATE_UNINSTALL_LINK ON)
+# Test if this macro is available in the code file below containing the check function
+set(CPACK_INNOSETUP_DEFINE_PascalMacro "end;")
+set(CPACK_INNOSETUP_CODE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/Code.pas")
+set(CPACK_INNOSETUP_EXECUTABLE "ISCC.exe")
+
+include(CPackComponent)
+
+cpack_add_install_type(basic DISPLAY_NAME "Basic installation")
+cpack_add_install_type(full DISPLAY_NAME "\"Large\" installation") # Test double quote syntax
+cpack_add_component_group(accessories DISPLAY_NAME "Accessories")
+
+cpack_add_component(application DISPLAY_NAME "Application" INSTALL_TYPES basic full REQUIRED)
+cpack_add_component(extras DISPLAY_NAME "Additional components" INSTALL_TYPES full GROUP accessories)
+cpack_add_component(hidden_component HIDDEN)
+cpack_add_component(hidden_component2 HIDDEN DISABLED)
+set(CPACK_INNOSETUP_extras_INSTALL_DIRECTORY "{userdocs}")
+
+include(CPack)
diff --git a/Tests/CPackInnoSetupGenerator/Code.pas b/Tests/CPackInnoSetupGenerator/Code.pas
new file mode 100644
index 0000000000..d96d82f2df
--- /dev/null
+++ b/Tests/CPackInnoSetupGenerator/Code.pas
@@ -0,0 +1,4 @@
+function ReturnTrue(): Boolean;
+begin
+ Result := true;
+{#PascalMacro}
diff --git a/Tests/CPackInnoSetupGenerator/RunCPackVerifyResult.cmake b/Tests/CPackInnoSetupGenerator/RunCPackVerifyResult.cmake
new file mode 100644
index 0000000000..72a26ee754
--- /dev/null
+++ b/Tests/CPackInnoSetupGenerator/RunCPackVerifyResult.cmake
@@ -0,0 +1,136 @@
+message(STATUS "=============================================================")
+message(STATUS "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)")
+message(STATUS "")
+
+if(NOT CPackInnoSetupGenerator_BINARY_DIR)
+ message(FATAL_ERROR "CPackInnoSetupGenerator_BINARY_DIR not set")
+endif()
+
+message(STATUS "CMAKE_COMMAND: ${CMAKE_COMMAND}")
+message(STATUS "CMAKE_CPACK_COMMAND: ${CMAKE_CPACK_COMMAND}")
+message(STATUS "CPackInnoSetupGenerator_BINARY_DIR: ${CPackInnoSetupGenerator_BINARY_DIR}")
+
+if(config)
+ set(_C_config -C ${config})
+endif()
+
+execute_process(COMMAND "${CMAKE_CPACK_COMMAND}"
+ ${_C_config}
+ RESULT_VARIABLE CPack_result
+ OUTPUT_VARIABLE CPack_output
+ ERROR_VARIABLE CPack_output
+ WORKING_DIRECTORY "${CPackInnoSetupGenerator_BINARY_DIR}")
+
+if(CPack_result)
+ message(FATAL_ERROR "CPack execution went wrong!, Output: ${CPack_output}")
+else ()
+ message(STATUS "Output: ${CPack_output}")
+endif()
+
+file(GLOB project_file "${CPackInnoSetupGenerator_BINARY_DIR}/_CPack_Packages/win32/INNOSETUP/ISScript.iss")
+file(GLOB installer_file "${CPackInnoSetupGenerator_BINARY_DIR}/_CPack_Packages/win32/INNOSETUP/hello_world_setup.exe")
+
+message(STATUS "Project file: '${project_file}'")
+message(STATUS "Installer file: '${installer_file}'")
+
+if(NOT project_file)
+ message(FATAL_ERROR "Project file does not exist")
+endif()
+
+if(NOT installer_file)
+ message(FATAL_ERROR "Installer file does not exist")
+endif()
+
+# Test if the correct registry key is set
+file(STRINGS "${project_file}" results REGEX "^AppId=hello_world$")
+if(results STREQUAL "")
+ message(FATAL_ERROR "CPACK_PACKAGE_INSTALL_REGISTRY_KEY doesn't match AppId")
+endif()
+
+# Test if only readme page is shown
+file(STRINGS "${project_file}" results REGEX "^LicenseFile=")
+file(STRINGS "${project_file}" results2 REGEX "^InfoBeforeFile=")
+if(NOT results STREQUAL "" OR results2 STREQUAL "")
+ message(FATAL_ERROR "Erroneous output with license and readme files")
+endif()
+
+# Test if classic style is used by default
+file(STRINGS "${project_file}" results REGEX "compiler:SetupClassicIcon\\.ico")
+file(STRINGS "${project_file}" results2 REGEX "compiler:WizClassicImage\\.bmp")
+if(results STREQUAL "" OR results2 STREQUAL "")
+ message(FATAL_ERROR "Images of classic style not used")
+endif()
+
+# Test if the top-level start menu folder is used
+file(STRINGS "${project_file}" results REGEX "{autoprograms}")
+file(STRINGS "${project_file}" results2 REGEX "{group}")
+if(results STREQUAL "" OR NOT results2 STREQUAL "")
+ message(FATAL_ERROR "Top-level start menu folder not used")
+endif()
+
+# Test CPACK_INNOSETUP_USE_CMAKE_BOOL_FORMAT
+file(STRINGS "${project_file}" results REGEX "^AppComments=yes$")
+if(results STREQUAL "")
+ message(FATAL_ERROR "CPACK_INNOSETUP_USE_CMAKE_BOOL_FORMAT doesn't convert booleans")
+endif()
+
+# Test the custom installation rule
+file(STRINGS "${project_file}" results REGEX "^Name: \"{userdocs}\\\\empty\"; Check: ReturnTrue; Components: accessories\\\\extras$")
+if(results STREQUAL "")
+ message(FATAL_ERROR "Custom installation rule not found or incomplete")
+endif()
+
+# Test if an uninstall shortcut has been created
+file(STRINGS "${project_file}" results REGEX "{uninstallexe}")
+if(results STREQUAL "")
+ message(FATAL_ERROR "No uninstall shortcut created")
+endif()
+
+# Test CPACK_INNOSETUP_<compName>_INSTALL_DIRECTORY
+file(STRINGS "${project_file}" results REGEX "{app}.*Components: accessories\\\\extras")
+if(NOT results STREQUAL "")
+ message(FATAL_ERROR "Component not in custom install directory")
+endif()
+
+# Test if component names are nested correctly
+file(STRINGS "${project_file}" results REGEX "Components:.* extras")
+if(NOT results STREQUAL "")
+ message(FATAL_ERROR "Component names must contain their parent groups according to the documentation")
+endif()
+
+# Test if custom installation type exists
+file(STRINGS "${project_file}" results REGEX "Flags: .*iscustom")
+if(results STREQUAL "")
+ message(FATAL_ERROR "Custom installation type doesn't exist")
+endif()
+
+# Test if hidden components are processed but not displayed
+file(STRINGS "${project_file}" results REGEX "Source:.+hidden_component\\\\my_file\\.txt")
+file(STRINGS "${project_file}" results2 REGEX "Name: \"hidden_component\"")
+if(results STREQUAL "" OR NOT results2 STREQUAL "")
+ message(FATAL_ERROR "Hidden component displayed or one of its files ignored")
+endif()
+
+# Test if disabled and hidden components are ignored at all
+file(STRINGS "${project_file}" results REGEX "Source:.+hidden_component2\\\\my_file\\.txt")
+if(NOT results STREQUAL "")
+ message(FATAL_ERROR "Disabled and hidden component not ignored")
+endif()
+
+# Test if required components ignore their installation types
+file(STRINGS "${project_file}" results REGEX "Types: (basic|full|custom|basic full|full basic|basic custom|full custom); Flags: fixed")
+if(NOT results STREQUAL "")
+ message(FATAL_ERROR "Required components don't ignore their installation types")
+endif()
+
+# Test constant escape (should contain Hello%2c World!)
+file(STRINGS "${project_file}" results REGEX "Hello%2c World!")
+if(results STREQUAL "")
+ message(FATAL_ERROR "The comma character isn't escaped to %2c")
+endif()
+
+# Test double quote syntax
+file(STRINGS "${project_file}" results REGEX "\"\"Large\"\"")
+if(results STREQUAL "")
+ message(FATAL_ERROR "The quote character isn't escaped correctly")
+endif()
diff --git a/Tests/CPackInnoSetupGenerator/main.c b/Tests/CPackInnoSetupGenerator/main.c
new file mode 100644
index 0000000000..413899c807
--- /dev/null
+++ b/Tests/CPackInnoSetupGenerator/main.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main()
+{
+ printf("Hello, World!\n");
+ return 42;
+}
diff --git a/Tests/CPackInnoSetupGenerator/my_bitmap.bmp b/Tests/CPackInnoSetupGenerator/my_bitmap.bmp
new file mode 100644
index 0000000000..d0e562fb37
--- /dev/null
+++ b/Tests/CPackInnoSetupGenerator/my_bitmap.bmp
Binary files differ
diff --git a/Tests/CPackInnoSetupGenerator/my_file.txt b/Tests/CPackInnoSetupGenerator/my_file.txt
new file mode 100644
index 0000000000..8ab686eafe
--- /dev/null
+++ b/Tests/CPackInnoSetupGenerator/my_file.txt
@@ -0,0 +1 @@
+Hello, World!
diff --git a/Tests/CompileFeatures/default_dialect.c b/Tests/CompileFeatures/default_dialect.c
index b990e53258..c696c83f3e 100644
--- a/Tests/CompileFeatures/default_dialect.c
+++ b/Tests/CompileFeatures/default_dialect.c
@@ -20,7 +20,8 @@
# error Buildsystem error
# endif
# if defined(__STDC_VERSION__) && \
- !(defined(__SUNPRO_C) && __STDC_VERSION__ == 199409L)
+ !(__STDC_VERSION__ == 199409L && \
+ (defined(__INTEL_COMPILER) || defined(__SUNPRO_C)))
# error Unexpected __STDC_VERSION__ definition
# endif
#endif
diff --git a/Tests/Cuda/Toolkit/CMakeLists.txt b/Tests/Cuda/Toolkit/CMakeLists.txt
index b67aa3279f..8432b71ff1 100644
--- a/Tests/Cuda/Toolkit/CMakeLists.txt
+++ b/Tests/Cuda/Toolkit/CMakeLists.txt
@@ -16,8 +16,22 @@ message(STATUS "CUDAToolkit_VERSION_PATCH: ${CUDAToolkit_VERSION_PATCH}")
message(STATUS "CUDAToolkit_BIN_DIR: ${CUDAToolkit_BIN_DIR}")
message(STATUS "CUDAToolkit_INCLUDE_DIRS: ${CUDAToolkit_INCLUDE_DIRS}")
message(STATUS "CUDAToolkit_LIBRARY_DIR: ${CUDAToolkit_LIBRARY_DIR}")
+message(STATUS "CUDAToolkit_LIBRARY_ROOT: ${CUDAToolkit_LIBRARY_ROOT}")
message(STATUS "CUDAToolkit_NVCC_EXECUTABLE ${CUDAToolkit_NVCC_EXECUTABLE}")
+set(should_exist
+ CUDAToolkit_BIN_DIR
+ CUDAToolkit_INCLUDE_DIRS
+ CUDAToolkit_LIBRARY_DIR
+ CUDAToolkit_LIBRARY_ROOT
+ )
+foreach (cuda_loc_var IN LISTS should_exist)
+ if(NOT EXISTS "${${cuda_loc_var}}")
+ message(FATAL_ERROR "${cuda_loc_var} variable is expected to be set to valid path")
+ endif()
+endforeach()
+
+
set(cuda_libs cudart cuda_driver cublas cufft cufftw curand cusolver cusparse)
if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 10.1)
list(APPEND cuda_libs cublasLt)
diff --git a/Tests/FindX11/Test/CMakeLists.txt b/Tests/FindX11/Test/CMakeLists.txt
index e39ffb1eff..3312f6f772 100644
--- a/Tests/FindX11/Test/CMakeLists.txt
+++ b/Tests/FindX11/Test/CMakeLists.txt
@@ -32,16 +32,38 @@ test_x11_component(x11_components Xau)
test_x11_component(x11_components Xaw)
test_x11_component(x11_components xcb)
test_x11_component(x11_components X11_xcb)
+test_x11_component(x11_components xcb_composite)
test_x11_component(x11_components xcb_cursor)
+test_x11_component(x11_components xcb_damage)
+test_x11_component(x11_components xcb_dpms)
+test_x11_component(x11_components xcb_dri2)
+test_x11_component(x11_components xcb_dri3)
+test_x11_component(x11_components xcb_errors)
+test_x11_component(x11_components xcb_ewmh)
+test_x11_component(x11_components xcb_glx)
test_x11_component(x11_components xcb_icccm)
+test_x11_component(x11_components xcb_image)
+test_x11_component(x11_components xcb_keysyms)
+test_x11_component(x11_components xcb_present)
test_x11_component(x11_components xcb_randr)
+test_x11_component(x11_components xcb_record)
+test_x11_component(x11_components xcb_render)
+test_x11_component(x11_components xcb_render_util)
+test_x11_component(x11_components xcb_res)
+test_x11_component(x11_components xcb_screensaver)
test_x11_component(x11_components xcb_shape)
+test_x11_component(x11_components xcb_shm)
+test_x11_component(x11_components xcb_sync)
test_x11_component(x11_components xcb_util)
+test_x11_component(x11_components xcb_xf86dri)
test_x11_component(x11_components xcb_xfixes)
+test_x11_component(x11_components xcb_xinerama)
+test_x11_component(x11_components xcb_xinput)
+test_x11_component(x11_components xcb_xkb)
test_x11_component(x11_components xcb_xrm)
test_x11_component(x11_components xcb_xtest)
-test_x11_component(x11_components xcb_keysyms)
-test_x11_component(x11_components xcb_xkb)
+test_x11_component(x11_components xcb_xvmc)
+test_x11_component(x11_components xcb_xv)
test_x11_component(x11_components Xcomposite)
test_x11_component(x11_components Xdamage)
test_x11_component(x11_components Xdmcp)
@@ -79,13 +101,38 @@ foreach(lib
Xaw
xcb
X11_xcb
+ xcb_composite
xcb_cursor
+ xcb_damage
+ xcb_dpms
+ xcb_dri2
+ xcb_dri3
+ xcb_errors
+ xcb_ewmh
+ xcb_glx
xcb_icccm
+ xcb_image
+ xcb_keysyms
+ xcb_present
xcb_randr
+ xcb_record
+ xcb_render
+ xcb_render_util
+ xcb_res
+ xcb_screensaver
xcb_shape
+ xcb_shm
+ xcb_sync
xcb_util
+ xcb_xf86dri
xcb_xfixes
+ xcb_xinerama
+ xcb_xinput
+ xcb_xkb
xcb_xrm
+ xcb_xtest
+ xcb_xvmc
+ xcb_xv
Xcomposite
Xdamage
Xdmcp
diff --git a/Tests/FindX11/Test/main.c b/Tests/FindX11/Test/main.c
index 5240de0f68..2542145e5f 100644
--- a/Tests/FindX11/Test/main.c
+++ b/Tests/FindX11/Test/main.c
@@ -326,7 +326,7 @@ static void test_Xaw(void)
#endif
-#ifdef HAVE_xcb
+#ifdef HAVE_X11_xcb
# include <xcb/xcb.h>
static void test_xcb(void)
@@ -336,24 +336,216 @@ static void test_xcb(void)
xcb_disconnect(connection);
}
-# ifdef HAVE_xcb_cursor
-# include <xcb/xcb_cursor.h>
+#endif
+
+#ifdef HAVE_X11_xcb_composite
+# include <xcb/composite.h>
+# include <xcb/xcb.h>
+
+static void test_xcb_composite(void)
+{
+ xcb_connection_t* connection = xcb_connect(NULL, NULL);
+ xcb_composite_query_version(connection, 0, 0);
+ xcb_disconnect(connection);
+}
+
+#endif
+
+#ifdef HAVE_X11_xcb_cursor
+# include <xcb/xcb.h>
+# include <xcb/xcb_cursor.h>
static void test_xcb_cursor(void)
{
int screen_nbr;
xcb_connection_t* connection = xcb_connect(NULL, &screen_nbr);
- xcb_screen_t* screen = xcb_aux_get_screen(conn, screen_nbr);
+ xcb_screen_iterator_t screens =
+ xcb_setup_roots_iterator(xcb_get_setup(connection));
xcb_cursor_context_t* ctx;
- xcb_cursor_context_new(connection, screen, &ctx);
+ xcb_cursor_context_new(connection, screens.data, &ctx);
xcb_cursor_context_free(ctx);
xcb_disconnect(connection);
}
-# endif
+#endif
-# ifdef HAVE_xcb_randr
-# include <xcb/randr.h>
+#ifdef HAVE_X11_xcb_damage
+# include <xcb/damage.h>
+# include <xcb/xcb.h>
+
+static void test_xcb_damage(void)
+{
+ int screen_nbr;
+ xcb_connection_t* connection = xcb_connect(NULL, &screen_nbr);
+ xcb_damage_query_version_cookie_t cookie =
+ xcb_damage_query_version(connection, 0, 0);
+ xcb_disconnect(connection);
+}
+
+#endif
+
+#ifdef HAVE_X11_xcb_dpms
+# include <xcb/dpms.h>
+# include <xcb/xcb.h>
+
+static void test_xcb_dpms(void)
+{
+ int screen_nbr;
+ xcb_connection_t* connection = xcb_connect(NULL, &screen_nbr);
+ xcb_dpms_get_version_cookie_t cookie =
+ xcb_dpms_get_version(connection, 0, 0);
+ xcb_disconnect(connection);
+}
+
+#endif
+
+#ifdef HAVE_X11_xcb_dri2
+# include <xcb/dri2.h>
+# include <xcb/xcb.h>
+
+static void test_xcb_dri2(void)
+{
+ int screen_nbr;
+ xcb_connection_t* connection = xcb_connect(NULL, &screen_nbr);
+ xcb_dri2_query_version_cookie_t cookie =
+ xcb_dri2_query_version(connection, 0, 0);
+ xcb_disconnect(connection);
+}
+
+#endif
+
+#ifdef HAVE_X11_xcb_dri3
+# include <xcb/dri3.h>
+# include <xcb/xcb.h>
+
+static void test_xcb_dri3(void)
+{
+ int screen_nbr;
+ xcb_connection_t* connection = xcb_connect(NULL, &screen_nbr);
+ xcb_dri3_query_version_cookie_t cookie =
+ xcb_dri3_query_version(connection, 0, 0);
+ xcb_disconnect(connection);
+}
+
+#endif
+
+#ifdef HAVE_X11_xcb_errors
+# include <xcb/xcb.h>
+# include <xcb/xcb_errors.h>
+
+static void test_xcb_errors(void)
+{
+ int screen_nbr;
+ xcb_connection_t* connection = xcb_connect(NULL, &screen_nbr);
+ xcb_errors_context_t* context;
+ xcb_errors_context_new(connection, &context);
+ xcb_errors_context_free(context);
+ xcb_disconnect(connection);
+}
+
+#endif
+
+#ifdef HAVE_X11_xcb_ewmh
+# include <xcb/xcb.h>
+# include <xcb/xcb_ewmh.h>
+
+static void test_xcb_ewmh(void)
+{
+ int screen_nbr;
+ xcb_connection_t* connection = xcb_connect(NULL, &screen_nbr);
+ xcb_ewmh_connection_t ewmh_connection;
+ xcb_intern_atom_cookie_t* cookie =
+ xcb_ewmh_init_atoms(connection, &ewmh_connection);
+ xcb_ewmh_init_atoms_replies(&ewmh_connection, cookie, NULL);
+ xcb_ewmh_connection_wipe(&ewmh_connection);
+ xcb_disconnect(connection);
+}
+
+#endif
+
+#ifdef HAVE_X11_xcb_glx
+# include <xcb/glx.h>
+# include <xcb/xcb.h>
+
+static void test_xcb_glx(void)
+{
+ int screen_nbr;
+ xcb_connection_t* connection = xcb_connect(NULL, &screen_nbr);
+ xcb_glx_query_version_cookie_t cookie =
+ xcb_glx_query_version(connection, 0, 0);
+ xcb_disconnect(connection);
+}
+
+#endif
+
+#ifdef HAVE_X11_xcb_icccm
+# include <xcb/xcb.h>
+# include <xcb/xcb_icccm.h>
+
+static void test_xcb_icccm(void)
+{
+ int screen_nbr;
+ xcb_connection_t* connection = xcb_connect(NULL, &screen_nbr);
+ xcb_window_t root =
+ xcb_setup_roots_iterator(xcb_get_setup(connection)).data->root;
+ xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_name(connection, root);
+ xcb_icccm_get_text_property_reply_t reply;
+ xcb_icccm_get_wm_name_reply(connection, cookie, &reply, NULL);
+ xcb_disconnect(connection);
+}
+
+#endif
+
+#ifdef HAVE_X11_xcb_image
+# include <xcb/xcb.h>
+# include <xcb/xcb_image.h>
+
+static void test_xcb_image(void)
+{
+ int screen_nbr;
+ xcb_connection_t* connection = xcb_connect(NULL, &screen_nbr);
+ // xcb_image is too convoluted/undocumented to make an
+ // actually working example, apologies :)
+ xcb_image_create(0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, 0, 0);
+ xcb_disconnect(connection);
+}
+
+#endif
+
+#ifdef HAVE_X11_xcb_keysyms
+# include <xcb/xcb.h>
+# include <xcb/xcb_keysyms.h>
+
+static void test_xcb_keysyms(void)
+{
+ int screen_nbr;
+ xcb_connection_t* connection = xcb_connect(NULL, &screen_nbr);
+ xcb_key_symbols_t* symbols = xcb_key_symbols_alloc(connection);
+ if (symbols != NULL)
+ xcb_key_symbols_free(symbols);
+ xcb_disconnect(connection);
+}
+
+#endif
+
+#ifdef HAVE_X11_xcb_present
+# include <xcb/present.h>
+# include <xcb/xcb.h>
+
+static void test_xcb_present(void)
+{
+ int screen_nbr;
+ xcb_connection_t* connection = xcb_connect(NULL, &screen_nbr);
+ xcb_present_query_version_cookie_t cookie =
+ xcb_present_query_version(connection, 0, 0);
+ xcb_disconnect(connection);
+}
+
+#endif
+
+#ifdef HAVE_X11_xcb_randr
+# include <xcb/randr.h>
+# include <xcb/xcb.h>
static void test_xcb_randr(void)
{
@@ -364,10 +556,86 @@ static void test_xcb_randr(void)
xcb_disconnect(connection);
}
-# endif
+#endif
+
+#ifdef HAVE_X11_xcb_record
+# include <xcb/record.h>
+# include <xcb/xcb.h>
+
+static void test_xcb_record(void)
+{
+ int screen_nbr;
+ xcb_connection_t* connection = xcb_connect(NULL, &screen_nbr);
+ xcb_record_query_version_cookie_t cookie =
+ xcb_record_query_version(connection, 0, 0);
+ xcb_disconnect(connection);
+}
-# ifdef HAVE_xcb_shape
-# include <xcb/shape.h>
+#endif
+
+#ifdef HAVE_X11_xcb_render
+# include <xcb/render.h>
+# include <xcb/xcb.h>
+
+static void test_xcb_render(void)
+{
+ int screen_nbr;
+ xcb_connection_t* connection = xcb_connect(NULL, &screen_nbr);
+ xcb_render_query_version_cookie_t cookie =
+ xcb_render_query_version(connection, 0, 0);
+ xcb_disconnect(connection);
+}
+
+#endif
+
+#ifdef HAVE_X11_xcb_render_util
+# include <xcb/xcb.h>
+# include <xcb/xcb_renderutil.h>
+
+static void test_xcb_render_util(void)
+{
+ int screen_nbr;
+ xcb_connection_t* connection = xcb_connect(NULL, &screen_nbr);
+ const xcb_render_query_version_reply_t* cookie =
+ xcb_render_util_query_version(connection);
+ xcb_disconnect(connection);
+}
+
+#endif
+
+#ifdef HAVE_X11_xcb_res
+# include <xcb/res.h>
+# include <xcb/xcb.h>
+
+static void test_xcb_res(void)
+{
+ int screen_nbr;
+ xcb_connection_t* connection = xcb_connect(NULL, &screen_nbr);
+ xcb_res_query_version_cookie_t cookie =
+ xcb_res_query_version(connection, 0, 0);
+ xcb_disconnect(connection);
+}
+
+#endif
+
+#ifdef HAVE_X11_xcb_screensaver
+# include <xcb/screensaver.h>
+# include <xcb/xcb.h>
+
+static void test_xcb_screensaver(void)
+{
+ int screen_nbr;
+ xcb_connection_t* connection = xcb_connect(NULL, &screen_nbr);
+ xcb_screensaver_query_version_cookie_t cookie =
+ xcb_screensaver_query_version(connection, 0, 0);
+ xcb_disconnect(connection);
+}
+
+#endif
+
+#ifdef HAVE_X11_xcb_shape
+# include <xcb/shape.h>
+# include <xcb/xcb.h>
static void test_xcb_shape(void)
{
@@ -378,10 +646,39 @@ static void test_xcb_shape(void)
xcb_disconnect(connection);
}
-# endif
+#endif
+
+#ifdef HAVE_X11_xcb_shm
+# include <xcb/shm.h>
+# include <xcb/xcb.h>
+
+static void test_xcb_shm(void)
+{
+ int screen_nbr;
+ xcb_connection_t* connection = xcb_connect(NULL, &screen_nbr);
+ xcb_shm_query_version_cookie_t cookie = xcb_shm_query_version(connection);
+ xcb_disconnect(connection);
+}
+
+#endif
+
+#ifdef HAVE_X11_xcb_sync
+# include <xcb/sync.h>
+# include <xcb/xcb.h>
+
+static void test_xcb_sync(void)
+{
+ int screen_nbr;
+ xcb_connection_t* connection = xcb_connect(NULL, &screen_nbr);
+ xcb_sync_initialize_cookie_t cookie = xcb_sync_initialize(connection, 0, 0);
+ xcb_disconnect(connection);
+}
+
+#endif
-# ifdef HAVE_xcb_util
-# include <xcb/xcb_aux.h>
+#ifdef HAVE_X11_xcb_util
+# include <xcb/xcb.h>
+# include <xcb/xcb_aux.h>
static void test_xcb_util(void)
{
@@ -391,10 +688,26 @@ static void test_xcb_util(void)
xcb_disconnect(connection);
}
-# endif
+#endif
+
+#ifdef HAVE_X11_xcb_xf86dri
+# include <xcb/xcb.h>
+# include <xcb/xf86dri.h>
+
+static void test_xcb_xf86dri(void)
+{
+ int screen_nbr;
+ xcb_connection_t* connection = xcb_connect(NULL, &screen_nbr);
+ xcb_xf86dri_query_version_cookie_t cookie =
+ xcb_xf86dri_query_version(connection);
+ xcb_disconnect(connection);
+}
+
+#endif
-# ifdef HAVE_xcb_xfixes
-# include <xcb/xcb_xfixes.h>
+#ifdef HAVE_X11_xcb_xfixes
+# include <xcb/xcb.h>
+# include <xcb/xfixes.h>
static void test_xcb_xfixes(void)
{
@@ -404,10 +717,56 @@ static void test_xcb_xfixes(void)
xcb_disconnect(connection);
}
-# endif
+#endif
+
+#ifdef HAVE_X11_xcb_xinerama
+# include <xcb/xcb.h>
+# include <xcb/xinerama.h>
+
+static void test_xcb_xinerama(void)
+{
+ int screen_nbr;
+ xcb_connection_t* connection = xcb_connect(NULL, &screen_nbr);
+ xcb_xinerama_query_version_cookie_t cookie =
+ xcb_xinerama_query_version(connection, 0, 0);
+ xcb_disconnect(connection);
+}
+
+#endif
+
+#ifdef HAVE_X11_xcb_xinput
+# include <xcb/xcb.h>
+# include <xcb/xinput.h>
+
+static void test_xcb_xinput(void)
+{
+ int screen_nbr;
+ xcb_connection_t* connection = xcb_connect(NULL, &screen_nbr);
+ xcb_input_xi_query_version_cookie_t cookie =
+ xcb_input_xi_query_version(connection, 0, 0);
+ xcb_disconnect(connection);
+}
+
+#endif
+
+#ifdef HAVE_X11_xcb_xkb
+# include <xcb/xcb.h>
+# include <xcb/xkb.h>
+
+static void test_xcb_xkb(void)
+{
+ int screen_nbr;
+ xcb_connection_t* connection = xcb_connect(NULL, &screen_nbr);
+ xcb_xkb_use_extension_cookie_t cookie =
+ xcb_xkb_use_extension(connection, 0, 0);
+ xcb_disconnect(connection);
+}
+
+#endif
-# ifdef HAVE_xcb_xrm
-# include <xcb/xcb_xrm.h>
+#ifdef HAVE_X11_xcb_xrm
+# include <xcb/xcb.h>
+# include <xcb/xcb_xrm.h>
static void test_xcb_xrm(void)
{
@@ -418,10 +777,11 @@ static void test_xcb_xrm(void)
xcb_disconnect(connection);
}
-# endif
+#endif
-# ifdef HAVE_xcb_xtest
-# include <xcb/xtest.h>
+#ifdef HAVE_X11_xcb_xtest
+# include <xcb/xcb.h>
+# include <xcb/xtest.h>
static void test_xcb_xtest(void)
{
@@ -431,22 +791,33 @@ static void test_xcb_xtest(void)
xcb_disconnect(connection);
}
-# endif
+#endif
-# ifdef HAVE_xcb_keysyms
-# include <xcb/xcb_keysyms.h>
+#ifdef HAVE_X11_xcb_xvmc
+# include <xcb/xcb.h>
+# include <xcb/xvmc.h>
-static void test_xcb_keysyms(void)
+static void test_xcb_xvmc(void)
{
int screen_nbr;
xcb_connection_t* connection = xcb_connect(NULL, &screen_nbr);
- xcb_key_symbols_t* symbols = xcb_key_symbols_alloc(connection);
- if (symbols != NULL)
- xcb_key_symbols_free(symbols);
+ xcb_xvmc_query_version_cookie_t cookie = xcb_xvmc_query_version(connection);
xcb_disconnect(connection);
}
-# endif
+#endif
+
+#ifdef HAVE_X11_xcb_xv
+# include <xcb/xcb.h>
+# include <xcb/xv.h>
+
+static void test_xcb_xv(void)
+{
+ int screen_nbr;
+ xcb_connection_t* connection = xcb_connect(NULL, &screen_nbr);
+ xcb_xv_query_extension_cookie_t cookie = xcb_xv_query_extension(connection);
+ xcb_disconnect(connection);
+}
#endif
@@ -537,28 +908,105 @@ int main(int argc, char* argv[])
#ifdef HAVE_X11_Xaw
test_Xaw,
#endif
-#ifdef HAVE_xcb
+#ifdef HAVE_X11_xcb
test_xcb,
#endif
-#ifdef HAVE_xcb_cursor
+#ifdef HAVE_X11_xcb_composite
+ test_xcb_composite,
+#endif
+#ifdef HAVE_X11_xcb_cursor
test_xcb_cursor,
#endif
-#ifdef HAVE_xcb_randr
+#ifdef HAVE_X11_xcb_damage
+ test_xcb_damage,
+#endif
+#ifdef HAVE_X11_xcb_dpms
+ test_xcb_dpms,
+#endif
+#ifdef HAVE_X11_xcb_dri2
+ test_xcb_dri2,
+#endif
+#ifdef HAVE_X11_xcb_dri3
+ test_xcb_dri3,
+#endif
+#ifdef HAVE_X11_xcb_errors
+ test_xcb_errors,
+#endif
+#ifdef HAVE_X11_xcb_ewmh
+ test_xcb_ewmh,
+#endif
+#ifdef HAVE_X11_xcb_glx
+ test_xcb_glx,
+#endif
+#ifdef HAVE_X11_xcb_icccm
+ test_xcb_icccm,
+#endif
+#ifdef HAVE_X11_xcb_image
+ test_xcb_image,
+#endif
+#ifdef HAVE_X11_xcb_keysyms
+ test_xcb_keysyms,
+#endif
+#ifdef HAVE_X11_xcb_present
+ test_xcb_present,
+#endif
+#ifdef HAVE_X11_xcb_randr
test_xcb_randr,
#endif
-#ifdef HAVE_xcb_shape
+#ifdef HAVE_X11_xcb_record
+ test_xcb_record,
+#endif
+#ifdef HAVE_X11_xcb_render
+ test_xcb_render,
+#endif
+#ifdef HAVE_X11_xcb_render_util
+ test_xcb_render_util,
+#endif
+#ifdef HAVE_X11_xcb_res
+ test_xcb_res,
+#endif
+#ifdef HAVE_X11_xcb_screensaver
+ test_xcb_screensaver,
+#endif
+#ifdef HAVE_X11_xcb_shape
test_xcb_shape,
#endif
-#ifdef HAVE_xcb_util
+#ifdef HAVE_X11_xcb_shm
+ test_xcb_shm,
+#endif
+#ifdef HAVE_X11_xcb_sync
+ test_xcb_sync,
+#endif
+#ifdef HAVE_X11_xcb_util
test_xcb_util,
#endif
-#ifdef HAVE_xcb_xfixes
+#ifdef HAVE_X11_xcb_xf86dri
+ test_xcb_xf86dri,
+#endif
+#ifdef HAVE_X11_xcb_xfixes
test_xcb_xfixes,
#endif
-#ifdef HAVE_xcb_xrm
+#ifdef HAVE_X11_xcb_xinerama
+ test_xcb_xinerama,
+#endif
+#ifdef HAVE_X11_xcb_xinput
+ test_xcb_xinput,
+#endif
+#ifdef HAVE_X11_xcb_xkb
+ test_xcb_xkb,
+#endif
+#ifdef HAVE_X11_xcb_xrm
test_xcb_xrm,
#endif
-
+#ifdef HAVE_X11_xcb_xtest
+ test_xcb_xtest,
+#endif
+#ifdef HAVE_X11_xcb_xvmc
+ test_xcb_xvmc,
+#endif
+#ifdef HAVE_X11_xcb_xv
+ test_xcb_xv,
+#endif
NULL,
};
@@ -567,5 +1015,6 @@ int main(int argc, char* argv[])
// always 1 in the test harness which always returns the sentinel at the end
// of the array. The array logic is there to ensure that the contents of
// `fptrs` is not optimized out.
+#pragma GCC diagnostic ignored "-Wpointer-to-int-cast"
return (int)fptrs[(sizeof(fptrs) / sizeof(*fptrs)) - argc];
}
diff --git a/Tests/QtAutogen/GlobalAutogenSystemUseInclude/CMakeLists.txt b/Tests/QtAutogen/GlobalAutogenSystemUseInclude/CMakeLists.txt
new file mode 100644
index 0000000000..1095fb1e66
--- /dev/null
+++ b/Tests/QtAutogen/GlobalAutogenSystemUseInclude/CMakeLists.txt
@@ -0,0 +1,28 @@
+cmake_minimum_required(VERSION 3.26)
+project(GlobalAutogenSystemUseInclude)
+
+include("../AutogenCoreTest.cmake")
+
+block()
+ set(test_autogen_use_system_include ON)
+ set(CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE ${test_autogen_use_system_include})
+
+ add_executable(autogen_test_on main.cpp)
+ get_target_property(target_autogen_use_system_include autogen_test_on AUTOGEN_USE_SYSTEM_INCLUDE)
+
+ if(NOT ${CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE} STREQUAL ${target_autogen_use_system_include})
+ message(FATAL_ERROR "CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE not set")
+ endif()
+endblock()
+
+block()
+ set(test_autogen_use_system_include OFF)
+ set(CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE ${test_autogen_use_system_include})
+
+ add_executable(autogen_test_off main.cpp)
+ get_target_property(target_autogen_use_system_include autogen_test_off AUTOGEN_USE_SYSTEM_INCLUDE)
+
+ if(NOT ${CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE} STREQUAL ${target_autogen_use_system_include})
+ message(FATAL_ERROR "CMAKE_AUTOGEN_USE_SYSTEM_INCLUDE not set")
+ endif()
+endblock()
diff --git a/Tests/QtAutogen/GlobalAutogenSystemUseInclude/main.cpp b/Tests/QtAutogen/GlobalAutogenSystemUseInclude/main.cpp
new file mode 100644
index 0000000000..f8b643afbf
--- /dev/null
+++ b/Tests/QtAutogen/GlobalAutogenSystemUseInclude/main.cpp
@@ -0,0 +1,4 @@
+int main()
+{
+ return 0;
+}
diff --git a/Tests/QtAutogen/RccAutogenBuildDir/CMakeLists.txt b/Tests/QtAutogen/RccAutogenBuildDir/CMakeLists.txt
new file mode 100644
index 0000000000..9bdb68986d
--- /dev/null
+++ b/Tests/QtAutogen/RccAutogenBuildDir/CMakeLists.txt
@@ -0,0 +1,33 @@
+cmake_minimum_required(VERSION 3.16)
+project(RccAutogenBuildDir)
+include("../AutogenCoreTest.cmake")
+
+set(PROJECTS_ROOT ${CMAKE_BINARY_DIR})
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTOUIC ON)
+set(CMAKE_AUTORCC ON)
+
+macro(set_build_type_dependent varName debugValue releaseValue
+ relWithDebInfoValue minSizeRelValue)
+
+ if(CMAKE_BUILD_TYPE MATCHES Debug)
+ set(${varName} ${debugValue})
+ elseif(CMAKE_BUILD_TYPE MATCHES Release)
+ set(${varName} ${releaseValue})
+ elseif(CMAKE_BUILD_TYPE MATCHES RelWithDebInfo)
+ set(${varName} ${relWithDebInfoValue})
+ elseif(CMAKE_BUILD_TYPE MATCHES MinSizeRel)
+ set(${varName} ${minSizeRelValue})
+ endif()
+endmacro()
+
+set_build_type_dependent(AUTOGEN_DIR agd agr ags agm)
+add_library(testlib SHARED lib.h lib.cpp resource.qrc)
+set_target_properties(testlib PROPERTIES AUTOGEN_BUILD_DIR "${PROJECTS_ROOT}/${AUTOGEN_DIR}/testlib_ag")
+target_link_libraries(testlib ${QT_LIBRARIES})
+
+set_build_type_dependent(AUTOGEN_DIR agd agr ags agm)
+add_executable(autorcctest main.cpp lib.h)
+set_target_properties(autorcctest PROPERTIES AUTOGEN_BUILD_DIR "${PROJECTS_ROOT}/${AUTOGEN_DIR}/autorcctest_ag")
+target_link_libraries(autorcctest ${QT_LIBRARIES} testlib)
diff --git a/Tests/QtAutogen/RccAutogenBuildDir/lib.cpp b/Tests/QtAutogen/RccAutogenBuildDir/lib.cpp
new file mode 100644
index 0000000000..3a5c48208f
--- /dev/null
+++ b/Tests/QtAutogen/RccAutogenBuildDir/lib.cpp
@@ -0,0 +1,6 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+ void foo()
+{
+}
diff --git a/Tests/QtAutogen/RccAutogenBuildDir/lib.h b/Tests/QtAutogen/RccAutogenBuildDir/lib.h
new file mode 100644
index 0000000000..28138f189a
--- /dev/null
+++ b/Tests/QtAutogen/RccAutogenBuildDir/lib.h
@@ -0,0 +1,6 @@
+#ifndef LIB_H
+#define LIB_H
+
+void foo();
+
+#endif
diff --git a/Tests/QtAutogen/RccAutogenBuildDir/main.cpp b/Tests/QtAutogen/RccAutogenBuildDir/main.cpp
new file mode 100644
index 0000000000..a211f4011e
--- /dev/null
+++ b/Tests/QtAutogen/RccAutogenBuildDir/main.cpp
@@ -0,0 +1,7 @@
+#include "lib.h"
+
+int main()
+{
+ foo();
+ return 0;
+}
diff --git a/Tests/QtAutogen/RccAutogenBuildDir/resource.qrc b/Tests/QtAutogen/RccAutogenBuildDir/resource.qrc
new file mode 100644
index 0000000000..90f4a8379a
--- /dev/null
+++ b/Tests/QtAutogen/RccAutogenBuildDir/resource.qrc
@@ -0,0 +1,2 @@
+<!DOCTYPE RCC>
+<RCC version="1.0"/>
diff --git a/Tests/QtAutogen/Tests.cmake b/Tests/QtAutogen/Tests.cmake
index 412d511349..3e4f04d07e 100644
--- a/Tests/QtAutogen/Tests.cmake
+++ b/Tests/QtAutogen/Tests.cmake
@@ -1,8 +1,9 @@
-# Qt4 and Qt5 tests
+# Qt4, Qt5 and Qt6 tests
ADD_AUTOGEN_TEST(AutogenOriginDependsOff autogenOriginDependsOff)
ADD_AUTOGEN_TEST(AutogenOriginDependsOn)
ADD_AUTOGEN_TEST(AutogenTargetDepends)
ADD_AUTOGEN_TEST(Complex QtAutogen)
+ADD_AUTOGEN_TEST(GlobalAutogenSystemUseInclude)
ADD_AUTOGEN_TEST(GlobalAutogenTarget)
ADD_AUTOGEN_TEST(GlobalAutogenExecutable)
ADD_AUTOGEN_TEST(LowMinimumVersion lowMinimumVersion)
@@ -17,6 +18,7 @@ ADD_AUTOGEN_TEST(Parallel2 parallel2)
ADD_AUTOGEN_TEST(Parallel3 parallel3)
ADD_AUTOGEN_TEST(Parallel4 parallel4)
ADD_AUTOGEN_TEST(ParallelAUTO parallelAUTO)
+ADD_AUTOGEN_TEST(RccAutogenBuildDir)
ADD_AUTOGEN_TEST(RccEmpty rccEmpty)
ADD_AUTOGEN_TEST(RccOffMocLibrary)
ADD_AUTOGEN_TEST(RccOnly rccOnly)
@@ -46,7 +48,7 @@ if(QT_TEST_ALLOW_QT_MACROS)
ADD_AUTOGEN_TEST(MocSkipSource)
endif()
-# Qt5 only tests
+# Qt5 and Qt6 only tests
if(QT_TEST_VERSION GREATER 4)
ADD_AUTOGEN_TEST(MocMacroName mocMacroName)
ADD_AUTOGEN_TEST(MocOsMacros)
diff --git a/Tests/RunCMake/Autogen/AutogenUseSystemIncludeCommon.cmake b/Tests/RunCMake/Autogen/AutogenUseSystemIncludeCommon.cmake
new file mode 100644
index 0000000000..bbefd5f55b
--- /dev/null
+++ b/Tests/RunCMake/Autogen/AutogenUseSystemIncludeCommon.cmake
@@ -0,0 +1,10 @@
+enable_language(CXX)
+
+find_package(Qt${with_qt_version} REQUIRED COMPONENTS Core Widgets Gui)
+
+set(CMAKE_AUTOMOC ON)
+
+add_library(dummy SHARED empty.cpp)
+target_link_libraries(dummy Qt${with_qt_version}::Core
+ Qt${with_qt_version}::Widgets
+ Qt${with_qt_version}::Gui)
diff --git a/Tests/RunCMake/Autogen/AutogenUseSystemIncludeOff.cmake b/Tests/RunCMake/Autogen/AutogenUseSystemIncludeOff.cmake
new file mode 100644
index 0000000000..dfdbb98b5b
--- /dev/null
+++ b/Tests/RunCMake/Autogen/AutogenUseSystemIncludeOff.cmake
@@ -0,0 +1,3 @@
+include("${CMAKE_CURRENT_LIST_DIR}/AutogenUseSystemIncludeCommon.cmake")
+
+set_target_properties(dummy PROPERTIES AUTOGEN_USE_SYSTEM_INCLUDE OFF)
diff --git a/Tests/RunCMake/Autogen/AutogenUseSystemIncludeOn.cmake b/Tests/RunCMake/Autogen/AutogenUseSystemIncludeOn.cmake
new file mode 100644
index 0000000000..f556ed43af
--- /dev/null
+++ b/Tests/RunCMake/Autogen/AutogenUseSystemIncludeOn.cmake
@@ -0,0 +1,3 @@
+include("${CMAKE_CURRENT_LIST_DIR}/AutogenUseSystemIncludeCommon.cmake")
+
+set_target_properties(dummy PROPERTIES AUTOGEN_USE_SYSTEM_INCLUDE ON)
diff --git a/Tests/RunCMake/Autogen/CMP0151-common.cmake b/Tests/RunCMake/Autogen/CMP0151-common.cmake
new file mode 100644
index 0000000000..bbefd5f55b
--- /dev/null
+++ b/Tests/RunCMake/Autogen/CMP0151-common.cmake
@@ -0,0 +1,10 @@
+enable_language(CXX)
+
+find_package(Qt${with_qt_version} REQUIRED COMPONENTS Core Widgets Gui)
+
+set(CMAKE_AUTOMOC ON)
+
+add_library(dummy SHARED empty.cpp)
+target_link_libraries(dummy Qt${with_qt_version}::Core
+ Qt${with_qt_version}::Widgets
+ Qt${with_qt_version}::Gui)
diff --git a/Tests/RunCMake/Autogen/CMP0151-new.cmake b/Tests/RunCMake/Autogen/CMP0151-new.cmake
new file mode 100644
index 0000000000..9c77e586f9
--- /dev/null
+++ b/Tests/RunCMake/Autogen/CMP0151-new.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/CMP0151-common.cmake")
diff --git a/Tests/RunCMake/Autogen/CMP0151-old.cmake b/Tests/RunCMake/Autogen/CMP0151-old.cmake
new file mode 100644
index 0000000000..9c77e586f9
--- /dev/null
+++ b/Tests/RunCMake/Autogen/CMP0151-old.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/CMP0151-common.cmake")
diff --git a/Tests/RunCMake/Autogen/Inspect.cmake b/Tests/RunCMake/Autogen/Inspect.cmake
new file mode 100644
index 0000000000..d5dc4b4093
--- /dev/null
+++ b/Tests/RunCMake/Autogen/Inspect.cmake
@@ -0,0 +1,13 @@
+enable_language(CXX)
+
+set(info "")
+foreach(var
+ CMAKE_INCLUDE_FLAG_CXX
+ CMAKE_INCLUDE_SYSTEM_FLAG_CXX
+ )
+ if(DEFINED ${var})
+ string(APPEND info "set(${var} \"${${var}}\")\n")
+ endif()
+endforeach()
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/info.cmake" "${info}")
diff --git a/Tests/RunCMake/Autogen/RunCMakeTest.cmake b/Tests/RunCMake/Autogen/RunCMakeTest.cmake
index 6a3c49b534..45051326cb 100644
--- a/Tests/RunCMake/Autogen/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Autogen/RunCMakeTest.cmake
@@ -22,4 +22,70 @@ if (DEFINED with_qt_version)
set(RunCMake_TEST_NO_CLEAN 1)
run_cmake_command(MocPredefs-build ${CMAKE_COMMAND} --build . --config Debug)
endblock()
+
+ # Detect information from the toolchain:
+ # - CMAKE_INCLUDE_FLAG_CXX
+ # - CMAKE_INCLUDE_SYSTEM_FLAG_CXX
+ run_cmake(Inspect)
+ include("${RunCMake_BINARY_DIR}/Inspect-build/info.cmake")
+
+ if(CMAKE_INCLUDE_SYSTEM_FLAG_CXX)
+ if(RunCMake_GENERATOR MATCHES "Visual Studio")
+ string(REGEX REPLACE "^-" "/" test_expect_stdout "${CMAKE_INCLUDE_SYSTEM_FLAG_CXX}")
+ else()
+ set(test_expect_stdout "-*${CMAKE_INCLUDE_SYSTEM_FLAG_CXX}")
+ endif()
+ string(APPEND test_expect_stdout " *(\"[^\"]*|([^ ]|\\ )*)[\\/]dummy_autogen[\\/]include")
+ if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+ string(APPEND test_expect_stdout "_Debug")
+ endif()
+
+ block()
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CMP0151-new-build)
+ run_cmake_with_options(CMP0151-new ${RunCMake_TEST_OPTIONS} -DCMAKE_POLICY_DEFAULT_CMP0151=NEW)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ set(RunCMake_TEST_EXPECT_stdout "${test_expect_stdout}")
+ message(STATUS "RunCMake_TEST_EXPECT_stdout: ${RunCMake_TEST_EXPECT_stdout}")
+ run_cmake_command(CMP0151-new-build ${CMAKE_COMMAND} --build . --config Debug --verbose)
+ endblock()
+
+ block()
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/AutogenUseSystemIncludeOn-build)
+ run_cmake_with_options(AutogenUseSystemIncludeOn ${RunCMake_TEST_OPTIONS} -DCMAKE_POLICY_DEFAULT_CMP0151=NEW)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ set(RunCMake_TEST_EXPECT_stdout "${test_expect_stdout}")
+ message(STATUS "RunCMake_TEST_EXPECT_stdout: ${RunCMake_TEST_EXPECT_stdout}")
+ run_cmake_command(AutogenUseSystemIncludeOn ${CMAKE_COMMAND} --build . --config Debug --verbose)
+ endblock()
+ endif()
+
+ if(CMAKE_INCLUDE_FLAG_CXX)
+ if(RunCMake_GENERATOR MATCHES "Visual Studio")
+ string(REGEX REPLACE "^-" "/" test_expect_stdout "${CMAKE_INCLUDE_FLAG_CXX}")
+ else()
+ set(test_expect_stdout "-*${CMAKE_INCLUDE_FLAG_CXX}")
+ endif()
+ string(APPEND test_expect_stdout " *(\"[^\"]*|([^ ]|\\ )*)[\\/]dummy_autogen[\\/]include")
+ if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+ string(APPEND test_expect_stdout "_Debug")
+ endif()
+
+ block()
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CMP0151-old-build)
+ run_cmake_with_options(CMP0151-old ${RunCMake_TEST_OPTIONS} -DCMAKE_POLICY_DEFAULT_CMP0151=OLD)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ set(RunCMake_TEST_EXPECT_stdout "${test_expect_stdout}")
+ message(STATUS "RunCMake_TEST_EXPECT_stdout: ${RunCMake_TEST_EXPECT_stdout}")
+ run_cmake_command(CMP0151-old-build ${CMAKE_COMMAND} --build . --config Debug --verbose)
+ endblock()
+
+ block()
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/AutogenUseSystemIncludeOff-build)
+ run_cmake_with_options(AutogenUseSystemIncludeOff ${RunCMake_TEST_OPTIONS} -DCMAKE_POLICY_DEFAULT_CMP0151=NEW)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ set(RunCMake_TEST_EXPECT_stdout "${test_expect_stdout}")
+ message(STATUS "RunCMake_TEST_EXPECT_stdout: ${RunCMake_TEST_EXPECT_stdout}")
+ run_cmake_command(AutogenUseSystemIncludeOff ${CMAKE_COMMAND} --build . --config Debug --verbose)
+ endblock()
+ endif()
endif ()
diff --git a/Tests/RunCMake/BuildDepends/LinkDepends.cmake b/Tests/RunCMake/BuildDepends/LinkDepends.cmake
new file mode 100644
index 0000000000..a414e03597
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/LinkDepends.cmake
@@ -0,0 +1,22 @@
+
+enable_language(C)
+
+include("${CMAKE_BINARY_DIR}/../LinkDependsExternalLibrary-build/ExternalLibrary-debug.cmake")
+cmake_path(GET EXTERNAL_LIBRARY PARENT_PATH EXTERNAL_DIR)
+
+add_library(LinkDependsLib SHARED "${CMAKE_CURRENT_BINARY_DIR}/lib_depends.c")
+target_link_directories(LinkDependsLib PRIVATE "${EXTERNAL_DIR}")
+target_link_libraries(LinkDependsLib PRIVATE External)
+
+add_executable(LinkDependsExe "${CMAKE_CURRENT_BINARY_DIR}/exe_depends.c")
+target_link_directories(LinkDependsExe PRIVATE "${EXTERNAL_DIR}")
+target_link_libraries(LinkDependsExe PRIVATE External)
+
+
+file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/check-$<LOWER_CASE:$<CONFIG>>.cmake"
+ CONTENT "
+set(check_pairs
+ \"$<TARGET_FILE:LinkDependsLib>|${EXTERNAL_LIBRARY}\"
+ \"$<TARGET_FILE:LinkDependsExe>|${EXTERNAL_LIBRARY}\"
+ )
+")
diff --git a/Tests/RunCMake/BuildDepends/LinkDepends.step1.cmake b/Tests/RunCMake/BuildDepends/LinkDepends.step1.cmake
new file mode 100644
index 0000000000..5ce55b0177
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/LinkDepends.step1.cmake
@@ -0,0 +1,23 @@
+
+file(WRITE "${RunCMake_TEST_BINARY_DIR}/lib_depends.c" [[
+
+extern void external(void);
+
+void lib_depends(void)
+{
+ external();
+}
+]])
+
+
+file(WRITE "${RunCMake_TEST_BINARY_DIR}/exe_depends.c" [[
+
+extern void external(void);
+
+int main(void)
+{
+ external();
+
+ return 0;
+}
+]])
diff --git a/Tests/RunCMake/BuildDepends/LinkDepends.step2.cmake b/Tests/RunCMake/BuildDepends/LinkDepends.step2.cmake
new file mode 100644
index 0000000000..f2c0067747
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/LinkDepends.step2.cmake
@@ -0,0 +1,4 @@
+
+include ("${RunCMake_TEST_BINARY_DIR}/../LinkDependsExternalLibrary-build/ExternalLibrary-debug.cmake")
+
+file(TOUCH "${EXTERNAL_LIBRARY}")
diff --git a/Tests/RunCMake/BuildDepends/LinkDependsCheck.cmake b/Tests/RunCMake/BuildDepends/LinkDependsCheck.cmake
new file mode 100644
index 0000000000..a21096b2ae
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/LinkDependsCheck.cmake
@@ -0,0 +1,11 @@
+
+enable_language(C)
+
+file(WRITE "${CMAKE_BINARY_DIR}/LinkDependsUseLinker.cmake"
+ "set(CMAKE_C_LINK_DEPENDS_USE_LINKER \"${CMAKE_C_LINK_DEPENDS_USE_LINKER}\")\n")
+
+
+file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/check-$<LOWER_CASE:$<CONFIG>>.cmake"
+ CONTENT "
+# no required actions
+")
diff --git a/Tests/RunCMake/BuildDepends/LinkDependsExternalLibrary.cmake b/Tests/RunCMake/BuildDepends/LinkDependsExternalLibrary.cmake
new file mode 100644
index 0000000000..fe6575c9b8
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/LinkDependsExternalLibrary.cmake
@@ -0,0 +1,13 @@
+
+enable_language(C)
+
+add_library(External SHARED "${CMAKE_CURRENT_BINARY_DIR}/external.c")
+
+file(GENERATE OUTPUT "${CMAKE_BINARY_DIR}/ExternalLibrary-$<LOWER_CASE:$<CONFIG>>.cmake"
+ CONTENT "set(EXTERNAL_LIBRARY \"$<TARGET_LINKER_FILE:External>\")\n")
+
+
+file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/check-$<LOWER_CASE:$<CONFIG>>.cmake"
+ CONTENT "
+# no required actions
+")
diff --git a/Tests/RunCMake/BuildDepends/LinkDependsExternalLibrary.step1.cmake b/Tests/RunCMake/BuildDepends/LinkDependsExternalLibrary.step1.cmake
new file mode 100644
index 0000000000..df302f7614
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/LinkDependsExternalLibrary.step1.cmake
@@ -0,0 +1,11 @@
+
+file(WRITE "${RunCMake_TEST_BINARY_DIR}/external.c" [[
+
+
+#if defined(_WIN32)
+__declspec(dllexport)
+#endif
+ void external(void)
+{
+}
+]])
diff --git a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
index 809907931d..b52758045e 100644
--- a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
+++ b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
@@ -194,3 +194,15 @@ if(RunCMake_GENERATOR MATCHES "^Visual Studio 9 " OR
endif()
run_BuildDepends(CustomCommandUnityBuild)
unset(run_BuildDepends_skip_step_2)
+
+#if (RunCMake_GENERATOR MATCHES "Make|Ninja" AND CMAKE_C_LINK_DEPENDS_USE_LINKER)
+if (RunCMake_GENERATOR MATCHES "Make|Ninja")
+ set(run_BuildDepends_skip_step_2 1)
+ run_BuildDepends(LinkDependsCheck)
+ include("${RunCMake_BINARY_DIR}/LinkDependsCheck-build/LinkDependsUseLinker.cmake")
+ if (CMAKE_C_LINK_DEPENDS_USE_LINKER)
+ run_BuildDepends(LinkDependsExternalLibrary)
+ unset(run_BuildDepends_skip_step_2)
+ run_BuildDepends(LinkDepends)
+ endif()
+endif()
diff --git a/Tests/RunCMake/CMP0121/CMP0121-ERANGE-OLD-stderr.txt b/Tests/RunCMake/CMP0121/CMP0121-ERANGE-OLD-stderr.txt
index 5a035596e3..ac01c80b32 100644
--- a/Tests/RunCMake/CMP0121/CMP0121-ERANGE-OLD-stderr.txt
+++ b/Tests/RunCMake/CMP0121/CMP0121-ERANGE-OLD-stderr.txt
@@ -1,5 +1,5 @@
CMake Error at CMP0121-ERANGE-Common.cmake:3 \(list\):
- list index: (-2147483643|2147483647) out of range \(-5, 4\)
+ list index: (-2147483648|2147483647) out of range \(-5, 4\)
Call Stack \(most recent call first\):
CMP0121-ERANGE-OLD.cmake:2 \(include\)
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CMP0121/CMP0121-ERANGE-WARN-stderr.txt b/Tests/RunCMake/CMP0121/CMP0121-ERANGE-WARN-stderr.txt
index cb4ea46439..c644dd3618 100644
--- a/Tests/RunCMake/CMP0121/CMP0121-ERANGE-WARN-stderr.txt
+++ b/Tests/RunCMake/CMP0121/CMP0121-ERANGE-WARN-stderr.txt
@@ -9,7 +9,7 @@ Call Stack \(most recent call first\):
This warning is for project developers. Use -Wno-dev to suppress it.
.*
CMake Error at CMP0121-ERANGE-Common.cmake:3 \(list\):
- list index: (-2147483643|2147483647) out of range \(-5, 4\)
+ list index: (-2147483648|2147483647) out of range \(-5, 4\)
Call Stack \(most recent call first\):
CMP0121-ERANGE-WARN.cmake:2 \(include\)
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/CMP0150/CMP0150-NEW-build-stdout.txt b/Tests/RunCMake/CMP0150/CMP0150-NEW-build-stdout.txt
new file mode 100644
index 0000000000..9e71b731c7
--- /dev/null
+++ b/Tests/RunCMake/CMP0150/CMP0150-NEW-build-stdout.txt
@@ -0,0 +1,7 @@
+.*-- Configured bottom project
+.*ExternalProject for ep-Y
+.*-- Configured bottom project
+[^\n]*-- Completed configuring project middle
+.*-- Configured bottom project
+.*ExternalProject for ep-X
+.*Non-ep top project
diff --git a/Tests/RunCMake/CMP0150/CMP0150-NEW-resolve.cmake b/Tests/RunCMake/CMP0150/CMP0150-NEW-resolve.cmake
new file mode 100644
index 0000000000..f43f3d5f7b
--- /dev/null
+++ b/Tests/RunCMake/CMP0150/CMP0150-NEW-resolve.cmake
@@ -0,0 +1,107 @@
+include(ExternalProject/shared_internal_commands)
+
+function(test_resolve parentUrl relativeUrl expectedResult)
+ _ep_resolve_relative_git_remote(result "${parentUrl}" "${relativeUrl}")
+ if(NOT result STREQUAL expectedResult)
+ message(SEND_ERROR "URL resolved to unexpected result:\n"
+ " Expected: ${expectedResult}\n"
+ " Actual : ${result}"
+ )
+ endif()
+endfunction()
+
+test_resolve(
+ "https://example.com/group/parent"
+ "../other"
+ "https://example.com/group/other"
+)
+test_resolve(
+ "https://example.com/group/parent"
+ "../../alt/other"
+ "https://example.com/alt/other"
+)
+
+test_resolve(
+ "git@example.com:group/parent"
+ "../other"
+ "git@example.com:group/other"
+)
+test_resolve(
+ "git@example.com:group/parent"
+ "../../alt/other"
+ "git@example.com:alt/other"
+)
+test_resolve(
+ "git@example.com:/group/parent"
+ "../other"
+ "git@example.com:/group/other"
+)
+test_resolve(
+ "git@example.com:/group/parent"
+ "../../alt/other"
+ "git@example.com:/alt/other"
+)
+test_resolve(
+ "git+ssh://git@example.com:group/parent"
+ "../other"
+ "git+ssh://git@example.com:group/other"
+)
+test_resolve(
+ "ssh://git@example.com:1234/group/parent"
+ "../../alt/other"
+ "ssh://git@example.com:1234/alt/other"
+)
+
+test_resolve(
+ "file:///group/parent"
+ "../other"
+ "file:///group/other"
+)
+test_resolve(
+ "file:///group/parent"
+ "../../alt/other"
+ "file:///alt/other"
+)
+test_resolve(
+ "file:///~/group/parent"
+ "../../other"
+ "file:///~/other"
+)
+test_resolve(
+ "/group/parent"
+ "../other"
+ "/group/other"
+)
+test_resolve(
+ "/group/parent"
+ "../../alt/other"
+ "/alt/other"
+)
+test_resolve(
+ "C:/group/parent"
+ "../other"
+ "C:/group/other"
+)
+test_resolve(
+ "C:/group/parent"
+ "../../alt/other"
+ "C:/alt/other"
+)
+
+test_resolve(
+ "x-Test+v1.0://example.com/group/parent"
+ "../other"
+ "x-Test+v1.0://example.com/group/other"
+)
+
+# IPv6 literals
+test_resolve(
+ "http://[::1]/group/parent"
+ "../../alt/other"
+ "http://[::1]/alt/other"
+)
+test_resolve(
+ "git@[::1]:group/parent"
+ "../../alt/other"
+ "git@[::1]:alt/other"
+)
diff --git a/Tests/RunCMake/CMP0150/CMP0150-NEW-stdout.txt b/Tests/RunCMake/CMP0150/CMP0150-NEW-stdout.txt
new file mode 100644
index 0000000000..0f25fabf40
--- /dev/null
+++ b/Tests/RunCMake/CMP0150/CMP0150-NEW-stdout.txt
@@ -0,0 +1,4 @@
+-- Configured bottom project
+-- Completed configuring project middle
+-- Completed configuring project top
+-- Configuring done
diff --git a/Tests/RunCMake/CMP0150/CMP0150-NEW.cmake b/Tests/RunCMake/CMP0150/CMP0150-NEW.cmake
new file mode 100644
index 0000000000..c1c5607af7
--- /dev/null
+++ b/Tests/RunCMake/CMP0150/CMP0150-NEW.cmake
@@ -0,0 +1,45 @@
+set(policyCommand "cmake_policy(SET CMP0150 NEW)")
+
+# Need to keep paths and file names short to avoid hitting limits on Windows.
+# Directory names "a" through to "g" are used here according to the following:
+# a = Top project
+# b/c = Middle project
+# d = Bottom project
+# e/f = Cloned Top project
+# g = Build directory for cloned Top project
+#
+# Dependency names map as follows:
+# X = middle dependency
+# Y = bottom dependency
+
+set(projName top)
+set(depName X)
+set(epRelativeGitRepo ../b/c)
+set(fcRelativeGitRepo ../b/c)
+configure_file(CMakeLists.txt.in a/CMakeLists.txt @ONLY)
+initGitRepo("${CMAKE_CURRENT_BINARY_DIR}/a")
+
+set(projName middle)
+set(depName Y)
+set(epRelativeGitRepo ../../d)
+set(fcRelativeGitRepo ../../d)
+configure_file(CMakeLists.txt.in b/c/CMakeLists.txt @ONLY)
+initGitRepo("${CMAKE_CURRENT_BINARY_DIR}/b/c")
+
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/d")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/d/CMakeLists.txt" [[
+cmake_minimum_required(VERSION 3.26)
+project(bottom LANGUAGES NONE)
+message(STATUS "Configured bottom project")
+]])
+initGitRepo("${CMAKE_CURRENT_BINARY_DIR}/d")
+
+set(clonedTopDir "${CMAKE_CURRENT_BINARY_DIR}/e/f")
+file(MAKE_DIRECTORY "${clonedTopDir}")
+execGitCommand(${CMAKE_CURRENT_BINARY_DIR} clone --quiet "file://${CMAKE_CURRENT_BINARY_DIR}/a" "${clonedTopDir}")
+add_subdirectory("${clonedTopDir}" "${CMAKE_CURRENT_BINARY_DIR}/g")
+
+# Ensure build order is predictable
+add_custom_target(non-ep-top ALL COMMAND ${CMAKE_COMMAND} -E echo "Non-ep top project")
+add_dependencies(non-ep-top ep-X)
+add_dependencies(ep-X ep-Y)
diff --git a/Tests/RunCMake/CMP0150/CMP0150-OLD-build-stdout.txt b/Tests/RunCMake/CMP0150/CMP0150-OLD-build-stdout.txt
new file mode 100644
index 0000000000..0150af769b
--- /dev/null
+++ b/Tests/RunCMake/CMP0150/CMP0150-OLD-build-stdout.txt
@@ -0,0 +1,3 @@
+.*-- Configured bottom project
+.*ExternalProject for ep-bottom
+.*Non-ep top project
diff --git a/Tests/RunCMake/CMP0150/CMP0150-OLD-common.cmake b/Tests/RunCMake/CMP0150/CMP0150-OLD-common.cmake
new file mode 100644
index 0000000000..69748f7325
--- /dev/null
+++ b/Tests/RunCMake/CMP0150/CMP0150-OLD-common.cmake
@@ -0,0 +1,21 @@
+# There's no point testing more than one level for OLD, since the behavior only
+# depends on the current build, not anything about the parent git repo, etc.
+set(projName top)
+set(depName bottom)
+set(epRelativeGitRepo ../../../Bottom)
+set(fcRelativeGitRepo ../Bottom)
+configure_file(CMakeLists.txt.in Top/CMakeLists.txt @ONLY)
+
+file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/Bottom")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/Bottom/CMakeLists.txt" [[
+cmake_minimum_required(VERSION 3.26)
+project(bottom LANGUAGES NONE)
+message(STATUS "Configured bottom project")
+]])
+initGitRepo("${CMAKE_CURRENT_BINARY_DIR}/Bottom")
+
+add_subdirectory("${CMAKE_CURRENT_BINARY_DIR}/Top" "${CMAKE_CURRENT_BINARY_DIR}/Top-build")
+
+# Ensure build order is predictable
+add_custom_target(non-ep-top ALL COMMAND ${CMAKE_COMMAND} -E echo "Non-ep top project")
+add_dependencies(non-ep-top ep-bottom)
diff --git a/Tests/RunCMake/CMP0150/CMP0150-OLD-stdout.txt b/Tests/RunCMake/CMP0150/CMP0150-OLD-stdout.txt
new file mode 100644
index 0000000000..680f9c1d3d
--- /dev/null
+++ b/Tests/RunCMake/CMP0150/CMP0150-OLD-stdout.txt
@@ -0,0 +1,3 @@
+-- Configured bottom project
+-- Completed configuring project top
+-- Configuring done
diff --git a/Tests/RunCMake/CMP0150/CMP0150-OLD.cmake b/Tests/RunCMake/CMP0150/CMP0150-OLD.cmake
new file mode 100644
index 0000000000..6b58e70c83
--- /dev/null
+++ b/Tests/RunCMake/CMP0150/CMP0150-OLD.cmake
@@ -0,0 +1,2 @@
+set(policyCommand "cmake_policy(SET CMP0150 OLD)")
+include(CMP0150-OLD-common.cmake)
diff --git a/Tests/RunCMake/CMP0150/CMP0150-WARN-build-stdout.txt b/Tests/RunCMake/CMP0150/CMP0150-WARN-build-stdout.txt
new file mode 100644
index 0000000000..0150af769b
--- /dev/null
+++ b/Tests/RunCMake/CMP0150/CMP0150-WARN-build-stdout.txt
@@ -0,0 +1,3 @@
+.*-- Configured bottom project
+.*ExternalProject for ep-bottom
+.*Non-ep top project
diff --git a/Tests/RunCMake/CMP0150/CMP0150-WARN-stderr.txt b/Tests/RunCMake/CMP0150/CMP0150-WARN-stderr.txt
new file mode 100644
index 0000000000..74c932aaa2
--- /dev/null
+++ b/Tests/RunCMake/CMP0150/CMP0150-WARN-stderr.txt
@@ -0,0 +1,25 @@
+CMake Warning \(dev\) at .*/Modules/ExternalProject/shared_internal_commands\.cmake:[0-9]+ \(message\):
+ Policy CMP0150 is not set: ExternalProject_Add and FetchContent_Declare
+ commands treat relative GIT_REPOSITORY paths as being relative to the
+ parent project's remote\. Run "cmake --help-policy CMP0150" for policy
+ details\. Use the cmake_policy command to set the policy and suppress this
+ warning\.
+
+ A relative GIT_REPOSITORY path was detected\. This will be interpreted as a
+ local path to where the project is being cloned\. Set GIT_REPOSITORY to an
+ absolute path or set policy CMP0150 to NEW to avoid this warning\.
+Call Stack \(most recent call first\):
+ .*/Modules/ExternalProject\.cmake:[0-9]+ \(_ep_resolve_git_remote\)
+.*
+CMake Warning \(dev\) at .*/Modules/ExternalProject/shared_internal_commands\.cmake:[0-9]+ \(message\):
+ Policy CMP0150 is not set: ExternalProject_Add and FetchContent_Declare
+ commands treat relative GIT_REPOSITORY paths as being relative to the
+ parent project's remote\. Run "cmake --help-policy CMP0150" for policy
+ details\. Use the cmake_policy command to set the policy and suppress this
+ warning\.
+
+ A relative GIT_REPOSITORY path was detected\. This will be interpreted as a
+ local path to where the project is being cloned\. Set GIT_REPOSITORY to an
+ absolute path or set policy CMP0150 to NEW to avoid this warning\.
+Call Stack \(most recent call first\):
+ .*/Modules/FetchContent\.cmake:[0-9]+ \(_ep_resolve_git_remote\)
diff --git a/Tests/RunCMake/CMP0150/CMP0150-WARN-stdout.txt b/Tests/RunCMake/CMP0150/CMP0150-WARN-stdout.txt
new file mode 100644
index 0000000000..680f9c1d3d
--- /dev/null
+++ b/Tests/RunCMake/CMP0150/CMP0150-WARN-stdout.txt
@@ -0,0 +1,3 @@
+-- Configured bottom project
+-- Completed configuring project top
+-- Configuring done
diff --git a/Tests/RunCMake/CMP0150/CMP0150-WARN.cmake b/Tests/RunCMake/CMP0150/CMP0150-WARN.cmake
new file mode 100644
index 0000000000..20fd45d4e6
--- /dev/null
+++ b/Tests/RunCMake/CMP0150/CMP0150-WARN.cmake
@@ -0,0 +1,2 @@
+set(policyCommand "")
+include(CMP0150-OLD-common.cmake)
diff --git a/Tests/RunCMake/CMP0150/CMakeLists.txt b/Tests/RunCMake/CMP0150/CMakeLists.txt
new file mode 100644
index 0000000000..371dccc7b2
--- /dev/null
+++ b/Tests/RunCMake/CMP0150/CMakeLists.txt
@@ -0,0 +1,27 @@
+cmake_minimum_required(VERSION 3.25)
+project(${RunCMake_TEST} NONE)
+
+find_package(Git REQUIRED)
+
+function(execGitCommand workDir)
+ execute_process(
+ WORKING_DIRECTORY "${workDir}"
+ COMMAND "${GIT_EXECUTABLE}" ${ARGN}
+ COMMAND_ECHO STDOUT
+ COMMAND_ERROR_IS_FATAL ANY
+ )
+endfunction()
+
+function(initGitRepo workDir)
+ # init.defaultBranch only works with git 2.28 or later, so we must use the
+ # historical default branch name "master". Force the old default in case test
+ # sites have overridden the default to something else.
+ execGitCommand("${workDir}" -c init.defaultBranch=master init)
+ execGitCommand("${workDir}" config user.email "testauthor@cmake.org")
+ execGitCommand("${workDir}" config user.name testauthor)
+ execGitCommand("${workDir}" config core.autocrlf false)
+ execGitCommand("${workDir}" add CMakeLists.txt)
+ execGitCommand("${workDir}" commit -m "Initial commit")
+endfunction()
+
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0150/CMakeLists.txt.in b/Tests/RunCMake/CMP0150/CMakeLists.txt.in
new file mode 100644
index 0000000000..db6cfc76e0
--- /dev/null
+++ b/Tests/RunCMake/CMP0150/CMakeLists.txt.in
@@ -0,0 +1,23 @@
+cmake_minimum_required(VERSION 3.25)
+project(@projName@ LANGUAGES NONE)
+
+@policyCommand@
+
+include(ExternalProject)
+ExternalProject_Add(ep-@depName@
+ GIT_REPOSITORY @epRelativeGitRepo@
+ GIT_TAG master
+ GIT_CONFIG init.defaultBranch=master
+ TEST_COMMAND ""
+ INSTALL_COMMAND "${CMAKE_COMMAND}" -E echo "ExternalProject for ep-@depName@"
+)
+
+include(FetchContent)
+FetchContent_Declare(@depName@
+ GIT_REPOSITORY @fcRelativeGitRepo@
+ GIT_TAG master
+ GIT_CONFIG init.defaultBranch=master
+)
+FetchContent_MakeAvailable(@depName@)
+
+message(STATUS "Completed configuring project @projName@")
diff --git a/Tests/RunCMake/CMP0150/RunCMakeTest.cmake b/Tests/RunCMake/CMP0150/RunCMakeTest.cmake
new file mode 100644
index 0000000000..940c33e65b
--- /dev/null
+++ b/Tests/RunCMake/CMP0150/RunCMakeTest.cmake
@@ -0,0 +1,17 @@
+include(RunCMake)
+
+function(test_CMP0150 val)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${val}-build)
+ run_cmake(CMP0150-${val})
+ set(RunCMake_TEST_NO_CLEAN TRUE)
+ # Some git versions write clone messages to stderr. These would cause the
+ # test to fail, so we need to merge them into stdout.
+ set(RunCMake_TEST_OUTPUT_MERGE TRUE)
+ run_cmake_command(CMP0150-${val}-build ${CMAKE_COMMAND} --build .)
+endfunction()
+
+test_CMP0150(WARN)
+test_CMP0150(OLD)
+test_CMP0150(NEW)
+
+run_cmake_script(CMP0150-NEW-resolve)
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index f05f784d7d..ada913299b 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -160,6 +160,7 @@ endif()
add_RunCMake_test(CMP0132)
add_RunCMake_test(CMP0135)
add_RunCMake_test(CMP0139)
+add_RunCMake_test(CMP0150)
# The test for Policy 65 requires the use of the
# CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS variable, which both the VS and Xcode
@@ -294,6 +295,7 @@ endif()
add_RunCMake_test(BuildDepends
-DMSVC_VERSION=${MSVC_VERSION}
-DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}
+ -DCMAKE_C_LINK_DEPENDS_USE_COMPILER=${CMAKE_C_LINK_DEPENDS_USE_COMPILER}
-DCMake_TEST_BuildDepends_GNU_AS=${CMake_TEST_BuildDepends_GNU_AS}
)
if(UNIX AND "${CMAKE_GENERATOR}" MATCHES "Unix Makefiles|Ninja")
@@ -370,6 +372,7 @@ add_RunCMake_test(GenEx-TARGET_PROPERTY)
add_RunCMake_test(GenEx-TARGET_RUNTIME_DLLS)
add_RunCMake_test(GenEx-PATH)
add_RunCMake_test(GenEx-PATH_EQUAL)
+add_RunCMake_test(GenEx-LIST)
add_RunCMake_test(GeneratorExpression)
add_RunCMake_test(GeneratorInstance)
add_RunCMake_test(GeneratorPlatform)
diff --git a/Tests/RunCMake/CMakePresets/EmptyPenvInInclude-result.txt b/Tests/RunCMake/CMakePresets/EmptyPenvInInclude-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/CMakePresets/EmptyPenvInInclude-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMakePresets/EmptyPenvInInclude-stderr.txt b/Tests/RunCMake/CMakePresets/EmptyPenvInInclude-stderr.txt
new file mode 100644
index 0000000000..e0f858a1e1
--- /dev/null
+++ b/Tests/RunCMake/CMakePresets/EmptyPenvInInclude-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error: Could not read presets from [^
+]*/Tests/RunCMake/CMakePresets/EmptyPenvInInclude:
+Error: @3,15: Invalid "include" field
+ "include": \["\$penv\{\}"\],
+ \^$
diff --git a/Tests/RunCMake/CMakePresets/EmptyPenvInInclude.json.in b/Tests/RunCMake/CMakePresets/EmptyPenvInInclude.json.in
new file mode 100644
index 0000000000..651b0de1b9
--- /dev/null
+++ b/Tests/RunCMake/CMakePresets/EmptyPenvInInclude.json.in
@@ -0,0 +1,11 @@
+{
+ "version": 7,
+ "include": ["$penv{}"],
+ "configurePresets": [
+ {
+ "name": "EmptyPenvInInclude",
+ "generator": "@RunCMake_GENERATOR@",
+ "binaryDir": "${sourceDir}/build"
+ }
+ ]
+}
diff --git a/Tests/RunCMake/CMakePresets/IncludeExpansion-stdout.txt b/Tests/RunCMake/CMakePresets/IncludeExpansion-stdout.txt
new file mode 100644
index 0000000000..d3f1afceb2
--- /dev/null
+++ b/Tests/RunCMake/CMakePresets/IncludeExpansion-stdout.txt
@@ -0,0 +1,5 @@
+^Not searching for unused variables given on the command line\.
+Available configure presets:
+
+ "Include"
+ "IncludeCommon"$
diff --git a/Tests/RunCMake/CMakePresets/IncludeExpansion.json.in b/Tests/RunCMake/CMakePresets/IncludeExpansion.json.in
new file mode 100644
index 0000000000..b4f82927b5
--- /dev/null
+++ b/Tests/RunCMake/CMakePresets/IncludeExpansion.json.in
@@ -0,0 +1,10 @@
+{
+ "version": 7,
+ "include": ["$penv{TEST_ENV_INCLUDE_DIR}/IncludeCommon.json"],
+ "configurePresets": [
+ {
+ "name": "Include",
+ "inherits": ["IncludeCommon"]
+ }
+ ]
+}
diff --git a/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake b/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake
index d67e8b14ee..c4a8b3f080 100644
--- a/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake
@@ -146,6 +146,7 @@ run_cmake_presets(NoSuchMacro)
run_cmake_presets(EnvCycle)
run_cmake_presets(EmptyEnv)
run_cmake_presets(EmptyPenv)
+run_cmake_presets(EmptyPenvInInclude)
run_cmake_presets(InvalidRegex)
set(CMakePresets_SCHEMA_EXPECTED_RESULT 1)
run_cmake_presets(ConditionFuture)
@@ -393,6 +394,12 @@ set(CMakePresets_EXTRA_FILES
"${RunCMake_SOURCE_DIR}/subdir/CMakePresets.json.in"
)
run_cmake_presets(Include --list-presets)
+set(CMakePresets_EXTRA_FILES
+ "${RunCMake_SOURCE_DIR}/IncludeCommon.json.in"
+ )
+set(ENV{TEST_ENV_INCLUDE_DIR} ${RunCMake_BINARY_DIR}/IncludeExpansion)
+run_cmake_presets(IncludeExpansion --list-presets)
+unset(ENV{TEST_ENV_INCLUDE_DIR})
unset(CMakePresets_EXTRA_FILES)
run_cmake_presets(IncludeNotFound)
run_cmake_presets(IncludeCycle)
diff --git a/Tests/RunCMake/CTestResourceAllocation/ctresalloc.cxx b/Tests/RunCMake/CTestResourceAllocation/ctresalloc.cxx
index 65f17b6e32..2824fbfe31 100644
--- a/Tests/RunCMake/CTestResourceAllocation/ctresalloc.cxx
+++ b/Tests/RunCMake/CTestResourceAllocation/ctresalloc.cxx
@@ -19,6 +19,7 @@
#include "cmCTestTestHandler.h"
#include "cmFileLock.h"
#include "cmFileLockResult.h"
+#include "cmList.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -282,7 +283,7 @@ static int doVerify(int argc, char const* const* argv)
if (argc == 5) {
testNames = argv[4];
}
- auto testNameList = cmExpandedList(testNames, false);
+ cmList testNameList{ testNames };
std::set<std::string> testNameSet(testNameList.begin(), testNameList.end());
cmCTestResourceSpec spec;
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-check.py b/Tests/RunCMake/FileAPI/codemodel-v2-check.py
index fda18b5c08..eb52975265 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-check.py
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-check.py
@@ -848,8 +848,204 @@ def gen_check_targets(c, g, inSource):
for e in expected:
if e["type"] == "UTILITY":
if e["id"] == "^ZERO_CHECK::@6890427a1f51a3e7e1df$":
+ # The json files have data for Xcode. Substitute data for VS.
e["sources"] = [
{
+ "path": "^CMakeLists\\.txt$",
+ "isGenerated": None,
+ "fileSetName": None,
+ "sourceGroupName": "",
+ "compileGroupLanguage": None,
+ "backtrace": [
+ {
+ "file": "^CMakeLists\\.txt$",
+ "line": None,
+ "command": None,
+ "hasParent": False,
+ },
+ ],
+ },
+ {
+ "path": "^alias/CMakeLists\\.txt$",
+ "isGenerated": None,
+ "fileSetName": None,
+ "sourceGroupName": "",
+ "compileGroupLanguage": None,
+ "backtrace": [
+ {
+ "file": "^CMakeLists\\.txt$",
+ "line": None,
+ "command": None,
+ "hasParent": False,
+ },
+ ],
+ },
+ {
+ "path": "^codemodel-v2\\.cmake$",
+ "isGenerated": None,
+ "fileSetName": None,
+ "sourceGroupName": "",
+ "compileGroupLanguage": None,
+ "backtrace": [
+ {
+ "file": "^CMakeLists\\.txt$",
+ "line": None,
+ "command": None,
+ "hasParent": False,
+ },
+ ],
+ },
+ {
+ "path": "^custom/CMakeLists\\.txt$",
+ "isGenerated": None,
+ "fileSetName": None,
+ "sourceGroupName": "",
+ "compileGroupLanguage": None,
+ "backtrace": [
+ {
+ "file": "^CMakeLists\\.txt$",
+ "line": None,
+ "command": None,
+ "hasParent": False,
+ },
+ ],
+ },
+ {
+ "path": "^cxx/CMakeLists\\.txt$",
+ "isGenerated": None,
+ "fileSetName": None,
+ "sourceGroupName": "",
+ "compileGroupLanguage": None,
+ "backtrace": [
+ {
+ "file": "^CMakeLists\\.txt$",
+ "line": None,
+ "command": None,
+ "hasParent": False,
+ },
+ ],
+ },
+ {
+ "path": "^dir/CMakeLists\\.txt$",
+ "isGenerated": None,
+ "fileSetName": None,
+ "sourceGroupName": "",
+ "compileGroupLanguage": None,
+ "backtrace": [
+ {
+ "file": "^CMakeLists\\.txt$",
+ "line": None,
+ "command": None,
+ "hasParent": False,
+ },
+ ],
+ },
+ {
+ "path": "^dir/dir/CMakeLists\\.txt$",
+ "isGenerated": None,
+ "fileSetName": None,
+ "sourceGroupName": "",
+ "compileGroupLanguage": None,
+ "backtrace": [
+ {
+ "file": "^CMakeLists\\.txt$",
+ "line": None,
+ "command": None,
+ "hasParent": False,
+ },
+ ],
+ },
+ {
+ "path": "^fileset/CMakeLists\\.txt$",
+ "isGenerated": None,
+ "fileSetName": None,
+ "sourceGroupName": "",
+ "compileGroupLanguage": None,
+ "backtrace": [
+ {
+ "file": "^CMakeLists\\.txt$",
+ "line": None,
+ "command": None,
+ "hasParent": False,
+ },
+ ],
+ },
+ {
+ "path": "^imported/CMakeLists\\.txt$",
+ "isGenerated": None,
+ "fileSetName": None,
+ "sourceGroupName": "",
+ "compileGroupLanguage": None,
+ "backtrace": [
+ {
+ "file": "^CMakeLists\\.txt$",
+ "line": None,
+ "command": None,
+ "hasParent": False,
+ },
+ ],
+ },
+ {
+ "path": "^include_test\\.cmake$",
+ "isGenerated": None,
+ "fileSetName": None,
+ "sourceGroupName": "",
+ "compileGroupLanguage": None,
+ "backtrace": [
+ {
+ "file": "^CMakeLists\\.txt$",
+ "line": None,
+ "command": None,
+ "hasParent": False,
+ },
+ ],
+ },
+ {
+ "path": "^interface/CMakeLists\\.txt$",
+ "isGenerated": None,
+ "fileSetName": None,
+ "sourceGroupName": "",
+ "compileGroupLanguage": None,
+ "backtrace": [
+ {
+ "file": "^CMakeLists\\.txt$",
+ "line": None,
+ "command": None,
+ "hasParent": False,
+ },
+ ],
+ },
+ {
+ "path": "^object/CMakeLists\\.txt$",
+ "isGenerated": None,
+ "fileSetName": None,
+ "sourceGroupName": "",
+ "compileGroupLanguage": None,
+ "backtrace": [
+ {
+ "file": "^CMakeLists\\.txt$",
+ "line": None,
+ "command": None,
+ "hasParent": False,
+ },
+ ],
+ },
+ {
+ "path": "^subdir/CMakeLists\\.txt$",
+ "isGenerated": None,
+ "fileSetName": None,
+ "sourceGroupName": "",
+ "compileGroupLanguage": None,
+ "backtrace": [
+ {
+ "file": "^CMakeLists\\.txt$",
+ "line": None,
+ "command": None,
+ "hasParent": False,
+ },
+ ],
+ },
+ {
"path": "^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/([0-9a-f]+/)?generate\\.stamp\\.rule$",
"isGenerated": True,
"fileSetName": None,
@@ -867,6 +1063,24 @@ def gen_check_targets(c, g, inSource):
]
e["sourceGroups"] = [
{
+ "name": "",
+ "sourcePaths": [
+ "^CMakeLists\\.txt$",
+ "^alias/CMakeLists\\.txt$",
+ "^codemodel-v2\\.cmake$",
+ "^custom/CMakeLists\\.txt$",
+ "^cxx/CMakeLists\\.txt$",
+ "^dir/CMakeLists\\.txt$",
+ "^dir/dir/CMakeLists\\.txt$",
+ "^fileset/CMakeLists\\.txt$",
+ "^imported/CMakeLists\\.txt$",
+ "^include_test\\.cmake$",
+ "^interface/CMakeLists\\.txt$",
+ "^object/CMakeLists\\.txt$",
+ "^subdir/CMakeLists\\.txt$",
+ ],
+ },
+ {
"name": "CMake Rules",
"sourcePaths": [
"^.*/Tests/RunCMake/FileAPI/codemodel-v2-build/CMakeFiles/([0-9a-f]+/)?generate\\.stamp\\.rule$",
diff --git a/Tests/RunCMake/GenEx-LIST/APPEND.cmake.in b/Tests/RunCMake/GenEx-LIST/APPEND.cmake.in
new file mode 100644
index 0000000000..19e1d127bb
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/APPEND.cmake.in
@@ -0,0 +1,34 @@
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+set(listvar a b c d)
+list(APPEND listvar e)
+set (output "$<LIST:APPEND,a;b;c;d,e>")
+if (NOT output STREQUAL listvar)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+set(listvar a b c d)
+list(APPEND listvar e f)
+set (output "$<LIST:APPEND,a;b;c;d,e,f>")
+if (NOT output STREQUAL listvar)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+set(listvar a b c d)
+list(APPEND listvar e f)
+set (output "$<LIST:APPEND,a;b;c;d,e;f>")
+if (NOT output STREQUAL listvar)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+unset(listvar)
+list(APPEND listvar e f)
+set (output "$<LIST:APPEND,,e,f>")
+if (NOT output STREQUAL listvar)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+
+check_errors("LIST:APPEND..." ${errors})
diff --git a/Tests/RunCMake/GenEx-LIST/CMakeLists.txt b/Tests/RunCMake/GenEx-LIST/CMakeLists.txt
new file mode 100644
index 0000000000..5161b995a9
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.18...3.25)
+
+project(${RunCMake_TEST} NONE)
+
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/GenEx-LIST/FILTER-wrong-operator-result.txt b/Tests/RunCMake/GenEx-LIST/FILTER-wrong-operator-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/FILTER-wrong-operator-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/FILTER-wrong-operator-stderr.txt b/Tests/RunCMake/GenEx-LIST/FILTER-wrong-operator-stderr.txt
new file mode 100644
index 0000000000..3064c00ee5
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/FILTER-wrong-operator-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at FILTER-wrong-operator.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:FILTER,a;b;c,WRONG_OPERATOR,\^a>
+
+ sub-command FILTER does not recognize operator "WRONG_OPERATOR". It must
+ be either INCLUDE or EXCLUDE.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/FILTER-wrong-operator.cmake b/Tests/RunCMake/GenEx-LIST/FILTER-wrong-operator.cmake
new file mode 100644
index 0000000000..e01b4fe7ae
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/FILTER-wrong-operator.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:FILTER,a;b;c,WRONG_OPERATOR,^a>")
diff --git a/Tests/RunCMake/GenEx-LIST/FILTER-wrong-regex-result.txt b/Tests/RunCMake/GenEx-LIST/FILTER-wrong-regex-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/FILTER-wrong-regex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/FILTER-wrong-regex-stderr.txt b/Tests/RunCMake/GenEx-LIST/FILTER-wrong-regex-stderr.txt
new file mode 100644
index 0000000000..b2f9b8a97b
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/FILTER-wrong-regex-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at FILTER-wrong-regex.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:FILTER,a;b;c,INCLUDE,\^\(a>
+
+ sub-command FILTER, failed to compile regex "\^\(a".
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/FILTER-wrong-regex.cmake b/Tests/RunCMake/GenEx-LIST/FILTER-wrong-regex.cmake
new file mode 100644
index 0000000000..1311f319cd
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/FILTER-wrong-regex.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:FILTER,a;b;c,INCLUDE,^(a>")
diff --git a/Tests/RunCMake/GenEx-LIST/FIND.cmake.in b/Tests/RunCMake/GenEx-LIST/FIND.cmake.in
new file mode 100644
index 0000000000..e2242c3a4c
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/FIND.cmake.in
@@ -0,0 +1,20 @@
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+set(listvar a b c d)
+
+list(FIND listvar "c" reference)
+set (output "$<LIST:FIND,a;b;c;d,c>")
+if (NOT output EQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(FIND listvar "e" reference)
+set (output "$<LIST:FIND,a;b;c;d,e>")
+if (NOT output EQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+
+check_errors("LIST:FIND..." ${errors})
diff --git a/Tests/RunCMake/GenEx-LIST/GET-wrong-index1-result.txt b/Tests/RunCMake/GenEx-LIST/GET-wrong-index1-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/GET-wrong-index1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/GET-wrong-index1-stderr.txt b/Tests/RunCMake/GenEx-LIST/GET-wrong-index1-stderr.txt
new file mode 100644
index 0000000000..dcd1f2f3bf
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/GET-wrong-index1-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at GET-wrong-index1.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:GET,,0>
+
+ given empty list
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/GET-wrong-index1.cmake b/Tests/RunCMake/GenEx-LIST/GET-wrong-index1.cmake
new file mode 100644
index 0000000000..4c395b318c
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/GET-wrong-index1.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:GET,,0>")
diff --git a/Tests/RunCMake/GenEx-LIST/GET-wrong-index2-result.txt b/Tests/RunCMake/GenEx-LIST/GET-wrong-index2-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/GET-wrong-index2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/GET-wrong-index2-stderr.txt b/Tests/RunCMake/GenEx-LIST/GET-wrong-index2-stderr.txt
new file mode 100644
index 0000000000..20f1af4fd6
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/GET-wrong-index2-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at GET-wrong-index2.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:GET,a;b,2>
+
+ index: 2 out of range \(-2, 1\)
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/GET-wrong-index2.cmake b/Tests/RunCMake/GenEx-LIST/GET-wrong-index2.cmake
new file mode 100644
index 0000000000..28c97e2fd8
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/GET-wrong-index2.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:GET,a;b,2>")
diff --git a/Tests/RunCMake/GenEx-LIST/GET-wrong-index3-result.txt b/Tests/RunCMake/GenEx-LIST/GET-wrong-index3-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/GET-wrong-index3-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/GET-wrong-index3-stderr.txt b/Tests/RunCMake/GenEx-LIST/GET-wrong-index3-stderr.txt
new file mode 100644
index 0000000000..a5dccbe953
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/GET-wrong-index3-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at GET-wrong-index3.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:GET,a;b,1,-3>
+
+ index: -3 out of range \(-2, 1\)
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/GET-wrong-index3.cmake b/Tests/RunCMake/GenEx-LIST/GET-wrong-index3.cmake
new file mode 100644
index 0000000000..fd7be176d3
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/GET-wrong-index3.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:GET,a;b,1,-3>")
diff --git a/Tests/RunCMake/GenEx-LIST/GET.cmake.in b/Tests/RunCMake/GenEx-LIST/GET.cmake.in
new file mode 100644
index 0000000000..102eb42e3d
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/GET.cmake.in
@@ -0,0 +1,20 @@
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+set(listvar a b c d)
+
+list(GET listvar 0 2 reference)
+set (output "$<LIST:GET,a;b;c;d,0,2>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(GET listvar 0 -3 2 reference)
+set (output "$<LIST:GET,a;b;c;d,0,-3,2>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+
+check_errors("LIST:GET..." ${errors})
diff --git a/Tests/RunCMake/GenEx-LIST/INSERT-wrong-index1-result.txt b/Tests/RunCMake/GenEx-LIST/INSERT-wrong-index1-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/INSERT-wrong-index1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/INSERT-wrong-index1-stderr.txt b/Tests/RunCMake/GenEx-LIST/INSERT-wrong-index1-stderr.txt
new file mode 100644
index 0000000000..ce36fb1197
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/INSERT-wrong-index1-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at INSERT-wrong-index1.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:INSERT,a;b;c,4,d>
+
+ index: 4 out of range \(-3, 3\)
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/INSERT-wrong-index1.cmake b/Tests/RunCMake/GenEx-LIST/INSERT-wrong-index1.cmake
new file mode 100644
index 0000000000..ead5832418
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/INSERT-wrong-index1.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:INSERT,a;b;c,4,d>")
diff --git a/Tests/RunCMake/GenEx-LIST/INSERT-wrong-index2-result.txt b/Tests/RunCMake/GenEx-LIST/INSERT-wrong-index2-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/INSERT-wrong-index2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/INSERT-wrong-index2-stderr.txt b/Tests/RunCMake/GenEx-LIST/INSERT-wrong-index2-stderr.txt
new file mode 100644
index 0000000000..f0ea1d70c3
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/INSERT-wrong-index2-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at INSERT-wrong-index2.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:INSERT,a;b;c,-4,d>
+
+ index: -4 out of range \(-3, 3\)
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/INSERT-wrong-index2.cmake b/Tests/RunCMake/GenEx-LIST/INSERT-wrong-index2.cmake
new file mode 100644
index 0000000000..c057b876a9
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/INSERT-wrong-index2.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:INSERT,a;b;c,-4,d>")
diff --git a/Tests/RunCMake/GenEx-LIST/INSERT.cmake.in b/Tests/RunCMake/GenEx-LIST/INSERT.cmake.in
new file mode 100644
index 0000000000..d3bb9b9b18
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/INSERT.cmake.in
@@ -0,0 +1,50 @@
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+set(listvar a b c d)
+
+list(INSERT listvar 1 e)
+set (output "$<LIST:INSERT,a;b;c;d,1,e>")
+if (NOT output STREQUAL listvar)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+set(listvar a b c d)
+
+list(INSERT listvar 2 e f)
+set (output "$<LIST:INSERT,a;b;c;d,2,e,f>")
+if (NOT output STREQUAL listvar)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+set(listvar a b c d)
+list(INSERT listvar 0 e f)
+set (output "$<LIST:INSERT,a;b;c;d,0,e;f>")
+if (NOT output STREQUAL listvar)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+set(listvar a b c d)
+list(INSERT listvar -2 e f)
+set (output "$<LIST:INSERT,a;b;c;d,-2,e;f>")
+if (NOT output STREQUAL listvar)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+set(listvar a b c d)
+list(INSERT listvar 3 e f)
+set (output "$<LIST:INSERT,a;b;c;d,3,e;f>")
+if (NOT output STREQUAL listvar)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+unset(listvar)
+list(INSERT listvar 0 e f)
+set (output "$<LIST:INSERT,,0,e,f>")
+if (NOT output STREQUAL listvar)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+
+check_errors("LIST:INSERT..." ${errors})
diff --git a/Tests/RunCMake/GenEx-LIST/JOIN.cmake.in b/Tests/RunCMake/GenEx-LIST/JOIN.cmake.in
new file mode 100644
index 0000000000..0a564507be
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/JOIN.cmake.in
@@ -0,0 +1,35 @@
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+set(listvar a b c d)
+
+list(JOIN listvar ":" reference)
+set (output "$<LIST:JOIN,a;b;c;d,:>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(JOIN listvar "" reference)
+set (output "$<LIST:JOIN,a;b;c;d,>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+set(listvar a)
+
+list(JOIN listvar ":" reference)
+set (output "$<LIST:JOIN,a,:>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+unset(listvar)
+
+list(JOIN listvar ":" reference)
+set (output "$<LIST:JOIN,,:>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+check_errors("LIST:JOIN..." ${errors})
diff --git a/Tests/RunCMake/GenEx-LIST/LENGTH.cmake.in b/Tests/RunCMake/GenEx-LIST/LENGTH.cmake.in
new file mode 100644
index 0000000000..0840e11116
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/LENGTH.cmake.in
@@ -0,0 +1,30 @@
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+set(listvar a b c d)
+
+list(LENGTH listvar reference)
+set (output "$<LIST:LENGTH,a;b;c;d>")
+if (NOT output EQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+set(listvar "")
+
+list(LENGTH listvar reference)
+set (output "$<LIST:LENGTH,>")
+if (NOT output EQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+unset(listvar)
+
+list(LENGTH listvar reference)
+set (output "$<LIST:LENGTH,>")
+if (NOT output EQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+
+check_errors("LIST:LENGTH..." ${errors})
diff --git a/Tests/RunCMake/GenEx-LIST/POP_BACK.cmake.in b/Tests/RunCMake/GenEx-LIST/POP_BACK.cmake.in
new file mode 100644
index 0000000000..ba95c839c0
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/POP_BACK.cmake.in
@@ -0,0 +1,18 @@
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+set(listvar a b c d)
+list(POP_BACK listvar)
+set (output "$<LIST:POP_BACK,a;b;c;d>")
+if (NOT output STREQUAL listvar)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+set (output "$<LIST:POP_BACK,>")
+if (NOT output STREQUAL "")
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+
+check_errors("LIST:POP_BACK..." ${errors})
diff --git a/Tests/RunCMake/GenEx-LIST/POP_FRONT.cmake.in b/Tests/RunCMake/GenEx-LIST/POP_FRONT.cmake.in
new file mode 100644
index 0000000000..0d676af60e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/POP_FRONT.cmake.in
@@ -0,0 +1,18 @@
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+set(listvar a b c d)
+list(POP_FRONT listvar)
+set (output "$<LIST:POP_FRONT,a;b;c;d>")
+if (NOT output STREQUAL listvar)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+set (output "$<LIST:POP_FRONT,>")
+if (NOT output STREQUAL "")
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+
+check_errors("LIST:POP_FRONT..." ${errors})
diff --git a/Tests/RunCMake/GenEx-LIST/PREPEND.cmake.in b/Tests/RunCMake/GenEx-LIST/PREPEND.cmake.in
new file mode 100644
index 0000000000..49b8f98239
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/PREPEND.cmake.in
@@ -0,0 +1,34 @@
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+set(listvar a b c d)
+list(PREPEND listvar e)
+set (output "$<LIST:PREPEND,a;b;c;d,e>")
+if (NOT output STREQUAL listvar)
+ list (PREPEND errors "returns bad value: ${output}")
+endif()
+
+set(listvar a b c d)
+list(PREPEND listvar e f)
+set (output "$<LIST:PREPEND,a;b;c;d,e,f>")
+if (NOT output STREQUAL listvar)
+ list (PREPEND errors "returns bad value: ${output}")
+endif()
+
+set(listvar a b c d)
+list(PREPEND listvar e f)
+set (output "$<LIST:PREPEND,a;b;c;d,e;f>")
+if (NOT output STREQUAL listvar)
+ list (PREPEND errors "returns bad value: ${output}")
+endif()
+
+unset(listvar)
+list(PREPEND listvar e f)
+set (output "$<LIST:PREPEND,,e,f>")
+if (NOT output STREQUAL listvar)
+ list (PREPEND errors "returns bad value: ${output}")
+endif()
+
+
+check_errors("LIST:PREPEND..." ${errors})
diff --git a/Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index1-result.txt b/Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index1-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index1-stderr.txt b/Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index1-stderr.txt
new file mode 100644
index 0000000000..b874f1d09b
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index1-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at REMOVE_AT-wrong-index1.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:REMOVE_AT,,0>
+
+ index: 0 out of range \(0, 0\)
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index1.cmake b/Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index1.cmake
new file mode 100644
index 0000000000..d87559e83b
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index1.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:REMOVE_AT,,0>")
diff --git a/Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index2-result.txt b/Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index2-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index2-stderr.txt b/Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index2-stderr.txt
new file mode 100644
index 0000000000..509eed4b16
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index2-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at REMOVE_AT-wrong-index2.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:REMOVE_AT,a;b;c,3>
+
+ index: 3 out of range \(-3, 2\)
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index2.cmake b/Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index2.cmake
new file mode 100644
index 0000000000..7ecfad2281
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index2.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:REMOVE_AT,a;b;c,3>")
diff --git a/Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index3-result.txt b/Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index3-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index3-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index3-stderr.txt b/Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index3-stderr.txt
new file mode 100644
index 0000000000..c8fc465062
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index3-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at REMOVE_AT-wrong-index3.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:REMOVE_AT,a;b;c,-4>
+
+ index: -4 out of range \(-3, 2\)
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index3.cmake b/Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index3.cmake
new file mode 100644
index 0000000000..f8f9a3e24b
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/REMOVE_AT-wrong-index3.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:REMOVE_AT,a;b;c,-4>")
diff --git a/Tests/RunCMake/GenEx-LIST/REMOVE_AT.cmake.in b/Tests/RunCMake/GenEx-LIST/REMOVE_AT.cmake.in
new file mode 100644
index 0000000000..42a94766f9
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/REMOVE_AT.cmake.in
@@ -0,0 +1,25 @@
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+set(listvar a b c d)
+list(REMOVE_AT listvar 1 3)
+set (output "$<LIST:REMOVE_AT,a;b;c;d,1,3>")
+if (NOT output STREQUAL listvar)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+set(listvar a b c d)
+list(REMOVE_AT listvar 1 -2)
+set (output "$<LIST:REMOVE_AT,a;b;c;d,1;-2>")
+if (NOT output STREQUAL listvar)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+set (output "$<LIST:REMOVE_AT,a;b;c;d,1,0,3;2>")
+if (NOT output STREQUAL "")
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+
+check_errors("LIST:REMOVE_AT..." ${errors})
diff --git a/Tests/RunCMake/GenEx-LIST/REMOVE_DUPLICATES.cmake.in b/Tests/RunCMake/GenEx-LIST/REMOVE_DUPLICATES.cmake.in
new file mode 100644
index 0000000000..8785ae522a
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/REMOVE_DUPLICATES.cmake.in
@@ -0,0 +1,20 @@
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+set(listvar a b c d)
+list(REMOVE_DUPLICATES listvar)
+set (output "$<LIST:REMOVE_DUPLICATES,a;b;c;d>")
+if (NOT output STREQUAL listvar)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+set(listvar "b;c;b;a;a;c;b;a;c;b")
+list(REMOVE_DUPLICATES listvar)
+set (output "$<LIST:REMOVE_DUPLICATES,b;c;b;a;a;c;b;a;c;b>")
+if (NOT output STREQUAL listvar)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+
+check_errors("LIST:REMOVE_DUPLICATES..." ${errors})
diff --git a/Tests/RunCMake/GenEx-LIST/REMOVE_ITEM.cmake.in b/Tests/RunCMake/GenEx-LIST/REMOVE_ITEM.cmake.in
new file mode 100644
index 0000000000..5434a5d51d
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/REMOVE_ITEM.cmake.in
@@ -0,0 +1,32 @@
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+set(listvar a b c d)
+list(REMOVE_ITEM listvar b d)
+set (output "$<LIST:REMOVE_ITEM,a;b;c;d,b,d>")
+if (NOT output STREQUAL listvar)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+set(listvar a b c d)
+list(REMOVE_ITEM listvar b e)
+set (output "$<LIST:REMOVE_ITEM,a;b;c;d,b,e>")
+if (NOT output STREQUAL listvar)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+set(listvar a b c d)
+list(REMOVE_ITEM listvar b a d c)
+set (output "$<LIST:REMOVE_ITEM,a;b;c;d,b;a;d;c>")
+if (NOT output STREQUAL listvar)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+set (output "$<LIST:REMOVE_ITEM,,b;a;d;c>")
+if (NOT output STREQUAL "")
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+
+check_errors("LIST:REMOVE_ITEM..." ${errors})
diff --git a/Tests/RunCMake/GenEx-LIST/REVERSE.cmake.in b/Tests/RunCMake/GenEx-LIST/REVERSE.cmake.in
new file mode 100644
index 0000000000..295e1a3c8a
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/REVERSE.cmake.in
@@ -0,0 +1,19 @@
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+set(listvar a b c d)
+
+list(REVERSE listvar)
+set (output "$<LIST:REVERSE,a;b;c;d>")
+if (NOT output STREQUAL listvar)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+set (output "$<LIST:REVERSE,>")
+if (NOT output STREQUAL "")
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+
+check_errors("LIST:REVERSE..." ${errors})
diff --git a/Tests/RunCMake/GenEx-LIST/RunCMakeTest.cmake b/Tests/RunCMake/GenEx-LIST/RunCMakeTest.cmake
new file mode 100644
index 0000000000..1946e84915
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/RunCMakeTest.cmake
@@ -0,0 +1,130 @@
+
+include(RunCMake)
+
+run_cmake(no-arguments)
+run_cmake(bad-option)
+
+function(check_list_syntax name test)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${name}-${test}-build)
+ set(RunCMake_TEST_VARIANT_DESCRIPTION " - ${name}")
+ run_cmake_with_options(${test} ${ARGN})
+endfunction()
+
+## Unexpected arguments
+### sub-commands with one argument
+foreach (subcommand IN ITEMS LENGTH POP_BACK POP_FRONT REMOVE_DUPLICATES REVERSE)
+ check_list_syntax (${subcommand} unexpected-arg "-DLIST_ARGUMENTS=${subcommand},ARG1,ARG2")
+endforeach()
+
+### sub-commands with two arguments
+foreach (subcommand IN ITEMS FIND JOIN)
+ check_list_syntax (${subcommand} unexpected-arg "-DLIST_ARGUMENTS=${subcommand},ARG1,ARG2,ARG3")
+endforeach()
+
+### sub-commands with three arguments
+foreach (subcommand IN ITEMS SUBLIST FILTER)
+ check_list_syntax (${subcommand} unexpected-arg "-DLIST_ARGUMENTS=${subcommand},ARG1,ARG2,ARG3,ARG4")
+endforeach()
+
+# TRANSFORM sub-commands
+ set(RunCMake-stderr-file "TRANSFORM-unexpected-arg-stderr.txt")
+foreach (action IN ITEMS TOLOWER TOUPPER STRIP)
+ check_list_syntax (TRANSFORM-${action} unexpected-arg "-DLIST_ARGUMENTS=TRANSFORM,ARG1,${action},ARG2")
+endforeach()
+foreach (action IN ITEMS APPEND PREPEND)
+ check_list_syntax (TRANSFORM-${action} unexpected-arg "-DLIST_ARGUMENTS=TRANSFORM,ARG1,${action},ARG2,ARG3")
+endforeach()
+foreach (action IN ITEMS REPLACE)
+ check_list_syntax (TRANSFORM-${action} unexpected-arg "-DLIST_ARGUMENTS=TRANSFORM,ARG1,${action},ARG2,ARG3,ARG4")
+endforeach()
+check_list_syntax (TRANSFORM-SELECTOR-REGEX unexpected-arg "-DLIST_ARGUMENTS=TRANSFORM,ARG1,STRIP,REGEX,ARG2,ARG3")
+check_list_syntax (TRANSFORM-SELECTOR-FOR unexpected-arg "-DLIST_ARGUMENTS=TRANSFORM,ARG1,STRIP,FOR,1,2,3,4")
+unset(RunCMake-stderr-file)
+
+## Missing arguments
+### sub-command with, at least, two arguments
+foreach (subcommand IN ITEMS GET APPEND PREPEND REMOVE_ITEM REMOVE_AT TRANSFORM)
+ check_list_syntax (${subcommand} missing-arg "-DLIST_ARGUMENTS=${subcommand},ARG1")
+endforeach()
+
+### sub-command with, at least, three arguments
+foreach (subcommand IN ITEMS INSERT)
+ check_list_syntax (${subcommand} missing-arg "-DLIST_ARGUMENTS=${subcommand},ARG1,ARG2")
+endforeach()
+
+# TRANSFORM sub-commands
+set(RunCMake-stderr-file "TRANSFORM-missing-arg-stderr.txt")
+foreach (action IN ITEMS APPEND PREPEND)
+ check_list_syntax (TRANSFORM-${action} missing-arg "-DLIST_ARGUMENTS=TRANSFORM,ARG1,${action}")
+endforeach()
+check_list_syntax (TRANSFORM-REPLACE-1 missing-arg "-DLIST_ARGUMENTS=TRANSFORM,ARG1,REPLACE,ARG2")
+check_list_syntax (TRANSFORM-REPLACE-2 missing-arg "-DLIST_ARGUMENTS=TRANSFORM,ARG1,REPLACE")
+unset(RunCMake-stderr-file)
+
+
+run_cmake(GET-wrong-index1)
+run_cmake(GET-wrong-index2)
+run_cmake(GET-wrong-index3)
+run_cmake(SUBLIST-wrong-argument1)
+run_cmake(SUBLIST-wrong-argument2)
+run_cmake(INSERT-wrong-index1)
+run_cmake(INSERT-wrong-index2)
+run_cmake(REMOVE_AT-wrong-index1)
+run_cmake(REMOVE_AT-wrong-index2)
+run_cmake(REMOVE_AT-wrong-index3)
+run_cmake(FILTER-wrong-operator)
+run_cmake(FILTER-wrong-regex)
+run_cmake(TRANSFORM-wrong-action)
+run_cmake(TRANSFORM-REPLACE-wrong-regex)
+run_cmake(TRANSFORM-REPLACE-invalid-replace1)
+run_cmake(TRANSFORM-REPLACE-invalid-replace2)
+run_cmake(TRANSFORM-selector-REGEX-no-arguments)
+run_cmake(TRANSFORM-selector-REGEX-wrong-regex)
+run_cmake(TRANSFORM-selector-AT-no-arguments)
+run_cmake(TRANSFORM-selector-AT-wrong-argument)
+run_cmake(TRANSFORM-selector-AT-wrong-index)
+run_cmake(TRANSFORM-selector-FOR-no-arguments)
+run_cmake(TRANSFORM-selector-FOR-missing-arguments)
+run_cmake(TRANSFORM-selector-FOR-wrong-argument)
+run_cmake(TRANSFORM-selector-FOR-wrong-index)
+run_cmake(TRANSFORM-selector-FOR-zero-step)
+run_cmake(TRANSFORM-selector-FOR-negative-step)
+run_cmake(TRANSFORM-selector-FOR-backwards-range)
+run_cmake(SORT-wrong-option)
+run_cmake(SORT-wrong-COMPARE-option)
+run_cmake(SORT-wrong-CASE-option)
+run_cmake(SORT-wrong-ORDER-option)
+run_cmake(SORT-duplicate-COMPARE-option)
+run_cmake(SORT-duplicate-CASE-option)
+run_cmake(SORT-duplicate-ORDER-option)
+
+
+function(check_list_execution name)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${name}-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ set(RunCMake_TEST_VARIANT_DESCRIPTION " - ${name}")
+ run_cmake_with_options(generate -DLIST_TEST=${name})
+ run_cmake_command(check "${CMAKE_COMMAND}" "-DRunCMake_SOURCE_DIR=${RunCMake_SOURCE_DIR}" -P "${RunCMake_TEST_BINARY_DIR}/${name}.cmake")
+endfunction()
+
+check_list_execution (LENGTH)
+check_list_execution (GET)
+check_list_execution (JOIN)
+check_list_execution (SUBLIST)
+check_list_execution (FIND)
+check_list_execution (APPEND)
+check_list_execution (PREPEND)
+check_list_execution (INSERT)
+check_list_execution (POP_BACK)
+check_list_execution (POP_FRONT)
+check_list_execution (REMOVE_ITEM)
+check_list_execution (REMOVE_AT)
+check_list_execution (REMOVE_DUPLICATES)
+check_list_execution (TRANSFORM-TOUPPER)
+check_list_execution (TRANSFORM-TOLOWER)
+check_list_execution (TRANSFORM-STRIP)
+check_list_execution (TRANSFORM-APPEND)
+check_list_execution (TRANSFORM-PREPEND)
+check_list_execution (TRANSFORM-REPLACE)
+check_list_execution (REVERSE)
+check_list_execution (SORT)
diff --git a/Tests/RunCMake/GenEx-LIST/SORT-duplicate-CASE-option-result.txt b/Tests/RunCMake/GenEx-LIST/SORT-duplicate-CASE-option-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/SORT-duplicate-CASE-option-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/SORT-duplicate-CASE-option-stderr.txt b/Tests/RunCMake/GenEx-LIST/SORT-duplicate-CASE-option-stderr.txt
new file mode 100644
index 0000000000..4f3121a361
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/SORT-duplicate-CASE-option-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at SORT-duplicate-CASE-option.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:SORT,a;b,COMPARE:STRING,CASE:SENSITIVE,CASE:SENSITIVE>
+
+ sub-command SORT, CASE option has been specified multiple times.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/SORT-duplicate-CASE-option.cmake b/Tests/RunCMake/GenEx-LIST/SORT-duplicate-CASE-option.cmake
new file mode 100644
index 0000000000..e09dc6ca07
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/SORT-duplicate-CASE-option.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:SORT,a;b,COMPARE:STRING,CASE:SENSITIVE,CASE:SENSITIVE>")
diff --git a/Tests/RunCMake/GenEx-LIST/SORT-duplicate-COMPARE-option-result.txt b/Tests/RunCMake/GenEx-LIST/SORT-duplicate-COMPARE-option-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/SORT-duplicate-COMPARE-option-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/SORT-duplicate-COMPARE-option-stderr.txt b/Tests/RunCMake/GenEx-LIST/SORT-duplicate-COMPARE-option-stderr.txt
new file mode 100644
index 0000000000..fbb96bbb29
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/SORT-duplicate-COMPARE-option-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at SORT-duplicate-COMPARE-option.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:SORT,a;b,COMPARE:STRING,COMPARE:NATURAL>
+
+ sub-command SORT, COMPARE option has been specified multiple times.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/SORT-duplicate-COMPARE-option.cmake b/Tests/RunCMake/GenEx-LIST/SORT-duplicate-COMPARE-option.cmake
new file mode 100644
index 0000000000..cf8da0d32e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/SORT-duplicate-COMPARE-option.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:SORT,a;b,COMPARE:STRING,COMPARE:NATURAL>")
diff --git a/Tests/RunCMake/GenEx-LIST/SORT-duplicate-ORDER-option-result.txt b/Tests/RunCMake/GenEx-LIST/SORT-duplicate-ORDER-option-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/SORT-duplicate-ORDER-option-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/SORT-duplicate-ORDER-option-stderr.txt b/Tests/RunCMake/GenEx-LIST/SORT-duplicate-ORDER-option-stderr.txt
new file mode 100644
index 0000000000..b45034a7db
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/SORT-duplicate-ORDER-option-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at SORT-duplicate-ORDER-option.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:SORT,a;b,ORDER:ASCENDING,COMPARE:STRING,ORDER:DESCENDING,CASE:SENSITIVE>
+
+ sub-command SORT, ORDER option has been specified multiple times.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/SORT-duplicate-ORDER-option.cmake b/Tests/RunCMake/GenEx-LIST/SORT-duplicate-ORDER-option.cmake
new file mode 100644
index 0000000000..3826072fdc
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/SORT-duplicate-ORDER-option.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:SORT,a;b,ORDER:ASCENDING,COMPARE:STRING,ORDER:DESCENDING,CASE:SENSITIVE>")
diff --git a/Tests/RunCMake/GenEx-LIST/SORT-wrong-CASE-option-result.txt b/Tests/RunCMake/GenEx-LIST/SORT-wrong-CASE-option-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/SORT-wrong-CASE-option-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/SORT-wrong-CASE-option-stderr.txt b/Tests/RunCMake/GenEx-LIST/SORT-wrong-CASE-option-stderr.txt
new file mode 100644
index 0000000000..d36e63b1ec
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/SORT-wrong-CASE-option-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at SORT-wrong-CASE-option.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:SORT,a;b,COMPARE:STRING,CASE:WRONG_OPTION>
+
+ sub-command SORT, an invalid CASE option has been specified:
+ "WRONG_OPTION".
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/SORT-wrong-CASE-option.cmake b/Tests/RunCMake/GenEx-LIST/SORT-wrong-CASE-option.cmake
new file mode 100644
index 0000000000..58df9ea3dc
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/SORT-wrong-CASE-option.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:SORT,a;b,COMPARE:STRING,CASE:WRONG_OPTION>")
diff --git a/Tests/RunCMake/GenEx-LIST/SORT-wrong-COMPARE-option-result.txt b/Tests/RunCMake/GenEx-LIST/SORT-wrong-COMPARE-option-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/SORT-wrong-COMPARE-option-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/SORT-wrong-COMPARE-option-stderr.txt b/Tests/RunCMake/GenEx-LIST/SORT-wrong-COMPARE-option-stderr.txt
new file mode 100644
index 0000000000..70a99c6419
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/SORT-wrong-COMPARE-option-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at SORT-wrong-COMPARE-option.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:SORT,a;b,COMPARE:WRONG_OPTION>
+
+ sub-command SORT, an invalid COMPARE option has been specified:
+ "WRONG_OPTION".
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/SORT-wrong-COMPARE-option.cmake b/Tests/RunCMake/GenEx-LIST/SORT-wrong-COMPARE-option.cmake
new file mode 100644
index 0000000000..73727bb416
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/SORT-wrong-COMPARE-option.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:SORT,a;b,COMPARE:WRONG_OPTION>")
diff --git a/Tests/RunCMake/GenEx-LIST/SORT-wrong-ORDER-option-result.txt b/Tests/RunCMake/GenEx-LIST/SORT-wrong-ORDER-option-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/SORT-wrong-ORDER-option-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/SORT-wrong-ORDER-option-stderr.txt b/Tests/RunCMake/GenEx-LIST/SORT-wrong-ORDER-option-stderr.txt
new file mode 100644
index 0000000000..2e23d8c4b0
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/SORT-wrong-ORDER-option-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at SORT-wrong-ORDER-option.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:SORT,a;b,COMPARE:STRING,CASE:SENSITIVE,ORDER:WRONG_OPTION>
+
+ sub-command SORT, an invalid ORDER option has been specified:
+ "WRONG_OPTION".
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/SORT-wrong-ORDER-option.cmake b/Tests/RunCMake/GenEx-LIST/SORT-wrong-ORDER-option.cmake
new file mode 100644
index 0000000000..135c9350eb
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/SORT-wrong-ORDER-option.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:SORT,a;b,COMPARE:STRING,CASE:SENSITIVE,ORDER:WRONG_OPTION>")
diff --git a/Tests/RunCMake/GenEx-LIST/SORT-wrong-option-result.txt b/Tests/RunCMake/GenEx-LIST/SORT-wrong-option-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/SORT-wrong-option-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/SORT-wrong-option-stderr.txt b/Tests/RunCMake/GenEx-LIST/SORT-wrong-option-stderr.txt
new file mode 100644
index 0000000000..3c2d492508
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/SORT-wrong-option-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at SORT-wrong-option.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:SORT,a;b,WRONG_OPTION>
+
+ sub-command SORT, option "WRONG_OPTION" is invalid.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/SORT-wrong-option.cmake b/Tests/RunCMake/GenEx-LIST/SORT-wrong-option.cmake
new file mode 100644
index 0000000000..fca268b817
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/SORT-wrong-option.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:SORT,a;b,WRONG_OPTION>")
diff --git a/Tests/RunCMake/GenEx-LIST/SORT.cmake.in b/Tests/RunCMake/GenEx-LIST/SORT.cmake.in
new file mode 100644
index 0000000000..aca6691f90
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/SORT.cmake.in
@@ -0,0 +1,92 @@
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+set(source_unsorted c/B.h a/c.h B/a.h)
+
+set(listvar ${source_unsorted})
+list(SORT listvar)
+set (output "$<LIST:SORT,c/B.h;a/c.h;B/a.h>")
+if (NOT output STREQUAL listvar)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+set(listvar ${source_unsorted})
+list(SORT listvar CASE INSENSITIVE ORDER ASCENDING COMPARE STRING)
+set (output "$<LIST:SORT,c/B.h;a/c.h;B/a.h,CASE:INSENSITIVE,ORDER:ASCENDING,COMPARE:STRING>")
+if (NOT output STREQUAL listvar)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+set(listvar ${source_unsorted})
+list(SORT listvar CASE INSENSITIVE ORDER DESCENDING COMPARE STRING)
+set (output "$<LIST:SORT,c/B.h;a/c.h;B/a.h,CASE:INSENSITIVE,ORDER:DESCENDING,COMPARE:STRING>")
+if (NOT output STREQUAL listvar)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+set(listvar ${source_unsorted})
+list(SORT listvar CASE SENSITIVE ORDER ASCENDING COMPARE STRING)
+set (output "$<LIST:SORT,c/B.h;a/c.h;B/a.h,CASE:SENSITIVE,ORDER:ASCENDING,COMPARE:STRING>")
+if (NOT output STREQUAL listvar)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+set(listvar ${source_unsorted})
+list(SORT listvar CASE SENSITIVE ORDER DESCENDING COMPARE STRING)
+set (output "$<LIST:SORT,c/B.h;a/c.h;B/a.h,CASE:SENSITIVE,ORDER:DESCENDING,COMPARE:STRING>")
+if (NOT output STREQUAL listvar)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+set(listvar ${source_unsorted})
+list(SORT listvar CASE INSENSITIVE ORDER ASCENDING COMPARE FILE_BASENAME)
+set (output "$<LIST:SORT,c/B.h;a/c.h;B/a.h,CASE:INSENSITIVE,ORDER:ASCENDING,COMPARE:FILE_BASENAME>")
+if (NOT output STREQUAL listvar)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+set(listvar ${source_unsorted})
+list(SORT listvar CASE INSENSITIVE ORDER DESCENDING COMPARE FILE_BASENAME)
+set (output "$<LIST:SORT,c/B.h;a/c.h;B/a.h,CASE:INSENSITIVE,ORDER:DESCENDING,COMPARE:FILE_BASENAME>")
+if (NOT output STREQUAL listvar)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+set(listvar ${source_unsorted})
+list(SORT listvar CASE SENSITIVE ORDER ASCENDING COMPARE FILE_BASENAME)
+set (output "$<LIST:SORT,c/B.h;a/c.h;B/a.h,CASE:SENSITIVE,ORDER:ASCENDING,COMPARE:FILE_BASENAME>")
+if (NOT output STREQUAL listvar)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+set(listvar ${source_unsorted})
+list(SORT listvar CASE SENSITIVE ORDER DESCENDING COMPARE FILE_BASENAME)
+set (output "$<LIST:SORT,c/B.h;a/c.h;B/a.h,CASE:SENSITIVE,ORDER:DESCENDING,COMPARE:FILE_BASENAME>")
+if (NOT output STREQUAL listvar)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+set(listvar 10.0 1.1 2.1 8.0 2.0 3.1)
+list(SORT listvar CASE SENSITIVE ORDER DESCENDING COMPARE STRING)
+set (output "$<LIST:SORT,10.0;1.1;2.1;8.0;2.0;3.1,CASE:SENSITIVE,ORDER:DESCENDING,COMPARE:STRING>")
+if (NOT output STREQUAL listvar)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+set(listvar 10.0 1.1 2.1 8.0 2.0 3.1)
+list(SORT listvar CASE SENSITIVE ORDER DESCENDING COMPARE NATURAL)
+set (output "$<LIST:SORT,10.0;1.1;2.1;8.0;2.0;3.1,CASE:SENSITIVE,ORDER:DESCENDING,COMPARE:NATURAL>")
+if (NOT output STREQUAL listvar)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+set(listvar 10.0 1.1 2.1 8.0 2.0 3.1)
+list(SORT listvar CASE SENSITIVE ORDER ASCENDING COMPARE NATURAL)
+set (output "$<LIST:SORT,10.0;1.1;2.1;8.0;2.0;3.1,CASE:SENSITIVE,ORDER:ASCENDING,COMPARE:NATURAL>")
+if (NOT output STREQUAL listvar)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+
+check_errors("LIST:SORT..." ${errors})
diff --git a/Tests/RunCMake/GenEx-LIST/SUBLIST-wrong-argument1-result.txt b/Tests/RunCMake/GenEx-LIST/SUBLIST-wrong-argument1-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/SUBLIST-wrong-argument1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/SUBLIST-wrong-argument1-stderr.txt b/Tests/RunCMake/GenEx-LIST/SUBLIST-wrong-argument1-stderr.txt
new file mode 100644
index 0000000000..078f345e3f
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/SUBLIST-wrong-argument1-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at SUBLIST-wrong-argument1.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:SUBLIST,a;b;c,3,-1>
+
+ begin index: 3 is out of range 0 - 2
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/SUBLIST-wrong-argument1.cmake b/Tests/RunCMake/GenEx-LIST/SUBLIST-wrong-argument1.cmake
new file mode 100644
index 0000000000..293c2ae977
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/SUBLIST-wrong-argument1.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:SUBLIST,a;b;c,3,-1>")
diff --git a/Tests/RunCMake/GenEx-LIST/SUBLIST-wrong-argument2-result.txt b/Tests/RunCMake/GenEx-LIST/SUBLIST-wrong-argument2-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/SUBLIST-wrong-argument2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/SUBLIST-wrong-argument2-stderr.txt b/Tests/RunCMake/GenEx-LIST/SUBLIST-wrong-argument2-stderr.txt
new file mode 100644
index 0000000000..7271b30b3f
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/SUBLIST-wrong-argument2-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at SUBLIST-wrong-argument2.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:SUBLIST,a;b;c,1,-2>
+
+ length: -2 should be -1 or greater
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/SUBLIST-wrong-argument2.cmake b/Tests/RunCMake/GenEx-LIST/SUBLIST-wrong-argument2.cmake
new file mode 100644
index 0000000000..9d1db53245
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/SUBLIST-wrong-argument2.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:SUBLIST,a;b;c,1,-2>")
diff --git a/Tests/RunCMake/GenEx-LIST/SUBLIST.cmake.in b/Tests/RunCMake/GenEx-LIST/SUBLIST.cmake.in
new file mode 100644
index 0000000000..9fcb6d50ab
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/SUBLIST.cmake.in
@@ -0,0 +1,32 @@
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+set(listvar a b c d)
+
+list(SUBLIST listvar 1 2 reference)
+set (output "$<LIST:SUBLIST,a;b;c;d,1,2>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(SUBLIST listvar 1 -1 reference)
+set (output "$<LIST:SUBLIST,a;b;c;d,1,-1>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(SUBLIST listvar 1 0 reference)
+set (output "$<LIST:SUBLIST,a;b;c;d,1,0>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(SUBLIST listvar 1 5 reference)
+set (output "$<LIST:SUBLIST,a;b;c;d,1,5>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+
+check_errors("LIST:SUBLIST..." ${errors})
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-APPEND.cmake.in b/Tests/RunCMake/GenEx-LIST/TRANSFORM-APPEND.cmake.in
new file mode 100644
index 0000000000..a6529ec578
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-APPEND.cmake.in
@@ -0,0 +1,50 @@
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+set(listvar alpha bravo charlie delta)
+
+list(TRANSFORM listvar APPEND "_A" OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,alpha;bravo;charlie;delta,APPEND,_A>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar APPEND "_A" AT 1 3 OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,alpha;bravo;charlie;delta,APPEND,_A,AT,1,3>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar APPEND "_A" AT 1 -2 OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,alpha;bravo;charlie;delta,APPEND,_A,AT,1,-2>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar APPEND "_A" FOR 1 2 OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,alpha;bravo;charlie;delta,APPEND,_A,FOR,1,2>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar APPEND "_A" FOR 1 -1 OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,alpha;bravo;charlie;delta,APPEND,_A,FOR,1,-1>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar APPEND "_A" FOR 1 -1 2 OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,alpha;bravo;charlie;delta,APPEND,_A,FOR,1,-1,2>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar APPEND "_A" REGEX "(r|t)a" OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,alpha;bravo;charlie;delta,APPEND,_A,REGEX,(r|t)a>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+
+check_errors("LIST:TRANSFORM,APPEND..." ${errors})
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-PREPEND.cmake.in b/Tests/RunCMake/GenEx-LIST/TRANSFORM-PREPEND.cmake.in
new file mode 100644
index 0000000000..5ec6acdcc8
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-PREPEND.cmake.in
@@ -0,0 +1,50 @@
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+set(listvar alpha bravo charlie delta)
+
+list(TRANSFORM listvar PREPEND "P_" OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,alpha;bravo;charlie;delta,PREPEND,P_>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar PREPEND "P_" AT 1 3 OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,alpha;bravo;charlie;delta,PREPEND,P_,AT,1,3>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar PREPEND "P_" AT 1 -2 OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,alpha;bravo;charlie;delta,PREPEND,P_,AT,1,-2>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar PREPEND "P_" FOR 1 2 OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,alpha;bravo;charlie;delta,PREPEND,P_,FOR,1,2>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar PREPEND "P_" FOR 1 -1 OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,alpha;bravo;charlie;delta,PREPEND,P_,FOR,1,-1>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar PREPEND "P_" FOR 1 -1 2 OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,alpha;bravo;charlie;delta,PREPEND,P_,FOR,1,-1,2>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar PREPEND "P_" REGEX "(r|t)a" OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,alpha;bravo;charlie;delta,PREPEND,P_,REGEX,(r|t)a>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+
+check_errors("LIST:TRANSFORM,PREPEND..." ${errors})
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-invalid-replace1-result.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-invalid-replace1-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-invalid-replace1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-invalid-replace1-stderr.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-invalid-replace1-stderr.txt
new file mode 100644
index 0000000000..6674b30688
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-invalid-replace1-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at TRANSFORM-REPLACE-invalid-replace1.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:TRANSFORM,a;b,REPLACE,\^a,b\\>
+
+ sub-command TRANSFORM, action REPLACE: replace-expression ends in a
+ backslash.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-invalid-replace1.cmake b/Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-invalid-replace1.cmake
new file mode 100644
index 0000000000..d45e1fdaf4
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-invalid-replace1.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:TRANSFORM,a;b,REPLACE,^a,b\\>")
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-invalid-replace2-result.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-invalid-replace2-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-invalid-replace2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-invalid-replace2-stderr.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-invalid-replace2-stderr.txt
new file mode 100644
index 0000000000..2351b72eb1
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-invalid-replace2-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at TRANSFORM-REPLACE-invalid-replace2.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:TRANSFORM,a;b,REPLACE,\^a,\\b>
+
+ sub-command TRANSFORM, action REPLACE: Unknown escape "\\b" in
+ replace-expression.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-invalid-replace2.cmake b/Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-invalid-replace2.cmake
new file mode 100644
index 0000000000..b800f24f2e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-invalid-replace2.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:TRANSFORM,a;b,REPLACE,^a,\\b>")
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-wrong-regex-result.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-wrong-regex-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-wrong-regex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-wrong-regex-stderr.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-wrong-regex-stderr.txt
new file mode 100644
index 0000000000..617c3d6d04
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-wrong-regex-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at TRANSFORM-REPLACE-wrong-regex.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:TRANSFORM,a;b,REPLACE,\(a,b>
+
+ sub-command TRANSFORM, action REPLACE: Failed to compile regex "\(a".
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-wrong-regex.cmake b/Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-wrong-regex.cmake
new file mode 100644
index 0000000000..941e3e7ff8
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE-wrong-regex.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:TRANSFORM,a;b,REPLACE,(a,b>")
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE.cmake.in b/Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE.cmake.in
new file mode 100644
index 0000000000..5fba23109c
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-REPLACE.cmake.in
@@ -0,0 +1,50 @@
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+set(listvar alpha bravo charlie delta)
+
+list(TRANSFORM listvar REPLACE "(.+a)$" "\\1_\\1" OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,alpha;bravo;charlie;delta,REPLACE,(.+a)$,\1_\1>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar REPLACE "(.+a)$" "\\1_\\1" AT 1 3 OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,alpha;bravo;charlie;delta,REPLACE,(.+a)$,\1_\1,AT,1,3>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar REPLACE "(.+a)$" "\\1_\\1" AT 1 -2 OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,alpha;bravo;charlie;delta,REPLACE,(.+a)$,\1_\1,AT,1,-2>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar REPLACE "(.+a)$" "\\1_\\1" FOR 1 2 OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,alpha;bravo;charlie;delta,REPLACE,(.+a)$,\1_\1,FOR,1,2>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar REPLACE "(.+a)$" "\\1_\\1" FOR 1 -1 OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,alpha;bravo;charlie;delta,REPLACE,(.+a)$,\1_\1,FOR,1,-1>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar REPLACE "(.+a)$" "\\1_\\1" FOR 1 -1 2 OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,alpha;bravo;charlie;delta,REPLACE,(.+a)$,\1_\1,FOR,1,-1,2>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar REPLACE "(.+a)$" "\\1_\\1" REGEX "(r|t)a" OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,alpha;bravo;charlie;delta,REPLACE,(.+a)$,\1_\1,REGEX,(r|t)a>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+
+check_errors("LIST:TRANSFORM,REPLACE..." ${errors})
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-STRIP.cmake.in b/Tests/RunCMake/GenEx-LIST/TRANSFORM-STRIP.cmake.in
new file mode 100644
index 0000000000..860faec771
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-STRIP.cmake.in
@@ -0,0 +1,50 @@
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+set(listvar " alpha" "bravo " " charlie " delta)
+
+list(TRANSFORM listvar STRIP OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM, alpha;bravo ; charlie ;delta,STRIP>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar STRIP AT 1 3 OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM, alpha;bravo ; charlie ;delta,STRIP,AT,1,3>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar STRIP AT 1 -2 OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM, alpha;bravo ; charlie ;delta,STRIP,AT,1,-2>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar STRIP FOR 1 2 OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM, alpha;bravo ; charlie ;delta,STRIP,FOR,1,2>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar STRIP FOR 1 -1 OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM, alpha;bravo ; charlie ;delta,STRIP,FOR,1,-1>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar STRIP FOR 1 -1 2 OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM, alpha;bravo ; charlie ;delta,STRIP,FOR,1,-1,2>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar STRIP REGEX "(r|t)a" OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM, alpha;bravo ; charlie ;delta,STRIP,REGEX,(r|t)a>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+
+check_errors("LIST:TRANSFORM,STRIP..." ${errors})
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-TOLOWER.cmake.in b/Tests/RunCMake/GenEx-LIST/TRANSFORM-TOLOWER.cmake.in
new file mode 100644
index 0000000000..43e99556c6
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-TOLOWER.cmake.in
@@ -0,0 +1,50 @@
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+set(listvar ALPHA BRAVO CHARLIE DELTA)
+
+list(TRANSFORM listvar TOLOWER OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,ALPHA;BRAVO;CHARLIE;DELTA,TOLOWER>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar TOLOWER AT 1 3 OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,ALPHA;BRAVO;CHARLIE;DELTA,TOLOWER,AT,1,3>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar TOLOWER AT 1 -2 OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,ALPHA;BRAVO;CHARLIE;DELTA,TOLOWER,AT,1,-2>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar TOLOWER FOR 1 2 OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,ALPHA;BRAVO;CHARLIE;DELTA,TOLOWER,FOR,1,2>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar TOLOWER FOR 1 -1 OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,ALPHA;BRAVO;CHARLIE;DELTA,TOLOWER,FOR,1,-1>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar TOLOWER FOR 1 -1 2 OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,ALPHA;BRAVO;CHARLIE;DELTA,TOLOWER,FOR,1,-1,2>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar TOLOWER REGEX "(R|T)A" OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,ALPHA;BRAVO;CHARLIE;DELTA,TOLOWER,REGEX,(R|T)A>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+
+check_errors("LIST:TRANSFORM,TOLOWER..." ${errors})
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-TOUPPER.cmake.in b/Tests/RunCMake/GenEx-LIST/TRANSFORM-TOUPPER.cmake.in
new file mode 100644
index 0000000000..be2bc3039c
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-TOUPPER.cmake.in
@@ -0,0 +1,50 @@
+
+include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
+unset (errors)
+
+set(listvar alpha bravo charlie delta)
+
+list(TRANSFORM listvar TOUPPER OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,alpha;bravo;charlie;delta,TOUPPER>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar TOUPPER AT 1 3 OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,alpha;bravo;charlie;delta,TOUPPER,AT,1,3>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar TOUPPER AT 1 -2 OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,alpha;bravo;charlie;delta,TOUPPER,AT,1,-2>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar TOUPPER FOR 1 2 OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,alpha;bravo;charlie;delta,TOUPPER,FOR,1,2>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar TOUPPER FOR 1 -1 OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,alpha;bravo;charlie;delta,TOUPPER,FOR,1,-1>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar TOUPPER FOR 1 -1 2 OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,alpha;bravo;charlie;delta,TOUPPER,FOR,1,-1,2>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+list(TRANSFORM listvar TOUPPER REGEX "(r|t)a" OUTPUT_VARIABLE reference)
+set (output "$<LIST:TRANSFORM,alpha;bravo;charlie;delta,TOUPPER,REGEX,(r|t)a>")
+if (NOT output STREQUAL reference)
+ list (APPEND errors "returns bad value: ${output}")
+endif()
+
+
+check_errors("LIST:TRANSFORM,TOUPPER..." ${errors})
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-missing-arg-stderr.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-missing-arg-stderr.txt
new file mode 100644
index 0000000000..46e36c3bcc
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-missing-arg-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at missing-arg.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:TRANSFORM,ARG1,[A-Z]+(,ARG[0-9])?>
+
+ sub-command TRANSFORM, action [A-Z]+ expects (1|2) argument\(s\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-no-arguments-result.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-no-arguments-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-no-arguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-no-arguments-stderr.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-no-arguments-stderr.txt
new file mode 100644
index 0000000000..69b4915e74
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-no-arguments-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at TRANSFORM-selector-AT-no-arguments.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:TRANSFORM,a;b,TOUPPER,AT>
+
+ sub-command TRANSFORM, selector AT expects at least one numeric value.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-no-arguments.cmake b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-no-arguments.cmake
new file mode 100644
index 0000000000..2447511598
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-no-arguments.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:TRANSFORM,a;b,TOUPPER,AT>")
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-wrong-argument-result.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-wrong-argument-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-wrong-argument-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-wrong-argument-stderr.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-wrong-argument-stderr.txt
new file mode 100644
index 0000000000..40007a181c
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-wrong-argument-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at TRANSFORM-selector-AT-wrong-argument.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:TRANSFORM,a;b,TOUPPER,AT,0,1x,2>
+
+ sub-command TRANSFORM, selector AT: '1x': unexpected argument.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-wrong-argument.cmake b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-wrong-argument.cmake
new file mode 100644
index 0000000000..49f4e908d8
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-wrong-argument.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:TRANSFORM,a;b,TOUPPER,AT,0,1x,2>")
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-wrong-index-result.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-wrong-index-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-wrong-index-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-wrong-index-stderr.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-wrong-index-stderr.txt
new file mode 100644
index 0000000000..66085ab862
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-wrong-index-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at TRANSFORM-selector-AT-wrong-index.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:TRANSFORM,a;b;c,TOUPPER,AT,0,3,2>
+
+ sub-command TRANSFORM, selector AT, index: 3 out of range \(-3, 2\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-wrong-index.cmake b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-wrong-index.cmake
new file mode 100644
index 0000000000..fd6c3ed1ef
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-AT-wrong-index.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:TRANSFORM,a;b;c,TOUPPER,AT,0,3,2>")
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-backwards-range-result.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-backwards-range-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-backwards-range-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-backwards-range-stderr.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-backwards-range-stderr.txt
new file mode 100644
index 0000000000..77cffdc831
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-backwards-range-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at TRANSFORM-selector-FOR-backwards-range.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:TRANSFORM,a;b;c,TOUPPER,FOR,2,0>
+
+ sub-command TRANSFORM, selector FOR expects <start> to be no greater than
+ <stop> \(2 > 0\)
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-backwards-range.cmake b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-backwards-range.cmake
new file mode 100644
index 0000000000..17f57f586e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-backwards-range.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:TRANSFORM,a;b;c,TOUPPER,FOR,2,0>")
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-missing-arguments-result.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-missing-arguments-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-missing-arguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-missing-arguments-stderr.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-missing-arguments-stderr.txt
new file mode 100644
index 0000000000..a9de7f8070
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-missing-arguments-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at TRANSFORM-selector-FOR-missing-arguments.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:TRANSFORM,a;b,TOUPPER,FOR,0>
+
+ sub-command TRANSFORM, selector FOR expects, at least, two arguments.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-missing-arguments.cmake b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-missing-arguments.cmake
new file mode 100644
index 0000000000..5ae481aac2
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-missing-arguments.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:TRANSFORM,a;b,TOUPPER,FOR,0>")
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-negative-step-result.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-negative-step-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-negative-step-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-negative-step-stderr.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-negative-step-stderr.txt
new file mode 100644
index 0000000000..9c81de4bf6
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-negative-step-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at TRANSFORM-selector-FOR-negative-step.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:TRANSFORM,a;b;c,TOUPPER,FOR,0,2,-1>
+
+ sub-command TRANSFORM, selector FOR expects positive numeric value for
+ <step>.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-negative-step.cmake b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-negative-step.cmake
new file mode 100644
index 0000000000..b8e6433617
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-negative-step.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:TRANSFORM,a;b;c,TOUPPER,FOR,0,2,-1>")
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-no-arguments-result.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-no-arguments-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-no-arguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-no-arguments-stderr.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-no-arguments-stderr.txt
new file mode 100644
index 0000000000..d31f171bfc
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-no-arguments-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at TRANSFORM-selector-FOR-no-arguments.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:TRANSFORM,a;b,TOUPPER,FOR>
+
+ sub-command TRANSFORM, selector FOR expects, at least, two arguments.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-no-arguments.cmake b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-no-arguments.cmake
new file mode 100644
index 0000000000..6545ff95e6
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-no-arguments.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:TRANSFORM,a;b,TOUPPER,FOR>")
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-wrong-argument-result.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-wrong-argument-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-wrong-argument-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-wrong-argument-stderr.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-wrong-argument-stderr.txt
new file mode 100644
index 0000000000..727be10714
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-wrong-argument-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at TRANSFORM-selector-FOR-wrong-argument.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:TRANSFORM,a;b;c,TOUPPER,FOR,0,1x,2>
+
+ sub-command TRANSFORM, selector FOR expects, at least, two numeric values.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-wrong-argument.cmake b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-wrong-argument.cmake
new file mode 100644
index 0000000000..a50b62c1d8
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-wrong-argument.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:TRANSFORM,a;b;c,TOUPPER,FOR,0,1x,2>")
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-wrong-index-result.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-wrong-index-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-wrong-index-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-wrong-index-stderr.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-wrong-index-stderr.txt
new file mode 100644
index 0000000000..664e35a591
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-wrong-index-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at TRANSFORM-selector-FOR-wrong-index.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:TRANSFORM,a;b;c,TOUPPER,FOR,0,4,2>
+
+ sub-command TRANSFORM, selector FOR, index: 4 out of range \(-3, 2\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-wrong-index.cmake b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-wrong-index.cmake
new file mode 100644
index 0000000000..f35bfbf027
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-wrong-index.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:TRANSFORM,a;b;c,TOUPPER,FOR,0,4,2>")
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-zero-step-result.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-zero-step-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-zero-step-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-zero-step-stderr.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-zero-step-stderr.txt
new file mode 100644
index 0000000000..e542fbfcdb
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-zero-step-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at TRANSFORM-selector-FOR-zero-step.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:TRANSFORM,a;b;c,TOUPPER,FOR,0,2,0>
+
+ sub-command TRANSFORM, selector FOR expects positive numeric value for
+ <step>.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-zero-step.cmake b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-zero-step.cmake
new file mode 100644
index 0000000000..2bfaab0907
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-FOR-zero-step.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:TRANSFORM,a;b;c,TOUPPER,FOR,0,2,0>")
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-REGEX-no-arguments-result.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-REGEX-no-arguments-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-REGEX-no-arguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-REGEX-no-arguments-stderr.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-REGEX-no-arguments-stderr.txt
new file mode 100644
index 0000000000..079172b03d
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-REGEX-no-arguments-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at TRANSFORM-selector-REGEX-no-arguments.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:TRANSFORM,a;b,TOUPPER,REGEX>
+
+ sub-command TRANSFORM, selector REGEX expects 'regular expression'
+ argument.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-REGEX-no-arguments.cmake b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-REGEX-no-arguments.cmake
new file mode 100644
index 0000000000..1f802b757e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-REGEX-no-arguments.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:TRANSFORM,a;b,TOUPPER,REGEX>")
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-REGEX-wrong-regex-result.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-REGEX-wrong-regex-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-REGEX-wrong-regex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-REGEX-wrong-regex-stderr.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-REGEX-wrong-regex-stderr.txt
new file mode 100644
index 0000000000..3fe2b014a7
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-REGEX-wrong-regex-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at TRANSFORM-selector-REGEX-wrong-regex.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:TRANSFORM,a;b,TOUPPER,REGEX,\(a>
+
+ sub-command TRANSFORM, selector REGEX failed to compile regex "\(a".
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-REGEX-wrong-regex.cmake b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-REGEX-wrong-regex.cmake
new file mode 100644
index 0000000000..164809206c
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-selector-REGEX-wrong-regex.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:TRANSFORM,a;b,TOUPPER,REGEX,(a>")
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-unexpected-arg-stderr.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-unexpected-arg-stderr.txt
new file mode 100644
index 0000000000..04e9df1679
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-unexpected-arg-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at unexpected-arg.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:TRANSFORM,ARG1,[A-Z_]+(,[A-Z0-9]+)+>
+
+ sub-command TRANSFORM, '[A-Z0-9]+': unexpected argument\(s\).
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-wrong-action-result.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-wrong-action-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-wrong-action-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-wrong-action-stderr.txt b/Tests/RunCMake/GenEx-LIST/TRANSFORM-wrong-action-stderr.txt
new file mode 100644
index 0000000000..1c30c4f903
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-wrong-action-stderr.txt
@@ -0,0 +1,7 @@
+CMake Error at TRANSFORM-wrong-action.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:TRANSFORM,a;b;c,WRONG_ACTION>
+ sub-command TRANSFORM, WRONG_ACTION invalid action.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/TRANSFORM-wrong-action.cmake b/Tests/RunCMake/GenEx-LIST/TRANSFORM-wrong-action.cmake
new file mode 100644
index 0000000000..fba6c90f43
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/TRANSFORM-wrong-action.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:TRANSFORM,a;b;c,WRONG_ACTION>")
diff --git a/Tests/RunCMake/GenEx-LIST/bad-option-result.txt b/Tests/RunCMake/GenEx-LIST/bad-option-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/bad-option-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/bad-option-stderr.txt b/Tests/RunCMake/GenEx-LIST/bad-option-stderr.txt
new file mode 100644
index 0000000000..37048c5f0e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/bad-option-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at bad-option.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:BAD_OPTION,ARG>
+
+ BAD_OPTION: invalid option.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/bad-option.cmake b/Tests/RunCMake/GenEx-LIST/bad-option.cmake
new file mode 100644
index 0000000000..d1dc85f276
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/bad-option.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:BAD_OPTION,ARG>")
diff --git a/Tests/RunCMake/GenEx-LIST/check_errors.cmake b/Tests/RunCMake/GenEx-LIST/check_errors.cmake
new file mode 100644
index 0000000000..7e60fc725e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/check_errors.cmake
@@ -0,0 +1,13 @@
+
+function (CHECK_ERRORS command)
+ set (errors ${ARGN})
+ set (command "$<${command}>")
+ if (errors)
+ string (LENGTH "${command}" length)
+ math (EXPR count "${length} + 2")
+ string (REPEAT " " ${count} shift)
+ list (TRANSFORM errors PREPEND "${shift}")
+ list (JOIN errors "\n" msg)
+ message (FATAL_ERROR "${command}: ${msg}")
+ endif()
+endfunction()
diff --git a/Tests/RunCMake/GenEx-LIST/generate.cmake b/Tests/RunCMake/GenEx-LIST/generate.cmake
new file mode 100644
index 0000000000..92cdca2a5d
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/generate.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT "${LIST_TEST}.cmake" INPUT "${LIST_TEST}.cmake.in")
diff --git a/Tests/RunCMake/GenEx-LIST/missing-arg-result.txt b/Tests/RunCMake/GenEx-LIST/missing-arg-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/missing-arg-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/missing-arg-stderr.txt b/Tests/RunCMake/GenEx-LIST/missing-arg-stderr.txt
new file mode 100644
index 0000000000..c7cbe4b13a
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/missing-arg-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at missing-arg.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:[A-Z_]+,.+>
+
+ \$<LIST:[A-Z_]+> expression requires at least (two|three) parameters.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/missing-arg.cmake b/Tests/RunCMake/GenEx-LIST/missing-arg.cmake
new file mode 100644
index 0000000000..48b26e13af
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/missing-arg.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:${LIST_ARGUMENTS}>")
diff --git a/Tests/RunCMake/GenEx-LIST/no-arguments-result.txt b/Tests/RunCMake/GenEx-LIST/no-arguments-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/no-arguments-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/no-arguments-stderr.txt b/Tests/RunCMake/GenEx-LIST/no-arguments-stderr.txt
new file mode 100644
index 0000000000..ee782ecfde
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/no-arguments-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at no-arguments.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:>
+
+ \$<LIST> expression requires at least two parameters.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/no-arguments.cmake b/Tests/RunCMake/GenEx-LIST/no-arguments.cmake
new file mode 100644
index 0000000000..f704e2b76e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/no-arguments.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:>")
diff --git a/Tests/RunCMake/GenEx-LIST/unexpected-arg-result.txt b/Tests/RunCMake/GenEx-LIST/unexpected-arg-result.txt
new file mode 100644
index 0000000000..d00491fd7e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/unexpected-arg-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GenEx-LIST/unexpected-arg-stderr.txt b/Tests/RunCMake/GenEx-LIST/unexpected-arg-stderr.txt
new file mode 100644
index 0000000000..a7b1f25e1e
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/unexpected-arg-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at unexpected-arg.cmake:[0-9]+ \(file\):
+ Error evaluating generator expression:
+
+ \$<LIST:[A-Z_]+,.+>
+
+ \$<LIST:[A-Z_]+(,[A-Z_]+)?> expression requires exactly (one|two|three) parameters?.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/GenEx-LIST/unexpected-arg.cmake b/Tests/RunCMake/GenEx-LIST/unexpected-arg.cmake
new file mode 100644
index 0000000000..48b26e13af
--- /dev/null
+++ b/Tests/RunCMake/GenEx-LIST/unexpected-arg.cmake
@@ -0,0 +1,2 @@
+
+file(GENERATE OUTPUT result.txt CONTENT "$<LIST:${LIST_ARGUMENTS}>")
diff --git a/Tests/RunCMake/IncludeWhatYouUse/C-error-Build-result.txt b/Tests/RunCMake/IncludeWhatYouUse/C-error-Build-result.txt
new file mode 100644
index 0000000000..d197c913c2
--- /dev/null
+++ b/Tests/RunCMake/IncludeWhatYouUse/C-error-Build-result.txt
@@ -0,0 +1 @@
+[^0]
diff --git a/Tests/RunCMake/IncludeWhatYouUse/C-error-Build-stdout.txt b/Tests/RunCMake/IncludeWhatYouUse/C-error-Build-stdout.txt
new file mode 100644
index 0000000000..cb7467705e
--- /dev/null
+++ b/Tests/RunCMake/IncludeWhatYouUse/C-error-Build-stdout.txt
@@ -0,0 +1,4 @@
+Warning: include-what-you-use reported diagnostics:
+should add these lines:
+*
+#include <\.\.\.>
diff --git a/Tests/RunCMake/IncludeWhatYouUse/C-error.cmake b/Tests/RunCMake/IncludeWhatYouUse/C-error.cmake
new file mode 100644
index 0000000000..d5230bbf8c
--- /dev/null
+++ b/Tests/RunCMake/IncludeWhatYouUse/C-error.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+set(CMAKE_C_INCLUDE_WHAT_YOU_USE "${PSEUDO_IWYU}" -Xiwyu --error)
+add_executable(main main.c)
diff --git a/Tests/RunCMake/IncludeWhatYouUse/CXX-error-Build-result.txt b/Tests/RunCMake/IncludeWhatYouUse/CXX-error-Build-result.txt
new file mode 100644
index 0000000000..d197c913c2
--- /dev/null
+++ b/Tests/RunCMake/IncludeWhatYouUse/CXX-error-Build-result.txt
@@ -0,0 +1 @@
+[^0]
diff --git a/Tests/RunCMake/IncludeWhatYouUse/CXX-error-Build-stdout.txt b/Tests/RunCMake/IncludeWhatYouUse/CXX-error-Build-stdout.txt
new file mode 100644
index 0000000000..cb7467705e
--- /dev/null
+++ b/Tests/RunCMake/IncludeWhatYouUse/CXX-error-Build-stdout.txt
@@ -0,0 +1,4 @@
+Warning: include-what-you-use reported diagnostics:
+should add these lines:
+*
+#include <\.\.\.>
diff --git a/Tests/RunCMake/IncludeWhatYouUse/CXX-error.cmake b/Tests/RunCMake/IncludeWhatYouUse/CXX-error.cmake
new file mode 100644
index 0000000000..1d10a550d4
--- /dev/null
+++ b/Tests/RunCMake/IncludeWhatYouUse/CXX-error.cmake
@@ -0,0 +1,3 @@
+enable_language(CXX)
+set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "$<1:${PSEUDO_IWYU}>" -Xiwyu --error)
+add_executable(main main.cxx)
diff --git a/Tests/RunCMake/IncludeWhatYouUse/RunCMakeTest.cmake b/Tests/RunCMake/IncludeWhatYouUse/RunCMakeTest.cmake
index 8f99eb1047..8ec24be5ca 100644
--- a/Tests/RunCMake/IncludeWhatYouUse/RunCMakeTest.cmake
+++ b/Tests/RunCMake/IncludeWhatYouUse/RunCMakeTest.cmake
@@ -16,6 +16,8 @@ endfunction()
run_iwyu(C)
run_iwyu(CXX)
+run_iwyu(C-error)
+run_iwyu(CXX-error)
if (NOT RunCMake_GENERATOR STREQUAL "Watcom WMake")
run_iwyu(C-launch)
run_iwyu(CXX-launch)
diff --git a/Tests/RunCMake/RunCMake.cmake b/Tests/RunCMake/RunCMake.cmake
index 8e85f6cf46..18dde944d7 100644
--- a/Tests/RunCMake/RunCMake.cmake
+++ b/Tests/RunCMake/RunCMake.cmake
@@ -47,6 +47,8 @@ function(run_cmake test)
elseif(EXISTS ${top_src}/${test}-${o}.txt)
file(READ ${top_src}/${test}-${o}.txt expect_${o})
string(REGEX REPLACE "\n+$" "" expect_${o} "${expect_${o}}")
+ elseif(DEFINED RunCMake_TEST_EXPECT_${o})
+ string(REGEX REPLACE "\n+$" "" expect_${o} "${RunCMake_TEST_EXPECT_${o}}")
else()
unset(expect_${o})
endif()
@@ -175,7 +177,7 @@ function(run_cmake test)
"|Your license to use PGI[^\n]*expired"
"|Please obtain a new version at"
"|contact PGI Sales at"
- "|icp?c: remark #10441: The Intel\\(R\\) C\\+\\+ Compiler Classic \\(ICC\\) is deprecated"
+ "|ic(p?c|l): remark #10441: The Intel\\(R\\) C\\+\\+ Compiler Classic \\(ICC\\) is deprecated"
"|[^\n]*install_name_tool: warning: changes being made to the file will invalidate the code signature in:"
"|[^\n]*xcodebuild[^\n]*DVTCoreDeviceEnabledState: DVTCoreDeviceEnabledState_Disabled set via user default"
diff --git a/Tests/RunCMake/TransformDepfile/deps-unix.d.txt b/Tests/RunCMake/TransformDepfile/deps-unix.d.txt
index fbdecc072b..2588181b8b 100644
--- a/Tests/RunCMake/TransformDepfile/deps-unix.d.txt
+++ b/Tests/RunCMake/TransformDepfile/deps-unix.d.txt
@@ -1,8 +1,8 @@
subdir/out1 \
/home/build/out2: \
- subdir/in1 \
- /home/build/in2
+ /home/build/in2 \
+ subdir/in1
subdir/out3 \
/home/build/out4: \
- subdir/in3 \
- /home/build/in4
+ /home/build/in4 \
+ subdir/in3
diff --git a/Tests/RunCMake/TransformDepfile/deps-windows.d.txt b/Tests/RunCMake/TransformDepfile/deps-windows.d.txt
index e09ae375a8..805a4c8362 100644
--- a/Tests/RunCMake/TransformDepfile/deps-windows.d.txt
+++ b/Tests/RunCMake/TransformDepfile/deps-windows.d.txt
@@ -1,8 +1,8 @@
subdir/out1 \
C:/build/out2: \
- subdir/in1 \
- C:/build/in2
+ C:/build/in2 \
+ subdir/in1
subdir/out3 \
C:/build/out4: \
- subdir/in3 \
- C:/build/in4
+ C:/build/in4 \
+ subdir/in3
diff --git a/Tests/RunCMake/VS10Project/CMakeInputs-check.cmake b/Tests/RunCMake/VS10Project/CMakeInputs-check.cmake
new file mode 100644
index 0000000000..a125574d8e
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/CMakeInputs-check.cmake
@@ -0,0 +1,25 @@
+set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/ZERO_CHECK.vcxproj")
+if(NOT EXISTS "${vcProjectFile}")
+ set(RunCMake_TEST_FAILED "Project file ${vcProjectFile} does not exist.")
+ return()
+endif()
+
+set(found_CMakeInputs 0)
+file(STRINGS "${vcProjectFile}" lines)
+foreach(line IN LISTS lines)
+ if(line MATCHES "<([A-Za-z0-9_]+) +Include=.*CMakeInputs.cmake")
+ set(rule "${CMAKE_MATCH_1}")
+ if(NOT rule STREQUAL "None")
+ set(RunCMake_TEST_FAILED "CMakeInputs.cmake referenced as ${rule} instead of None")
+ return()
+ endif()
+ if(found_CMakeInputs)
+ set(RunCMake_TEST_FAILED "CMakeInputs.cmake referenced multiple times")
+ return()
+ endif()
+ set(found_CMakeInputs 1)
+ endif()
+endforeach()
+if(NOT found_CMakeInputs)
+ set(RunCMake_TEST_FAILED "CMakeInputs.cmake not referenced")
+endif()
diff --git a/Tests/RunCMake/VS10Project/CMakeInputs.cmake b/Tests/RunCMake/VS10Project/CMakeInputs.cmake
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/CMakeInputs.cmake
diff --git a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
index 669049a737..cb1a5d5403 100644
--- a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
+++ b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
@@ -7,6 +7,7 @@ if(CMAKE_C_COMPILER_ID STREQUAL "MSVC" AND CMAKE_C_COMPILER_VERSION VERSION_GREA
run_cmake(LanguageStandard)
endif()
+run_cmake(CMakeInputs)
run_cmake(CustomCommandGenex)
if(NOT RunCMake_GENERATOR MATCHES "^Visual Studio 1[1-5] ")
run_cmake(CustomCommandParallel)
diff --git a/Utilities/Scripts/update-libarchive.bash b/Utilities/Scripts/update-libarchive.bash
index 856a6ea7c9..5a4f11a0b6 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.6.0"
+readonly tag="v3.6.2"
readonly shortlog=false
readonly paths="
CMakeLists.txt
diff --git a/Utilities/cmlibarchive/CMakeLists.txt b/Utilities/cmlibarchive/CMakeLists.txt
index b38e6530a3..027de5c589 100644
--- a/Utilities/cmlibarchive/CMakeLists.txt
+++ b/Utilities/cmlibarchive/CMakeLists.txt
@@ -238,7 +238,7 @@ OPTION(ENABLE_BZip2 "Enable the use of the system BZip2 library if found" ON)
OPTION(ENABLE_LIBXML2 "Enable the use of the system libxml2 library if found" ON)
OPTION(ENABLE_EXPAT "Enable the use of the system EXPAT library if found" ON)
OPTION(ENABLE_PCREPOSIX "Enable the use of the system PCREPOSIX library if found" ON)
-OPTION(ENABLE_LibGCC "Enable the use of the system LibGCC library if found" ON)
+OPTION(ENABLE_LIBGCC "Enable the use of the system LibGCC library if found" ON)
# CNG is used for encrypt/decrypt Zip archives on Windows.
OPTION(ENABLE_CNG "Enable the use of CNG(Crypto Next Generation)" ON)
@@ -257,7 +257,7 @@ OPTION(ENABLE_INSTALL "Enable installing of libraries" ON)
SET(POSIX_REGEX_LIB "AUTO" CACHE STRING "Choose what library should provide POSIX regular expression support")
SET(ENABLE_SAFESEH "AUTO" CACHE STRING "Enable use of /SAFESEH linker flag (MSVC only)")
-SET(WINDOWS_VERSION "WIN7" CACHE STRING "Set Windows version to use (Windows only)")
+SET(WINDOWS_VERSION "WIN10" CACHE STRING "Set Windows version to use (Windows only)")
IF(ENABLE_COVERAGE)
include(LibarchiveCodeCoverage)
@@ -268,7 +268,11 @@ IF(ENABLE_TEST)
ENDIF(ENABLE_TEST)
IF(WIN32)
- IF(WINDOWS_VERSION STREQUAL "WIN8")
+ IF(WINDOWS_VERSION STREQUAL "WIN10")
+ SET(NTDDI_VERSION 0x0A000000)
+ SET(_WIN32_WINNT 0x0A00)
+ SET(WINVER 0x0A00)
+ ELSEIF(WINDOWS_VERSION STREQUAL "WIN8")
SET(NTDDI_VERSION 0x06020000)
SET(_WIN32_WINNT 0x0602)
SET(WINVER 0x0602)
@@ -292,12 +296,12 @@ IF(WIN32)
SET(NTDDI_VERSION 0x05010000)
SET(_WIN32_WINNT 0x0501)
SET(WINVER 0x0501)
- ELSE(WINDOWS_VERSION STREQUAL "WIN8")
+ ELSE(WINDOWS_VERSION STREQUAL "WIN10")
# Default to Windows Server 2003 API if we don't recognize the specifier
SET(NTDDI_VERSION 0x05020000)
SET(_WIN32_WINNT 0x0502)
SET(WINVER 0x0502)
- ENDIF(WINDOWS_VERSION STREQUAL "WIN8")
+ ENDIF(WINDOWS_VERSION STREQUAL "WIN10")
ENDIF(WIN32)
IF(MSVC)
@@ -632,8 +636,15 @@ IF(ENABLE_ZSTD)
SET(ZSTD_FIND_QUIETLY TRUE)
ENDIF (ZSTD_INCLUDE_DIR)
- FIND_PATH(ZSTD_INCLUDE_DIR zstd.h)
- FIND_LIBRARY(ZSTD_LIBRARY NAMES zstd libzstd)
+ IF(0) # CMake does not let pkg-config override its search paths.
+ IF(UNIX)
+ FIND_PACKAGE(PkgConfig QUIET)
+ PKG_SEARCH_MODULE(PC_ZSTD libzstd)
+ ENDIF()
+ ENDIF()
+
+ FIND_PATH(ZSTD_INCLUDE_DIR zstd.h HINTS ${PC_ZSTD_INCLUDEDIR} ${PC_ZSTD_INCLUDE_DIRS})
+ FIND_LIBRARY(ZSTD_LIBRARY NAMES zstd libzstd HINTS ${PC_ZSTD_LIBDIR} ${PC_ZSTD_LIBRARY_DIRS})
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(ZSTD DEFAULT_MSG ZSTD_LIBRARY ZSTD_INCLUDE_DIR)
ELSE(ENABLE_ZSTD)
@@ -1284,9 +1295,10 @@ IF(NOT FOUND_POSIX_REGEX_LIB AND POSIX_REGEX_LIB MATCHES "^(AUTO|LIBPCREPOSIX)$"
#
# If requested, try finding library for PCREPOSIX
#
- IF(ENABLE_LibGCC)
- FIND_PACKAGE(LibGCC)
+ IF(ENABLE_LIBGCC)
+ FIND_PACKAGE(LIBGCC)
ELSE()
+ MESSAGE(FATAL_ERROR "libgcc not found.")
SET(LIBGCC_FOUND FALSE) # Override cached value
ENDIF()
IF(ENABLE_PCREPOSIX)
@@ -1996,6 +2008,19 @@ CHECK_CRYPTO("MD5;RMD160;SHA1;SHA256;SHA512" LIBMD)
CHECK_CRYPTO_WIN("MD5;SHA1;SHA256;SHA384;SHA512")
+IF(0) # CMake does not build libarchive's shared library.
+# Check visibility annotations
+SET(OLD_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
+SET(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fvisibility=hidden -Werror")
+CHECK_C_SOURCE_COMPILES("void __attribute__((visibility(\"default\"))) foo(void);
+int main() { return 0; }" HAVE_VISIBILITY_ATTR)
+IF (HAVE_VISIBILITY_ATTR)
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden")
+ ADD_DEFINITIONS(-D__LIBARCHIVE_ENABLE_VISIBILITY)
+ENDIF(HAVE_VISIBILITY_ATTR)
+SET(CMAKE_REQUIRED_FLAGS "${OLD_CMAKE_REQUIRED_FLAGS}")
+ENDIF()
+
# Generate "config.h" from "build/cmake/config.h.in"
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/build/cmake/config.h.in
${CMAKE_CURRENT_BINARY_DIR}/config.h)
diff --git a/Utilities/cmlibarchive/build/cmake/FindLibGCC.cmake b/Utilities/cmlibarchive/build/cmake/FindLIBGCC.cmake
index 7985f2b003..7985f2b003 100644
--- a/Utilities/cmlibarchive/build/cmake/FindLibGCC.cmake
+++ b/Utilities/cmlibarchive/build/cmake/FindLIBGCC.cmake
diff --git a/Utilities/cmlibarchive/build/cmake/config.h.in b/Utilities/cmlibarchive/build/cmake/config.h.in
index 72467a5461..e44a514080 100644
--- a/Utilities/cmlibarchive/build/cmake/config.h.in
+++ b/Utilities/cmlibarchive/build/cmake/config.h.in
@@ -147,13 +147,13 @@
#cmakedefine ARCHIVE_XATTR_LINUX 1
/* Version number of bsdcpio */
-#cmakedefine BSDCPIO_VERSION_STRING "${BSDCPIO_VERSION_STRING}"
+#cmakedefine BSDCPIO_VERSION_STRING "@BSDCPIO_VERSION_STRING@"
/* Version number of bsdtar */
-#cmakedefine BSDTAR_VERSION_STRING "${BSDTAR_VERSION_STRING}"
+#cmakedefine BSDTAR_VERSION_STRING "@BSDTAR_VERSION_STRING@"
/* Version number of bsdcat */
-#cmakedefine BSDCAT_VERSION_STRING "${BSDCAT_VERSION_STRING}"
+#cmakedefine BSDCAT_VERSION_STRING "@BSDCAT_VERSION_STRING@"
/* Define to 1 if you have the `acl_create_entry' function. */
#cmakedefine HAVE_ACL_CREATE_ENTRY 1
@@ -1012,13 +1012,13 @@
#cmakedefine HAVE__MKGMTIME64 1
/* Define as const if the declaration of iconv() needs const. */
-#define ICONV_CONST ${ICONV_CONST}
+#define ICONV_CONST @ICONV_CONST@
/* Version number of libarchive as a single integer */
-#cmakedefine LIBARCHIVE_VERSION_NUMBER "${LIBARCHIVE_VERSION_NUMBER}"
+#cmakedefine LIBARCHIVE_VERSION_NUMBER "@LIBARCHIVE_VERSION_NUMBER@"
/* Version number of libarchive */
-#cmakedefine LIBARCHIVE_VERSION_STRING "${LIBARCHIVE_VERSION_STRING}"
+#cmakedefine LIBARCHIVE_VERSION_STRING "@LIBARCHIVE_VERSION_STRING@"
/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
slash. */
@@ -1036,7 +1036,7 @@
#cmakedefine NO_MINUS_C_MINUS_O 1
/* The size of `wchar_t', as computed by sizeof. */
-#cmakedefine SIZEOF_WCHAR_T ${SIZEOF_WCHAR_T}
+#cmakedefine SIZEOF_WCHAR_T @SIZEOF_WCHAR_T@
/* Define to 1 if strerror_r returns char *. */
#cmakedefine STRERROR_R_CHAR_P 1
@@ -1072,56 +1072,56 @@
#endif /* SAFE_TO_DEFINE_EXTENSIONS */
/* Version number of package */
-#cmakedefine VERSION "${VERSION}"
+#cmakedefine VERSION "@VERSION@"
/* Number of bits in a file offset, on hosts where this is settable. */
-#cmakedefine _FILE_OFFSET_BITS ${_FILE_OFFSET_BITS}
+#cmakedefine _FILE_OFFSET_BITS @_FILE_OFFSET_BITS@
/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
#cmakedefine _LARGEFILE_SOURCE 1
/* Define for large files, on AIX-style hosts. */
-#cmakedefine _LARGE_FILES ${_LARGE_FILES}
+#cmakedefine _LARGE_FILES @_LARGE_FILES@
/* Define to control Windows SDK version */
#ifndef NTDDI_VERSION
-#cmakedefine NTDDI_VERSION ${NTDDI_VERSION}
+#cmakedefine NTDDI_VERSION @NTDDI_VERSION@
#endif // NTDDI_VERSION
#ifndef _WIN32_WINNT
-#cmakedefine _WIN32_WINNT ${_WIN32_WINNT}
+#cmakedefine _WIN32_WINNT @_WIN32_WINNT@
#endif // _WIN32_WINNT
#ifndef WINVER
-#cmakedefine WINVER ${WINVER}
+#cmakedefine WINVER @WINVER@
#endif // WINVER
/* Define to empty if `const' does not conform to ANSI C. */
-#cmakedefine const ${const}
+#cmakedefine const @const@
/* Define to `int' if <sys/types.h> doesn't define. */
-#cmakedefine gid_t ${gid_t}
+#cmakedefine gid_t @gid_t@
/* Define to `unsigned long' if <sys/types.h> does not define. */
-#cmakedefine id_t ${id_t}
+#cmakedefine id_t @id_t@
/* Define to `int' if <sys/types.h> does not define. */
-#cmakedefine mode_t ${mode_t}
+#cmakedefine mode_t @mode_t@
/* Define to `long long' if <sys/types.h> does not define. */
-#cmakedefine off_t ${off_t}
+#cmakedefine off_t @off_t@
/* Define to `int' if <sys/types.h> doesn't define. */
-#cmakedefine pid_t ${pid_t}
+#cmakedefine pid_t @pid_t@
/* Define to `unsigned int' if <sys/types.h> does not define. */
-#cmakedefine size_t ${size_t}
+#cmakedefine size_t @size_t@
/* Define to `int' if <sys/types.h> does not define. */
-#cmakedefine ssize_t ${ssize_t}
+#cmakedefine ssize_t @ssize_t@
/* Define to `int' if <sys/types.h> doesn't define. */
-#cmakedefine uid_t ${uid_t}
+#cmakedefine uid_t @uid_t@
#include <cm3p/kwiml/int.h>
diff --git a/Utilities/cmlibarchive/build/pkgconfig/libarchive.pc.in b/Utilities/cmlibarchive/build/pkgconfig/libarchive.pc.in
index 4b631e635c..1f51e77f16 100644
--- a/Utilities/cmlibarchive/build/pkgconfig/libarchive.pc.in
+++ b/Utilities/cmlibarchive/build/pkgconfig/libarchive.pc.in
@@ -10,3 +10,4 @@ Cflags: -I${includedir}
Cflags.private: -DLIBARCHIVE_STATIC
Libs: -L${libdir} -larchive
Libs.private: @LIBS@
+Requires.private: @LIBSREQUIRED@
diff --git a/Utilities/cmlibarchive/build/version b/Utilities/cmlibarchive/build/version
index 102ec29cb7..1af1bec7bb 100644
--- a/Utilities/cmlibarchive/build/version
+++ b/Utilities/cmlibarchive/build/version
@@ -1 +1 @@
-3006000
+3006002
diff --git a/Utilities/cmlibarchive/libarchive/CMakeLists.txt b/Utilities/cmlibarchive/libarchive/CMakeLists.txt
index feb8697805..bee69c23e2 100644
--- a/Utilities/cmlibarchive/libarchive/CMakeLists.txt
+++ b/Utilities/cmlibarchive/libarchive/CMakeLists.txt
@@ -5,6 +5,10 @@
#
############################################
+if (ANDROID)
+ include_directories(${PROJECT_SOURCE_DIR}/contrib/android/include)
+endif()
+
# Public headers
SET(include_HEADERS
archive.h
@@ -78,6 +82,7 @@ SET(libarchive_SOURCES
archive_read_set_format.c
archive_read_set_options.c
archive_read_support_filter_all.c
+ archive_read_support_filter_by_code.c
archive_read_support_filter_bzip2.c
archive_read_support_filter_compress.c
archive_read_support_filter_gzip.c
diff --git a/Utilities/cmlibarchive/libarchive/archive.h b/Utilities/cmlibarchive/libarchive/archive.h
index ac01738235..180f3e4cbd 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 3006000
+#define ARCHIVE_VERSION_NUMBER 3006002
#include <sys/stat.h>
#include <stddef.h> /* for wchar_t */
@@ -120,6 +120,8 @@ typedef ssize_t la_ssize_t;
# define __LA_DECL __declspec(dllimport)
# endif
# endif
+#elif defined __LIBARCHIVE_ENABLE_VISIBILITY
+# define __LA_DECL __attribute__((visibility("default")))
#else
/* Static libraries or non-Windows needs no special declaration. */
# define __LA_DECL
@@ -152,7 +154,7 @@ __LA_DECL int archive_version_number(void);
/*
* Textual name/version of the library, useful for version displays.
*/
-#define ARCHIVE_VERSION_ONLY_STRING "3.6.0"
+#define ARCHIVE_VERSION_ONLY_STRING "3.6.2"
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
__LA_DECL const char * archive_version_string(void);
diff --git a/Utilities/cmlibarchive/libarchive/archive_digest.c b/Utilities/cmlibarchive/libarchive/archive_digest.c
index 410df01563..3361b19ada 100644
--- a/Utilities/cmlibarchive/libarchive/archive_digest.c
+++ b/Utilities/cmlibarchive/libarchive/archive_digest.c
@@ -49,16 +49,16 @@
* Initialize a Message digest.
*/
static int
-win_crypto_init(Digest_CTX *ctx, ALG_ID algId)
+win_crypto_init(Digest_CTX *ctx, DWORD prov, ALG_ID algId)
{
ctx->valid = 0;
if (!CryptAcquireContext(&ctx->cryptProv, NULL, NULL,
- PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
+ prov, CRYPT_VERIFYCONTEXT)) {
if (GetLastError() != (DWORD)NTE_BAD_KEYSET)
return (ARCHIVE_FAILED);
if (!CryptAcquireContext(&ctx->cryptProv, NULL, NULL,
- PROV_RSA_FULL, CRYPT_NEWKEYSET))
+ prov, CRYPT_NEWKEYSET))
return (ARCHIVE_FAILED);
}
@@ -243,7 +243,8 @@ __archive_md5init(archive_md5_ctx *ctx)
{
if ((*ctx = EVP_MD_CTX_new()) == NULL)
return (ARCHIVE_FAILED);
- EVP_DigestInit(*ctx, EVP_md5());
+ if (!EVP_DigestInit(*ctx, EVP_md5()))
+ return (ARCHIVE_FAILED);
return (ARCHIVE_OK);
}
@@ -275,7 +276,7 @@ __archive_md5final(archive_md5_ctx *ctx, void *md)
static int
__archive_md5init(archive_md5_ctx *ctx)
{
- return (win_crypto_init(ctx, CALG_MD5));
+ return (win_crypto_init(ctx, PROV_RSA_FULL, CALG_MD5));
}
static int
@@ -434,7 +435,8 @@ __archive_ripemd160init(archive_rmd160_ctx *ctx)
{
if ((*ctx = EVP_MD_CTX_new()) == NULL)
return (ARCHIVE_FAILED);
- EVP_DigestInit(*ctx, EVP_ripemd160());
+ if (!EVP_DigestInit(*ctx, EVP_ripemd160()))
+ return (ARCHIVE_FAILED);
return (ARCHIVE_OK);
}
@@ -624,7 +626,8 @@ __archive_sha1init(archive_sha1_ctx *ctx)
{
if ((*ctx = EVP_MD_CTX_new()) == NULL)
return (ARCHIVE_FAILED);
- EVP_DigestInit(*ctx, EVP_sha1());
+ if (!EVP_DigestInit(*ctx, EVP_sha1()))
+ return (ARCHIVE_FAILED);
return (ARCHIVE_OK);
}
@@ -656,7 +659,7 @@ __archive_sha1final(archive_sha1_ctx *ctx, void *md)
static int
__archive_sha1init(archive_sha1_ctx *ctx)
{
- return (win_crypto_init(ctx, CALG_SHA1));
+ return (win_crypto_init(ctx, PROV_RSA_FULL, CALG_SHA1));
}
static int
@@ -887,7 +890,8 @@ __archive_sha256init(archive_sha256_ctx *ctx)
{
if ((*ctx = EVP_MD_CTX_new()) == NULL)
return (ARCHIVE_FAILED);
- EVP_DigestInit(*ctx, EVP_sha256());
+ if (!EVP_DigestInit(*ctx, EVP_sha256()))
+ return (ARCHIVE_FAILED);
return (ARCHIVE_OK);
}
@@ -915,7 +919,7 @@ __archive_sha256final(archive_sha256_ctx *ctx, void *md)
static int
__archive_sha256init(archive_sha256_ctx *ctx)
{
- return (win_crypto_init(ctx, CALG_SHA_256));
+ return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_256));
}
static int
@@ -1122,7 +1126,8 @@ __archive_sha384init(archive_sha384_ctx *ctx)
{
if ((*ctx = EVP_MD_CTX_new()) == NULL)
return (ARCHIVE_FAILED);
- EVP_DigestInit(*ctx, EVP_sha384());
+ if (!EVP_DigestInit(*ctx, EVP_sha384()))
+ return (ARCHIVE_FAILED);
return (ARCHIVE_OK);
}
@@ -1150,7 +1155,7 @@ __archive_sha384final(archive_sha384_ctx *ctx, void *md)
static int
__archive_sha384init(archive_sha384_ctx *ctx)
{
- return (win_crypto_init(ctx, CALG_SHA_384));
+ return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_384));
}
static int
@@ -1381,7 +1386,8 @@ __archive_sha512init(archive_sha512_ctx *ctx)
{
if ((*ctx = EVP_MD_CTX_new()) == NULL)
return (ARCHIVE_FAILED);
- EVP_DigestInit(*ctx, EVP_sha512());
+ if (!EVP_DigestInit(*ctx, EVP_sha512()))
+ return (ARCHIVE_FAILED);
return (ARCHIVE_OK);
}
@@ -1409,7 +1415,7 @@ __archive_sha512final(archive_sha512_ctx *ctx, void *md)
static int
__archive_sha512init(archive_sha512_ctx *ctx)
{
- return (win_crypto_init(ctx, CALG_SHA_512));
+ return (win_crypto_init(ctx, PROV_RSA_AES, CALG_SHA_512));
}
static int
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry.c b/Utilities/cmlibarchive/libarchive/archive_entry.c
index ca7a4bdb50..ae6dc33361 100644
--- a/Utilities/cmlibarchive/libarchive/archive_entry.c
+++ b/Utilities/cmlibarchive/libarchive/archive_entry.c
@@ -568,6 +568,13 @@ archive_entry_nlink(struct archive_entry *entry)
return (entry->ae_stat.aest_nlink);
}
+/* Instead, our caller could have chosen a specific encoding
+ * (archive_mstring_get_mbs, archive_mstring_get_utf8,
+ * archive_mstring_get_wcs). So we should try multiple
+ * encodings. Try mbs first because of history, even though
+ * utf8 might be better for pathname portability.
+ * Also omit wcs because of type mismatch (char * versus wchar *)
+ */
const char *
archive_entry_pathname(struct archive_entry *entry)
{
@@ -575,6 +582,13 @@ archive_entry_pathname(struct archive_entry *entry)
if (archive_mstring_get_mbs(
entry->archive, &entry->ae_pathname, &p) == 0)
return (p);
+#if HAVE_EILSEQ /*{*/
+ if (errno == EILSEQ) {
+ if (archive_mstring_get_utf8(
+ entry->archive, &entry->ae_pathname, &p) == 0)
+ return (p);
+ }
+#endif /*}*/
if (errno == ENOMEM)
__archive_errx(1, "No memory");
return (NULL);
diff --git a/Utilities/cmlibarchive/libarchive/archive_entry.h b/Utilities/cmlibarchive/libarchive/archive_entry.h
index 221ef80ee8..91ef0c97e4 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 3006000
+#define ARCHIVE_VERSION_NUMBER 3006002
/*
* Note: archive_entry.h is for use outside of libarchive; the
@@ -122,6 +122,8 @@ typedef ssize_t la_ssize_t;
# define __LA_DECL __declspec(dllimport)
# endif
# endif
+#elif defined __LIBARCHIVE_ENABLE_VISIBILITY
+# define __LA_DECL __attribute__((visibility("default")))
#else
/* Static libraries on all platforms and shared libraries on non-Windows. */
# define __LA_DECL
diff --git a/Utilities/cmlibarchive/libarchive/archive_hmac.c b/Utilities/cmlibarchive/libarchive/archive_hmac.c
index 2a9d04c8d8..012fe15962 100644
--- a/Utilities/cmlibarchive/libarchive/archive_hmac.c
+++ b/Utilities/cmlibarchive/libarchive/archive_hmac.c
@@ -230,10 +230,23 @@ __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
static int
__hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
{
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ OSSL_PARAM params[2];
+
+ EVP_MAC *mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
+ *ctx = EVP_MAC_CTX_new(mac);
+ if (*ctx == NULL)
+ return -1;
+ EVP_MAC_free(mac);
+ params[0] = OSSL_PARAM_construct_utf8_string("digest", "SHA1", 0);
+ params[1] = OSSL_PARAM_construct_end();
+ EVP_MAC_init(*ctx, key, key_len, params);
+#else
*ctx = HMAC_CTX_new();
if (*ctx == NULL)
return -1;
HMAC_Init_ex(*ctx, key, key_len, EVP_sha1(), NULL);
+#endif
return 0;
}
@@ -241,22 +254,38 @@ static void
__hmac_sha1_update(archive_hmac_sha1_ctx *ctx, const uint8_t *data,
size_t data_len)
{
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ EVP_MAC_update(*ctx, data, data_len);
+#else
HMAC_Update(*ctx, data, data_len);
+#endif
}
static void
__hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
{
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ size_t len = *out_len;
+#else
unsigned int len = (unsigned int)*out_len;
+#endif
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ EVP_MAC_final(*ctx, out, &len, *out_len);
+#else
HMAC_Final(*ctx, out, &len);
+#endif
*out_len = len;
}
static void
__hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
{
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ EVP_MAC_CTX_free(*ctx);
+#else
HMAC_CTX_free(*ctx);
+#endif
*ctx = NULL;
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_hmac_private.h b/Utilities/cmlibarchive/libarchive/archive_hmac_private.h
index 13a67d4955..50044a045e 100644
--- a/Utilities/cmlibarchive/libarchive/archive_hmac_private.h
+++ b/Utilities/cmlibarchive/libarchive/archive_hmac_private.h
@@ -74,9 +74,16 @@ typedef mbedtls_md_context_t archive_hmac_sha1_ctx;
typedef struct hmac_sha1_ctx archive_hmac_sha1_ctx;
#elif defined(HAVE_LIBCRYPTO)
+#include <openssl/opensslv.h>
+#include <openssl/hmac.h>
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+typedef EVP_MAC_CTX *archive_hmac_sha1_ctx;
+
+#else
#include "archive_openssl_hmac_private.h"
typedef HMAC_CTX* archive_hmac_sha1_ctx;
+#endif
#else
diff --git a/Utilities/cmlibarchive/libarchive/archive_platform.h b/Utilities/cmlibarchive/libarchive/archive_platform.h
index f87b423a54..63b255ee9d 100644
--- a/Utilities/cmlibarchive/libarchive/archive_platform.h
+++ b/Utilities/cmlibarchive/libarchive/archive_platform.h
@@ -188,8 +188,9 @@
/*
* glibc 2.24 deprecates readdir_r
+ * bionic c deprecates readdir_r too
*/
-#if defined(HAVE_READDIR_R) && (!defined(__GLIBC__) || !defined(__GLIBC_MINOR__) || __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 24))
+#if defined(HAVE_READDIR_R) && (!defined(__GLIBC__) || !defined(__GLIBC_MINOR__) || __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 24)) && (!defined(__ANDROID__))
#define USE_READDIR_R 1
#else
#undef USE_READDIR_R
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c b/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c
index d0e1f35c82..5a94ec5d43 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk_posix.c
@@ -34,9 +34,6 @@ __FBSDID("$FreeBSD$");
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
-#ifdef HAVE_SYS_MOUNT_H
-#include <sys/mount.h>
-#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
@@ -54,6 +51,8 @@ __FBSDID("$FreeBSD$");
#endif
#ifdef HAVE_LINUX_FS_H
#include <linux/fs.h>
+#elif HAVE_SYS_MOUNT_H
+#include <sys/mount.h>
#endif
/*
* Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h.
@@ -109,6 +108,11 @@ __FBSDID("$FreeBSD$");
#define O_CLOEXEC 0
#endif
+#if defined(__hpux) && !defined(HAVE_DIRFD)
+#define dirfd(x) ((x)->__dd_fd)
+#define HAVE_DIRFD
+#endif
+
/*-
* This is a new directory-walking system that addresses a number
* of problems I've had with fts(3). In particular, it has no
@@ -2098,6 +2102,8 @@ tree_push(struct tree *t, const char *path, int filesystem_id,
struct tree_entry *te;
te = calloc(1, sizeof(*te));
+ if (te == NULL)
+ __archive_errx(1, "Out of memory");
te->next = t->stack;
te->parent = t->current;
if (te->parent)
@@ -2428,7 +2434,7 @@ tree_dir_next_posix(struct tree *t)
#else /* HAVE_FDOPENDIR */
if (tree_enter_working_dir(t) == 0) {
t->d = opendir(".");
-#if HAVE_DIRFD || defined(dirfd)
+#ifdef HAVE_DIRFD
__archive_ensure_cloexec_flag(dirfd(t->d));
#endif
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c b/Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c
index ea32e2aac0..f9d139557e 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_disk_windows.c
@@ -418,8 +418,9 @@ la_linkname_from_pathw(const wchar_t *path, wchar_t **outbuf, int *linktype)
FILE_FLAG_OPEN_REPARSE_POINT;
int ret;
- h = CreateFileW(path, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, flag,
- NULL);
+ h = CreateFileW(path, 0,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
+ OPEN_EXISTING, flag, NULL);
if (h == INVALID_HANDLE_VALUE) {
la_dosmaperr(GetLastError());
return (-1);
@@ -1073,7 +1074,9 @@ next_entry(struct archive_read_disk *a, struct tree *t,
else
flags |= FILE_FLAG_SEQUENTIAL_SCAN;
t->entry_fh = CreateFileW(tree_current_access_path(t),
- GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, flags, NULL);
+ GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL, OPEN_EXISTING, flags, NULL);
if (t->entry_fh == INVALID_HANDLE_VALUE) {
la_dosmaperr(GetLastError());
archive_set_error(&a->archive, errno,
@@ -2046,7 +2049,8 @@ tree_current_file_information(struct tree *t, BY_HANDLE_FILE_INFORMATION *st,
if (sim_lstat && tree_current_is_physical_link(t))
flag |= FILE_FLAG_OPEN_REPARSE_POINT;
- h = CreateFileW(tree_current_access_path(t), 0, FILE_SHARE_READ, NULL,
+ h = CreateFileW(tree_current_access_path(t), 0,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
OPEN_EXISTING, flag, NULL);
if (h == INVALID_HANDLE_VALUE) {
la_dosmaperr(GetLastError());
@@ -2275,7 +2279,8 @@ archive_read_disk_entry_from_file(struct archive *_a,
} else
desiredAccess = GENERIC_READ;
- h = CreateFileW(path, desiredAccess, FILE_SHARE_READ, NULL,
+ h = CreateFileW(path, desiredAccess,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
OPEN_EXISTING, flag, NULL);
if (h == INVALID_HANDLE_VALUE) {
la_dosmaperr(GetLastError());
@@ -2337,7 +2342,8 @@ archive_read_disk_entry_from_file(struct archive *_a,
if (fd >= 0) {
h = (HANDLE)_get_osfhandle(fd);
} else {
- h = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL,
+ h = CreateFileW(path, GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (h == INVALID_HANDLE_VALUE) {
la_dosmaperr(GetLastError());
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c
index ae0b08003f..1e99542d7b 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lz4.c
@@ -450,7 +450,9 @@ lz4_filter_read_descriptor(struct archive_read_filter *self)
chsum = (chsum >> 8) & 0xff;
chsum_verifier = read_buf[descriptor_bytes-1] & 0xff;
if (chsum != chsum_verifier)
+#ifndef DONT_FAIL_ON_CRC_ERROR
goto malformed_error;
+#endif
__archive_read_filter_consume(self->upstream, descriptor_bytes);
@@ -521,7 +523,9 @@ lz4_filter_read_data_block(struct archive_read_filter *self, const void **p)
unsigned int chsum_block =
archive_le32dec(read_buf + 4 + compressed_size);
if (chsum != chsum_block)
+#ifndef DONT_FAIL_ON_CRC_ERROR
goto malformed_error;
+#endif
}
@@ -652,10 +656,12 @@ lz4_filter_read_default_stream(struct archive_read_filter *self, const void **p)
state->xxh32_state);
state->xxh32_state = NULL;
if (checksum != checksum_stream) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
archive_set_error(&self->archive->archive,
ARCHIVE_ERRNO_MISC,
"lz4 stream checksum error");
return (ARCHIVE_FATAL);
+#endif
}
} else if (ret > 0)
__archive_xxhash.XXH32_update(state->xxh32_state,
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lzop.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lzop.c
index 42e2636dfc..cc1572f9d0 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lzop.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_lzop.c
@@ -283,7 +283,9 @@ consume_header(struct archive_read_filter *self)
else
checksum = adler32(adler32(0, NULL, 0), p, len);
if (archive_be32dec(p + len) != checksum)
+#ifndef DONT_FAIL_ON_CRC_ERROR
goto corrupted;
+#endif
__archive_read_filter_consume(self->upstream, len + 4);
if (flags & EXTRA_FIELD) {
/* Skip extra field */
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_xz.c b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_xz.c
index b978eb034e..90b0da2338 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_filter_xz.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_filter_xz.c
@@ -612,9 +612,11 @@ lzip_tail(struct archive_read_filter *self)
/* Check the crc32 value of the uncompressed data of the current
* member */
if (state->crc32 != archive_le32dec(f)) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
archive_set_error(&self->archive->archive, ARCHIVE_ERRNO_MISC,
"Lzip: CRC32 error");
return (ARCHIVE_FAILED);
+#endif
}
/* Check the uncompressed size of the current member */
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c
index 7d7e70243f..722edf1dbf 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_7zip.c
@@ -287,6 +287,7 @@ struct _7zip {
const unsigned char *next_in;
int64_t avail_in;
int64_t total_in;
+ int64_t stream_in;
unsigned char *next_out;
int64_t avail_out;
int64_t total_out;
@@ -775,7 +776,7 @@ archive_read_format_7zip_read_header(struct archive_read *a,
}
/* Set up a more descriptive format name. */
- sprintf(zip->format_name, "7-Zip");
+ snprintf(zip->format_name, sizeof(zip->format_name), "7-Zip");
a->archive.archive_format_name = zip->format_name;
return (ret);
@@ -986,15 +987,30 @@ ppmd_read(void *p)
struct _7zip *zip = (struct _7zip *)(a->format->data);
Byte b;
- if (zip->ppstream.avail_in == 0) {
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
- "Truncated RAR file data");
- zip->ppstream.overconsumed = 1;
- return (0);
+ if (zip->ppstream.avail_in <= 0) {
+ /*
+ * Ppmd7_DecodeSymbol might require reading multiple bytes
+ * and we are on boundary;
+ * last resort to read using __archive_read_ahead.
+ */
+ ssize_t bytes_avail = 0;
+ const uint8_t* data = __archive_read_ahead(a,
+ zip->ppstream.stream_in+1, &bytes_avail);
+ if(bytes_avail < zip->ppstream.stream_in+1) {
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_FILE_FORMAT,
+ "Truncated 7z file data");
+ zip->ppstream.overconsumed = 1;
+ return (0);
+ }
+ zip->ppstream.next_in++;
+ b = data[zip->ppstream.stream_in];
+ } else {
+ b = *zip->ppstream.next_in++;
}
- b = *zip->ppstream.next_in++;
zip->ppstream.avail_in--;
zip->ppstream.total_in++;
+ zip->ppstream.stream_in++;
return (b);
}
@@ -1485,6 +1501,7 @@ decompress(struct archive_read *a, struct _7zip *zip,
}
zip->ppstream.next_in = t_next_in;
zip->ppstream.avail_in = t_avail_in;
+ zip->ppstream.stream_in = 0;
zip->ppstream.next_out = t_next_out;
zip->ppstream.avail_out = t_avail_out;
if (zip->ppmd7_stat == 0) {
@@ -2840,8 +2857,10 @@ slurp_central_directory(struct archive_read *a, struct _7zip *zip,
/* CRC check. */
if (crc32(0, (const unsigned char *)p + 12, 20)
!= archive_le32dec(p + 8)) {
+#ifdef DONT_FAIL_ON_CRC_ERROR
archive_set_error(&a->archive, -1, "Header CRC error");
return (ARCHIVE_FATAL);
+#endif
}
next_header_offset = archive_le64dec(p + 12);
@@ -2891,8 +2910,10 @@ slurp_central_directory(struct archive_read *a, struct _7zip *zip,
/* Check the EncodedHeader CRC.*/
if (r == 0 && zip->header_crc32 != next_header_crc) {
archive_set_error(&a->archive, -1,
+#ifndef DONT_FAIL_ON_CRC_ERROR
"Damaged 7-Zip archive");
r = -1;
+#endif
}
if (r == 0) {
if (zip->si.ci.folders[0].digest_defined)
@@ -2943,9 +2964,11 @@ slurp_central_directory(struct archive_read *a, struct _7zip *zip,
/* Check the Header CRC.*/
if (check_header_crc && zip->header_crc32 != next_header_crc) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
archive_set_error(&a->archive, -1,
"Malformed 7-Zip archive");
return (ARCHIVE_FATAL);
+#endif
}
break;
default:
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c
index 874237844f..6fcfbfcd30 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_cab.c
@@ -996,7 +996,7 @@ archive_read_format_cab_read_header(struct archive_read *a,
cab->end_of_entry_cleanup = cab->end_of_entry = 1;
/* Set up a more descriptive format name. */
- sprintf(cab->format_name, "CAB %d.%d (%s)",
+ snprintf(cab->format_name, sizeof(cab->format_name), "CAB %d.%d (%s)",
hd->major, hd->minor, cab->entry_cffolder->compname);
a->archive.archive_format_name = cab->format_name;
@@ -1134,7 +1134,7 @@ cab_checksum_update(struct archive_read *a, size_t bytes)
}
if (sumbytes) {
int odd = sumbytes & 3;
- if (sumbytes - odd > 0)
+ if ((int)(sumbytes - odd) > 0)
cfdata->sum_calculated = cab_checksum_cfdata_4(
p, sumbytes - odd, cfdata->sum_calculated);
if (odd)
@@ -1171,12 +1171,14 @@ cab_checksum_finish(struct archive_read *a)
cfdata->sum_calculated = cab_checksum_cfdata(
cfdata->memimage + CFDATA_cbData, l, cfdata->sum_calculated);
if (cfdata->sum_calculated != cfdata->sum) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Checksum error CFDATA[%d] %" PRIx32 ":%" PRIx32 " in %d bytes",
cab->entry_cffolder->cfdata_index -1,
cfdata->sum, cfdata->sum_calculated,
cfdata->compressed_size);
return (ARCHIVE_FAILED);
+#endif
}
return (ARCHIVE_OK);
}
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c
index 912116675f..380cbb8b42 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_iso9660.c
@@ -1007,7 +1007,8 @@ read_children(struct archive_read *a, struct file_info *parent)
p = b;
b += iso9660->logical_block_size;
step -= iso9660->logical_block_size;
- for (; *p != 0 && p < b && p + *p <= b; p += *p) {
+ for (; *p != 0 && p + DR_name_offset < b && p + *p <= b;
+ p += *p) {
struct file_info *child;
/* N.B.: these special directory identifiers
@@ -1756,7 +1757,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
size_t name_len;
const unsigned char *rr_start, *rr_end;
const unsigned char *p;
- size_t dr_len;
+ size_t dr_len = 0;
uint64_t fsize, offset;
int32_t location;
int flags;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c
index 1357f9aabf..8b7bf663ba 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_lha.c
@@ -739,7 +739,7 @@ archive_read_format_lha_read_header(struct archive_read *a,
if (lha->directory || lha->compsize == 0)
lha->end_of_entry = 1;
- sprintf(lha->format_name, "lha -%c%c%c-",
+ snprintf(lha->format_name, sizeof(lha->format_name), "lha -%c%c%c-",
lha->method[0], lha->method[1], lha->method[2]);
a->archive.archive_format_name = lha->format_name;
@@ -1039,9 +1039,11 @@ lha_read_file_header_2(struct archive_read *a, struct lha *lha)
}
if (header_crc != lha->header_crc) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"LHa header CRC error");
return (ARCHIVE_FATAL);
+#endif
}
return (err);
}
@@ -1107,9 +1109,11 @@ lha_read_file_header_3(struct archive_read *a, struct lha *lha)
return (err);
if (header_crc != lha->header_crc) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"LHa header CRC error");
return (ARCHIVE_FATAL);
+#endif
}
return (err);
invalid:
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c
index 88bca76fb9..2bc3ba066c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_mtree.c
@@ -692,7 +692,7 @@ detect_form(struct archive_read *a, int *is_form_d)
{
const char *p;
ssize_t avail, ravail;
- ssize_t detected_bytes = 0, len, nl;
+ ssize_t len, nl;
int entry_cnt = 0, multiline = 0;
int form_D = 0;/* The archive is generated by `NetBSD mtree -D'
* (In this source we call it `form D') . */
@@ -728,8 +728,6 @@ detect_form(struct archive_read *a, int *is_form_d)
* character of previous line was '\' character. */
if (bid_keyword_list(p, len, 0, 0) <= 0)
break;
- if (multiline == 1)
- detected_bytes += len;
if (p[len-nl-1] != '\\') {
if (multiline == 1 &&
++entry_cnt >= MAX_BID_ENTRY)
@@ -745,7 +743,6 @@ detect_form(struct archive_read *a, int *is_form_d)
keywords = bid_entry(p, len, nl, &last_is_path);
if (keywords >= 0) {
- detected_bytes += len;
if (form_D == 0) {
if (last_is_path)
form_D = 1;
@@ -997,9 +994,11 @@ process_add_entry(struct archive_read *a, struct mtree *mtree,
struct mtree_entry *alt;
alt = (struct mtree_entry *)__archive_rb_tree_find_node(
&mtree->rbtree, entry->name);
- while (alt->next_dup)
- alt = alt->next_dup;
- alt->next_dup = entry;
+ if (alt != NULL) {
+ while (alt->next_dup)
+ alt = alt->next_dup;
+ alt->next_dup = entry;
+ }
}
}
@@ -1074,7 +1073,7 @@ read_mtree(struct archive_read *a, struct mtree *mtree)
continue;
/* Non-printable characters are not allowed */
for (s = p;s < p + len - 1; s++) {
- if (!isprint((unsigned char)*s)) {
+ if (!isprint((unsigned char)*s) && *s != '\t') {
r = ARCHIVE_FATAL;
break;
}
@@ -1253,9 +1252,17 @@ parse_file(struct archive_read *a, struct archive_entry *entry,
archive_entry_filetype(entry) == AE_IFDIR) {
mtree->fd = open(path, O_RDONLY | O_BINARY | O_CLOEXEC);
__archive_ensure_cloexec_flag(mtree->fd);
- if (mtree->fd == -1 &&
- (errno != ENOENT ||
- archive_strlen(&mtree->contents_name) > 0)) {
+ if (mtree->fd == -1 && (
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ /*
+ * On Windows, attempting to open a file with an
+ * invalid name result in EINVAL (Error 22)
+ */
+ (errno != ENOENT && errno != EINVAL)
+#else
+ errno != ENOENT
+#endif
+ || archive_strlen(&mtree->contents_name) > 0)) {
archive_set_error(&a->archive, errno,
"Can't open %s", path);
r = ARCHIVE_WARN;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c
index 5c02a25cbb..1c9a057b60 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar.c
@@ -430,7 +430,7 @@ static int new_node(struct huffman_code *);
static int make_table(struct archive_read *, struct huffman_code *);
static int make_table_recurse(struct archive_read *, struct huffman_code *, int,
struct huffman_table_entry *, int, int);
-static int64_t expand(struct archive_read *, int64_t);
+static int expand(struct archive_read *, int64_t *);
static int copy_from_lzss_window_to_unp(struct archive_read *, const void **,
int64_t, int);
static const void *rar_read_ahead(struct archive_read *, size_t, ssize_t *);
@@ -1007,9 +1007,11 @@ archive_read_format_rar_read_header(struct archive_read *a,
crc32_val = crc32(0, (const unsigned char *)p + 2, (unsigned)skip - 2);
if ((crc32_val & 0xffff) != archive_le16dec(p)) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Header CRC error");
return (ARCHIVE_FATAL);
+#endif
}
__archive_read_consume(a, skip);
break;
@@ -1065,9 +1067,11 @@ archive_read_format_rar_read_header(struct archive_read *a,
skip -= to_read;
}
if ((crc32_val & 0xffff) != crc32_expected) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Header CRC error");
return (ARCHIVE_FATAL);
+#endif
}
if (head_type == ENDARC_HEAD)
return (ARCHIVE_EOF);
@@ -1432,9 +1436,11 @@ read_header(struct archive_read *a, struct archive_entry *entry,
/* File Header CRC check. */
crc32_val = crc32(crc32_val, h, (unsigned)(header_size - 7));
if ((crc32_val & 0xffff) != archive_le16dec(rar_header.crc)) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Header CRC error");
return (ARCHIVE_FATAL);
+#endif
}
/* If no CRC error, Go on parsing File Header. */
p = h;
@@ -1952,9 +1958,11 @@ read_data_stored(struct archive_read *a, const void **buff, size_t *size,
*size = 0;
*offset = rar->offset;
if (rar->file_crc != rar->crc_calculated) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"File CRC error");
return (ARCHIVE_FATAL);
+#endif
}
rar->entry_eof = 1;
return (ARCHIVE_EOF);
@@ -1988,7 +1996,7 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
return (ARCHIVE_FATAL);
struct rar *rar;
- int64_t start, end, actualend;
+ int64_t start, end;
size_t bs;
int ret = (ARCHIVE_OK), sym, code, lzss_offset, length, i;
@@ -2045,9 +2053,11 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
*size = 0;
*offset = rar->offset;
if (rar->file_crc != rar->crc_calculated) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"File CRC error");
return (ARCHIVE_FATAL);
+#endif
}
rar->entry_eof = 1;
return (ARCHIVE_EOF);
@@ -2179,11 +2189,12 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
end = rar->filters.filterstart;
}
- if ((actualend = expand(a, end)) < 0)
- return ((int)actualend);
+ ret = expand(a, &end);
+ if (ret != ARCHIVE_OK)
+ return (ret);
- rar->bytes_uncopied = actualend - start;
- rar->filters.lastend = actualend;
+ rar->bytes_uncopied = end - start;
+ rar->filters.lastend = end;
if (rar->filters.lastend != rar->filters.filterstart && rar->bytes_uncopied == 0) {
/* Broken RAR files cause this case.
* NOTE: If this case were possible on a normal RAR file
@@ -2825,8 +2836,8 @@ make_table_recurse(struct archive_read *a, struct huffman_code *code, int node,
return ret;
}
-static int64_t
-expand(struct archive_read *a, int64_t end)
+static int
+expand(struct archive_read *a, int64_t *end)
{
static const unsigned char lengthbases[] =
{ 0, 1, 2, 3, 4, 5, 6,
@@ -2873,16 +2884,19 @@ expand(struct archive_read *a, int64_t end)
struct rar *rar = (struct rar *)(a->format->data);
struct rar_br *br = &(rar->br);
- if (rar->filters.filterstart < end)
- end = rar->filters.filterstart;
+ if (rar->filters.filterstart < *end)
+ *end = rar->filters.filterstart;
while (1)
{
- if(lzss_position(&rar->lzss) >= end)
- return end;
+ if(lzss_position(&rar->lzss) >= *end) {
+ return (ARCHIVE_OK);
+ }
- if(rar->is_ppmd_block)
- return lzss_position(&rar->lzss);
+ if(rar->is_ppmd_block) {
+ *end = lzss_position(&rar->lzss);
+ return (ARCHIVE_OK);
+ }
if ((symbol = read_next_symbol(a, &rar->maincode)) < 0)
return (ARCHIVE_FATAL);
@@ -2906,7 +2920,8 @@ expand(struct archive_read *a, int64_t end)
goto truncated_data;
rar->start_new_table = rar_br_bits(br, 1);
rar_br_consume(br, 1);
- return lzss_position(&rar->lzss);
+ *end = lzss_position(&rar->lzss);
+ return (ARCHIVE_OK);
}
else
{
@@ -2917,7 +2932,7 @@ expand(struct archive_read *a, int64_t end)
}
else if(symbol==257)
{
- if (!read_filter(a, &end))
+ if (!read_filter(a, end))
return (ARCHIVE_FATAL);
continue;
}
@@ -3323,14 +3338,43 @@ run_filters(struct archive_read *a)
struct rar *rar = (struct rar *)(a->format->data);
struct rar_filters *filters = &rar->filters;
struct rar_filter *filter = filters->stack;
- size_t start = filters->filterstart;
- size_t end = start + filter->blocklength;
+ struct rar_filter *f;
+ size_t start, end;
+ int64_t tend;
uint32_t lastfilteraddress;
uint32_t lastfilterlength;
int ret;
+ if (filters == NULL || filter == NULL)
+ return (0);
+
+ start = filters->filterstart;
+ end = start + filter->blocklength;
+
filters->filterstart = INT64_MAX;
- end = (size_t)expand(a, end);
+ tend = (int64_t)end;
+ ret = expand(a, &tend);
+ if (ret != ARCHIVE_OK)
+ return 0;
+
+ /* Check if filter stack was modified in expand() */
+ ret = ARCHIVE_FATAL;
+ f = filters->stack;
+ while (f)
+ {
+ if (f == filter)
+ {
+ ret = ARCHIVE_OK;
+ break;
+ }
+ f = f->next;
+ }
+ if (ret != ARCHIVE_OK)
+ return 0;
+
+ if (tend < 0)
+ return 0;
+ end = (size_t)tend;
if (end != start + filter->blocklength)
return 0;
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c
index 8850c93e9e..548da4e6a9 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_rar5.c
@@ -2821,11 +2821,13 @@ static int parse_block_header(struct archive_read* a, const uint8_t* p,
^ (uint8_t) (*block_size >> 16);
if(calculated_cksum != hdr->block_cksum) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Block checksum error: got 0x%x, expected 0x%x",
hdr->block_cksum, calculated_cksum);
return ARCHIVE_FATAL;
+#endif
}
return ARCHIVE_OK;
@@ -3911,6 +3913,13 @@ static int do_unpack(struct archive_read* a, struct rar5* rar,
case GOOD:
/* fallthrough */
case BEST:
+ /* No data is returned here. But because a sparse-file aware
+ * caller (like archive_read_data_into_fd) may treat zero-size
+ * as a sparse file block, we need to update the offset
+ * accordingly. At this point the decoder doesn't have any
+ * pending uncompressed data blocks, so the current position in
+ * the output file should be last_write_ptr. */
+ if (offset) *offset = rar->cstate.last_write_ptr;
return uncompress_file(a);
default:
archive_set_error(&a->archive,
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c
index bfdad7f873..93c3fd5857 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_tar.c
@@ -407,14 +407,13 @@ archive_read_format_tar_bid(struct archive_read *a, int best_bid)
/*
* Check format of mode/uid/gid/mtime/size/rdevmajor/rdevminor fields.
*/
- if (bid > 0 && (
- validate_number_field(header->mode, sizeof(header->mode)) == 0
+ if (validate_number_field(header->mode, sizeof(header->mode)) == 0
|| validate_number_field(header->uid, sizeof(header->uid)) == 0
|| validate_number_field(header->gid, sizeof(header->gid)) == 0
|| validate_number_field(header->mtime, sizeof(header->mtime)) == 0
|| validate_number_field(header->size, sizeof(header->size)) == 0
|| validate_number_field(header->rdevmajor, sizeof(header->rdevmajor)) == 0
- || validate_number_field(header->rdevminor, sizeof(header->rdevminor)) == 0)) {
+ || validate_number_field(header->rdevminor, sizeof(header->rdevminor)) == 0) {
bid = 0;
}
@@ -2108,6 +2107,21 @@ pax_attribute(struct archive_read *a, struct tar *tar,
/* "size" is the size of the data in the entry. */
tar->entry_bytes_remaining
= tar_atol10(value, strlen(value));
+ if (tar->entry_bytes_remaining < 0) {
+ tar->entry_bytes_remaining = 0;
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Tar size attribute is negative");
+ return (ARCHIVE_FATAL);
+ }
+ if (tar->entry_bytes_remaining == INT64_MAX) {
+ /* Note: tar_atol returns INT64_MAX on overflow */
+ tar->entry_bytes_remaining = 0;
+ archive_set_error(&a->archive,
+ ARCHIVE_ERRNO_MISC,
+ "Tar size attribute overflow");
+ return (ARCHIVE_FATAL);
+ }
/*
* The "size" pax header keyword always overrides the
* "size" field in the tar header.
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c
index 2e60cf7213..330df5879a 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_xar.c
@@ -624,7 +624,9 @@ read_toc(struct archive_read *a)
__archive_read_consume(a, xar->toc_chksum_size);
xar->offset += xar->toc_chksum_size;
if (r != ARCHIVE_OK)
+#ifndef DONT_FAIL_ON_CRC_ERROR
return (ARCHIVE_FATAL);
+#endif
}
/*
@@ -827,10 +829,12 @@ xar_read_header(struct archive_read *a, struct archive_entry *entry)
xattr->a_sum.val, xattr->a_sum.len,
xattr->e_sum.val, xattr->e_sum.len);
if (r != ARCHIVE_OK) {
+#ifndef DONT_FAIL_ON_CRC_ERROR
archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
"Xattr checksum error");
r = ARCHIVE_WARN;
break;
+#endif
}
if (xattr->name.s == NULL) {
archive_set_error(&(a->archive), ARCHIVE_ERRNO_MISC,
diff --git a/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c b/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
index 8ad73b6cc5..e126ae38fa 100644
--- a/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
+++ b/Utilities/cmlibarchive/libarchive/archive_read_support_format_zip.c
@@ -1667,7 +1667,7 @@ zipx_lzma_alone_init(struct archive_read *a, struct zip *zip)
*/
/* Read magic1,magic2,lzma_params from the ZIPX stream. */
- if((p = __archive_read_ahead(a, 9, NULL)) == NULL) {
+ if(zip->entry_bytes_remaining < 9 || (p = __archive_read_ahead(a, 9, NULL)) == NULL) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Truncated lzma data");
return (ARCHIVE_FATAL);
diff --git a/Utilities/cmlibarchive/libarchive/archive_string.c b/Utilities/cmlibarchive/libarchive/archive_string.c
index d7f2c46b28..69458e1a12 100644
--- a/Utilities/cmlibarchive/libarchive/archive_string.c
+++ b/Utilities/cmlibarchive/libarchive/archive_string.c
@@ -3988,10 +3988,10 @@ int
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 */
+ int ret = 0;
#if defined(_WIN32) && !defined(__CYGWIN__)
+ int r;
+
/*
* Internationalization programming on Windows must use Wide
* characters because Windows platform cannot make locale UTF-8.
diff --git a/Utilities/cmlibarchive/libarchive/archive_write.c b/Utilities/cmlibarchive/libarchive/archive_write.c
index 66592e8268..27626b5414 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write.c
@@ -201,6 +201,10 @@ __archive_write_allocate_filter(struct archive *_a)
struct archive_write_filter *f;
f = calloc(1, sizeof(*f));
+
+ if (f == NULL)
+ return (NULL);
+
f->archive = _a;
f->state = ARCHIVE_WRITE_FILTER_STATE_NEW;
if (a->filter_first == NULL)
@@ -548,6 +552,10 @@ archive_write_open2(struct archive *_a, void *client_data,
a->client_data = client_data;
client_filter = __archive_write_allocate_filter(_a);
+
+ if (client_filter == NULL)
+ return (ARCHIVE_FATAL);
+
client_filter->open = archive_write_client_open;
client_filter->write = archive_write_client_write;
client_filter->close = archive_write_client_close;
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c b/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c
index b6d3d0ae01..bd5180e763 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c
@@ -1996,6 +1996,8 @@ archive_write_disk_new(void)
free(a);
return (NULL);
}
+ a->path_safe.s[0] = 0;
+
#ifdef HAVE_ZLIB_H
a->decmpfs_compression_level = 5;
#endif
@@ -2793,7 +2795,7 @@ check_symlinks_fsobj(char *path, int *a_eno, struct archive_string *a_estr,
char *tail;
char *head;
int last;
- char c;
+ char c = '\0';
int r;
struct stat st;
int chdir_fd;
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c b/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
index 1b12a299ca..88df3ce020 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_disk_windows.c
@@ -1370,6 +1370,7 @@ archive_write_disk_new(void)
free(a);
return (NULL);
}
+ a->path_safe.s[0] = 0;
return (&a->archive);
}
@@ -2154,6 +2155,8 @@ check_symlinks(struct archive_write_disk *a)
return (ARCHIVE_FAILED);
}
}
+ if (!c)
+ break;
pn[0] = c;
pn++;
}
@@ -2258,6 +2261,9 @@ cleanup_pathname(struct archive_write_disk *a, wchar_t *name)
return (ARCHIVE_FAILED);
} else
p += 4;
+ /* Network drive path like "\\<server-name>\<share-name>\file" */
+ } else if (p[0] == L'\\' && p[1] == L'\\') {
+ p += 2;
}
/* Skip leading drive letter from archives created
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_open.3 b/Utilities/cmlibarchive/libarchive/archive_write_open.3
index 29bffe49eb..6bceb964f5 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_open.3
+++ b/Utilities/cmlibarchive/libarchive/archive_write_open.3
@@ -218,6 +218,7 @@ 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
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c
index 52911491f6..cf1f4770eb 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_pax.c
@@ -1717,7 +1717,7 @@ build_pax_attribute_name(char *dest, const char *src)
* to having clients override it.
*/
#if HAVE_GETPID && 0 /* Disable this for now; see above comment. */
- sprintf(buff, "PaxHeader.%d", getpid());
+ snprintf(buff, sizeof(buff), "PaxHeader.%d", getpid());
#else
/* If the platform can't fetch the pid, don't include it. */
strcpy(buff, "PaxHeader");
diff --git a/Utilities/cmlibarchive/libarchive/cpio.5 b/Utilities/cmlibarchive/libarchive/cpio.5
index 837a45692e..c71018b199 100644
--- a/Utilities/cmlibarchive/libarchive/cpio.5
+++ b/Utilities/cmlibarchive/libarchive/cpio.5
@@ -354,7 +354,7 @@ while working in AT&T's Unix Support Group.
It appeared in 1977 as part of PWB/UNIX 1.0, the
.Dq Programmer's Work Bench
derived from
-.At 6th Edition UNIX
+.At v6
that was used internally at AT&T.
Both the new binary and old character formats were in use
by 1980, according to the System III source released
diff --git a/Utilities/cmlibarchive/libarchive/filter_fork_posix.c b/Utilities/cmlibarchive/libarchive/filter_fork_posix.c
index ac255c4f8b..62085a7099 100644
--- a/Utilities/cmlibarchive/libarchive/filter_fork_posix.c
+++ b/Utilities/cmlibarchive/libarchive/filter_fork_posix.c
@@ -76,7 +76,7 @@ int
__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout,
pid_t *out_child)
{
- pid_t child;
+ pid_t child = -1;
int stdin_pipe[2], stdout_pipe[2], tmp;
#if HAVE_POSIX_SPAWNP
posix_spawn_file_actions_t actions;